Compare commits

...

33 Commits

Author SHA1 Message Date
dependabot[bot]
4e094eaa55 Bump webpack-dev-server from 5.2.0 to 5.2.1 in /wasm/demo (#5801)
Bumps [webpack-dev-server](https://github.com/webpack/webpack-dev-server) from 5.2.0 to 5.2.1.
- [Release notes](https://github.com/webpack/webpack-dev-server/releases)
- [Changelog](https://github.com/webpack/webpack-dev-server/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack/webpack-dev-server/compare/v5.2.0...v5.2.1)

---
updated-dependencies:
- dependency-name: webpack-dev-server
  dependency-version: 5.2.1
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-06 23:17:32 +09:00
Jeong, YunWon
2e368baf2a Fix Nightly clippy (#5798) 2025-06-06 22:00:07 +09:00
Aneesh Durg
323ea3b96b Support incomplete parsing (#5764)
* continue accepting REPL input for multiline strings

* Match cpython behavior for all multi-line statements (execute when complete)

* Emit _IncompleteInputError when compiling with incomplete flag

* Refine when _IncompleteInputError is emitted

* Support multiline strings emitting _IncompleteInputError

* lint

* Undo accidental change to PyTabError

* match -> if let

* Fix test_baseexception and test_codeop

* fix spelling

* fix exception name

* Skip pickle test of _IncompleteInputError

* Use py3.15's codeop implementation

* Update Lib/test/test_baseexception.py

---------

Co-authored-by: Jeong, YunWon <69878+youknowone@users.noreply.github.com>
2025-06-05 14:41:56 +09:00
Noa
e27d03179f Remove getrandom 0.2 from dependencies 2025-05-21 12:12:14 +09:00
Jeong YunWon
81a9002ef2 Rename Dockerfile 2025-05-20 11:10:13 +09:00
Noa
18521290bf Update dependencies 2025-05-19 14:41:24 +09:00
Noa
5e682e3f17 Merge pull request #5788 from coolreader18/fix-prec
Fix panic with high precision
2025-05-16 20:28:25 -05:00
Noa
163296d306 Fix test_memoryio 2025-05-16 15:20:10 -05:00
Noa
1ae98ee177 Fix panic with high precision 2025-05-16 14:17:25 -05:00
Noa
2c02e2776b Fix warnings for rust 1.87 2025-05-16 18:52:14 +09:00
Ashwin Naren
72dc4954ad dev container update 2025-05-16 18:25:08 +09:00
Rex Ledesma
b696e56c5f chore: rely on the default inclusions for ruff 2025-05-15 19:15:51 +09:00
dependabot[bot]
d11d5c65e6 Bump streetsidesoftware/cspell-action in the github-actions group
Bumps the github-actions group with 1 update: [streetsidesoftware/cspell-action](https://github.com/streetsidesoftware/cspell-action).


Updates `streetsidesoftware/cspell-action` from 6 to 7
- [Release notes](https://github.com/streetsidesoftware/cspell-action/releases)
- [Changelog](https://github.com/streetsidesoftware/cspell-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/streetsidesoftware/cspell-action/compare/v6...v7)

---
updated-dependencies:
- dependency-name: streetsidesoftware/cspell-action
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-13 04:08:12 +09:00
Ashwin Naren
5c0f70c361 add instructions 2025-05-12 14:24:10 +09:00
Rex Ledesma
4e2e0b41c6 chore: add ruff format --check (#5774)
* chore: add `ruff format --check`

* fix tests
2025-05-12 14:20:01 +09:00
Ashwin Naren
df380bca96 lzma FORMAT_ALONE implementation (#5777)
* implement init_alone

* error if format is raw and there is a memlimit
2025-05-09 13:26:28 +09:00
Ashwin Naren
9bd7f1810b Update README.md
Co-authored-by: Jeong, YunWon <69878+youknowone@users.noreply.github.com>
2025-05-08 14:59:46 +09:00
Ashwin Naren
31e6cca916 Update README.md 2025-05-08 14:59:46 +09:00
Rex Ledesma
b8095b84ff chore: allow uv run python -I ./whats_left.py 2025-05-08 14:51:52 +09:00
Rex Ledesma
908386091b feat: implement zlib.__version__ 2025-05-08 14:48:11 +09:00
Rex Ledesma
aee4c7ac69 chore: migrate settings to ruff.toml (#5773) 2025-05-08 14:46:57 +09:00
Rex Ledesma
dc75d203ff chore: upgrade to ruff==0.11.8 2025-05-08 14:11:43 +09:00
Jeong, YunWon
ce5524d72a Merge pull request #5769 from youknowone/radium-patch 2025-05-08 13:42:38 +09:00
Jeong YunWon
06c4b151d6 Add radium patch to fix CI 2025-05-07 18:21:36 +09:00
Jeong, YunWon
79646fd222 Merge pull request #5717 from arihant2math/lzma
lzma implementation
2025-05-07 18:00:06 +09:00
Jeong YunWon
d9c18c5593 flatten compression modules 2025-05-07 15:42:31 +09:00
Jeong YunWon
acae154f1b more diff-friendly disabling xz 2025-05-07 15:01:23 +09:00
Ashwin Naren
a5016446f4 _lzma implementation and test marking
Signed-off-by: Ashwin Naren <arihant2math@gmail.com>
2025-05-07 15:01:23 +09:00
Ashwin Naren
2042d877f9 add lzma.py and test_lzma.py at 3.13.2
Signed-off-by: Ashwin Naren <arihant2math@gmail.com>
2025-05-07 15:01:23 +09:00
Ashwin Naren
2a1ea45659 add _lzma module with new dependency
Signed-off-by: Ashwin Naren <arihant2math@gmail.com>
2025-05-07 15:01:23 +09:00
Jeong YunWon
48b08a2b7f Revert "Split out common compression routines into separate file (#5728)"
This reverts commit 9c88475b31.
2025-05-07 15:01:09 +09:00
Noa
9c88475b31 Split out common compression routines into separate file (#5728) 2025-05-06 15:26:54 +09:00
Undersk0re
6aa80aa596 Update .gitignore, folder fix (#5762) 2025-05-06 14:07:12 +09:00
187 changed files with 8099 additions and 3377 deletions

6
.devcontainer/Dockerfile Normal file
View File

@@ -0,0 +1,6 @@
FROM mcr.microsoft.com/vscode/devcontainers/rust:1-bullseye
# Install clang
RUN apt-get update \
&& apt-get install -y clang \
&& rm -rf /var/lib/apt/lists/*

View File

@@ -1,4 +1,25 @@
{
"image": "mcr.microsoft.com/devcontainers/base:jammy",
"onCreateCommand": "curl https://sh.rustup.rs -sSf | sh -s -- -y"
}
"name": "Rust",
"build": {
"dockerfile": "Dockerfile"
},
"runArgs": ["--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined"],
"customizations": {
"vscode": {
"settings": {
"lldb.executable": "/usr/bin/lldb",
// VS Code don't watch files under ./target
"files.watcherExclude": {
"**/target/**": true
},
"extensions": [
"rust-lang.rust-analyzer",
"tamasfe.even-better-toml",
"vadimcn.vscode-lldb",
"mutantdino.resourcemonitor"
]
}
}
},
"remoteUser": "vscode"
}

View File

@@ -324,11 +324,13 @@ jobs:
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: install ruff
run: python -m pip install ruff==0.0.291 # astral-sh/ruff#7778
run: python -m pip install ruff==0.11.8
- name: Ensure docs generate no warnings
run: cargo doc
- name: run python lint
run: ruff extra_tests wasm examples --exclude='./.*',./Lib,./vm/Lib,./benches/ --select=E9,F63,F7,F82 --show-source
- name: run ruff check
run: ruff check --diff
- name: run ruff format
run: ruff format --check
- name: install prettier
run: yarn global add prettier && echo "$(yarn global bin)" >>$GITHUB_PATH
- name: check wasm code with prettier
@@ -338,7 +340,7 @@ jobs:
- name: install extra dictionaries
run: npm install @cspell/dict-en_us @cspell/dict-cpp @cspell/dict-python @cspell/dict-rust @cspell/dict-win32 @cspell/dict-shell
- name: spell checker
uses: streetsidesoftware/cspell-action@v6
uses: streetsidesoftware/cspell-action@v7
with:
files: '**/*.rs'
incremental_files_only: true

4
.gitignore vendored
View File

@@ -2,11 +2,11 @@
/*/target
**/*.rs.bk
**/*.bytecode
__pycache__
__pycache__/
**/*.pytest_cache
.*sw*
.repl_history.txt
.vscode
.vscode/
wasm-pack.log
.idea/
.envrc

379
Cargo.lock generated
View File

@@ -16,15 +16,15 @@ checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
[[package]]
name = "ahash"
version = "0.8.11"
version = "0.8.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75"
dependencies = [
"cfg-if",
"getrandom 0.2.15",
"getrandom 0.3.2",
"once_cell",
"version_check",
"zerocopy 0.7.35",
"zerocopy",
]
[[package]]
@@ -115,9 +115,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.97"
version = "1.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
[[package]]
name = "approx"
@@ -178,7 +178,7 @@ dependencies = [
"regex",
"rustc-hash",
"shlex",
"syn 2.0.100",
"syn 2.0.101",
]
[[package]]
@@ -213,9 +213,9 @@ dependencies = [
[[package]]
name = "bstr"
version = "1.11.3"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "531a9155a481e2ee699d4f98f43c0ca4ff8ee1bfd55c31e9e98fb29d2b176fe0"
checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4"
dependencies = [
"memchr",
"regex-automata",
@@ -233,9 +233,9 @@ dependencies = [
[[package]]
name = "bytemuck"
version = "1.22.0"
version = "1.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540"
checksum = "9134a6ef01ce4b366b50689c94f82c14bc72bc5d0386829828a2e2752ef7958c"
[[package]]
name = "bzip2"
@@ -283,9 +283,9 @@ dependencies = [
[[package]]
name = "cc"
version = "1.2.18"
version = "1.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "525046617d8376e3db1deffb079e91cef90a89fc3ca5c185bbf8c9ecdd15cd5c"
checksum = "8691782945451c1c383942c4874dbe63814f61cb57ef773cda2972682b7bb3c0"
dependencies = [
"shlex",
]
@@ -313,9 +313,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
[[package]]
name = "chrono"
version = "0.4.40"
version = "0.4.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c"
checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d"
dependencies = [
"android-tzdata",
"iana-time-zone",
@@ -365,18 +365,18 @@ dependencies = [
[[package]]
name = "clap"
version = "4.5.36"
version = "4.5.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2df961d8c8a0d08aa9945718ccf584145eee3f3aa06cddbeac12933781102e04"
checksum = "ed93b9805f8ba930df42c2590f05453d5ec36cbb85d018868a5b24d31f6ac000"
dependencies = [
"clap_builder",
]
[[package]]
name = "clap_builder"
version = "4.5.36"
version = "4.5.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "132dbda40fb6753878316a489d5a1242a8ef2f0d9e47ba01c951ea8aa7d013a5"
checksum = "379026ff283facf611b0ea629334361c4211d1b12ee01024eec1591133b04120"
dependencies = [
"anstyle",
"clap_lex",
@@ -472,9 +472,9 @@ dependencies = [
[[package]]
name = "cranelift"
version = "0.118.0"
version = "0.119.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e482b051275b415cf7627bb6b26e9902ce6aec058b443266c2a1e7a0de148960"
checksum = "6d07c374d4da962eca0833c1d14621d5b4e32e68c8ca185b046a3b6b924ad334"
dependencies = [
"cranelift-codegen",
"cranelift-frontend",
@@ -483,39 +483,42 @@ dependencies = [
[[package]]
name = "cranelift-assembler-x64"
version = "0.118.0"
version = "0.119.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e4b56ebe316895d3fa37775d0a87b0c889cc933f5c8b253dbcc7c7bcb7fe7e4"
checksum = "263cc79b8a23c29720eb596d251698f604546b48c34d0d84f8fd2761e5bf8888"
dependencies = [
"cranelift-assembler-x64-meta",
]
[[package]]
name = "cranelift-assembler-x64-meta"
version = "0.118.0"
version = "0.119.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95cabbc01dfbd7dcd6c329ca44f0212910309c221797ac736a67a5bc8857fe1b"
checksum = "5b4a113455f8c0e13e3b3222a9c38d6940b958ff22573108be083495c72820e1"
dependencies = [
"cranelift-srcgen",
]
[[package]]
name = "cranelift-bforest"
version = "0.118.0"
version = "0.119.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76ffe46df300a45f1dc6f609dc808ce963f0e3a2e971682c479a2d13e3b9b8ef"
checksum = "58f96dca41c5acf5d4312c1d04b3391e21a312f8d64ce31a2723a3bb8edd5d4d"
dependencies = [
"cranelift-entity",
]
[[package]]
name = "cranelift-bitset"
version = "0.118.0"
version = "0.119.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b265bed7c51e1921fdae6419791d31af77d33662ee56d7b0fa0704dc8d231cab"
checksum = "7d821ed698dd83d9c012447eb63a5406c1e9c23732a2f674fb5b5015afd42202"
[[package]]
name = "cranelift-codegen"
version = "0.118.0"
version = "0.119.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e606230a7e3a6897d603761baee0d19f88d077f17b996bb5089488a29ae96e41"
checksum = "06c52fdec4322cb8d5545a648047819aaeaa04e630f88d3a609c0d3c1a00e9a0"
dependencies = [
"bumpalo",
"cranelift-assembler-x64",
@@ -538,43 +541,44 @@ dependencies = [
[[package]]
name = "cranelift-codegen-meta"
version = "0.118.0"
version = "0.119.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a63bffafc23bc60969ad528e138788495999d935f0adcfd6543cb151ca8637d"
checksum = "af2c215e0c9afa8069aafb71d22aa0e0dde1048d9a5c3c72a83cacf9b61fcf4a"
dependencies = [
"cranelift-assembler-x64",
"cranelift-assembler-x64-meta",
"cranelift-codegen-shared",
"cranelift-srcgen",
]
[[package]]
name = "cranelift-codegen-shared"
version = "0.118.0"
version = "0.119.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af50281b67324b58e843170a6a5943cf6d387c06f7eeacc9f5696e4ab7ae7d7e"
checksum = "97524b2446fc26a78142132d813679dda19f620048ebc9a9fbb0ac9f2d320dcb"
[[package]]
name = "cranelift-control"
version = "0.118.0"
version = "0.119.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c20c1b38d1abfbcebb0032e497e71156c0e3b8dcb3f0a92b9863b7bcaec290c"
checksum = "8e32e900aee81f9e3cc493405ef667a7812cb5c79b5fc6b669e0a2795bda4b22"
dependencies = [
"arbitrary",
]
[[package]]
name = "cranelift-entity"
version = "0.118.0"
version = "0.119.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c2c67d95507c51b4a1ff3f3555fe4bfec36b9e13c1b684ccc602736f5d5f4a2"
checksum = "d16a2e28e0fa6b9108d76879d60fe1cc95ba90e1bcf52bac96496371044484ee"
dependencies = [
"cranelift-bitset",
]
[[package]]
name = "cranelift-frontend"
version = "0.118.0"
version = "0.119.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e002691cc69c38b54fc7ec93e5be5b744f627d027031d991cc845d1d512d0ce"
checksum = "328181a9083d99762d85954a16065d2560394a862b8dc10239f39668df528b95"
dependencies = [
"cranelift-codegen",
"log",
@@ -584,15 +588,15 @@ dependencies = [
[[package]]
name = "cranelift-isle"
version = "0.118.0"
version = "0.119.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e93588ed1796cbcb0e2ad160403509e2c5d330d80dd6e0014ac6774c7ebac496"
checksum = "e916f36f183e377e9a3ed71769f2721df88b72648831e95bb9fa6b0cd9b1c709"
[[package]]
name = "cranelift-jit"
version = "0.118.0"
version = "0.119.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17f6682f0b193d6b7873cc8e7ed67e8776a8a26f50eeabf88534e9be618b9a03"
checksum = "d6bb584ac927f1076d552504b0075b833b9d61e2e9178ba55df6b2d966b4375d"
dependencies = [
"anyhow",
"cranelift-codegen",
@@ -610,9 +614,9 @@ dependencies = [
[[package]]
name = "cranelift-module"
version = "0.118.0"
version = "0.119.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff19784c6de05116e63e6a34791012bd927b2a4eac56233039c46f1b6a4edac8"
checksum = "40c18ccb8e4861cf49cec79998af73b772a2b47212d12d3d63bf57cc4293a1e3"
dependencies = [
"anyhow",
"cranelift-codegen",
@@ -621,15 +625,21 @@ dependencies = [
[[package]]
name = "cranelift-native"
version = "0.118.0"
version = "0.119.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5b09bdd6407bf5d89661b80cf926ce731c9e8cc184bf49102267a2369a8358e"
checksum = "fc852cf04128877047dc2027aa1b85c64f681dc3a6a37ff45dcbfa26e4d52d2f"
dependencies = [
"cranelift-codegen",
"libc",
"target-lexicon",
]
[[package]]
name = "cranelift-srcgen"
version = "0.119.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47e1a86340a16e74b4285cc86ac69458fa1c8e7aaff313da4a89d10efd3535ee"
[[package]]
name = "crc32fast"
version = "1.4.2"
@@ -840,9 +850,9 @@ dependencies = [
[[package]]
name = "error-code"
version = "3.3.1"
version = "3.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5d9305ccc6942a704f4335694ecd3de2ea531b114ac2d51f5f843750787a92f"
checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59"
[[package]]
name = "exitcode"
@@ -953,9 +963,9 @@ dependencies = [
[[package]]
name = "gethostname"
version = "1.0.1"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed7131e57abbde63513e0e6636f76668a1ca9798dcae2df4e283cae9ee83859e"
checksum = "fc257fdb4038301ce4b9cd1b3b51704509692bb3ff716a410cbd07925d9dae55"
dependencies = [
"rustix",
"windows-targets 0.52.6",
@@ -972,15 +982,13 @@ dependencies = [
[[package]]
name = "getrandom"
version = "0.2.15"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
dependencies = [
"cfg-if",
"js-sys",
"libc",
"wasi 0.11.0+wasi-snapshot-preview1",
"wasm-bindgen",
]
[[package]]
@@ -1016,9 +1024,9 @@ checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
[[package]]
name = "half"
version = "2.5.0"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7db2ff139bba50379da6aa0766b52fdcb62cb5b263009b09ed58ba604e14bbd1"
checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9"
dependencies = [
"cfg-if",
"crunchy",
@@ -1026,9 +1034,9 @@ dependencies = [
[[package]]
name = "hashbrown"
version = "0.15.2"
version = "0.15.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3"
dependencies = [
"foldhash",
]
@@ -1047,9 +1055,9 @@ checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
[[package]]
name = "hermit-abi"
version = "0.5.0"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbd780fe5cc30f81464441920d82ac8740e2e46b29a6fad543ddd075229ce37e"
checksum = "f154ce46856750ed433c8649605bf7ed2de3bc35fd9d2a9f30cddd873c80cb08"
[[package]]
name = "hex"
@@ -1114,14 +1122,12 @@ checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd"
[[package]]
name = "insta"
version = "1.42.2"
version = "1.43.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50259abbaa67d11d2bcafc7ba1d094ed7a0c70e3ce893f0d0997f73558cb3084"
checksum = "154934ea70c58054b556dd430b99a98c2a7ff5309ac9891597e339b5c28f4371"
dependencies = [
"console",
"linked-hash-map",
"once_cell",
"pin-project",
"similar",
]
@@ -1134,7 +1140,7 @@ dependencies = [
"heck",
"proc-macro2",
"quote",
"syn 2.0.100",
"syn 2.0.101",
]
[[package]]
@@ -1143,7 +1149,7 @@ version = "0.4.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9"
dependencies = [
"hermit-abi 0.5.0",
"hermit-abi 0.5.1",
"libc",
"windows-sys 0.59.0",
]
@@ -1189,9 +1195,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "jiff"
version = "0.2.5"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c102670231191d07d37a35af3eb77f1f0dbf7a71be51a962dcd57ea607be7260"
checksum = "f02000660d30638906021176af16b17498bd0d12813dbfe7b276d8bc7f3c0806"
dependencies = [
"jiff-static",
"log",
@@ -1202,13 +1208,13 @@ dependencies = [
[[package]]
name = "jiff-static"
version = "0.2.5"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cdde31a9d349f1b1f51a0b3714a5940ac022976f4b49485fc04be052b183b4c"
checksum = "f3c30758ddd7188629c6713fc45d1188af4f44c90582311d0c8d8c9907f60c48"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.100",
"syn 2.0.101",
]
[[package]]
@@ -1290,15 +1296,15 @@ checksum = "0864a00c8d019e36216b69c2c4ce50b83b7bd966add3cf5ba554ec44f8bebcf5"
[[package]]
name = "libc"
version = "0.2.171"
version = "0.2.172"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
[[package]]
name = "libffi"
version = "4.0.0"
version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a9434b6fc77375fb624698d5f8c49d7e80b10d59eb1219afda27d1f824d4074"
checksum = "ebfd30a67b482a08116e753d0656cb626548cf4242543e5cc005be7639d99838"
dependencies = [
"libc",
"libffi-sys",
@@ -1306,9 +1312,9 @@ dependencies = [
[[package]]
name = "libffi-sys"
version = "3.2.0"
version = "3.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ead36a2496acfc8edd6cc32352110e9478ac5b9b5f5b9856ebd3d28019addb84"
checksum = "f003aa318c9f0ee69eb0ada7c78f5c9d2fedd2ceb274173b5c7ff475eee584a3"
dependencies = [
"cc",
]
@@ -1325,9 +1331,9 @@ dependencies = [
[[package]]
name = "libm"
version = "0.2.11"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa"
checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
[[package]]
name = "libredox"
@@ -1359,17 +1365,11 @@ dependencies = [
"zlib-rs",
]
[[package]]
name = "linked-hash-map"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
[[package]]
name = "linux-raw-sys"
version = "0.9.3"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413"
checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
[[package]]
name = "lock_api"
@@ -1396,6 +1396,17 @@ dependencies = [
"twox-hash",
]
[[package]]
name = "lzma-sys"
version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27"
dependencies = [
"cc",
"libc",
"pkg-config",
]
[[package]]
name = "mac_address"
version = "1.1.8"
@@ -1516,9 +1527,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "miniz_oxide"
version = "0.8.7"
version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff70ce3e48ae43fa075863cef62e8b43b71a4f2382229920e0df362592919430"
checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a"
dependencies = [
"adler2",
]
@@ -1618,7 +1629,7 @@ checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.100",
"syn 2.0.101",
]
[[package]]
@@ -1656,7 +1667,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.100",
"syn 2.0.101",
]
[[package]]
@@ -1667,18 +1678,18 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
[[package]]
name = "openssl-src"
version = "300.4.2+3.4.1"
version = "300.5.0+3.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "168ce4e058f975fe43e89d9ccf78ca668601887ae736090aacc23ae353c298e2"
checksum = "e8ce546f549326b0e6052b649198487d91320875da901e7bd11a06d1ee3f9c2f"
dependencies = [
"cc",
]
[[package]]
name = "openssl-sys"
version = "0.9.107"
version = "0.9.108"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8288979acd84749c744a9014b4382d42b8f7b2592847b5afb2ed29e5d16ede07"
checksum = "e145e1651e858e820e4860f7b9c5e169bc1d8ce1c86043be79fa7b7634821847"
dependencies = [
"cc",
"libc",
@@ -1721,7 +1732,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
dependencies = [
"cfg-if",
"libc",
"redox_syscall 0.5.11",
"redox_syscall 0.5.12",
"smallvec",
"windows-targets 0.52.6",
]
@@ -1770,26 +1781,6 @@ dependencies = [
"siphasher",
]
[[package]]
name = "pin-project"
version = "1.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a"
dependencies = [
"pin-project-internal",
]
[[package]]
name = "pin-project-internal"
version = "1.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.100",
]
[[package]]
name = "pkg-config"
version = "0.3.32"
@@ -1832,7 +1823,7 @@ checksum = "52a40bc70c2c58040d2d8b167ba9a5ff59fc9dab7ad44771cfde3dcfde7a09c6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.100",
"syn 2.0.101",
]
[[package]]
@@ -1856,7 +1847,7 @@ version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
dependencies = [
"zerocopy 0.8.24",
"zerocopy",
]
[[package]]
@@ -1866,14 +1857,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "664ec5419c51e34154eec046ebcba56312d5a2fc3b09a06da188e1ad21afadf6"
dependencies = [
"proc-macro2",
"syn 2.0.100",
"syn 2.0.101",
]
[[package]]
name = "proc-macro2"
version = "1.0.94"
version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
dependencies = [
"unicode-ident",
]
@@ -1889,9 +1880,9 @@ dependencies = [
[[package]]
name = "pyo3"
version = "0.24.1"
version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17da310086b068fbdcefbba30aeb3721d5bb9af8db4987d6735b2183ca567229"
checksum = "e5203598f366b11a02b13aa20cab591229ff0a89fd121a308a5df751d5fc9219"
dependencies = [
"cfg-if",
"indoc",
@@ -1907,9 +1898,9 @@ dependencies = [
[[package]]
name = "pyo3-build-config"
version = "0.24.1"
version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e27165889bd793000a098bb966adc4300c312497ea25cf7a690a9f0ac5aa5fc1"
checksum = "99636d423fa2ca130fa5acde3059308006d46f98caac629418e53f7ebb1e9999"
dependencies = [
"once_cell",
"target-lexicon",
@@ -1917,9 +1908,9 @@ dependencies = [
[[package]]
name = "pyo3-ffi"
version = "0.24.1"
version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05280526e1dbf6b420062f3ef228b78c0c54ba94e157f5cb724a609d0f2faabc"
checksum = "78f9cf92ba9c409279bc3305b5409d90db2d2c22392d443a87df3a1adad59e33"
dependencies = [
"libc",
"pyo3-build-config",
@@ -1927,27 +1918,27 @@ dependencies = [
[[package]]
name = "pyo3-macros"
version = "0.24.1"
version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c3ce5686aa4d3f63359a5100c62a127c9f15e8398e5fdeb5deef1fed5cd5f44"
checksum = "0b999cb1a6ce21f9a6b147dcf1be9ffedf02e0043aec74dc390f3007047cecd9"
dependencies = [
"proc-macro2",
"pyo3-macros-backend",
"quote",
"syn 2.0.100",
"syn 2.0.101",
]
[[package]]
name = "pyo3-macros-backend"
version = "0.24.1"
version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4cf6faa0cbfb0ed08e89beb8103ae9724eb4750e3a78084ba4017cbe94f3855"
checksum = "822ece1c7e1012745607d5cf0bcb2874769f0f7cb34c4cde03b9358eb9ef911a"
dependencies = [
"heck",
"proc-macro2",
"pyo3-build-config",
"quote",
"syn 2.0.100",
"syn 2.0.101",
]
[[package]]
@@ -1968,8 +1959,7 @@ checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
[[package]]
name = "radium"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db0b76288902db304c864a12046b73d2d895cc34a4bb8137baaeebe9978a072c"
source = "git+https://github.com/youknowone/ferrilab?branch=fix-nightly#4a301c3a223e096626a2773d1a1eed1fc4e21140"
dependencies = [
"cfg-if",
]
@@ -1997,13 +1987,12 @@ dependencies = [
[[package]]
name = "rand"
version = "0.9.0"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97"
dependencies = [
"rand_chacha 0.9.0",
"rand_core 0.9.3",
"zerocopy 0.8.24",
]
[[package]]
@@ -2032,7 +2021,7 @@ version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom 0.2.15",
"getrandom 0.2.16",
]
[[package]]
@@ -2072,9 +2061,9 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
[[package]]
name = "redox_syscall"
version = "0.5.11"
version = "0.5.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3"
checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af"
dependencies = [
"bitflags 2.9.0",
]
@@ -2085,7 +2074,7 @@ version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
dependencies = [
"getrandom 0.2.15",
"getrandom 0.2.16",
"libredox",
"thiserror 1.0.69",
]
@@ -2163,7 +2152,7 @@ dependencies = [
"pmutil",
"proc-macro2",
"quote",
"syn 2.0.100",
"syn 2.0.101",
]
[[package]]
@@ -2235,9 +2224,9 @@ checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
[[package]]
name = "rustix"
version = "1.0.5"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf"
checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266"
dependencies = [
"bitflags 2.9.0",
"errno",
@@ -2326,7 +2315,7 @@ dependencies = [
name = "rustpython-compiler"
version = "0.4.0"
dependencies = [
"rand 0.9.0",
"rand 0.9.1",
"ruff_python_ast",
"ruff_python_parser",
"ruff_source_file",
@@ -2366,7 +2355,7 @@ dependencies = [
"proc-macro2",
"rustpython-compiler",
"rustpython-derive-impl",
"syn 2.0.100",
"syn 2.0.101",
]
[[package]]
@@ -2379,7 +2368,7 @@ dependencies = [
"quote",
"rustpython-compiler-core",
"rustpython-doc",
"syn 2.0.100",
"syn 2.0.101",
"syn-ext",
"textwrap",
]
@@ -2415,7 +2404,7 @@ dependencies = [
"is-macro",
"lexical-parse-float",
"num-traits",
"rand 0.9.0",
"rand 0.9.1",
"rustpython-wtf8",
"unic-ucd-category",
]
@@ -2467,6 +2456,7 @@ dependencies = [
"libc",
"libsqlite3-sys",
"libz-rs-sys",
"lzma-sys",
"mac_address",
"malachite-bigint",
"md-5",
@@ -2512,6 +2502,7 @@ dependencies = [
"widestring",
"windows-sys 0.59.0",
"xml-rs",
"xz2",
]
[[package]]
@@ -2609,7 +2600,6 @@ name = "rustpython_wasm"
version = "0.4.0"
dependencies = [
"console_error_panic_hook",
"getrandom 0.2.15",
"js-sys",
"ruff_python_parser",
"rustpython-common",
@@ -2710,7 +2700,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.100",
"syn 2.0.101",
]
[[package]]
@@ -2738,9 +2728,9 @@ dependencies = [
[[package]]
name = "sha2"
version = "0.10.8"
version = "0.10.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
dependencies = [
"cfg-if",
"cpufeatures",
@@ -2827,7 +2817,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustversion",
"syn 2.0.100",
"syn 2.0.101",
]
[[package]]
@@ -2849,9 +2839,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.100"
version = "2.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
dependencies = [
"proc-macro2",
"quote",
@@ -2866,7 +2856,7 @@ checksum = "b126de4ef6c2a628a68609dd00733766c3b015894698a438ebdf374933fc31d1"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.100",
"syn 2.0.101",
]
[[package]]
@@ -2946,7 +2936,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.100",
"syn 2.0.101",
]
[[package]]
@@ -2957,7 +2947,7 @@ checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.100",
"syn 2.0.101",
]
[[package]]
@@ -3298,7 +3288,7 @@ dependencies = [
"log",
"proc-macro2",
"quote",
"syn 2.0.100",
"syn 2.0.101",
"wasm-bindgen-shared",
]
@@ -3333,7 +3323,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.100",
"syn 2.0.101",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@@ -3349,9 +3339,9 @@ dependencies = [
[[package]]
name = "wasmtime-jit-icache-coherence"
version = "31.0.0"
version = "32.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a54f6c6c7e9d7eeee32dfcc10db7f29d505ee7dd28d00593ea241d5f70698e64"
checksum = "eb399eaabd7594f695e1159d236bf40ef55babcb3af97f97c027864ed2104db6"
dependencies = [
"anyhow",
"cfg-if",
@@ -3458,7 +3448,7 @@ checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.100",
"syn 2.0.101",
]
[[package]]
@@ -3469,7 +3459,7 @@ checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.100",
"syn 2.0.101",
]
[[package]]
@@ -3671,48 +3661,37 @@ dependencies = [
[[package]]
name = "xml-rs"
version = "0.8.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a62ce76d9b56901b19a74f19431b0d8b3bc7ca4ad685a746dfd78ca8f4fc6bda"
[[package]]
name = "xz2"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2"
dependencies = [
"lzma-sys",
]
[[package]]
name = "zerocopy"
version = "0.8.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5b940ebc25896e71dd073bad2dbaa2abfe97b0a391415e22ad1326d9c54e3c4"
[[package]]
name = "zerocopy"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb"
dependencies = [
"zerocopy-derive 0.7.35",
]
[[package]]
name = "zerocopy"
version = "0.8.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879"
dependencies = [
"zerocopy-derive 0.8.24",
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.35"
version = "0.8.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.100",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.100",
"syn 2.0.101",
]
[[package]]

View File

@@ -79,6 +79,7 @@ opt-level = 3
lto = "thin"
[patch.crates-io]
radium = { version = "1.1.0", git = "https://github.com/youknowone/ferrilab", branch = "fix-nightly" }
# REDOX START, Uncomment when you want to compile/check with redoxer
# REDOX END
@@ -186,6 +187,7 @@ paste = "1.0.15"
proc-macro2 = "1.0.93"
pymath = "0.0.2"
quote = "1.0.38"
radium = "1.1"
rand = "0.9"
rand_core = { version = "0.9", features = ["os_rng"] }
rustix = { version = "1.0", features = ["event"] }

10
Lib/codeop.py vendored
View File

@@ -65,14 +65,10 @@ def _maybe_compile(compiler, source, filename, symbol):
try:
compiler(source + "\n", filename, symbol)
return None
except _IncompleteInputError as e:
return None
except SyntaxError as e:
# XXX: RustPython; support multiline definitions in REPL
# See also: https://github.com/RustPython/RustPython/pull/5743
strerr = str(e)
if source.endswith(":") and "expected an indented block" in strerr:
return None
elif "incomplete input" in str(e):
return None
pass
# fallthrough
return compiler(source, filename, symbol, incomplete_input=False)

364
Lib/lzma.py vendored Normal file
View File

@@ -0,0 +1,364 @@
"""Interface to the liblzma compression library.
This module provides a class for reading and writing compressed files,
classes for incremental (de)compression, and convenience functions for
one-shot (de)compression.
These classes and functions support both the XZ and legacy LZMA
container formats, as well as raw compressed data streams.
"""
__all__ = [
"CHECK_NONE", "CHECK_CRC32", "CHECK_CRC64", "CHECK_SHA256",
"CHECK_ID_MAX", "CHECK_UNKNOWN",
"FILTER_LZMA1", "FILTER_LZMA2", "FILTER_DELTA", "FILTER_X86", "FILTER_IA64",
"FILTER_ARM", "FILTER_ARMTHUMB", "FILTER_POWERPC", "FILTER_SPARC",
"FORMAT_AUTO", "FORMAT_XZ", "FORMAT_ALONE", "FORMAT_RAW",
"MF_HC3", "MF_HC4", "MF_BT2", "MF_BT3", "MF_BT4",
"MODE_FAST", "MODE_NORMAL", "PRESET_DEFAULT", "PRESET_EXTREME",
"LZMACompressor", "LZMADecompressor", "LZMAFile", "LZMAError",
"open", "compress", "decompress", "is_check_supported",
]
import builtins
import io
import os
from _lzma import *
from _lzma import _encode_filter_properties, _decode_filter_properties
import _compression
# Value 0 no longer used
_MODE_READ = 1
# Value 2 no longer used
_MODE_WRITE = 3
class LZMAFile(_compression.BaseStream):
"""A file object providing transparent LZMA (de)compression.
An LZMAFile can act as a wrapper for an existing file object, or
refer directly to a named file on disk.
Note that LZMAFile provides a *binary* file interface - data read
is returned as bytes, and data to be written must be given as bytes.
"""
def __init__(self, filename=None, mode="r", *,
format=None, check=-1, preset=None, filters=None):
"""Open an LZMA-compressed file in binary mode.
filename can be either an actual file name (given as a str,
bytes, or PathLike object), in which case the named file is
opened, or it can be an existing file object to read from or
write to.
mode can be "r" for reading (default), "w" for (over)writing,
"x" for creating exclusively, or "a" for appending. These can
equivalently be given as "rb", "wb", "xb" and "ab" respectively.
format specifies the container format to use for the file.
If mode is "r", this defaults to FORMAT_AUTO. Otherwise, the
default is FORMAT_XZ.
check specifies the integrity check to use. This argument can
only be used when opening a file for writing. For FORMAT_XZ,
the default is CHECK_CRC64. FORMAT_ALONE and FORMAT_RAW do not
support integrity checks - for these formats, check must be
omitted, or be CHECK_NONE.
When opening a file for reading, the *preset* argument is not
meaningful, and should be omitted. The *filters* argument should
also be omitted, except when format is FORMAT_RAW (in which case
it is required).
When opening a file for writing, the settings used by the
compressor can be specified either as a preset compression
level (with the *preset* argument), or in detail as a custom
filter chain (with the *filters* argument). For FORMAT_XZ and
FORMAT_ALONE, the default is to use the PRESET_DEFAULT preset
level. For FORMAT_RAW, the caller must always specify a filter
chain; the raw compressor does not support preset compression
levels.
preset (if provided) should be an integer in the range 0-9,
optionally OR-ed with the constant PRESET_EXTREME.
filters (if provided) should be a sequence of dicts. Each dict
should have an entry for "id" indicating ID of the filter, plus
additional entries for options to the filter.
"""
self._fp = None
self._closefp = False
self._mode = None
if mode in ("r", "rb"):
if check != -1:
raise ValueError("Cannot specify an integrity check "
"when opening a file for reading")
if preset is not None:
raise ValueError("Cannot specify a preset compression "
"level when opening a file for reading")
if format is None:
format = FORMAT_AUTO
mode_code = _MODE_READ
elif mode in ("w", "wb", "a", "ab", "x", "xb"):
if format is None:
format = FORMAT_XZ
mode_code = _MODE_WRITE
self._compressor = LZMACompressor(format=format, check=check,
preset=preset, filters=filters)
self._pos = 0
else:
raise ValueError("Invalid mode: {!r}".format(mode))
if isinstance(filename, (str, bytes, os.PathLike)):
if "b" not in mode:
mode += "b"
self._fp = builtins.open(filename, mode)
self._closefp = True
self._mode = mode_code
elif hasattr(filename, "read") or hasattr(filename, "write"):
self._fp = filename
self._mode = mode_code
else:
raise TypeError("filename must be a str, bytes, file or PathLike object")
if self._mode == _MODE_READ:
raw = _compression.DecompressReader(self._fp, LZMADecompressor,
trailing_error=LZMAError, format=format, filters=filters)
self._buffer = io.BufferedReader(raw)
def close(self):
"""Flush and close the file.
May be called more than once without error. Once the file is
closed, any other operation on it will raise a ValueError.
"""
if self.closed:
return
try:
if self._mode == _MODE_READ:
self._buffer.close()
self._buffer = None
elif self._mode == _MODE_WRITE:
self._fp.write(self._compressor.flush())
self._compressor = None
finally:
try:
if self._closefp:
self._fp.close()
finally:
self._fp = None
self._closefp = False
@property
def closed(self):
"""True if this file is closed."""
return self._fp is None
@property
def name(self):
self._check_not_closed()
return self._fp.name
@property
def mode(self):
return 'wb' if self._mode == _MODE_WRITE else 'rb'
def fileno(self):
"""Return the file descriptor for the underlying file."""
self._check_not_closed()
return self._fp.fileno()
def seekable(self):
"""Return whether the file supports seeking."""
return self.readable() and self._buffer.seekable()
def readable(self):
"""Return whether the file was opened for reading."""
self._check_not_closed()
return self._mode == _MODE_READ
def writable(self):
"""Return whether the file was opened for writing."""
self._check_not_closed()
return self._mode == _MODE_WRITE
def peek(self, size=-1):
"""Return buffered data without advancing the file position.
Always returns at least one byte of data, unless at EOF.
The exact number of bytes returned is unspecified.
"""
self._check_can_read()
# Relies on the undocumented fact that BufferedReader.peek() always
# returns at least one byte (except at EOF)
return self._buffer.peek(size)
def read(self, size=-1):
"""Read up to size uncompressed bytes from the file.
If size is negative or omitted, read until EOF is reached.
Returns b"" if the file is already at EOF.
"""
self._check_can_read()
return self._buffer.read(size)
def read1(self, size=-1):
"""Read up to size uncompressed bytes, while trying to avoid
making multiple reads from the underlying stream. Reads up to a
buffer's worth of data if size is negative.
Returns b"" if the file is at EOF.
"""
self._check_can_read()
if size < 0:
size = io.DEFAULT_BUFFER_SIZE
return self._buffer.read1(size)
def readline(self, size=-1):
"""Read a line of uncompressed bytes from the file.
The terminating newline (if present) is retained. If size is
non-negative, no more than size bytes will be read (in which
case the line may be incomplete). Returns b'' if already at EOF.
"""
self._check_can_read()
return self._buffer.readline(size)
def write(self, data):
"""Write a bytes object to the file.
Returns the number of uncompressed bytes written, which is
always the length of data in bytes. Note that due to buffering,
the file on disk may not reflect the data written until close()
is called.
"""
self._check_can_write()
if isinstance(data, (bytes, bytearray)):
length = len(data)
else:
# accept any data that supports the buffer protocol
data = memoryview(data)
length = data.nbytes
compressed = self._compressor.compress(data)
self._fp.write(compressed)
self._pos += length
return length
def seek(self, offset, whence=io.SEEK_SET):
"""Change the file position.
The new position is specified by offset, relative to the
position indicated by whence. Possible values for whence are:
0: start of stream (default): offset must not be negative
1: current stream position
2: end of stream; offset must not be positive
Returns the new file position.
Note that seeking is emulated, so depending on the parameters,
this operation may be extremely slow.
"""
self._check_can_seek()
return self._buffer.seek(offset, whence)
def tell(self):
"""Return the current file position."""
self._check_not_closed()
if self._mode == _MODE_READ:
return self._buffer.tell()
return self._pos
def open(filename, mode="rb", *,
format=None, check=-1, preset=None, filters=None,
encoding=None, errors=None, newline=None):
"""Open an LZMA-compressed file in binary or text mode.
filename can be either an actual file name (given as a str, bytes,
or PathLike object), in which case the named file is opened, or it
can be an existing file object to read from or write to.
The mode argument can be "r", "rb" (default), "w", "wb", "x", "xb",
"a", or "ab" for binary mode, or "rt", "wt", "xt", or "at" for text
mode.
The format, check, preset and filters arguments specify the
compression settings, as for LZMACompressor, LZMADecompressor and
LZMAFile.
For binary mode, this function is equivalent to the LZMAFile
constructor: LZMAFile(filename, mode, ...). In this case, the
encoding, errors and newline arguments must not be provided.
For text mode, an LZMAFile object is created, and wrapped in an
io.TextIOWrapper instance with the specified encoding, error
handling behavior, and line ending(s).
"""
if "t" in mode:
if "b" in mode:
raise ValueError("Invalid mode: %r" % (mode,))
else:
if encoding is not None:
raise ValueError("Argument 'encoding' not supported in binary mode")
if errors is not None:
raise ValueError("Argument 'errors' not supported in binary mode")
if newline is not None:
raise ValueError("Argument 'newline' not supported in binary mode")
lz_mode = mode.replace("t", "")
binary_file = LZMAFile(filename, lz_mode, format=format, check=check,
preset=preset, filters=filters)
if "t" in mode:
encoding = io.text_encoding(encoding)
return io.TextIOWrapper(binary_file, encoding, errors, newline)
else:
return binary_file
def compress(data, format=FORMAT_XZ, check=-1, preset=None, filters=None):
"""Compress a block of data.
Refer to LZMACompressor's docstring for a description of the
optional arguments *format*, *check*, *preset* and *filters*.
For incremental compression, use an LZMACompressor instead.
"""
comp = LZMACompressor(format, check, preset, filters)
return comp.compress(data) + comp.flush()
def decompress(data, format=FORMAT_AUTO, memlimit=None, filters=None):
"""Decompress a block of data.
Refer to LZMADecompressor's docstring for a description of the
optional arguments *format*, *check* and *filters*.
For incremental decompression, use an LZMADecompressor instead.
"""
results = []
while True:
decomp = LZMADecompressor(format, memlimit, filters)
try:
res = decomp.decompress(data)
except LZMAError:
if results:
break # Leftover data is not a valid LZMA/XZ stream; ignore it.
else:
raise # Error on the first iteration; bail out.
results.append(res)
if not decomp.eof:
raise LZMAError("Compressed data ended before the "
"end-of-stream marker was reached")
data = decomp.unused_data
if not data:
break
return b"".join(results)

7
Lib/tarfile.py vendored
View File

@@ -395,6 +395,10 @@ class _Stream:
import lzma
except ImportError:
raise CompressionError("lzma module is not available") from None
# XXX: RUSTPYTHON; xz is not supported yet
raise CompressionError("lzma module is not available") from None
if mode == "r":
self.dbuf = b""
self.cmp = lzma.LZMADecompressor()
@@ -1927,6 +1931,9 @@ class TarFile(object):
except ImportError:
raise CompressionError("lzma module is not available") from None
# XXX: RUSTPYTHON; xz is not supported yet
raise CompressionError("lzma module is not available") from None
fileobj = LZMAFile(fileobj or name, mode, preset=preset)
try:

View File

@@ -498,6 +498,8 @@ def requires_lzma(reason='requires lzma'):
import lzma
except ImportError:
lzma = None
# XXX: RUSTPYTHON; xz is not supported yet
lzma = None
return unittest.skipUnless(lzma, reason)
def has_no_debug_ranges():

View File

@@ -83,6 +83,8 @@ class ExceptionClassTests(unittest.TestCase):
exc_set = set(e for e in exc_set if not e.startswith('_'))
# RUSTPYTHON specific
exc_set.discard("JitError")
# TODO: RUSTPYTHON; this will be officially introduced in Python 3.15
exc_set.discard("IncompleteInputError")
self.assertEqual(len(exc_set), 0, "%s not accounted for" % exc_set)
interface_tests = ("length", "args", "str", "repr")

2197
Lib/test/test_lzma.py vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -664,6 +664,9 @@ class CompatPickleTests(unittest.TestCase):
BaseExceptionGroup,
ExceptionGroup):
continue
# TODO: RUSTPYTHON: fix name mapping for _IncompleteInputError
if exc is _IncompleteInputError:
continue
if exc is not OSError and issubclass(exc, OSError):
self.assertEqual(reverse_mapping('builtins', name),
('exceptions', 'OSError'))

View File

@@ -31,6 +31,8 @@ try:
import lzma
except ImportError:
lzma = None
# XXX: RUSTPYTHON; xz is not supported yet
lzma = None
def sha256sum(data):
return sha256(data).hexdigest()

View File

@@ -1728,6 +1728,8 @@ class TzPathTest(TzPathUserMixin, ZoneInfoTestBase):
with self.subTest("filtered", path_var=path_var):
self.assertSequenceEqual(tzpath, expected_paths)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_env_variable_relative_paths_warning_location(self):
path_var = "path/to/somewhere"
@@ -1822,6 +1824,8 @@ class TestModule(ZoneInfoTestBase):
with self.assertRaises(AttributeError):
self.module.NOATTRIBUTE
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_dir_contains_all(self):
"""dir(self.module) should at least contain everything in __all__."""
module_all_set = set(self.module.__all__)
@@ -1925,12 +1929,16 @@ class ExtensionBuiltTest(unittest.TestCase):
rely on these tests as an indication of stable properties of these classes.
"""
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_cache_location(self):
# The pure Python version stores caches on attributes, but the C
# extension stores them in C globals (at least for now)
self.assertFalse(hasattr(c_zoneinfo.ZoneInfo, "_weak_cache"))
self.assertTrue(hasattr(py_zoneinfo.ZoneInfo, "_weak_cache"))
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_gc_tracked(self):
import gc

View File

@@ -31,6 +31,11 @@ To build RustPython locally, first, clone the source code:
git clone https://github.com/RustPython/RustPython
```
RustPython uses symlinks to manage python libraries in `Lib/`. If on windows, running the following helps:
```bash
git config core.symlinks true
```
Then you can change into the RustPython directory and run the demo (Note: `--release` is
needed to prevent stack overflow on Windows):
@@ -221,7 +226,7 @@ To enhance CPython compatibility, try to increase unittest coverage by checking
Another approach is to checkout the source code: builtin functions and object
methods are often the simplest and easiest way to contribute.
You can also simply run `./whats_left.py` to assist in finding any unimplemented
You can also simply run `uv run python -I whats_left.py` to assist in finding any unimplemented
method.
## Compiling to WebAssembly

View File

@@ -30,9 +30,9 @@ num-traits = { workspace = true }
once_cell = { workspace = true }
parking_lot = { workspace = true, optional = true }
unicode_names2 = { workspace = true }
radium = { workspace = true }
lock_api = "0.4"
radium = "1.1"
siphasher = "1"
[target.'cfg(windows)'.dependencies]

View File

@@ -151,7 +151,7 @@ pub fn compile_program(
let mut compiler = Compiler::new(opts, source_code, "<module>".to_owned());
compiler.compile_program(ast, symbol_table)?;
let code = compiler.pop_code_object();
trace!("Compilation completed: {:?}", code);
trace!("Compilation completed: {code:?}");
Ok(code)
}
@@ -166,7 +166,7 @@ pub fn compile_program_single(
let mut compiler = Compiler::new(opts, source_code, "<module>".to_owned());
compiler.compile_program_single(&ast.body, symbol_table)?;
let code = compiler.pop_code_object();
trace!("Compilation completed: {:?}", code);
trace!("Compilation completed: {code:?}");
Ok(code)
}
@@ -180,7 +180,7 @@ pub fn compile_block_expression(
let mut compiler = Compiler::new(opts, source_code, "<module>".to_owned());
compiler.compile_block_expr(&ast.body, symbol_table)?;
let code = compiler.pop_code_object();
trace!("Compilation completed: {:?}", code);
trace!("Compilation completed: {code:?}");
Ok(code)
}
@@ -233,7 +233,7 @@ fn eprint_location(zelf: &Compiler<'_>) {
fn unwrap_internal<T>(zelf: &Compiler<'_>, r: InternalResult<T>) -> T {
if let Err(ref r_err) = r {
eprintln!("=== CODEGEN PANIC INFO ===");
eprintln!("This IS an internal error: {}", r_err);
eprintln!("This IS an internal error: {r_err}");
eprint_location(zelf);
eprintln!("=== END PANIC INFO ===");
}
@@ -671,7 +671,7 @@ impl Compiler<'_> {
fn compile_statement(&mut self, statement: &Stmt) -> CompileResult<()> {
use ruff_python_ast::*;
trace!("Compiling {:?}", statement);
trace!("Compiling {statement:?}");
self.set_source_range(statement.range());
match &statement {
@@ -1907,7 +1907,7 @@ impl Compiler<'_> {
fn compile_error_forbidden_name(&mut self, name: &str) -> CodegenError {
// TODO: make into error (fine for now since it realistically errors out earlier)
panic!("Failing due to forbidden name {:?}", name);
panic!("Failing due to forbidden name {name:?}");
}
/// Ensures that `pc.fail_pop` has at least `n + 1` entries.
@@ -3209,7 +3209,7 @@ impl Compiler<'_> {
fn compile_expression(&mut self, expression: &Expr) -> CompileResult<()> {
use ruff_python_ast::*;
trace!("Compiling {:?}", expression);
trace!("Compiling {expression:?}");
let range = expression.range();
self.set_source_range(range);
@@ -4432,7 +4432,7 @@ pub fn ruff_int_to_bigint(int: &Int) -> Result<BigInt, CodegenErrorType> {
fn parse_big_integer(int: &Int) -> Result<BigInt, CodegenErrorType> {
// TODO: Improve ruff API
// Can we avoid this copy?
let s = format!("{}", int);
let s = format!("{int}");
let mut s = s.as_str();
// See: https://peps.python.org/pep-0515/#literal-grammar
let radix = match s.get(0..2) {

View File

@@ -1388,12 +1388,12 @@ impl Instruction {
let value = ctx.get_constant(idx.get(arg) as usize);
match value.borrow_constant() {
BorrowedConstant::Code { code } if expand_code_objects => {
write!(f, "{:pad$}({:?}):", op, code)?;
write!(f, "{op:pad$}({code:?}):")?;
code.display_inner(f, true, level + 1)?;
Ok(())
}
c => {
write!(f, "{:pad$}(", op)?;
write!(f, "{op:pad$}(")?;
c.fmt_display(f)?;
write!(f, ")")
}

View File

@@ -55,6 +55,7 @@ pub fn format_fixed(precision: usize, magnitude: f64, case: Case, alternate_form
match magnitude {
magnitude if magnitude.is_finite() => {
let point = decimal_point_or_empty(precision, alternate_form);
let precision = std::cmp::min(precision, u16::MAX as usize);
format!("{magnitude:.precision$}{point}")
}
magnitude if magnitude.is_nan() => format_nan(case),

View File

@@ -25,6 +25,7 @@ pub enum CompileErrorType {
pub struct ParseError {
#[source]
pub error: parser::ParseErrorType,
pub raw_location: ruff_text_size::TextRange,
pub location: SourceLocation,
pub source_path: String,
}
@@ -48,6 +49,7 @@ impl CompileError {
let location = source_code.source_location(error.location.start());
Self::Parse(ParseError {
error: error.error,
raw_location: error.location,
location,
source_path: source_code.path.to_owned(),
})

View File

@@ -1,4 +1,4 @@
""" This script can be used to test the equivalence in parsing between
"""This script can be used to test the equivalence in parsing between
rustpython and cpython.
Usage example:
@@ -8,76 +8,80 @@ $ cargo run crawl_sourcecode.py crawl_sourcecode.py > rustpython.txt
$ diff cpython.txt rustpython.txt
"""
import ast
import sys
import symtable
import dis
filename = sys.argv[1]
print('Crawling file:', filename)
print("Crawling file:", filename)
with open(filename, 'r') as f:
with open(filename, "r") as f:
source = f.read()
t = ast.parse(source)
print(t)
shift = 3
def print_node(node, indent=0):
indents = ' ' * indent
indents = " " * indent
if isinstance(node, ast.AST):
lineno = 'row={}'.format(node.lineno) if hasattr(node, 'lineno') else ''
lineno = "row={}".format(node.lineno) if hasattr(node, "lineno") else ""
print(indents, "NODE", node.__class__.__name__, lineno)
for field in node._fields:
print(indents,'-', field)
print(indents, "-", field)
f = getattr(node, field)
if isinstance(f, list):
for f2 in f:
print_node(f2, indent=indent+shift)
print_node(f2, indent=indent + shift)
else:
print_node(f, indent=indent+shift)
print_node(f, indent=indent + shift)
else:
print(indents, 'OBJ', node)
print(indents, "OBJ", node)
print_node(t)
# print(ast.dump(t))
flag_names = [
'is_referenced',
'is_assigned',
'is_global',
'is_local',
'is_parameter',
'is_free',
"is_referenced",
"is_assigned",
"is_global",
"is_local",
"is_parameter",
"is_free",
]
def print_table(table, indent=0):
indents = ' ' * indent
print(indents, 'table:', table.get_name())
print(indents, ' ', 'name:', table.get_name())
print(indents, ' ', 'type:', table.get_type())
print(indents, ' ', 'line:', table.get_lineno())
print(indents, ' ', 'identifiers:', table.get_identifiers())
print(indents, ' ', 'Syms:')
indents = " " * indent
print(indents, "table:", table.get_name())
print(indents, " ", "name:", table.get_name())
print(indents, " ", "type:", table.get_type())
print(indents, " ", "line:", table.get_lineno())
print(indents, " ", "identifiers:", table.get_identifiers())
print(indents, " ", "Syms:")
for sym in table.get_symbols():
flags = []
for flag_name in flag_names:
func = getattr(sym, flag_name)
if func():
flags.append(flag_name)
print(indents, ' sym:', sym.get_name(), 'flags:', ' '.join(flags))
print(indents, " sym:", sym.get_name(), "flags:", " ".join(flags))
if table.has_children():
print(indents, ' ', 'Child tables:')
print(indents, " ", "Child tables:")
for child in table.get_children():
print_table(child, indent=indent+shift)
print_table(child, indent=indent + shift)
table = symtable.symtable(source, 'a', 'exec')
table = symtable.symtable(source, "a", "exec")
print_table(table)
print()
print('======== dis.dis ========')
print("======== dis.dis ========")
print()
co = compile(source, filename, 'exec')
co = compile(source, filename, "exec")
dis.dis(co)

View File

@@ -1,13 +1,12 @@
def foo(x):
def bar(z):
return z + x
return bar
f = foo(9)
g = foo(10)
print(f(2))
print(g(2))

View File

@@ -1,7 +1,9 @@
import atexit
import sys
def myexit():
sys.exit(2)
atexit.register(myexit)

View File

@@ -1,14 +1,17 @@
from rust_py_module import RustStruct, rust_function
class PythonPerson:
def __init__(self, name):
self.name = name
def python_callback():
python_person = PythonPerson("Peter Python")
rust_object = rust_function(42, "This is a python string", python_person)
print("Printing member 'numbers' from rust struct: ", rust_object.numbers)
rust_object.print_in_rust_from_python()
def take_string(string):
print("Calling python function from rust with string: " + string)

View File

@@ -1,4 +1,3 @@
import time
print("Hello world!!!", time.time())

View File

@@ -2,14 +2,15 @@ def fib(n):
a = 1
b = 1
for _ in range(n - 1):
temp = b
b = a + b
a = temp
temp = b
b = a + b
a = temp
return b
print(fib(1))
print(fib(2))
print(fib(3))
print(fib(4))
print(fib(5))
print(fib(5))

View File

@@ -36,10 +36,12 @@ from unittest.runner import result
from unittest.runner import registerResult
from functools import reduce
class TablePrinter(object):
# Modified from https://github.com/agramian/table-printer, same license as above
"Print a list of dicts as a table"
def __init__(self, fmt, sep='', ul=None, tl=None, bl=None):
def __init__(self, fmt, sep="", ul=None, tl=None, bl=None):
"""
@param fmt: list of tuple(heading, key, width)
heading: str, column label
@@ -50,20 +52,44 @@ class TablePrinter(object):
@param tl: string, character to draw as top line over table, or None
@param bl: string, character to draw as bottom line under table, or None
"""
super(TablePrinter,self).__init__()
fmt = [x + ('left',) if len(x) < 4 else x for x in fmt]
self.fmt = str(sep).join('{lb}{0}:{align}{1}{rb}'.format(key, width, lb='{', rb='}', align='<' if alignment == 'left' else '>') for heading,key,width,alignment in fmt)
self.head = {key:heading for heading,key,width,alignment in fmt}
self.ul = {key:str(ul)*width for heading,key,width,alignment in fmt} if ul else None
self.width = {key:width for heading,key,width,alignment in fmt}
self.tl = {key:str(tl)*width for heading,key,width,alignment in fmt} if tl else None
self.bl = {key:str(bl)*width for heading,key,width,alignment in fmt} if bl else None
super(TablePrinter, self).__init__()
fmt = [x + ("left",) if len(x) < 4 else x for x in fmt]
self.fmt = str(sep).join(
"{lb}{0}:{align}{1}{rb}".format(
key, width, lb="{", rb="}", align="<" if alignment == "left" else ">"
)
for heading, key, width, alignment in fmt
)
self.head = {key: heading for heading, key, width, alignment in fmt}
self.ul = (
{key: str(ul) * width for heading, key, width, alignment in fmt}
if ul
else None
)
self.width = {key: width for heading, key, width, alignment in fmt}
self.tl = (
{key: str(tl) * width for heading, key, width, alignment in fmt}
if tl
else None
)
self.bl = (
{key: str(bl) * width for heading, key, width, alignment in fmt}
if bl
else None
)
def row(self, data, separation_character=False):
if separation_character:
return self.fmt.format(**{ k:str(data.get(k,''))[:w] for k,w in self.width.items() })
return self.fmt.format(
**{k: str(data.get(k, ""))[:w] for k, w in self.width.items()}
)
else:
data = { k:str(data.get(k,'')) if len(str(data.get(k,''))) <= w else '%s...' %str(data.get(k,''))[:(w-3)] for k,w in self.width.items() }
data = {
k: str(data.get(k, ""))
if len(str(data.get(k, ""))) <= w
else "%s..." % str(data.get(k, ""))[: (w - 3)]
for k, w in self.width.items()
}
return self.fmt.format(**data)
def __call__(self, data_list, totals=None):
@@ -80,89 +106,111 @@ class TablePrinter(object):
res.insert(len(res), _r(totals))
if self.bl:
res.insert(len(res), _r(self.bl, True))
return '\n'.join(res)
return "\n".join(res)
def get_function_args(func_ref):
try:
return [p for p in inspect.getargspec(func_ref).args if p != 'self']
return [p for p in inspect.getargspec(func_ref).args if p != "self"]
except:
return None
def store_class_fields(class_ref, args_passed):
""" Store the passed in class fields in self
"""
"""Store the passed in class fields in self"""
params = get_function_args(class_ref.__init__)
for p in params: setattr(class_ref, p, args_passed[p])
for p in params:
setattr(class_ref, p, args_passed[p])
def sum_dict_key(d, key, cast_type=None):
""" Sum together all values matching a key given a passed dict
"""
return reduce( (lambda x, y: x + y), [eval("%s(x['%s'])" %(cast_type, key)) if cast_type else x[key] for x in d] )
"""Sum together all values matching a key given a passed dict"""
return reduce(
(lambda x, y: x + y),
[eval("%s(x['%s'])" % (cast_type, key)) if cast_type else x[key] for x in d],
)
def case_name(name):
""" Test case name decorator to override function name.
"""
"""Test case name decorator to override function name."""
def decorator(function):
function.__dict__['test_case_name'] = name
function.__dict__["test_case_name"] = name
return function
return decorator
def skip_device(name):
""" Decorator to mark a test to only run on certain devices
Takes single device name or list of names as argument
"""Decorator to mark a test to only run on certain devices
Takes single device name or list of names as argument
"""
def decorator(function):
name_list = name if type(name) == list else [name]
function.__dict__['skip_device'] = name_list
function.__dict__["skip_device"] = name_list
return function
return decorator
def _set_test_type(function, test_type):
""" Test type setter
"""
if 'test_type' in function.__dict__:
function.__dict__['test_type'].append(test_type)
"""Test type setter"""
if "test_type" in function.__dict__:
function.__dict__["test_type"].append(test_type)
else:
function.__dict__['test_type'] = [test_type]
function.__dict__["test_type"] = [test_type]
return function
def smoke(function):
""" Test decorator to mark test as smoke type
"""
return _set_test_type(function, 'smoke')
"""Test decorator to mark test as smoke type"""
return _set_test_type(function, "smoke")
def guide_discovery(function):
""" Test decorator to mark test as guide_discovery type
"""
return _set_test_type(function, 'guide_discovery')
"""Test decorator to mark test as guide_discovery type"""
return _set_test_type(function, "guide_discovery")
def focus(function):
""" Test decorator to mark test as focus type to all rspec style debugging of cases
"""
return _set_test_type(function, 'focus')
"""Test decorator to mark test as focus type to all rspec style debugging of cases"""
return _set_test_type(function, "focus")
class _WritelnDecorator(object):
"""Used to decorate file-like objects with a handy 'writeln' method"""
def __init__(self,stream):
def __init__(self, stream):
self.stream = stream
def __getattr__(self, attr):
if attr in ('stream', '__getstate__'):
if attr in ("stream", "__getstate__"):
raise AttributeError(attr)
return getattr(self.stream,attr)
return getattr(self.stream, attr)
def writeln(self, arg=None):
if arg:
self.write(arg)
self.write('\n') # text-mode streams translate to \r\n if needed
self.write("\n") # text-mode streams translate to \r\n if needed
class CustomTextTestResult(result.TestResult):
_num_formatting_chars = 150
_execution_time_significant_digits = 4
_pass_percentage_significant_digits = 2
def __init__(self, stream, descriptions, verbosity, results_file_path, result_screenshots_dir, show_previous_results, config, test_types):
def __init__(
self,
stream,
descriptions,
verbosity,
results_file_path,
result_screenshots_dir,
show_previous_results,
config,
test_types,
):
super(CustomTextTestResult, self).__init__(stream, descriptions, verbosity)
store_class_fields(self, locals())
self.show_overall_results = verbosity > 0
@@ -178,12 +226,12 @@ class CustomTextTestResult(result.TestResult):
self.separator3 = "_" * CustomTextTestResult._num_formatting_chars
self.separator4 = "*" * CustomTextTestResult._num_formatting_chars
self.separator_failure = "!" * CustomTextTestResult._num_formatting_chars
self.separator_pre_result = '.' * CustomTextTestResult._num_formatting_chars
self.separator_pre_result = "." * CustomTextTestResult._num_formatting_chars
def getDescription(self, test):
doc_first_line = test.shortDescription()
if self.descriptions and doc_first_line:
return '\n'.join((str(test), doc_first_line))
return "\n".join((str(test), doc_first_line))
else:
return str(test)
@@ -195,109 +243,170 @@ class CustomTextTestResult(result.TestResult):
self.results = None
self.previous_suite_runs = []
if os.path.isfile(self.results_file_path):
with open(self.results_file_path, 'rb') as f:
with open(self.results_file_path, "rb") as f:
try:
self.results = json.load(f)
# recreated results dict with int keys
self.results['suites'] = {int(k):v for (k,v) in list(self.results['suites'].items())}
self.suite_map = {v['name']:int(k) for (k,v) in list(self.results['suites'].items())}
self.previous_suite_runs = list(self.results['suites'].keys())
self.results["suites"] = {
int(k): v for (k, v) in list(self.results["suites"].items())
}
self.suite_map = {
v["name"]: int(k)
for (k, v) in list(self.results["suites"].items())
}
self.previous_suite_runs = list(self.results["suites"].keys())
except:
pass
if not self.results:
self.results = {'suites': {},
'name': '',
'num_passed': 0,
'num_failed': 0,
'num_skipped': 0,
'num_expected_failures': 0,
'execution_time': None}
self.suite_number = int(sorted(self.results['suites'].keys())[-1]) + 1 if len(self.results['suites']) else 0
self.results = {
"suites": {},
"name": "",
"num_passed": 0,
"num_failed": 0,
"num_skipped": 0,
"num_expected_failures": 0,
"execution_time": None,
}
self.suite_number = (
int(sorted(self.results["suites"].keys())[-1]) + 1
if len(self.results["suites"])
else 0
)
self.case_number = 0
self.suite_map = {}
def stopTestRun(self):
# if no tests or some failure occurred execution time may not have been set
try:
self.results['suites'][self.suite_map[self.suite]]['execution_time'] = format(self.suite_execution_time, '.%sf' %CustomTextTestResult._execution_time_significant_digits)
self.results["suites"][self.suite_map[self.suite]]["execution_time"] = (
format(
self.suite_execution_time,
".%sf" % CustomTextTestResult._execution_time_significant_digits,
)
)
except:
pass
self.results['execution_time'] = format(self.total_execution_time, '.%sf' %CustomTextTestResult._execution_time_significant_digits)
self.results["execution_time"] = format(
self.total_execution_time,
".%sf" % CustomTextTestResult._execution_time_significant_digits,
)
self.stream.writeln(self.separator3)
with open(self.results_file_path, 'w') as f:
with open(self.results_file_path, "w") as f:
json.dump(self.results, f)
def startTest(self, test):
suite_base_category = test.__class__.base_test_category if hasattr(test.__class__, 'base_test_category') else ''
self.next_suite = os.path.join(suite_base_category, test.__class__.name if hasattr(test.__class__, 'name') else test.__class__.__name__)
suite_base_category = (
test.__class__.base_test_category
if hasattr(test.__class__, "base_test_category")
else ""
)
self.next_suite = os.path.join(
suite_base_category,
test.__class__.name
if hasattr(test.__class__, "name")
else test.__class__.__name__,
)
self.case = test._testMethodName
super(CustomTextTestResult, self).startTest(test)
if not self.suite or self.suite != self.next_suite:
if self.suite:
self.results['suites'][self.suite_map[self.suite]]['execution_time'] = format(self.suite_execution_time, '.%sf' %CustomTextTestResult._execution_time_significant_digits)
self.results["suites"][self.suite_map[self.suite]]["execution_time"] = (
format(
self.suite_execution_time,
".%sf"
% CustomTextTestResult._execution_time_significant_digits,
)
)
self.suite_execution_time = 0
self.suite = self.next_suite
if self.show_test_info:
self.stream.writeln(self.separator1)
self.stream.writeln("TEST SUITE: %s" %self.suite)
self.stream.writeln("Description: %s" %self.getSuiteDescription(test))
self.stream.writeln("TEST SUITE: %s" % self.suite)
self.stream.writeln("Description: %s" % self.getSuiteDescription(test))
try:
name_override = getattr(test, test._testMethodName).__func__.__dict__['test_case_name']
name_override = getattr(test, test._testMethodName).__func__.__dict__[
"test_case_name"
]
except:
name_override = None
self.case = name_override if name_override else self.case
if self.show_test_info:
# self.stream.writeln(self.separator2)
self.stream.write("CASE: %s" %self.case)
if desc := test.shortDescription(): self.stream.write(" (Description: %s)" % desc)
self.stream.write("CASE: %s" % self.case)
if desc := test.shortDescription():
self.stream.write(" (Description: %s)" % desc)
self.stream.write("... ")
# self.stream.writeln(self.separator2)
self.stream.flush()
self.current_case_number = self.case_number
if self.suite not in self.suite_map:
self.suite_map[self.suite] = self.suite_number
self.results['suites'][self.suite_number] = {
'name': self.suite,
'class': test.__class__.__name__,
'module': re.compile('.* \((.*)\)').match(str(test)).group(1),
'description': self.getSuiteDescription(test),
'cases': {},
'used_case_names': {},
'num_passed': 0,
'num_failed': 0,
'num_skipped': 0,
'num_expected_failures': 0,
'execution_time': None}
self.results["suites"][self.suite_number] = {
"name": self.suite,
"class": test.__class__.__name__,
"module": re.compile(".* \((.*)\)").match(str(test)).group(1),
"description": self.getSuiteDescription(test),
"cases": {},
"used_case_names": {},
"num_passed": 0,
"num_failed": 0,
"num_skipped": 0,
"num_expected_failures": 0,
"execution_time": None,
}
self.suite_number += 1
self.num_cases = 0
self.num_passed = 0
self.num_failed = 0
self.num_skipped = 0
self.num_expected_failures = 0
self.results['suites'][self.suite_map[self.suite]]['cases'][self.case_number] = {
'name': self.case,
'method': test._testMethodName,
'result': None,
'description': test.shortDescription(),
'note': None,
'errors': None,
'failures': None,
'screenshots': [],
'new_version': 'No',
'execution_time': None}
self.results["suites"][self.suite_map[self.suite]]["cases"][
self.case_number
] = {
"name": self.case,
"method": test._testMethodName,
"result": None,
"description": test.shortDescription(),
"note": None,
"errors": None,
"failures": None,
"screenshots": [],
"new_version": "No",
"execution_time": None,
}
self.start_time = time.time()
if self.test_types:
if ('test_type' in getattr(test, test._testMethodName).__func__.__dict__
and set([s.lower() for s in self.test_types]) == set([s.lower() for s in getattr(test, test._testMethodName).__func__.__dict__['test_type']])):
if "test_type" in getattr(
test, test._testMethodName
).__func__.__dict__ and set([s.lower() for s in self.test_types]) == set(
[
s.lower()
for s in getattr(test, test._testMethodName).__func__.__dict__[
"test_type"
]
]
):
pass
else:
getattr(test, test._testMethodName).__func__.__dict__['__unittest_skip_why__'] = 'Test run specified to only run tests of type "%s"' %','.join(self.test_types)
getattr(test, test._testMethodName).__func__.__dict__['__unittest_skip__'] = True
if 'skip_device' in getattr(test, test._testMethodName).__func__.__dict__:
for device in getattr(test, test._testMethodName).__func__.__dict__['skip_device']:
if self.config and device.lower() in self.config['device_name'].lower():
getattr(test, test._testMethodName).__func__.__dict__['__unittest_skip_why__'] = 'Test is marked to be skipped on %s' %device
getattr(test, test._testMethodName).__func__.__dict__['__unittest_skip__'] = True
getattr(test, test._testMethodName).__func__.__dict__[
"__unittest_skip_why__"
] = 'Test run specified to only run tests of type "%s"' % ",".join(
self.test_types
)
getattr(test, test._testMethodName).__func__.__dict__[
"__unittest_skip__"
] = True
if "skip_device" in getattr(test, test._testMethodName).__func__.__dict__:
for device in getattr(test, test._testMethodName).__func__.__dict__[
"skip_device"
]:
if self.config and device.lower() in self.config["device_name"].lower():
getattr(test, test._testMethodName).__func__.__dict__[
"__unittest_skip_why__"
] = "Test is marked to be skipped on %s" % device
getattr(test, test._testMethodName).__func__.__dict__[
"__unittest_skip__"
] = True
break
def stopTest(self, test):
@@ -307,19 +416,32 @@ class CustomTextTestResult(result.TestResult):
self.total_execution_time += self.execution_time
super(CustomTextTestResult, self).stopTest(test)
self.num_cases += 1
self.results['suites'][self.suite_map[self.suite]]['num_passed'] = self.num_passed
self.results['suites'][self.suite_map[self.suite]]['num_failed'] = self.num_failed
self.results['suites'][self.suite_map[self.suite]]['num_skipped'] = self.num_skipped
self.results['suites'][self.suite_map[self.suite]]['num_expected_failures'] = self.num_expected_failures
self.results['suites'][self.suite_map[self.suite]]['cases'][self.current_case_number]['execution_time']= format(self.execution_time, '.%sf' %CustomTextTestResult._execution_time_significant_digits)
self.results['num_passed'] += self.num_passed
self.results['num_failed'] += self.num_failed
self.results['num_skipped'] += self.num_skipped
self.results['num_expected_failures'] += self.num_expected_failures
self.results["suites"][self.suite_map[self.suite]]["num_passed"] = (
self.num_passed
)
self.results["suites"][self.suite_map[self.suite]]["num_failed"] = (
self.num_failed
)
self.results["suites"][self.suite_map[self.suite]]["num_skipped"] = (
self.num_skipped
)
self.results["suites"][self.suite_map[self.suite]]["num_expected_failures"] = (
self.num_expected_failures
)
self.results["suites"][self.suite_map[self.suite]]["cases"][
self.current_case_number
]["execution_time"] = format(
self.execution_time,
".%sf" % CustomTextTestResult._execution_time_significant_digits,
)
self.results["num_passed"] += self.num_passed
self.results["num_failed"] += self.num_failed
self.results["num_skipped"] += self.num_skipped
self.results["num_expected_failures"] += self.num_expected_failures
self.case_number += 1
def print_error_string(self, err):
error_string = ''.join(traceback.format_exception(err[0], err[1], err[2]))
error_string = "".join(traceback.format_exception(err[0], err[1], err[2]))
if self.show_errors:
self.stream.writeln(self.separator_failure)
self.stream.write(error_string)
@@ -328,7 +450,9 @@ class CustomTextTestResult(result.TestResult):
def addScreenshots(self, test):
for root, dirs, files in os.walk(self.result_screenshots_dir):
for file in files:
self.results['suites'][self.suite_map[self.suite]]['cases'][self.current_case_number]['screenshots'].append(os.path.join(root, file))
self.results["suites"][self.suite_map[self.suite]]["cases"][
self.current_case_number
]["screenshots"].append(os.path.join(root, file))
def addSuccess(self, test):
super(CustomTextTestResult, self).addSuccess(test)
@@ -336,7 +460,9 @@ class CustomTextTestResult(result.TestResult):
# self.stream.writeln(self.separator_pre_result)
self.stream.writeln("PASS")
self.stream.flush()
self.results['suites'][self.suite_map[self.suite]]['cases'][self.current_case_number]['result'] = 'passed'
self.results["suites"][self.suite_map[self.suite]]["cases"][
self.current_case_number
]["result"] = "passed"
self.num_passed += 1
self.addScreenshots(test)
@@ -347,8 +473,12 @@ class CustomTextTestResult(result.TestResult):
# self.stream.writeln(self.separator_pre_result)
self.stream.writeln("ERROR")
self.stream.flush()
self.results['suites'][self.suite_map[self.suite]]['cases'][self.current_case_number]['result'] = 'error'
self.results['suites'][self.suite_map[self.suite]]['cases'][self.current_case_number]['errors'] = error_string
self.results["suites"][self.suite_map[self.suite]]["cases"][
self.current_case_number
]["result"] = "error"
self.results["suites"][self.suite_map[self.suite]]["cases"][
self.current_case_number
]["errors"] = error_string
self.num_failed += 1
self.addScreenshots(test)
@@ -359,8 +489,12 @@ class CustomTextTestResult(result.TestResult):
# self.stream.writeln(self.separator_pre_result)
self.stream.writeln("FAIL")
self.stream.flush()
self.results['suites'][self.suite_map[self.suite]]['cases'][self.current_case_number]['result'] = 'failed'
self.results['suites'][self.suite_map[self.suite]]['cases'][self.current_case_number]['failures'] = error_string
self.results["suites"][self.suite_map[self.suite]]["cases"][
self.current_case_number
]["result"] = "failed"
self.results["suites"][self.suite_map[self.suite]]["cases"][
self.current_case_number
]["failures"] = error_string
self.num_failed += 1
self.addScreenshots(test)
@@ -370,8 +504,12 @@ class CustomTextTestResult(result.TestResult):
# self.stream.writeln(self.separator_pre_result)
self.stream.writeln("SKIPPED {0!r}".format(reason))
self.stream.flush()
self.results['suites'][self.suite_map[self.suite]]['cases'][self.current_case_number]['result'] = 'skipped'
self.results['suites'][self.suite_map[self.suite]]['cases'][self.current_case_number]['note'] = reason
self.results["suites"][self.suite_map[self.suite]]["cases"][
self.current_case_number
]["result"] = "skipped"
self.results["suites"][self.suite_map[self.suite]]["cases"][
self.current_case_number
]["note"] = reason
self.num_skipped += 1
def addExpectedFailure(self, test, err):
@@ -380,7 +518,9 @@ class CustomTextTestResult(result.TestResult):
# self.stream.writeln(self.separator_pre_result)
self.stream.writeln("EXPECTED FAILURE")
self.stream.flush()
self.results['suites'][self.suite_map[self.suite]]['cases'][self.current_case_number]['result'] = 'expected_failure'
self.results["suites"][self.suite_map[self.suite]]["cases"][
self.current_case_number
]["result"] = "expected_failure"
self.num_expected_failures += 1
self.addScreenshots(test)
@@ -396,103 +536,189 @@ class CustomTextTestResult(result.TestResult):
def printOverallSuiteResults(self, r):
self.stream.writeln()
self.stream.writeln(self.separator4)
self.stream.writeln('OVERALL SUITE RESULTS')
self.stream.writeln("OVERALL SUITE RESULTS")
fmt = [
('SUITE', 'suite', 50, 'left'),
('CASES', 'cases', 15, 'right'),
('PASSED', 'passed', 15, 'right'),
('FAILED', 'failed', 15, 'right'),
('SKIPPED', 'skipped', 15, 'right'),
('%', 'percentage', 20, 'right'),
('TIME (s)', 'time', 20, 'right')
("SUITE", "suite", 50, "left"),
("CASES", "cases", 15, "right"),
("PASSED", "passed", 15, "right"),
("FAILED", "failed", 15, "right"),
("SKIPPED", "skipped", 15, "right"),
("%", "percentage", 20, "right"),
("TIME (s)", "time", 20, "right"),
]
data = []
for x in r: data.append({'suite': r[x]['name'],
'cases': r[x]['num_passed'] + r[x]['num_failed'],
'passed': r[x]['num_passed'],
'failed': r[x]['num_failed'],
'skipped': r[x]['num_skipped'],
'expected_failures': r[x]['num_expected_failures'],
'percentage': float(r[x]['num_passed'])/(r[x]['num_passed'] + r[x]['num_failed']) * 100 if (r[x]['num_passed'] + r[x]['num_failed']) > 0 else 0,
'time': r[x]['execution_time']})
total_suites_passed = len([x for x in data if not x['failed']])
total_suites_passed_percentage = format(float(total_suites_passed)/len(data) * 100, '.%sf' %CustomTextTestResult._pass_percentage_significant_digits)
totals = {'suite': 'TOTALS %s/%s (%s%%) suites passed' %(total_suites_passed, len(data), total_suites_passed_percentage),
'cases': sum_dict_key(data, 'cases'),
'passed': sum_dict_key(data, 'passed'),
'failed': sum_dict_key(data, 'failed'),
'skipped': sum_dict_key(data, 'skipped'),
'percentage': sum_dict_key(data, 'percentage')/len(data),
'time': sum_dict_key(data, 'time', 'float')}
for x in data: operator.setitem(x, 'percentage', format(x['percentage'], '.%sf' %CustomTextTestResult._pass_percentage_significant_digits))
totals['percentage'] = format(totals['percentage'], '.%sf' %CustomTextTestResult._pass_percentage_significant_digits)
self.stream.writeln( TablePrinter(fmt, tl=self.separator1, ul=self.separator2, bl=self.separator3)(data, totals) )
for x in r:
data.append(
{
"suite": r[x]["name"],
"cases": r[x]["num_passed"] + r[x]["num_failed"],
"passed": r[x]["num_passed"],
"failed": r[x]["num_failed"],
"skipped": r[x]["num_skipped"],
"expected_failures": r[x]["num_expected_failures"],
"percentage": float(r[x]["num_passed"])
/ (r[x]["num_passed"] + r[x]["num_failed"])
* 100
if (r[x]["num_passed"] + r[x]["num_failed"]) > 0
else 0,
"time": r[x]["execution_time"],
}
)
total_suites_passed = len([x for x in data if not x["failed"]])
total_suites_passed_percentage = format(
float(total_suites_passed) / len(data) * 100,
".%sf" % CustomTextTestResult._pass_percentage_significant_digits,
)
totals = {
"suite": "TOTALS %s/%s (%s%%) suites passed"
% (total_suites_passed, len(data), total_suites_passed_percentage),
"cases": sum_dict_key(data, "cases"),
"passed": sum_dict_key(data, "passed"),
"failed": sum_dict_key(data, "failed"),
"skipped": sum_dict_key(data, "skipped"),
"percentage": sum_dict_key(data, "percentage") / len(data),
"time": sum_dict_key(data, "time", "float"),
}
for x in data:
operator.setitem(
x,
"percentage",
format(
x["percentage"],
".%sf" % CustomTextTestResult._pass_percentage_significant_digits,
),
)
totals["percentage"] = format(
totals["percentage"],
".%sf" % CustomTextTestResult._pass_percentage_significant_digits,
)
self.stream.writeln(
TablePrinter(
fmt, tl=self.separator1, ul=self.separator2, bl=self.separator3
)(data, totals)
)
self.stream.writeln()
def printIndividualSuiteResults(self, r):
self.stream.writeln()
self.stream.writeln(self.separator4)
self.stream.writeln('INDIVIDUAL SUITE RESULTS')
self.stream.writeln("INDIVIDUAL SUITE RESULTS")
fmt = [
('CASE', 'case', 50, 'left'),
('DESCRIPTION', 'description', 50, 'right'),
('RESULT', 'result', 25, 'right'),
('TIME (s)', 'time', 25, 'right')
("CASE", "case", 50, "left"),
("DESCRIPTION", "description", 50, "right"),
("RESULT", "result", 25, "right"),
("TIME (s)", "time", 25, "right"),
]
for suite in r:
self.stream.writeln(self.separator1)
self.stream.write('{0: <50}'.format('SUITE: %s' %r[suite]['name']))
self.stream.writeln('{0: <100}'.format('DESCRIPTION: %s' %(r[suite]['description'] if not r[suite]['description'] or len(r[suite]['description']) <= (100 - len('DESCRIPTION: '))
else '%s...' %r[suite]['description'][:(97 - len('DESCRIPTION: '))])))
self.stream.write("{0: <50}".format("SUITE: %s" % r[suite]["name"]))
self.stream.writeln(
"{0: <100}".format(
"DESCRIPTION: %s"
% (
r[suite]["description"]
if not r[suite]["description"]
or len(r[suite]["description"]) <= (100 - len("DESCRIPTION: "))
else "%s..."
% r[suite]["description"][: (97 - len("DESCRIPTION: "))]
)
)
)
data = []
cases = r[suite]['cases']
for x in cases: data.append({'case': cases[x]['name'],
'description': cases[x]['description'],
'result': cases[x]['result'].upper() if cases[x]['result'] else cases[x]['result'],
'time': cases[x]['execution_time']})
self.stream.writeln( TablePrinter(fmt, tl=self.separator1, ul=self.separator2)(data) )
cases = r[suite]["cases"]
for x in cases:
data.append(
{
"case": cases[x]["name"],
"description": cases[x]["description"],
"result": cases[x]["result"].upper()
if cases[x]["result"]
else cases[x]["result"],
"time": cases[x]["execution_time"],
}
)
self.stream.writeln(
TablePrinter(fmt, tl=self.separator1, ul=self.separator2)(data)
)
self.stream.writeln(self.separator3)
self.stream.writeln()
def printErrorsOverview(self, r):
self.stream.writeln()
self.stream.writeln(self.separator4)
self.stream.writeln('FAILURES AND ERRORS OVERVIEW')
self.stream.writeln("FAILURES AND ERRORS OVERVIEW")
fmt = [
('SUITE', 'suite', 50, 'left'),
('CASE', 'case', 50, 'left'),
('RESULT', 'result', 50, 'right')
("SUITE", "suite", 50, "left"),
("CASE", "case", 50, "left"),
("RESULT", "result", 50, "right"),
]
data = []
for suite in r:
cases = {k:v for (k,v) in list(r[suite]['cases'].items()) if v['failures'] or v['errors']}
for x in cases: data.append({'suite': '%s%s' %(r[suite]['name'], ' (%s)' %r[suite]['module'] if r[suite]['class'] != r[suite]['name'] else ''),
'case': '%s%s' %(cases[x]['name'], ' (%s)' %cases[x]['method'] if cases[x]['name'] != cases[x]['method'] else ''),
'result': cases[x]['result'].upper()})
self.stream.writeln( TablePrinter(fmt, tl=self.separator1, ul=self.separator2)(data) )
cases = {
k: v
for (k, v) in list(r[suite]["cases"].items())
if v["failures"] or v["errors"]
}
for x in cases:
data.append(
{
"suite": "%s%s"
% (
r[suite]["name"],
" (%s)" % r[suite]["module"]
if r[suite]["class"] != r[suite]["name"]
else "",
),
"case": "%s%s"
% (
cases[x]["name"],
" (%s)" % cases[x]["method"]
if cases[x]["name"] != cases[x]["method"]
else "",
),
"result": cases[x]["result"].upper(),
}
)
self.stream.writeln(
TablePrinter(fmt, tl=self.separator1, ul=self.separator2)(data)
)
self.stream.writeln(self.separator3)
self.stream.writeln()
def printErrorsDetail(self, r):
self.stream.writeln()
self.stream.writeln(self.separator4)
self.stream.writeln('FAILURES AND ERRORS DETAIL')
self.stream.writeln("FAILURES AND ERRORS DETAIL")
for suite in r:
failures_and_errors = [k for (k,v) in list(r[suite]['cases'].items()) if v['failures'] or v['errors']]
#print failures_and_errors
suite_str = '%s%s' %(r[suite]['name'], ' (%s)' %r[suite]['module'] if r[suite]['class'] != r[suite]['name'] else '')
failures_and_errors = [
k
for (k, v) in list(r[suite]["cases"].items())
if v["failures"] or v["errors"]
]
# print failures_and_errors
suite_str = "%s%s" % (
r[suite]["name"],
" (%s)" % r[suite]["module"]
if r[suite]["class"] != r[suite]["name"]
else "",
)
for case in failures_and_errors:
case_ref = r[suite]['cases'][case]
case_str = '%s%s' %(case_ref['name'], ' (%s)' %case_ref['method'] if case_ref['name'] != case_ref['method'] else '')
errors = case_ref['errors']
failures = case_ref['failures']
case_ref = r[suite]["cases"][case]
case_str = "%s%s" % (
case_ref["name"],
" (%s)" % case_ref["method"]
if case_ref["name"] != case_ref["method"]
else "",
)
errors = case_ref["errors"]
failures = case_ref["failures"]
self.stream.writeln(self.separator1)
if errors:
self.stream.writeln('ERROR: %s [%s]' %(case_str, suite_str))
self.stream.writeln("ERROR: %s [%s]" % (case_str, suite_str))
self.stream.writeln(self.separator2)
self.stream.writeln(errors)
if failures:
self.stream.writeln('FAILURE: %s [%s]' %(case_str, suite_str))
self.stream.writeln("FAILURE: %s [%s]" % (case_str, suite_str))
self.stream.writeln(self.separator2)
self.stream.writeln(failures)
self.stream.writeln(self.separator3)
@@ -501,52 +727,85 @@ class CustomTextTestResult(result.TestResult):
def printSkippedDetail(self, r):
self.stream.writeln()
self.stream.writeln(self.separator4)
self.stream.writeln('SKIPPED DETAIL')
self.stream.writeln("SKIPPED DETAIL")
fmt = [
('SUITE', 'suite', 50, 'left'),
('CASE', 'case', 50, 'left'),
('REASON', 'reason', 50, 'right')
("SUITE", "suite", 50, "left"),
("CASE", "case", 50, "left"),
("REASON", "reason", 50, "right"),
]
data = []
for suite in r:
cases = {k:v for (k,v) in list(r[suite]['cases'].items()) if v['result'] == 'skipped'}
for x in cases: data.append({'suite': '%s%s' %(r[suite]['name'], ' (%s)' %r[suite]['module'] if r[suite]['class'] != r[suite]['name'] else ''),
'case': '%s%s' %(cases[x]['name'], ' (%s)' %cases[x]['method'] if cases[x]['name'] != cases[x]['method'] else ''),
'reason': cases[x]['note']})
self.stream.writeln( TablePrinter(fmt, tl=self.separator1, ul=self.separator2)(data) )
cases = {
k: v
for (k, v) in list(r[suite]["cases"].items())
if v["result"] == "skipped"
}
for x in cases:
data.append(
{
"suite": "%s%s"
% (
r[suite]["name"],
" (%s)" % r[suite]["module"]
if r[suite]["class"] != r[suite]["name"]
else "",
),
"case": "%s%s"
% (
cases[x]["name"],
" (%s)" % cases[x]["method"]
if cases[x]["name"] != cases[x]["method"]
else "",
),
"reason": cases[x]["note"],
}
)
self.stream.writeln(
TablePrinter(fmt, tl=self.separator1, ul=self.separator2)(data)
)
self.stream.writeln(self.separator3)
self.stream.writeln()
def returnCode(self):
return not self.wasSuccessful()
class CustomTextTestRunner(unittest.TextTestRunner):
"""A test runner class that displays results in textual form.
It prints out the names of tests as they are run, errors as they
occur, and a summary of the results at the end of the test run.
"""
def __init__(self,
stream=sys.stderr,
descriptions=True,
verbosity=1,
failfast=False,
buffer=False,
resultclass=CustomTextTestResult,
results_file_path="results.json",
result_screenshots_dir='',
show_previous_results=False,
test_name=None,
test_description=None,
config=None,
test_types=None):
def __init__(
self,
stream=sys.stderr,
descriptions=True,
verbosity=1,
failfast=False,
buffer=False,
resultclass=CustomTextTestResult,
results_file_path="results.json",
result_screenshots_dir="",
show_previous_results=False,
test_name=None,
test_description=None,
config=None,
test_types=None,
):
store_class_fields(self, locals())
self.stream = _WritelnDecorator(stream)
def _makeResult(self):
return self.resultclass(self.stream, self.descriptions, self.verbosity,
self.results_file_path, self.result_screenshots_dir, self.show_previous_results,
self.config, self.test_types)
return self.resultclass(
self.stream,
self.descriptions,
self.verbosity,
self.results_file_path,
self.result_screenshots_dir,
self.show_previous_results,
self.config,
self.test_types,
)
def run(self, test):
output = ""
@@ -556,22 +815,26 @@ class CustomTextTestRunner(unittest.TextTestRunner):
result.failfast = self.failfast
result.buffer = self.buffer
startTime = time.time()
startTestRun = getattr(result, 'startTestRun', None)
startTestRun = getattr(result, "startTestRun", None)
if startTestRun is not None:
startTestRun()
try:
test(result)
finally:
stopTestRun = getattr(result, 'stopTestRun', None)
stopTestRun = getattr(result, "stopTestRun", None)
if stopTestRun is not None:
stopTestRun()
stopTime = time.time()
timeTaken = stopTime - startTime
# filter results to output
if result.show_previous_results:
r = result.results['suites']
r = result.results["suites"]
else:
r = {k:v for (k,v) in list(result.results['suites'].items()) if k not in result.previous_suite_runs}
r = {
k: v
for (k, v) in list(result.results["suites"].items())
if k not in result.previous_suite_runs
}
# print results based on verbosity
if result.show_all:
result.printSkippedDetail(r)
@@ -584,15 +847,17 @@ class CustomTextTestRunner(unittest.TextTestRunner):
if result.show_overall_results:
result.printOverallSuiteResults(r)
run = result.testsRun
self.stream.writeln("Ran %d test case%s in %.4fs" %
(run, run != 1 and "s" or "", timeTaken))
self.stream.writeln(
"Ran %d test case%s in %.4fs" % (run, run != 1 and "s" or "", timeTaken)
)
self.stream.writeln()
expectedFails = unexpectedSuccesses = skipped = 0
try:
results = map(len, (result.expectedFailures,
result.unexpectedSuccesses,
result.skipped))
results = map(
len,
(result.expectedFailures, result.unexpectedSuccesses, result.skipped),
)
except AttributeError:
pass
else:

View File

@@ -6,8 +6,9 @@ import os
testnames = findtests()
# idk why this fixes the hanging, if it does
testnames.remove('test_importlib')
testnames.insert(0, 'test_importlib')
testnames.remove("test_importlib")
testnames.insert(0, "test_importlib")
def loadTestsOrSkip(loader, name):
try:
@@ -17,12 +18,16 @@ def loadTestsOrSkip(loader, name):
@unittest.skip(str(exc))
def testSkipped(self):
pass
attrs = {name: testSkipped}
TestClass = type("ModuleSkipped", (unittest.TestCase,), attrs)
return loader.suiteClass((TestClass(name),))
loader = unittest.defaultTestLoader
suite = loader.suiteClass([loadTestsOrSkip(loader, 'test.' + name) for name in testnames])
suite = loader.suiteClass(
[loadTestsOrSkip(loader, "test." + name) for name in testnames]
)
resultsfile = os.path.join(os.path.dirname(__file__), "cpython_tests_results.json")
if os.path.exists(resultsfile):

View File

@@ -1,3 +1,2 @@
l = [1,2,3]
assert [1,2,3,4,5] == (l + [4,5])
l = [1, 2, 3]
assert [1, 2, 3, 4, 5] == (l + [4, 5])

View File

@@ -1,3 +1,3 @@
x = [1,999,3]
x = [1, 999, 3]
x[1] = 2
assert [1,2,3] == x
assert [1, 2, 3] == x

View File

@@ -2,4 +2,3 @@ assert abs(-3) == 3
assert abs(7) == 7
assert abs(-3.21) == 3.21
assert abs(6.25) == 6.25

View File

@@ -1,7 +1,7 @@
assert ascii('hello world') == "'hello world'"
assert ascii('안녕 세상') == "'\\uc548\\ub155 \\uc138\\uc0c1'"
assert ascii('안녕 RustPython') == "'\\uc548\\ub155 RustPython'"
assert ascii(5) == '5'
assert ascii("hello world") == "'hello world'"
assert ascii("안녕 세상") == "'\\uc548\\ub155 \\uc138\\uc0c1'"
assert ascii("안녕 RustPython") == "'\\uc548\\ub155 RustPython'"
assert ascii(5) == "5"
assert ascii(chr(0x10001)) == "'\\U00010001'"
assert ascii(chr(0x9999)) == "'\\u9999'"
assert ascii(chr(0x0A)) == "'\\n'"
assert ascii(chr(0x0A)) == "'\\n'"

View File

@@ -1,13 +1,13 @@
assert bin(0) == '0b0'
assert bin(1) == '0b1'
assert bin(-1) == '-0b1'
assert bin(2**24) == '0b1' + '0' * 24
assert bin(2**24-1) == '0b' + '1' * 24
assert bin(-(2**24)) == '-0b1' + '0' * 24
assert bin(-(2**24-1)) == '-0b' + '1' * 24
assert bin(0) == "0b0"
assert bin(1) == "0b1"
assert bin(-1) == "-0b1"
assert bin(2**24) == "0b1" + "0" * 24
assert bin(2**24 - 1) == "0b" + "1" * 24
assert bin(-(2**24)) == "-0b1" + "0" * 24
assert bin(-(2**24 - 1)) == "-0b" + "1" * 24
a = 2 ** 65
assert bin(a) == '0b1' + '0' * 65
assert bin(a-1) == '0b' + '1' * 65
assert bin(-(a)) == '-0b1' + '0' * 65
assert bin(-(a-1)) == '-0b' + '1' * 65
a = 2**65
assert bin(a) == "0b1" + "0" * 65
assert bin(a - 1) == "0b" + "1" * 65
assert bin(-(a)) == "-0b1" + "0" * 65
assert bin(-(a - 1)) == "-0b" + "1" * 65

View File

@@ -30,18 +30,20 @@ if not {} and not [1]:
if not object():
raise BaseException
class Falsey:
def __bool__(self):
return False
assert not Falsey()
assert (True or fake) # noqa: F821
assert (False or True)
assert True or fake # noqa: F821
assert False or True
assert not (False or False)
assert ("thing" or 0) == "thing"
assert (True and True)
assert True and True
assert not (False and fake) # noqa: F821
assert (True and 5) == 5
@@ -92,15 +94,17 @@ assert bool(set()) is False
assert bool({"key": "value"}) is True
assert bool([1]) is True
assert bool(set([1,2])) is True
assert bool(set([1, 2])) is True
assert repr(True) == "True"
# Check __len__ work
class TestMagicMethodLenZero:
def __len__(self):
return 0
class TestMagicMethodLenOne:
def __len__(self):
return 1
@@ -118,6 +122,7 @@ class TestMagicMethodBoolTrueLenFalse:
def __len__(self):
return 0
class TestMagicMethodBoolFalseLenTrue:
def __bool__(self):
return False
@@ -125,6 +130,7 @@ class TestMagicMethodBoolFalseLenTrue:
def __len__(self):
return 1
assert bool(TestMagicMethodBoolTrueLenFalse()) is True
assert bool(TestMagicMethodBoolFalseLenTrue()) is False
@@ -134,9 +140,11 @@ class TestBoolThrowError:
def __bool__(self):
return object()
with assert_raises(TypeError):
bool(TestBoolThrowError())
class TestLenThrowError:
def __len__(self):
return object()
@@ -145,6 +153,7 @@ class TestLenThrowError:
with assert_raises(TypeError):
bool(TestLenThrowError())
# Verify that TypeError occurs when bad things are returned
# from __bool__(). This isn't really a bool test, but
# it's related.
@@ -152,31 +161,45 @@ def check(o):
with assert_raises(TypeError):
bool(o)
class Foo(object):
def __bool__(self):
return self
check(Foo())
class Bar(object):
def __bool__(self):
return "Yes"
check(Bar())
class Baz(int):
def __bool__(self):
return self
check(Baz())
# __bool__() must return a bool not an int
class Spam(int):
def __bool__(self):
return 1
check(Spam())
class Eggs:
def __len__(self):
return -1
with assert_raises(ValueError):
bool(Eggs())

View File

@@ -40,9 +40,11 @@ assert (
)
assert repr(bytearray(b"abcd")) == "bytearray(b'abcd')"
class B(bytearray):
pass
assert repr(B()) == "B(b'')"
assert (
repr(B([0, 1, 9, 10, 11, 13, 31, 32, 33, 89, 120, 255]))
@@ -283,9 +285,9 @@ assert bytearray(b"").join(
) == bytearray(b"jiljlkmoomkaaaa")
with assert_raises(TypeError):
bytearray(b"").join((b"km", "kl"))
assert bytearray(b"abc").join((
bytearray(b"123"), bytearray(b"xyz")
)) == bytearray(b"123abcxyz")
assert bytearray(b"abc").join((bytearray(b"123"), bytearray(b"xyz"))) == bytearray(
b"123abcxyz"
)
# endswith startswith
@@ -372,16 +374,45 @@ assert bytearray(b" spacious \n ").rstrip() == bytearray(b" spacious")
assert bytearray(b"mississippi").rstrip(b"ipz") == bytearray(b"mississ")
# split
assert bytearray(b"1,2,3").split(bytearray(b",")) == [bytearray(b"1"), bytearray(b"2"), bytearray(b"3")]
assert bytearray(b"1,2,3").split(bytearray(b","), maxsplit=1) == [bytearray(b"1"), bytearray(b"2,3")]
assert bytearray(b"1,2,,3,").split(bytearray(b",")) == [bytearray(b"1"), bytearray(b"2"), bytearray(b""), bytearray(b"3"), bytearray(b"")]
assert bytearray(b"1 2 3").split() == [bytearray(b"1"), bytearray(b"2"), bytearray(b"3")]
assert bytearray(b"1,2,3").split(bytearray(b",")) == [
bytearray(b"1"),
bytearray(b"2"),
bytearray(b"3"),
]
assert bytearray(b"1,2,3").split(bytearray(b","), maxsplit=1) == [
bytearray(b"1"),
bytearray(b"2,3"),
]
assert bytearray(b"1,2,,3,").split(bytearray(b",")) == [
bytearray(b"1"),
bytearray(b"2"),
bytearray(b""),
bytearray(b"3"),
bytearray(b""),
]
assert bytearray(b"1 2 3").split() == [
bytearray(b"1"),
bytearray(b"2"),
bytearray(b"3"),
]
assert bytearray(b"1 2 3").split(maxsplit=1) == [bytearray(b"1"), bytearray(b"2 3")]
assert bytearray(b" 1 2 3 ").split() == [bytearray(b"1"), bytearray(b"2"), bytearray(b"3")]
assert bytearray(b"k\ruh\nfz e f").split() == [bytearray(b"k"), bytearray(b"uh"), bytearray(b"fz"), bytearray(b"e"), bytearray(b"f")]
assert bytearray(b"Two lines\n").split(bytearray(b"\n")) == [bytearray(b"Two lines"), bytearray(b"")]
assert bytearray(b" 1 2 3 ").split() == [
bytearray(b"1"),
bytearray(b"2"),
bytearray(b"3"),
]
assert bytearray(b"k\ruh\nfz e f").split() == [
bytearray(b"k"),
bytearray(b"uh"),
bytearray(b"fz"),
bytearray(b"e"),
bytearray(b"f"),
]
assert bytearray(b"Two lines\n").split(bytearray(b"\n")) == [
bytearray(b"Two lines"),
bytearray(b""),
]
assert bytearray(b"").split() == []
assert bytearray(b"").split(bytearray(b"\n")) == [bytearray(b"")]
assert bytearray(b"\n").split(bytearray(b"\n")) == [bytearray(b""), bytearray(b"")]
@@ -534,16 +565,21 @@ while n_sp < len(SPLIT_FIXTURES):
i = SPLIT_FIXTURES[n_sp]
sep = None if i[1] == None else bytearray(i[1])
try:
assert bytearray(i[0]).split(sep=sep, maxsplit=i[4]) == [bytearray(j) for j in i[2]]
assert bytearray(i[0]).split(sep=sep, maxsplit=i[4]) == [
bytearray(j) for j in i[2]
]
except AssertionError:
print(i[0], i[1], i[2])
print(
"Expected : ", [list(x) for x in bytearray(i[0]).split(sep=sep, maxsplit=i[4])]
"Expected : ",
[list(x) for x in bytearray(i[0]).split(sep=sep, maxsplit=i[4])],
)
break
try:
assert bytearray(i[0]).rsplit(sep=sep, maxsplit=i[4]) == [bytearray(j) for j in i[3]]
assert bytearray(i[0]).rsplit(sep=sep, maxsplit=i[4]) == [
bytearray(j) for j in i[3]
]
except AssertionError:
print(i[0], i[1], i[2])
print(
@@ -557,34 +593,61 @@ while n_sp < len(SPLIT_FIXTURES):
# expandtabs
a = bytearray(b"\x01\x03\r\x05\t8CYZ\t\x06CYZ\t\x17cba`\n\x12\x13\x14")
assert (
a.expandtabs() == bytearray(b"\x01\x03\r\x05 8CYZ \x06CYZ \x17cba`\n\x12\x13\x14")
assert a.expandtabs() == bytearray(
b"\x01\x03\r\x05 8CYZ \x06CYZ \x17cba`\n\x12\x13\x14"
)
assert a.expandtabs(5) == bytearray(
b"\x01\x03\r\x05 8CYZ \x06CYZ \x17cba`\n\x12\x13\x14"
)
assert bytearray(b"01\t012\t0123\t01234").expandtabs() == bytearray(
b"01 012 0123 01234"
)
assert bytearray(b"01\t012\t0123\t01234").expandtabs(4) == bytearray(
b"01 012 0123 01234"
)
assert a.expandtabs(5) == bytearray(b"\x01\x03\r\x05 8CYZ \x06CYZ \x17cba`\n\x12\x13\x14")
assert bytearray(b"01\t012\t0123\t01234").expandtabs() == bytearray(b"01 012 0123 01234")
assert bytearray(b"01\t012\t0123\t01234").expandtabs(4) == bytearray(b"01 012 0123 01234")
assert bytearray(b"123\t123").expandtabs(-5) == bytearray(b"123123")
assert bytearray(b"123\t123").expandtabs(0) == bytearray(b"123123")
# # partition
assert bytearray(b"123456789").partition(b"45") == ((b"123"), bytearray(b"45"), bytearray(b"6789"))
assert bytearray(b"14523456789").partition(b"45") == ((b"1"), bytearray(b"45"), bytearray(b"23456789"))
assert bytearray(b"123456789").partition(b"45") == (
(b"123"),
bytearray(b"45"),
bytearray(b"6789"),
)
assert bytearray(b"14523456789").partition(b"45") == (
(b"1"),
bytearray(b"45"),
bytearray(b"23456789"),
)
a = bytearray(b"14523456789").partition(b"45")
assert isinstance(a[1], bytearray)
a = bytearray(b"14523456789").partition(memoryview(b"45"))
assert isinstance(a[1], bytearray)
# partition
assert bytearray(b"123456789").rpartition(bytearray(b"45")) == ((bytearray(b"123")), bytearray(b"45"), bytearray(b"6789"))
assert bytearray(b"14523456789").rpartition(bytearray(b"45")) == ((bytearray(b"14523")), bytearray(b"45"), bytearray(b"6789"))
assert bytearray(b"123456789").rpartition(bytearray(b"45")) == (
(bytearray(b"123")),
bytearray(b"45"),
bytearray(b"6789"),
)
assert bytearray(b"14523456789").rpartition(bytearray(b"45")) == (
(bytearray(b"14523")),
bytearray(b"45"),
bytearray(b"6789"),
)
a = bytearray(b"14523456789").rpartition(b"45")
assert isinstance(a[1], bytearray)
a = bytearray(b"14523456789").rpartition(memoryview(b"45"))
assert isinstance(a[1], bytearray)
# splitlines
assert bytearray(b"ab c\n\nde fg\rkl\r\n").splitlines() == [bytearray(b"ab c"), bytearray(b""), bytearray(b"de fg"), bytearray(b"kl")]
assert bytearray(b"ab c\n\nde fg\rkl\r\n").splitlines() == [
bytearray(b"ab c"),
bytearray(b""),
bytearray(b"de fg"),
bytearray(b"kl"),
]
assert bytearray(b"ab c\n\nde fg\rkl\r\n").splitlines(keepends=True) == [
bytearray(b"ab c\n"),
bytearray(b"\n"),
@@ -602,11 +665,15 @@ assert bytearray(b"42").zfill(1) == bytearray(b"42")
assert bytearray(b"42").zfill(-1) == bytearray(b"42")
# replace
assert bytearray(b"123456789123").replace(b"23",b"XX") ==bytearray(b'1XX4567891XX')
assert bytearray(b"123456789123").replace(b"23",b"XX", 1) ==bytearray(b'1XX456789123')
assert bytearray(b"123456789123").replace(b"23",b"XX", 0) == bytearray(b"123456789123")
assert bytearray(b"123456789123").replace(b"23",b"XX", -1) ==bytearray(b'1XX4567891XX')
assert bytearray(b"123456789123").replace(b"23", bytearray(b"")) == bytearray(b"14567891")
assert bytearray(b"123456789123").replace(b"23", b"XX") == bytearray(b"1XX4567891XX")
assert bytearray(b"123456789123").replace(b"23", b"XX", 1) == bytearray(b"1XX456789123")
assert bytearray(b"123456789123").replace(b"23", b"XX", 0) == bytearray(b"123456789123")
assert bytearray(b"123456789123").replace(b"23", b"XX", -1) == bytearray(
b"1XX4567891XX"
)
assert bytearray(b"123456789123").replace(b"23", bytearray(b"")) == bytearray(
b"14567891"
)
# clear
@@ -642,25 +709,24 @@ assert a.pop() == 100
# title
assert bytearray(b"Hello world").title() == bytearray(b"Hello World")
assert (
bytearray(b"they're bill's friends from the UK").title()
== bytearray(b"They'Re Bill'S Friends From The Uk")
assert bytearray(b"they're bill's friends from the UK").title() == bytearray(
b"They'Re Bill'S Friends From The Uk"
)
# repeat by multiply
a = bytearray(b'abcd')
assert a * 0 == bytearray(b'')
assert a * -1 == bytearray(b'')
assert a * 1 == bytearray(b'abcd')
assert a * 3 == bytearray(b'abcdabcdabcd')
assert 3 * a == bytearray(b'abcdabcdabcd')
a = bytearray(b"abcd")
assert a * 0 == bytearray(b"")
assert a * -1 == bytearray(b"")
assert a * 1 == bytearray(b"abcd")
assert a * 3 == bytearray(b"abcdabcdabcd")
assert 3 * a == bytearray(b"abcdabcdabcd")
a = bytearray(b'abcd')
a = bytearray(b"abcd")
a.__imul__(3)
assert a == bytearray(b'abcdabcdabcd')
assert a == bytearray(b"abcdabcdabcd")
a.__imul__(0)
assert a == bytearray(b'')
assert a == bytearray(b"")
# copy
@@ -696,70 +762,89 @@ assert a == bytearray(b"owhello, worlwdo"), a
# remove
a = bytearray(b'abcdabcd')
a = bytearray(b"abcdabcd")
a.remove(99) # the letter c
# Only the first is removed
assert a == bytearray(b'abdabcd')
assert a == bytearray(b"abdabcd")
# reverse
a = bytearray(b'hello, world')
a = bytearray(b"hello, world")
a.reverse()
assert a == bytearray(b'dlrow ,olleh')
assert a == bytearray(b"dlrow ,olleh")
# __setitem__
a = bytearray(b'test')
a = bytearray(b"test")
a[0] = 1
assert a == bytearray(b'\x01est')
assert a == bytearray(b"\x01est")
with assert_raises(TypeError):
a[0] = b'a'
a[0] = b"a"
with assert_raises(TypeError):
a[0] = memoryview(b'a')
a[0] = memoryview(b"a")
a[:2] = [0, 9]
assert a == bytearray(b'\x00\x09st')
a[1:3] = b'test'
assert a == bytearray(b'\x00testt')
a[:6] = memoryview(b'test')
assert a == bytearray(b'test')
assert a == bytearray(b"\x00\x09st")
a[1:3] = b"test"
assert a == bytearray(b"\x00testt")
a[:6] = memoryview(b"test")
assert a == bytearray(b"test")
# mod
assert bytearray('rust%bpython%b', 'utf-8') % (b' ', b'!') == bytearray(b'rust python!')
assert bytearray('x=%i y=%f', 'utf-8') % (1, 2.5) == bytearray(b'x=1 y=2.500000')
assert bytearray("rust%bpython%b", "utf-8") % (b" ", b"!") == bytearray(b"rust python!")
assert bytearray("x=%i y=%f", "utf-8") % (1, 2.5) == bytearray(b"x=1 y=2.500000")
# eq, ne
a = bytearray(b'hello, world')
a = bytearray(b"hello, world")
b = a.copy()
assert a.__ne__(b) is False
b = bytearray(b'my bytearray')
b = bytearray(b"my bytearray")
assert a.__ne__(b) is True
# pickle
a = bytearray(b'\xffab\x80\0\0\370\0\0')
assert pickle.dumps(a, 0) == b'c__builtin__\nbytearray\np0\n(c_codecs\nencode\np1\n(V\xffab\x80\\u0000\\u0000\xf8\\u0000\\u0000\np2\nVlatin1\np3\ntp4\nRp5\ntp6\nRp7\n.'
assert pickle.dumps(a, 1) == b'c__builtin__\nbytearray\nq\x00(c_codecs\nencode\nq\x01(X\x0c\x00\x00\x00\xc3\xbfab\xc2\x80\x00\x00\xc3\xb8\x00\x00q\x02X\x06\x00\x00\x00latin1q\x03tq\x04Rq\x05tq\x06Rq\x07.'
assert pickle.dumps(a, 2) == b'\x80\x02c__builtin__\nbytearray\nq\x00c_codecs\nencode\nq\x01X\x0c\x00\x00\x00\xc3\xbfab\xc2\x80\x00\x00\xc3\xb8\x00\x00q\x02X\x06\x00\x00\x00latin1q\x03\x86q\x04Rq\x05\x85q\x06Rq\x07.'
assert pickle.dumps(a, 3) == b'\x80\x03cbuiltins\nbytearray\nq\x00C\t\xffab\x80\x00\x00\xf8\x00\x00q\x01\x85q\x02Rq\x03.'
assert pickle.dumps(a, 4) == b'\x80\x04\x95*\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x94\x8c\tbytearray\x94\x93\x94C\t\xffab\x80\x00\x00\xf8\x00\x00\x94\x85\x94R\x94.'
a = bytearray(b"\xffab\x80\0\0\370\0\0")
assert (
pickle.dumps(a, 0)
== b"c__builtin__\nbytearray\np0\n(c_codecs\nencode\np1\n(V\xffab\x80\\u0000\\u0000\xf8\\u0000\\u0000\np2\nVlatin1\np3\ntp4\nRp5\ntp6\nRp7\n."
)
assert (
pickle.dumps(a, 1)
== b"c__builtin__\nbytearray\nq\x00(c_codecs\nencode\nq\x01(X\x0c\x00\x00\x00\xc3\xbfab\xc2\x80\x00\x00\xc3\xb8\x00\x00q\x02X\x06\x00\x00\x00latin1q\x03tq\x04Rq\x05tq\x06Rq\x07."
)
assert (
pickle.dumps(a, 2)
== b"\x80\x02c__builtin__\nbytearray\nq\x00c_codecs\nencode\nq\x01X\x0c\x00\x00\x00\xc3\xbfab\xc2\x80\x00\x00\xc3\xb8\x00\x00q\x02X\x06\x00\x00\x00latin1q\x03\x86q\x04Rq\x05\x85q\x06Rq\x07."
)
assert (
pickle.dumps(a, 3)
== b"\x80\x03cbuiltins\nbytearray\nq\x00C\t\xffab\x80\x00\x00\xf8\x00\x00q\x01\x85q\x02Rq\x03."
)
assert (
pickle.dumps(a, 4)
== b"\x80\x04\x95*\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x94\x8c\tbytearray\x94\x93\x94C\t\xffab\x80\x00\x00\xf8\x00\x00\x94\x85\x94R\x94."
)
# pickle with subclass
class A(bytes):
pass
a = A()
a.x = 10
a.y = A(b'123')
a.y = A(b"123")
b = pickle.loads(pickle.dumps(a, 4))
assert type(a) == type(b)
assert a.x == b.x
assert a.y == b.y
assert a == b
class B(bytearray):
pass
a = B()
a.x = 10
a.y = B(b'123')
a.y = B(b"123")
b = pickle.loads(pickle.dumps(a, 4))
assert type(a) == type(b)
assert a.x == b.x
@@ -768,4 +853,6 @@ assert a == b
a = bytearray()
for i in range(-1, 2, 1):
assert_raises(IndexError, lambda: a[-sys.maxsize - i], _msg='bytearray index out of range')
assert_raises(
IndexError, lambda: a[-sys.maxsize - i], _msg="bytearray index out of range"
)

View File

@@ -596,51 +596,56 @@ assert (
# repeat by multiply
a = b'abcd'
assert a * 0 == b''
assert a * -1 == b''
assert a * 1 == b'abcd'
assert a * 3 == b'abcdabcdabcd'
assert 3 * a == b'abcdabcdabcd'
a = b"abcd"
assert a * 0 == b""
assert a * -1 == b""
assert a * 1 == b"abcd"
assert a * 3 == b"abcdabcdabcd"
assert 3 * a == b"abcdabcdabcd"
# decode
assert b'\x72\x75\x73\x74'.decode('ascii') == 'rust'
assert b'\xc2\xae\x75\x73\x74'.decode('ascii', 'replace') == '<EFBFBD><EFBFBD>ust'
assert b'\xc2\xae\x75\x73\x74'.decode('ascii', 'ignore') == 'ust'
assert b'\xc2\xae\x75\x73\x74'.decode('utf-8') == '®ust'
assert b'\xc2\xae\x75\x73\x74'.decode() == '®ust'
assert b'\xe4\xb8\xad\xe6\x96\x87\xe5\xad\x97'.decode('utf-8') == '中文字'
assert b"\x72\x75\x73\x74".decode("ascii") == "rust"
assert b"\xc2\xae\x75\x73\x74".decode("ascii", "replace") == "<EFBFBD><EFBFBD>ust"
assert b"\xc2\xae\x75\x73\x74".decode("ascii", "ignore") == "ust"
assert b"\xc2\xae\x75\x73\x74".decode("utf-8") == "®ust"
assert b"\xc2\xae\x75\x73\x74".decode() == "®ust"
assert b"\xe4\xb8\xad\xe6\x96\x87\xe5\xad\x97".decode("utf-8") == "中文字"
# mod
assert b'rust%bpython%b' % (b' ', b'!') == b'rust python!'
assert b'x=%i y=%f' % (1, 2.5) == b'x=1 y=2.500000'
assert b"rust%bpython%b" % (b" ", b"!") == b"rust python!"
assert b"x=%i y=%f" % (1, 2.5) == b"x=1 y=2.500000"
# __bytes__
def test__bytes__():
foo = b'foo\x00bar'
foo = b"foo\x00bar"
assert foo.__bytes__() == foo
assert type(foo.__bytes__()) == bytes
class bytes_subclass(bytes):
pass
bar = bytes_subclass(b'bar\x00foo')
bar = bytes_subclass(b"bar\x00foo")
assert bar.__bytes__() == bar
assert type(bar.__bytes__()) == bytes
class A:
def __bytes__(self):
return b"bytess"
assert bytes(A()) == b"bytess"
# Issue #2125
b = b'abc'
b = b"abc"
assert bytes(b) is b
# Regression to
# https://github.com/RustPython/RustPython/issues/2840
a = b'123abc!?'
a = b"123abc!?"
assert id(a) == id(a)
assert id(a) != id(a * -1)
assert id(a) != id(a * 0)
@@ -652,20 +657,24 @@ assert id(a) != id(a * 2)
class SubBytes(bytes):
pass
b = SubBytes(b'0123abc*&')
b = SubBytes(b"0123abc*&")
assert id(b) == id(b)
assert id(b) != id(b * -1)
assert id(b) != id(b * 0)
assert id(b) != id(b * 1)
assert id(b) != id(b * 2)
class B1(bytearray):
def __new__(cls, value):
assert type(value) == bytes
me = super().__new__(cls, value)
me.foo = 'bar'
me.foo = "bar"
return me
b = B1.fromhex('a0a1a2')
assert b.foo == 'bar'
skip_if_unsupported(3,11,test__bytes__)
b = B1.fromhex("a0a1a2")
assert b.foo == "bar"
skip_if_unsupported(3, 11, test__bytes__)

View File

@@ -1,25 +1,48 @@
assert not callable(1)
def f(): pass
def f():
pass
assert callable(f)
assert callable(len)
assert callable(lambda: 1)
assert callable(int)
class C:
def __init__(self):
# must be defined on class
self.__call__ = lambda self: 1
def f(self): pass
def f(self):
pass
assert callable(C)
assert not callable(C())
assert callable(C().f)
class C:
def __call__(self): pass
def __call__(self):
pass
assert callable(C())
class C1(C): pass
class C1(C):
pass
assert callable(C1())
class C:
__call__ = 1
# CPython returns true here, but fails when actually calling it
assert callable(C())

View File

@@ -4,5 +4,7 @@ assert "a" == chr(97)
assert "é" == chr(233)
assert "🤡" == chr(129313)
assert_raises(TypeError, chr, _msg='chr() takes exactly one argument (0 given)')
assert_raises(ValueError, chr, 0x110005, _msg='ValueError: chr() arg not in range(0x110000)')
assert_raises(TypeError, chr, _msg="chr() takes exactly one argument (0 given)")
assert_raises(
ValueError, chr, 0x110005, _msg="ValueError: chr() arg not in range(0x110000)"
)

View File

@@ -5,49 +5,49 @@ assert len(dict()) == 0
assert len({}) == 0
assert len({"a": "b"}) == 1
assert len({"a": "b", "b": 1}) == 2
assert len({"a": "b", "b": 1, "a" + "b": 2*2}) == 3
assert len({"a": "b", "b": 1, "a" + "b": 2 * 2}) == 3
d = {}
d['a'] = d
d["a"] = d
assert repr(d) == "{'a': {...}}"
assert {'a': 123}.get('a') == 123
assert {'a': 123}.get('b') == None
assert {'a': 123}.get('b', 456) == 456
assert {"a": 123}.get("a") == 123
assert {"a": 123}.get("b") == None
assert {"a": 123}.get("b", 456) == 456
d = {'a': 123, 'b': 456}
assert list(reversed(d)) == ['b', 'a']
assert list(reversed(d.keys())) == ['b', 'a']
d = {"a": 123, "b": 456}
assert list(reversed(d)) == ["b", "a"]
assert list(reversed(d.keys())) == ["b", "a"]
assert list(reversed(d.values())) == [456, 123]
assert list(reversed(d.items())) == [('b', 456), ('a', 123)]
assert list(reversed(d.items())) == [("b", 456), ("a", 123)]
with assert_raises(StopIteration):
dict_reversed = reversed(d)
for _ in range(len(d) + 1):
next(dict_reversed)
assert 'dict' in dict().__doc__
assert "dict" in dict().__doc__
d = {'a': 123, 'b': 456}
d = {"a": 123, "b": 456}
assert 1 not in d.items()
assert 'a' not in d.items()
assert 'a', 123 not in d.items()
assert "a" not in d.items()
assert "a", 123 not in d.items()
assert () not in d.items()
assert (1) not in d.items()
assert ('a') not in d.items()
assert ('a', 123) in d.items()
assert ('b', 456) in d.items()
assert ('a', 123, 3) not in d.items()
assert ('a', 123, 'b', 456) not in d.items()
assert ("a") not in d.items()
assert ("a", 123) in d.items()
assert ("b", 456) in d.items()
assert ("a", 123, 3) not in d.items()
assert ("a", 123, "b", 456) not in d.items()
d = {1: 10, "a": "ABC", (3,4): 5}
d = {1: 10, "a": "ABC", (3, 4): 5}
assert 1 in d.keys()
assert (1) in d.keys()
assert "a" in d.keys()
assert (3,4) in d.keys()
assert (3, 4) in d.keys()
assert () not in d.keys()
assert 10 not in d.keys()
assert (1, 10) not in d.keys()
assert "abc" not in d.keys()
assert ((3,4),5) not in d.keys()
assert ((3, 4), 5) not in d.keys()
d1 = {"a": 1, "b": 2}
d2 = {"c": 3, "d": 4}
@@ -64,55 +64,55 @@ assert not d1.items().isdisjoint(d2.items())
assert not d1.keys().isdisjoint(d2.keys())
assert dict(a=2, b=3) == {'a': 2, 'b': 3}
assert dict({'a': 2, 'b': 3}, b=4) == {'a': 2, 'b': 4}
assert dict([('a', 2), ('b', 3)]) == {'a': 2, 'b': 3}
assert dict(a=2, b=3) == {"a": 2, "b": 3}
assert dict({"a": 2, "b": 3}, b=4) == {"a": 2, "b": 4}
assert dict([("a", 2), ("b", 3)]) == {"a": 2, "b": 3}
assert {} == {}
assert not {'a': 2} == {}
assert not {} == {'a': 2}
assert not {'b': 2} == {'a': 2}
assert not {'a': 4} == {'a': 2}
assert {'a': 2} == {'a': 2}
assert not {"a": 2} == {}
assert not {} == {"a": 2}
assert not {"b": 2} == {"a": 2}
assert not {"a": 4} == {"a": 2}
assert {"a": 2} == {"a": 2}
nan = float('nan')
assert {'a': nan} == {'a': nan}
nan = float("nan")
assert {"a": nan} == {"a": nan}
a = {'g': 5}
b = {'a': a, 'd': 9}
a = {"g": 5}
b = {"a": a, "d": 9}
c = dict(b)
c['d'] = 3
c['a']['g'] = 2
assert a == {'g': 2}
assert b == {'a': a, 'd': 9}
c["d"] = 3
c["a"]["g"] = 2
assert a == {"g": 2}
assert b == {"a": a, "d": 9}
a.clear()
assert len(a) == 0
a = {'a': 5, 'b': 6}
a = {"a": 5, "b": 6}
res = set()
for value in a.values():
res.add(value)
assert res == set([5,6])
res.add(value)
assert res == set([5, 6])
count = 0
for (key, value) in a.items():
assert a[key] == value
count += 1
for key, value in a.items():
assert a[key] == value
count += 1
assert count == len(a)
res = set()
for key in a.keys():
res.add(key)
assert res == set(['a','b'])
res.add(key)
assert res == set(["a", "b"])
# Deleted values are correctly skipped over:
x = {'a': 1, 'b': 2, 'c': 3, 'd': 3}
del x['c']
x = {"a": 1, "b": 2, "c": 3, "d": 3}
del x["c"]
it = iter(x.items())
assert ('a', 1) == next(it)
assert ('b', 2) == next(it)
assert ('d', 3) == next(it)
assert ("a", 1) == next(it)
assert ("b", 2) == next(it)
assert ("d", 3) == next(it)
with assert_raises(StopIteration):
next(it)
@@ -121,7 +121,7 @@ with assert_raises(KeyError) as cm:
assert cm.exception.args[0] == 10
# Iterating a dictionary is just its keys:
assert ['a', 'b', 'd'] == list(x)
assert ["a", "b", "d"] == list(x)
# Iterating view captures dictionary when iterated.
data = {1: 2, 3: 4}
@@ -140,12 +140,12 @@ assert (3, "changed") == next(items)
# But we can't add or delete items during iteration.
d = {}
a = iter(d.items())
d['a'] = 2
d["a"] = 2
b = iter(d.items())
assert ('a', 2) == next(b)
assert ("a", 2) == next(b)
with assert_raises(RuntimeError):
next(a)
del d['a']
del d["a"]
with assert_raises(RuntimeError):
next(b)
@@ -164,21 +164,23 @@ x[2] = 2
x[(5, 6)] = 5
with assert_raises(TypeError):
x[[]] # Unhashable type.
x[[]] # Unhashable type.
x["here"] = "here"
assert x.get("not here", "default") == "default"
assert x.get("here", "default") == "here"
assert x.get("not here") == None
class LengthDict(dict):
def __getitem__(self, k):
return len(k)
x = LengthDict()
assert type(x) == LengthDict
assert x['word'] == 4
assert x.get('word') is None
assert x["word"] == 4
assert x.get("word") is None
assert 5 == eval("a + word", LengthDict())
@@ -189,15 +191,19 @@ class Squares(dict):
self[k] = v
return v
x = Squares()
assert x[-5] == 25
# An object that hashes to the same value always, and compares equal if any its values match.
class Hashable(object):
def __init__(self, *args):
self.values = args
def __hash__(self):
return 1
def __eq__(self, other):
for x in self.values:
for y in other.values:
@@ -205,39 +211,40 @@ class Hashable(object):
return True
return False
x = {}
x[Hashable(1,2)] = 8
assert x[Hashable(1,2)] == 8
assert x[Hashable(3,1)] == 8
x = {}
x[Hashable(1, 2)] = 8
assert x[Hashable(1, 2)] == 8
assert x[Hashable(3, 1)] == 8
x[Hashable(8)] = 19
x[Hashable(19,8)] = 1
x[Hashable(19, 8)] = 1
assert x[Hashable(8)] == 1
assert len(x) == 2
assert list({'a': 2, 'b': 10}) == ['a', 'b']
assert list({"a": 2, "b": 10}) == ["a", "b"]
x = {}
x['a'] = 2
x['b'] = 10
assert list(x) == ['a', 'b']
x["a"] = 2
x["b"] = 10
assert list(x) == ["a", "b"]
y = x.copy()
x['c'] = 12
assert y == {'a': 2, 'b': 10}
x["c"] = 12
assert y == {"a": 2, "b": 10}
y.update({'c': 19, "d": -1, 'b': 12})
assert y == {'a': 2, 'b': 12, 'c': 19, 'd': -1}
y.update({"c": 19, "d": -1, "b": 12})
assert y == {"a": 2, "b": 12, "c": 19, "d": -1}
y.update(y)
assert y == {'a': 2, 'b': 12, 'c': 19, 'd': -1} # hasn't changed
assert y == {"a": 2, "b": 12, "c": 19, "d": -1} # hasn't changed
# KeyError has object that used as key as an .args[0]
with assert_raises(KeyError) as cm:
x['not here']
x["not here"]
assert cm.exception.args[0] == "not here"
with assert_raises(KeyError) as cm:
x.pop('not here')
x.pop("not here")
assert cm.exception.args[0] == "not here"
with assert_raises(KeyError) as cm:
@@ -247,7 +254,11 @@ with assert_raises(KeyError) as cm:
x.pop(10)
assert cm.exception.args[0] == 10
class MyClass: pass
class MyClass:
pass
obj = MyClass()
with assert_raises(KeyError) as cm:
@@ -257,49 +268,65 @@ with assert_raises(KeyError) as cm:
x.pop(obj)
assert cm.exception.args[0] == obj
x = {1: 'a', '1': None}
assert x.pop(1) == 'a'
assert x.pop('1') is None
x = {1: "a", "1": None}
assert x.pop(1) == "a"
assert x.pop("1") is None
assert x == {}
x = {1: 'a'}
assert (1, 'a') == x.popitem()
x = {1: "a"}
assert (1, "a") == x.popitem()
assert x == {}
with assert_raises(KeyError) as cm:
x.popitem()
assert cm.exception.args == ('popitem(): dictionary is empty',)
assert cm.exception.args == ("popitem(): dictionary is empty",)
x = {'a': 4}
assert 4 == x.setdefault('a', 0)
assert x['a'] == 4
assert 0 == x.setdefault('b', 0)
assert x['b'] == 0
assert None == x.setdefault('c')
assert x['c'] is None
x = {"a": 4}
assert 4 == x.setdefault("a", 0)
assert x["a"] == 4
assert 0 == x.setdefault("b", 0)
assert x["b"] == 0
assert None == x.setdefault("c")
assert x["c"] is None
assert {1: None, "b": None} == dict.fromkeys([1, "b"])
assert {1: 0, "b": 0} == dict.fromkeys([1, "b"], 0)
x = {'a': 1, 'b': 1, 'c': 1}
y = {'b': 2, 'c': 2, 'd': 2}
z = {'c': 3, 'd': 3, 'e': 3}
x = {"a": 1, "b": 1, "c": 1}
y = {"b": 2, "c": 2, "d": 2}
z = {"c": 3, "d": 3, "e": 3}
w = {1: 1, **x, 2: 2, **y, 3: 3, **z, 4: 4}
assert w == {1: 1, 'a': 1, 'b': 2, 'c': 3, 2: 2, 'd': 3, 3: 3, 'e': 3, 4: 4} # not in cpython test suite
assert w == {
1: 1,
"a": 1,
"b": 2,
"c": 3,
2: 2,
"d": 3,
3: 3,
"e": 3,
4: 4,
} # not in cpython test suite
assert str({True: True, 1.0: 1.0}) == str({True: 1.0})
class A:
def __hash__(self):
return 1
def __eq__(self, other):
return isinstance(other, A)
class B:
def __hash__(self):
return 1
def __eq__(self, other):
return isinstance(other, B)
s = {1: 0, A(): 1, B(): 2}
assert len(s) == 3
assert s[1] == 0
@@ -307,19 +334,19 @@ assert s[A()] == 1
assert s[B()] == 2
# Test dict usage in set with star expressions!
a = {'bla': 2}
b = {'c': 44, 'bla': 332, 'd': 6}
x = ['bla', 'c', 'd', 'f']
a = {"bla": 2}
b = {"c": 44, "bla": 332, "d": 6}
x = ["bla", "c", "d", "f"]
c = {*a, *b, *x}
# print(c, type(c))
assert isinstance(c, set)
assert c == {'bla', 'c', 'd', 'f'}
assert c == {"bla", "c", "d", "f"}
assert not {}.__ne__({})
assert {}.__ne__({'a':'b'})
assert {}.__ne__({"a": "b"})
assert {}.__ne__(1) == NotImplemented
it = iter({0: 1, 2: 3, 4:5, 6:7})
it = iter({0: 1, 2: 3, 4: 5, 6: 7})
assert it.__length_hint__() == 4
next(it)
assert it.__length_hint__() == 3

View File

@@ -1,78 +1,91 @@
from testutils import assert_raises, skip_if_unsupported
def test_dunion_ior0():
a={1:2,2:3}
b={3:4,5:6}
a|=b
assert a == {1:2,2:3,3:4,5:6}, f"wrong value assigned {a=}"
assert b == {3:4,5:6}, f"right hand side modified, {b=}"
def test_dunion_ior0():
a = {1: 2, 2: 3}
b = {3: 4, 5: 6}
a |= b
assert a == {1: 2, 2: 3, 3: 4, 5: 6}, f"wrong value assigned {a=}"
assert b == {3: 4, 5: 6}, f"right hand side modified, {b=}"
def test_dunion_or0():
a={1:2,2:3}
b={3:4,5:6}
c=a|b
a = {1: 2, 2: 3}
b = {3: 4, 5: 6}
c = a | b
assert a == {1:2,2:3}, f"left hand side of non-assignment operator modified {a=}"
assert b == {3:4,5:6}, f"right hand side of non-assignment operator modified, {b=}"
assert c == {1:2,2:3, 3:4, 5:6}, f"unexpected result of dict union {c=}"
assert a == {1: 2, 2: 3}, f"left hand side of non-assignment operator modified {a=}"
assert b == {3: 4, 5: 6}, (
f"right hand side of non-assignment operator modified, {b=}"
)
assert c == {1: 2, 2: 3, 3: 4, 5: 6}, f"unexpected result of dict union {c=}"
def test_dunion_or1():
a={1:2,2:3}
b={3:4,5:6}
c=a.__or__(b)
a = {1: 2, 2: 3}
b = {3: 4, 5: 6}
c = a.__or__(b)
assert a == {1:2,2:3}, f"left hand side of non-assignment operator modified {a=}"
assert b == {3:4,5:6}, f"right hand side of non-assignment operator modified, {b=}"
assert c == {1:2,2:3, 3:4, 5:6}, f"unexpected result of dict union {c=}"
assert a == {1: 2, 2: 3}, f"left hand side of non-assignment operator modified {a=}"
assert b == {3: 4, 5: 6}, (
f"right hand side of non-assignment operator modified, {b=}"
)
assert c == {1: 2, 2: 3, 3: 4, 5: 6}, f"unexpected result of dict union {c=}"
def test_dunion_ror0():
a={1:2,2:3}
b={3:4,5:6}
c=b.__ror__(a)
a = {1: 2, 2: 3}
b = {3: 4, 5: 6}
c = b.__ror__(a)
assert a == {1:2,2:3}, f"left hand side of non-assignment operator modified {a=}"
assert b == {3:4,5:6}, f"right hand side of non-assignment operator modified, {b=}"
assert c == {1:2,2:3, 3:4, 5:6}, f"unexpected result of dict union {c=}"
assert a == {1: 2, 2: 3}, f"left hand side of non-assignment operator modified {a=}"
assert b == {3: 4, 5: 6}, (
f"right hand side of non-assignment operator modified, {b=}"
)
assert c == {1: 2, 2: 3, 3: 4, 5: 6}, f"unexpected result of dict union {c=}"
def test_dunion_other_types():
def perf_test_or(other_obj):
d={1:2}
d = {1: 2}
return d.__or__(other_obj) is NotImplemented
def perf_test_ror(other_obj):
d={1:2}
d = {1: 2}
return d.__ror__(other_obj) is NotImplemented
test_fct={'__or__':perf_test_or, '__ror__':perf_test_ror}
others=['FooBar', 42, [36], set([19]), ['aa'], None]
for tfn,tf in test_fct.items():
test_fct = {"__or__": perf_test_or, "__ror__": perf_test_ror}
others = ["FooBar", 42, [36], set([19]), ["aa"], None]
for tfn, tf in test_fct.items():
for other in others:
assert tf(other), f"Failed: dict {tfn}, accepted {other}"
# __ior__() has different behavior and needs to be tested separately
d = {1: 2}
assert_raises(ValueError,
lambda: d.__ior__('FooBar'),
_msg='dictionary update sequence element #0 has length 1; 2 is required')
assert_raises(TypeError,
lambda: d.__ior__(42),
_msg='\'int\' object is not iterable')
assert_raises(TypeError,
lambda: d.__ior__([36]),
_msg='cannot convert dictionary update sequence element #0 to a sequence')
assert_raises(TypeError,
lambda: d.__ior__(set([36])),
_msg='cannot convert dictionary update sequence element #0 to a sequence')
res = d.__ior__(['aa'])
assert res == {1: 2, 'a': 'a'}, f"unexpected result of dict union {res=}"
assert_raises(TypeError,
lambda: d.__ior__(None),
_msg='TypeError: \'NoneType\' object is not iterable')
assert_raises(
ValueError,
lambda: d.__ior__("FooBar"),
_msg="dictionary update sequence element #0 has length 1; 2 is required",
)
assert_raises(TypeError, lambda: d.__ior__(42), _msg="'int' object is not iterable")
assert_raises(
TypeError,
lambda: d.__ior__([36]),
_msg="cannot convert dictionary update sequence element #0 to a sequence",
)
assert_raises(
TypeError,
lambda: d.__ior__(set([36])),
_msg="cannot convert dictionary update sequence element #0 to a sequence",
)
res = d.__ior__(["aa"])
assert res == {1: 2, "a": "a"}, f"unexpected result of dict union {res=}"
assert_raises(
TypeError,
lambda: d.__ior__(None),
_msg="TypeError: 'NoneType' object is not iterable",
)
skip_if_unsupported(3, 9, test_dunion_ior0)

View File

@@ -1,9 +1,11 @@
assert isinstance(dir(), list)
assert '__builtins__' in dir()
assert "__builtins__" in dir()
class A:
def test():
pass
def test():
pass
a = A()
@@ -13,24 +15,30 @@ assert "test" in dir(A), "test not in A"
a.x = 3
assert "x" in dir(a), "x not in a"
class B(A):
def __dir__(self):
return ('q', 'h')
def __dir__(self):
return ("q", "h")
# Gets sorted and turned into a list
assert ['h', 'q'] == dir(B())
assert ["h", "q"] == dir(B())
# This calls type.__dir__ so isn't changed (but inheritance works)!
assert 'test' in dir(A)
assert "test" in dir(A)
# eval() takes any mapping-like type, so dir() must support them
# TODO: eval() should take any mapping as locals, not just dict-derived types
class A(dict):
def __getitem__(self, x):
return dir
def keys(self):
yield 6
yield 5
def __getitem__(self, x):
return dir
def keys(self):
yield 6
yield 5
assert eval("dir()", {}, A()) == [5, 6]
import socket

View File

@@ -1,9 +1,9 @@
from testutils import assert_raises
assert divmod(11, 3) == (3, 2)
assert divmod(8,11) == (0, 8)
assert divmod(8, 11) == (0, 8)
assert divmod(0.873, 0.252) == (3.0, 0.11699999999999999)
assert divmod(-86340, 86400) == (-1, 60)
assert_raises(ZeroDivisionError, divmod, 5, 0, _msg='divmod by zero')
assert_raises(ZeroDivisionError, divmod, 5.0, 0.0, _msg='divmod by zero')
assert_raises(ZeroDivisionError, divmod, 5, 0, _msg="divmod by zero")
assert_raises(ZeroDivisionError, divmod, 5.0, 0.0, _msg="divmod by zero")

View File

@@ -1,5 +1,3 @@
a = ...
b = ...
c = type(a)() # Test singleton behavior
@@ -11,22 +9,22 @@ assert b is c
assert b is d
assert d is e
assert Ellipsis.__repr__() == 'Ellipsis'
assert Ellipsis.__reduce__() == 'Ellipsis'
assert Ellipsis.__repr__() == "Ellipsis"
assert Ellipsis.__reduce__() == "Ellipsis"
assert type(Ellipsis).__new__(type(Ellipsis)) == Ellipsis
assert type(Ellipsis).__reduce__(Ellipsis) == 'Ellipsis'
assert type(Ellipsis).__reduce__(Ellipsis) == "Ellipsis"
try:
type(Ellipsis).__new__(type(1))
except TypeError:
pass
else:
assert False, '`Ellipsis.__new__` should only accept `type(Ellipsis)` as argument'
assert False, "`Ellipsis.__new__` should only accept `type(Ellipsis)` as argument"
try:
type(Ellipsis).__reduce__(1)
except TypeError:
pass
else:
assert False, '`Ellipsis.__reduce__` should only accept `Ellipsis` as argument'
assert False, "`Ellipsis.__reduce__` should only accept `Ellipsis` as argument"
assert Ellipsis is ...
Ellipsis = 2

View File

@@ -1,9 +1,14 @@
assert list(enumerate(['a', 'b', 'c'])) == [(0, 'a'), (1, 'b'), (2, 'c')]
assert list(enumerate(["a", "b", "c"])) == [(0, "a"), (1, "b"), (2, "c")]
assert type(enumerate([])) == enumerate
assert list(enumerate(['a', 'b', 'c'], -100)) == [(-100, 'a'), (-99, 'b'), (-98, 'c')]
assert list(enumerate(['a', 'b', 'c'], 2**200)) == [(2**200, 'a'), (2**200 + 1, 'b'), (2**200 + 2, 'c')]
assert list(enumerate(["a", "b", "c"], -100)) == [(-100, "a"), (-99, "b"), (-98, "c")]
assert list(enumerate(["a", "b", "c"], 2**200)) == [
(2**200, "a"),
(2**200 + 1, "b"),
(2**200 + 2, "c"),
]
# test infinite iterator
class Counter(object):

View File

@@ -1,4 +1,4 @@
assert 3 == eval('1+2')
assert 3 == eval("1+2")
code = compile('5+3', 'x.py', 'eval')
code = compile("5+3", "x.py", "eval")
assert eval(code) == 8

View File

@@ -3,41 +3,48 @@ import platform
import pickle
import sys
def exceptions_eq(e1, e2):
return type(e1) is type(e2) and e1.args == e2.args
def round_trip_repr(e):
return exceptions_eq(e, eval(repr(e)))
# KeyError
empty_exc = KeyError()
assert str(empty_exc) == ''
assert str(empty_exc) == ""
assert round_trip_repr(empty_exc)
assert len(empty_exc.args) == 0
assert type(empty_exc.args) == tuple
exc = KeyError('message')
exc = KeyError("message")
assert str(exc) == "'message'"
assert round_trip_repr(exc)
assert LookupError.__str__(exc) == "message"
exc = KeyError('message', 'another message')
exc = KeyError("message", "another message")
assert str(exc) == "('message', 'another message')"
assert round_trip_repr(exc)
assert exc.args[0] == 'message'
assert exc.args[1] == 'another message'
assert exc.args[0] == "message"
assert exc.args[1] == "another message"
class A:
def __repr__(self):
return 'A()'
return "A()"
def __str__(self):
return 'str'
return "str"
def __eq__(self, other):
return type(other) is A
exc = KeyError(A())
assert str(exc) == 'A()'
assert str(exc) == "A()"
assert round_trip_repr(exc)
# ImportError / ModuleNotFoundError
@@ -47,33 +54,32 @@ assert exc.path is None
assert exc.msg is None
assert exc.args == ()
exc = ImportError('hello')
exc = ImportError("hello")
assert exc.name is None
assert exc.path is None
assert exc.msg == 'hello'
assert exc.args == ('hello',)
assert exc.msg == "hello"
assert exc.args == ("hello",)
exc = ImportError('hello', name='name', path='path')
assert exc.name == 'name'
assert exc.path == 'path'
assert exc.msg == 'hello'
assert exc.args == ('hello',)
exc = ImportError("hello", name="name", path="path")
assert exc.name == "name"
assert exc.path == "path"
assert exc.msg == "hello"
assert exc.args == ("hello",)
class NewException(Exception):
def __init__(self, value):
self.value = value
def __init__(self, value):
self.value = value
try:
raise NewException("test")
raise NewException("test")
except NewException as e:
assert e.value == "test"
assert e.value == "test"
exc = SyntaxError('msg', 1, 2, 3, 4, 5)
assert exc.msg == 'msg'
exc = SyntaxError("msg", 1, 2, 3, 4, 5)
assert exc.msg == "msg"
assert exc.filename is None
assert exc.lineno is None
assert exc.offset is None
@@ -82,11 +88,12 @@ assert exc.text is None
# Regression to:
# https://github.com/RustPython/RustPython/issues/2779
class MyError(Exception):
pass
e = MyError('message')
e = MyError("message")
try:
raise e from e
@@ -97,23 +104,23 @@ except MyError as exc:
assert exc.__cause__ is e
assert exc.__context__ is None
else:
assert False, 'exception not raised'
assert False, "exception not raised"
try:
raise ValueError('test') from e
raise ValueError("test") from e
except ValueError as exc:
sys.excepthook(type(exc), exc, exc.__traceback__) # ok, will print two excs
assert isinstance(exc, ValueError)
assert exc.__cause__ is e
assert exc.__context__ is None
else:
assert False, 'exception not raised'
assert False, "exception not raised"
# New case:
# potential recursion on `__context__` field
e = MyError('message')
e = MyError("message")
try:
try:
@@ -121,15 +128,15 @@ try:
except MyError as exc:
raise e
else:
assert False, 'exception not raised'
assert False, "exception not raised"
except MyError as exc:
sys.excepthook(type(exc), exc, exc.__traceback__)
assert exc.__cause__ is None
assert exc.__context__ is None
else:
assert False, 'exception not raised'
assert False, "exception not raised"
e = MyError('message')
e = MyError("message")
try:
try:
@@ -137,15 +144,15 @@ try:
except MyError as exc:
raise exc
else:
assert False, 'exception not raised'
assert False, "exception not raised"
except MyError as exc:
sys.excepthook(type(exc), exc, exc.__traceback__)
assert exc.__cause__ is None
assert exc.__context__ is None
else:
assert False, 'exception not raised'
assert False, "exception not raised"
e = MyError('message')
e = MyError("message")
try:
try:
@@ -153,15 +160,15 @@ try:
except MyError as exc:
raise e from e
else:
assert False, 'exception not raised'
assert False, "exception not raised"
except MyError as exc:
sys.excepthook(type(exc), exc, exc.__traceback__)
assert exc.__cause__ is e
assert exc.__context__ is None
else:
assert False, 'exception not raised'
assert False, "exception not raised"
e = MyError('message')
e = MyError("message")
try:
try:
@@ -169,23 +176,25 @@ try:
except MyError as exc:
raise exc from e
else:
assert False, 'exception not raised'
assert False, "exception not raised"
except MyError as exc:
sys.excepthook(type(exc), exc, exc.__traceback__)
assert exc.__cause__ is e
assert exc.__context__ is None
else:
assert False, 'exception not raised'
assert False, "exception not raised"
# New case:
# two exception in a recursion loop
class SubError(MyError):
pass
e = MyError('message')
d = SubError('sub')
e = MyError("message")
d = SubError("sub")
try:
@@ -197,9 +206,9 @@ except MyError as exc:
assert exc.__cause__ is d
assert exc.__context__ is None
else:
assert False, 'exception not raised'
assert False, "exception not raised"
e = MyError('message')
e = MyError("message")
try:
raise d from e
@@ -210,20 +219,20 @@ except SubError as exc:
assert exc.__cause__ is e
assert exc.__context__ is None
else:
assert False, 'exception not raised'
assert False, "exception not raised"
# New case:
# explicit `__context__` manipulation.
e = MyError('message')
e = MyError("message")
e.__context__ = e
try:
raise e
except MyError as exc:
# It was a segmentation fault before, will print info to stdout:
if platform.python_implementation() == 'RustPython':
if platform.python_implementation() == "RustPython":
# For some reason `CPython` hangs on this code:
sys.excepthook(type(exc), exc, exc.__traceback__)
assert isinstance(exc, MyError)
@@ -235,30 +244,36 @@ except MyError as exc:
# https://github.com/RustPython/RustPython/issues/2771
# `BaseException` and `Exception`:
assert BaseException.__new__.__qualname__ == 'BaseException.__new__'
assert BaseException.__init__.__qualname__ == 'BaseException.__init__'
assert BaseException.__new__.__qualname__ == "BaseException.__new__"
assert BaseException.__init__.__qualname__ == "BaseException.__init__"
assert BaseException().__dict__ == {}
assert Exception.__new__.__qualname__ == 'Exception.__new__', Exception.__new__.__qualname__
assert Exception.__init__.__qualname__ == 'Exception.__init__', Exception.__init__.__qualname__
assert Exception.__new__.__qualname__ == "Exception.__new__", (
Exception.__new__.__qualname__
)
assert Exception.__init__.__qualname__ == "Exception.__init__", (
Exception.__init__.__qualname__
)
assert Exception().__dict__ == {}
# Extends `BaseException`, simple:
assert KeyboardInterrupt.__new__.__qualname__ == 'KeyboardInterrupt.__new__', KeyboardInterrupt.__new__.__qualname__
assert KeyboardInterrupt.__init__.__qualname__ == 'KeyboardInterrupt.__init__'
assert KeyboardInterrupt.__new__.__qualname__ == "KeyboardInterrupt.__new__", (
KeyboardInterrupt.__new__.__qualname__
)
assert KeyboardInterrupt.__init__.__qualname__ == "KeyboardInterrupt.__init__"
assert KeyboardInterrupt().__dict__ == {}
# Extends `Exception`, simple:
assert TypeError.__new__.__qualname__ == 'TypeError.__new__'
assert TypeError.__init__.__qualname__ == 'TypeError.__init__'
assert TypeError.__new__.__qualname__ == "TypeError.__new__"
assert TypeError.__init__.__qualname__ == "TypeError.__init__"
assert TypeError().__dict__ == {}
# Extends `Exception`, complex:
assert OSError.__new__.__qualname__ == 'OSError.__new__'
assert OSError.__init__.__qualname__ == 'OSError.__init__'
assert OSError.__new__.__qualname__ == "OSError.__new__"
assert OSError.__init__.__qualname__ == "OSError.__init__"
assert OSError().__dict__ == {}
assert OSError.errno
assert OSError.strerror
@@ -299,7 +314,7 @@ assert x.filename == None
assert x.filename2 == None
assert str(x) == "0"
w = OSError('foo')
w = OSError("foo")
assert w.errno == None
assert not sys.platform.startswith("win") or w.winerror == None
assert w.strerror == None
@@ -315,7 +330,7 @@ assert x.filename == None
assert x.filename2 == None
assert str(x) == "foo"
w = OSError('a', 'b', 'c', 'd', 'e', 'f')
w = OSError("a", "b", "c", "d", "e", "f")
assert w.errno == None
assert not sys.platform.startswith("win") or w.winerror == None
assert w.strerror == None
@@ -332,12 +347,10 @@ assert x.filename2 == None
assert str(x) == "('a', 'b', 'c', 'd', 'e', 'f')"
# Custom `__new__` and `__init__`:
assert ImportError.__init__.__qualname__ == 'ImportError.__init__'
assert ImportError(name='a').name == 'a'
assert (
ModuleNotFoundError.__init__.__qualname__ == 'ModuleNotFoundError.__init__'
)
assert ModuleNotFoundError(name='a').name == 'a'
assert ImportError.__init__.__qualname__ == "ImportError.__init__"
assert ImportError(name="a").name == "a"
assert ModuleNotFoundError.__init__.__qualname__ == "ModuleNotFoundError.__init__"
assert ModuleNotFoundError(name="a").name == "a"
# Check that all exceptions have string `__doc__`:

View File

@@ -3,11 +3,11 @@ assert 16 == square(4) # noqa: F821
d = {}
exec("def square(x):\n return x * x\n", {}, d)
assert 16 == d['square'](4)
assert 16 == d["square"](4)
exec("assert 2 == x", {}, {'x': 2})
exec("assert 2 == x", {'x': 2}, {})
exec("assert 4 == x", {'x': 2}, {'x': 4})
exec("assert 2 == x", {}, {"x": 2})
exec("assert 2 == x", {"x": 2}, {})
exec("assert 4 == x", {"x": 2}, {"x": 4})
exec("assert max(1, 2) == 2", {}, {})
@@ -16,9 +16,11 @@ exec("assert max(1, 5, square(5)) == 25", None)
# Local environment shouldn't replace global environment:
exec("assert max(1, 5, square(5)) == 25", None, {})
# Closures aren't available if local scope is replaced:
def g():
seven = "seven"
def f():
try:
exec("seven", None, {})
@@ -26,7 +28,10 @@ def g():
pass
else:
raise NameError("seven shouldn't be in scope")
f()
g()
try:
@@ -37,16 +42,16 @@ else:
raise TypeError("exec should fail unless globals is a dict or None")
g = globals()
g['x'] = 2
exec('x += 2')
g["x"] = 2
exec("x += 2")
assert x == 4 # noqa: F821
assert g['x'] == x # noqa: F821
assert g["x"] == x # noqa: F821
exec("del x")
assert 'x' not in g
assert "x" not in g
assert 'g' in globals()
assert 'g' in locals()
assert "g" in globals()
assert "g" in locals()
exec("assert 'g' in globals()")
exec("assert 'g' in locals()")
exec("assert 'g' not in globals()", {})
@@ -54,13 +59,15 @@ exec("assert 'g' not in locals()", {})
del g
def f():
g = 1
assert 'g' not in globals()
assert 'g' in locals()
assert "g" not in globals()
assert "g" in locals()
exec("assert 'g' not in globals()")
exec("assert 'g' in locals()")
exec("assert 'g' not in globals()", {})
exec("assert 'g' not in locals()", {})
f()

View File

@@ -36,4 +36,4 @@ with assert_raises(SystemExit):
sys.exit(1)
with assert_raises(SystemExit):
sys.exit("AB")
sys.exit("AB")

View File

@@ -2,37 +2,52 @@ from testutils import assert_raises
assert format(5, "b") == "101"
assert_raises(TypeError, format, 2, 3, _msg='format called with number')
assert_raises(TypeError, format, 2, 3, _msg="format called with number")
assert format({}) == "{}"
assert_raises(TypeError, format, {}, 'b', _msg='format_spec not empty for dict')
assert_raises(TypeError, format, {}, "b", _msg="format_spec not empty for dict")
class BadFormat:
def __format__(self, spec):
return 42
assert_raises(TypeError, format, BadFormat())
def test_zero_padding():
i = 1
assert f'{i:04d}' == '0001'
assert f"{i:04d}" == "0001"
test_zero_padding()
assert '{:,}'.format(100) == '100'
assert '{:,}'.format(1024) == '1,024'
assert '{:_}'.format(65536) == '65_536'
assert '{:_}'.format(4294967296) == '4_294_967_296'
assert f'{100:_}' == '100'
assert f'{1024:_}' == '1_024'
assert f'{65536:,}' == '65,536'
assert f'{4294967296:,}' == '4,294,967,296'
assert 'F' == "{0:{base}}".format(15, base="X")
assert f'{255:#X}' == "0XFF"
assert "{:,}".format(100) == "100"
assert "{:,}".format(1024) == "1,024"
assert "{:_}".format(65536) == "65_536"
assert "{:_}".format(4294967296) == "4_294_967_296"
assert f"{100:_}" == "100"
assert f"{1024:_}" == "1_024"
assert f"{65536:,}" == "65,536"
assert f"{4294967296:,}" == "4,294,967,296"
assert "F" == "{0:{base}}".format(15, base="X")
assert f"{255:#X}" == "0XFF"
assert f"{65:c}" == "A"
assert f"{0x1f5a5:c}" == "🖥"
assert_raises(ValueError, "{:+c}".format, 1, _msg="Sign not allowed with integer format specifier 'c'")
assert_raises(ValueError, "{:#c}".format, 1, _msg="Alternate form (#) not allowed with integer format specifier 'c'")
assert f"{0x1F5A5:c}" == "🖥"
assert_raises(
ValueError,
"{:+c}".format,
1,
_msg="Sign not allowed with integer format specifier 'c'",
)
assert_raises(
ValueError,
"{:#c}".format,
1,
_msg="Alternate form (#) not allowed with integer format specifier 'c'",
)
assert f"{256:#010x}" == "0x00000100"
assert f"{256:0=#10x}" == "0x00000100"
assert f"{256:0>#10x}" == "000000x100"
@@ -66,14 +81,31 @@ assert f"{123.456:011,}" == "000,123.456"
assert f"{123.456:+011,}" == "+00,123.456"
assert f"{1234:.3g}" == "1.23e+03"
assert f"{1234567:.6G}" == "1.23457E+06"
assert f'{"🐍":4}' == "🐍 "
assert_raises(ValueError, "{:,o}".format, 1, _msg="ValueError: Cannot specify ',' with 'o'.")
assert_raises(ValueError, "{:_n}".format, 1, _msg="ValueError: Cannot specify '_' with 'n'.")
assert_raises(ValueError, "{:,o}".format, 1.0, _msg="ValueError: Cannot specify ',' with 'o'.")
assert_raises(ValueError, "{:_n}".format, 1.0, _msg="ValueError: Cannot specify '_' with 'n'.")
assert_raises(ValueError, "{:,}".format, "abc", _msg="ValueError: Cannot specify ',' with 's'.")
assert_raises(ValueError, "{:,x}".format, "abc", _msg="ValueError: Cannot specify ',' with 'x'.")
assert_raises(OverflowError, "{:c}".format, 0x110000, _msg="OverflowError: %c arg not in range(0x110000)")
assert f"{'🐍':4}" == "🐍 "
assert_raises(
ValueError, "{:,o}".format, 1, _msg="ValueError: Cannot specify ',' with 'o'."
)
assert_raises(
ValueError, "{:_n}".format, 1, _msg="ValueError: Cannot specify '_' with 'n'."
)
assert_raises(
ValueError, "{:,o}".format, 1.0, _msg="ValueError: Cannot specify ',' with 'o'."
)
assert_raises(
ValueError, "{:_n}".format, 1.0, _msg="ValueError: Cannot specify '_' with 'n'."
)
assert_raises(
ValueError, "{:,}".format, "abc", _msg="ValueError: Cannot specify ',' with 's'."
)
assert_raises(
ValueError, "{:,x}".format, "abc", _msg="ValueError: Cannot specify ',' with 'x'."
)
assert_raises(
OverflowError,
"{:c}".format,
0x110000,
_msg="OverflowError: %c arg not in range(0x110000)",
)
assert f"{3:f}" == "3.000000"
assert f"{3.1415:.0f}" == "3"
assert f"{3.1415:.1f}" == "3.1"
@@ -115,14 +147,14 @@ assert f"{3.1415:#.3e}" == "3.142e+00"
assert f"{3.1415:#.4e}" == "3.1415e+00"
assert f"{3.1415:#.5e}" == "3.14150e+00"
assert f"{3.1415:#.5E}" == "3.14150E+00"
assert f"{3.1415:.0%}" == '314%'
assert f"{3.1415:.1%}" == '314.2%'
assert f"{3.1415:.2%}" == '314.15%'
assert f"{3.1415:.3%}" == '314.150%'
assert f"{3.1415:#.0%}" == '314.%'
assert f"{3.1415:#.1%}" == '314.2%'
assert f"{3.1415:#.2%}" == '314.15%'
assert f"{3.1415:#.3%}" == '314.150%'
assert f"{3.1415:.0%}" == "314%"
assert f"{3.1415:.1%}" == "314.2%"
assert f"{3.1415:.2%}" == "314.15%"
assert f"{3.1415:.3%}" == "314.150%"
assert f"{3.1415:#.0%}" == "314.%"
assert f"{3.1415:#.1%}" == "314.2%"
assert f"{3.1415:#.2%}" == "314.15%"
assert f"{3.1415:#.3%}" == "314.150%"
assert f"{3.1415:.0}" == "3e+00"
assert f"{3.1415:.1}" == "3e+00"
assert f"{3.1415:.2}" == "3.1"
@@ -137,5 +169,5 @@ assert f"{3.1415:#.4}" == "3.142"
# test issue 4558
x = 123456789012345678901234567890
for i in range(0, 30):
format(x, ',')
format(x, ",")
x = x // 10

View File

@@ -1,4 +1,3 @@
from testutils import assert_raises

View File

@@ -1,6 +1,6 @@
from testutils import assert_raises
assert hex(16) == '0x10'
assert hex(-16) == '-0x10'
assert hex(16) == "0x10"
assert hex(-16) == "-0x10"
assert_raises(TypeError, hex, {}, _msg='ord() called with dict')
assert_raises(TypeError, hex, {}, _msg="ord() called with dict")

View File

@@ -1,4 +1,3 @@
class Regular:
pass
@@ -41,14 +40,17 @@ assert isinstance(AlwaysInstanceOf(), AlwaysInstanceOf)
assert isinstance(Regular(), AlwaysInstanceOf)
assert isinstance(1, AlwaysInstanceOf)
class GenericInstance:
def __instancecheck__(self, _):
return True
assert isinstance(Regular(), GenericInstance())
assert isinstance([], GenericInstance())
assert isinstance(1, GenericInstance())
class MCReturnInt(type):
def __instancecheck__(self, instance):
return 3
@@ -60,4 +62,13 @@ class ReturnInt(metaclass=MCReturnInt):
assert isinstance("a", ReturnInt) is True
assert isinstance(1, ((int, float,), str))
assert isinstance(
1,
(
(
int,
float,
),
str,
),
)

View File

@@ -1,4 +1,3 @@
class A:
pass
@@ -49,14 +48,17 @@ assert issubclass(AlwaysSubClass, AlwaysSubClass)
assert issubclass(InheritedAlwaysSubClass, AlwaysSubClass)
assert issubclass(AlwaysSubClass, InheritedAlwaysSubClass)
class GenericInstance:
def __subclasscheck__(self, _):
return True
assert issubclass(A, GenericInstance())
assert issubclass(list, GenericInstance())
assert issubclass([], GenericInstance())
class MCAVirtualSubClass(type):
def __subclasscheck__(self, subclass):
return subclass is A

View File

@@ -1,2 +1,2 @@
assert 3 == len([1,2,3])
assert 2 == len((1,2))
assert 3 == len([1, 2, 3])
assert 2 == len((1, 2))

View File

@@ -12,38 +12,85 @@ y.extend(x)
assert y == [2, 1, 2, 3, 1, 2, 3]
a = []
a.extend((1,2,3,4))
a.extend((1, 2, 3, 4))
assert a == [1, 2, 3, 4]
a.extend('abcdefg')
assert a == [1, 2, 3, 4, 'a', 'b', 'c', 'd', 'e', 'f', 'g']
a.extend("abcdefg")
assert a == [1, 2, 3, 4, "a", "b", "c", "d", "e", "f", "g"]
a.extend(range(10))
assert a == [1, 2, 3, 4, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
assert a == [
1,
2,
3,
4,
"a",
"b",
"c",
"d",
"e",
"f",
"g",
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
]
a = []
a.extend({1,2,3,4})
a.extend({1, 2, 3, 4})
assert a == [1, 2, 3, 4]
a.extend({'a': 1, 'b': 2, 'z': 51})
assert a == [1, 2, 3, 4, 'a', 'b', 'z']
a.extend({"a": 1, "b": 2, "z": 51})
assert a == [1, 2, 3, 4, "a", "b", "z"]
class Iter:
def __iter__(self):
yield 12
yield 28
a.extend(Iter())
assert a == [1, 2, 3, 4, 'a', 'b', 'z', 12, 28]
a.extend(bytes(b'hello world'))
assert a == [1, 2, 3, 4, 'a', 'b', 'z', 12, 28, 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]
a.extend(Iter())
assert a == [1, 2, 3, 4, "a", "b", "z", 12, 28]
a.extend(bytes(b"hello world"))
assert a == [
1,
2,
3,
4,
"a",
"b",
"z",
12,
28,
104,
101,
108,
108,
111,
32,
119,
111,
114,
108,
100,
]
class Next:
def __next__(self):
yield 12
yield 28
assert_raises(TypeError, lambda: [].extend(3))
assert_raises(TypeError, lambda: [].extend(slice(0, 10, 1)))
@@ -56,12 +103,12 @@ assert y is x
assert x == [1, 2, 3] * 2
# index()
assert ['a', 'b', 'c'].index('b') == 1
assert ["a", "b", "c"].index("b") == 1
assert [5, 6, 7].index(7) == 2
assert_raises(ValueError, lambda: ['a', 'b', 'c'].index('z'))
assert_raises(ValueError, lambda: ["a", "b", "c"].index("z"))
x = [[1,0,-3], 'a', 1]
y = [[3,2,1], 'z', 2]
x = [[1, 0, -3], "a", 1]
y = [[3, 2, 1], "z", 2]
assert x < y, "list __lt__ failed"
x = [5, 13, 31]
@@ -73,9 +120,12 @@ x = [0, 1, 2]
assert x.pop() == 2
assert x == [0, 1]
def test_pop(lst, idx, value, new_lst):
assert lst.pop(idx) == value
assert lst == new_lst
test_pop([0, 1, 2], -1, 2, [0, 1])
test_pop([0, 1, 2], 0, 0, [1, 2])
test_pop([0, 1, 2], 1, 1, [0, 2])
@@ -91,23 +141,23 @@ recursive.append(recursive)
assert repr(recursive) == "[[...]]"
# insert()
x = ['a', 'b', 'c']
x.insert(0, 'z') # insert is in-place, no return value
assert x == ['z', 'a', 'b', 'c']
x = ["a", "b", "c"]
x.insert(0, "z") # insert is in-place, no return value
assert x == ["z", "a", "b", "c"]
x = ['a', 'b', 'c']
x.insert(100, 'z')
assert x == ['a', 'b', 'c', 'z']
x = ["a", "b", "c"]
x.insert(100, "z")
assert x == ["a", "b", "c", "z"]
x = ['a', 'b', 'c']
x.insert(-1, 'z')
assert x == ['a', 'b', 'z', 'c']
x = ["a", "b", "c"]
x.insert(-1, "z")
assert x == ["a", "b", "z", "c"]
x = ['a', 'b', 'c']
x.insert(-100, 'z')
assert x == ['z', 'a', 'b', 'c']
x = ["a", "b", "c"]
x.insert(-100, "z")
assert x == ["z", "a", "b", "c"]
assert_raises(OverflowError, lambda: x.insert(100000000000000000000, 'z'))
assert_raises(OverflowError, lambda: x.insert(100000000000000000000, "z"))
x = [[], 2, {}]
y = x.copy()
@@ -123,7 +173,7 @@ a.remove(1)
assert len(a) == 2
assert not 1 in a
assert_raises(ValueError, lambda: a.remove(10), _msg='Remove not exist element')
assert_raises(ValueError, lambda: a.remove(10), _msg="Remove not exist element")
foo = bar = [1]
foo += [2]
@@ -138,10 +188,12 @@ assert x.count(x) == 1
x.remove(x)
assert x not in x
class Foo(object):
def __eq__(self, x):
return False
foo = Foo()
foo1 = Foo()
x = [1, foo, 2, foo, []]
@@ -173,17 +225,17 @@ assert a == b
assert [foo] == [foo]
for size in [1, 2, 3, 4, 5, 8, 10, 100, 1000]:
lst = list(range(size))
orig = lst[:]
lst.sort()
assert lst == orig
assert sorted(lst) == orig
assert_raises(ZeroDivisionError, sorted, lst, key=lambda x: 1/x)
lst.reverse()
assert sorted(lst) == orig
assert sorted(lst, reverse=True) == lst
assert sorted(lst, key=lambda x: -x) == lst
assert sorted(lst, key=lambda x: -x, reverse=True) == orig
lst = list(range(size))
orig = lst[:]
lst.sort()
assert lst == orig
assert sorted(lst) == orig
assert_raises(ZeroDivisionError, sorted, lst, key=lambda x: 1 / x)
lst.reverse()
assert sorted(lst) == orig
assert sorted(lst, reverse=True) == lst
assert sorted(lst, key=lambda x: -x) == lst
assert sorted(lst, key=lambda x: -x, reverse=True) == orig
assert sorted([(1, 2, 3), (0, 3, 6)]) == [(0, 3, 6), (1, 2, 3)]
assert sorted([(1, 2, 3), (0, 3, 6)], key=lambda x: x[0]) == [(0, 3, 6), (1, 2, 3)]
@@ -191,34 +243,52 @@ assert sorted([(1, 2, 3), (0, 3, 6)], key=lambda x: x[1]) == [(1, 2, 3), (0, 3,
assert sorted([(1, 2), (), (5,)], key=len) == [(), (5,), (1, 2)]
lst = [3, 1, 5, 2, 4]
class C:
def __init__(self, x): self.x = x
def __lt__(self, other): return self.x < other.x
def __init__(self, x):
self.x = x
def __lt__(self, other):
return self.x < other.x
lst.sort(key=C)
assert lst == [1, 2, 3, 4, 5]
lst = [3, 1, 5, 2, 4]
class C:
def __init__(self, x): self.x = x
def __gt__(self, other): return self.x > other.x
def __init__(self, x):
self.x = x
def __gt__(self, other):
return self.x > other.x
lst.sort(key=C)
assert lst == [1, 2, 3, 4, 5]
lst = [5, 1, 2, 3, 4]
def f(x):
lst.append(1)
return x
assert_raises(ValueError, lambda: lst.sort(key=f)) # "list modified during sort"
assert_raises(ValueError, lambda: lst.sort(key=f)) # "list modified during sort"
assert lst == [1, 2, 3, 4, 5]
# __delitem__
x = ['a', 'b', 'c']
x = ["a", "b", "c"]
del x[0]
assert x == ['b', 'c']
assert x == ["b", "c"]
x = ['a', 'b', 'c']
x = ["a", "b", "c"]
del x[-1]
assert x == ['a', 'b']
assert x == ["a", "b"]
x = y = [1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15]
del x[2:14:3]
@@ -232,24 +302,30 @@ assert x == [1, 2, 3, 4, 5, 6, 7, 8, 10]
x = list(range(12))
del x[10:2:-2]
assert x == [0,1,2,3,5,7,9,11]
assert x == [0, 1, 2, 3, 5, 7, 9, 11]
def bad_del_1():
del ['a', 'b']['a']
del ["a", "b"]["a"]
assert_raises(TypeError, bad_del_1)
def bad_del_2():
del ['a', 'b'][2]
del ["a", "b"][2]
assert_raises(IndexError, bad_del_2)
# __setitem__
# simple index
x = [1, 2, 3, 4, 5]
x[0] = 'a'
assert x == ['a', 2, 3, 4, 5]
x[-1] = 'b'
assert x == ['a', 2, 3, 4, 'b']
x[0] = "a"
assert x == ["a", 2, 3, 4, 5]
x[-1] = "b"
assert x == ["a", 2, 3, 4, "b"]
# make sure refrences are assigned correctly
y = []
x[1] = y
@@ -257,14 +333,17 @@ y.append(100)
assert x[1] == y
assert x[1] == [100]
#index bounds
# index bounds
def set_index_out_of_bounds_high():
x = [0, 1, 2, 3, 4]
x[5] = 'a'
x = [0, 1, 2, 3, 4]
x[5] = "a"
def set_index_out_of_bounds_low():
x = [0, 1, 2, 3, 4]
x[-6] = 'a'
x = [0, 1, 2, 3, 4]
x[-6] = "a"
assert_raises(IndexError, set_index_out_of_bounds_high)
assert_raises(IndexError, set_index_out_of_bounds_low)
@@ -275,20 +354,20 @@ x = a[:]
y = a[:]
assert x == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# replace whole list
x[:] = ['a', 'b', 'c']
y[::1] = ['a', 'b', 'c']
assert x == ['a', 'b', 'c']
x[:] = ["a", "b", "c"]
y[::1] = ["a", "b", "c"]
assert x == ["a", "b", "c"]
assert x == y
# splice list start
x = a[:]
y = a[:]
z = a[:]
zz = a[:]
x[:1] = ['a', 'b', 'c']
y[0:1] = ['a', 'b', 'c']
z[:1:1] = ['a', 'b', 'c']
zz[0:1:1] = ['a', 'b', 'c']
assert x == ['a', 'b', 'c', 1, 2, 3, 4, 5, 6, 7, 8, 9]
x[:1] = ["a", "b", "c"]
y[0:1] = ["a", "b", "c"]
z[:1:1] = ["a", "b", "c"]
zz[0:1:1] = ["a", "b", "c"]
assert x == ["a", "b", "c", 1, 2, 3, 4, 5, 6, 7, 8, 9]
assert x == y
assert x == z
assert x == zz
@@ -297,11 +376,11 @@ x = a[:]
y = a[:]
z = a[:]
zz = a[:]
x[5:] = ['a', 'b', 'c']
y[5::1] = ['a', 'b', 'c']
z[5:10] = ['a', 'b', 'c']
zz[5:10:1] = ['a', 'b', 'c']
assert x == [0, 1, 2, 3, 4, 'a', 'b', 'c']
x[5:] = ["a", "b", "c"]
y[5::1] = ["a", "b", "c"]
z[5:10] = ["a", "b", "c"]
zz[5:10:1] = ["a", "b", "c"]
assert x == [0, 1, 2, 3, 4, "a", "b", "c"]
assert x == y
assert x == z
assert x == zz
@@ -310,11 +389,11 @@ x = a[:]
y = a[:]
z = a[:]
zz = a[:]
x[1:1] = ['a', 'b', 'c']
y[1:0] = ['a', 'b', 'c']
z[1:1:1] = ['a', 'b', 'c']
zz[1:0:1] = ['a', 'b', 'c']
assert x == [0, 'a', 'b', 'c', 1, 2, 3, 4, 5, 6, 7, 8, 9]
x[1:1] = ["a", "b", "c"]
y[1:0] = ["a", "b", "c"]
z[1:1:1] = ["a", "b", "c"]
zz[1:0:1] = ["a", "b", "c"]
assert x == [0, "a", "b", "c", 1, 2, 3, 4, 5, 6, 7, 8, 9]
assert x == y
assert x == z
assert x == zz
@@ -323,24 +402,24 @@ x = a[:]
y = a[:]
z = a[:]
zz = a[:]
x[-1:-1] = ['a', 'b', 'c']
y[-1:9] = ['a', 'b', 'c']
z[-1:-1:1] = ['a', 'b', 'c']
zz[-1:9:1] = ['a', 'b', 'c']
assert x == [0, 1, 2, 3, 4, 5, 6, 7, 8, 'a', 'b', 'c', 9]
x[-1:-1] = ["a", "b", "c"]
y[-1:9] = ["a", "b", "c"]
z[-1:-1:1] = ["a", "b", "c"]
zz[-1:9:1] = ["a", "b", "c"]
assert x == [0, 1, 2, 3, 4, 5, 6, 7, 8, "a", "b", "c", 9]
assert x == y
assert x == z
assert x == zz
# splice mid
x = a[:]
y = a[:]
x[3:5] = ['a', 'b', 'c', 'd', 'e']
y[3:5:1] = ['a', 'b', 'c', 'd', 'e']
assert x == [0, 1, 2, 'a', 'b', 'c', 'd', 'e', 5, 6, 7, 8, 9]
x[3:5] = ["a", "b", "c", "d", "e"]
y[3:5:1] = ["a", "b", "c", "d", "e"]
assert x == [0, 1, 2, "a", "b", "c", "d", "e", 5, 6, 7, 8, 9]
assert x == y
x = a[:]
x[3:5] = ['a']
assert x == [0, 1, 2, 'a', 5, 6, 7, 8, 9]
x[3:5] = ["a"]
assert x == [0, 1, 2, "a", 5, 6, 7, 8, 9]
# assign empty to non stepped empty slice does nothing
x = a[:]
y = a[:]
@@ -359,84 +438,93 @@ assert x == y
yy = []
x = a[:]
y = a[:]
x[3:5] = ['a', 'b', 'c', 'd', yy]
y[3:5:1] = ['a', 'b', 'c', 'd', yy]
assert x == [0, 1, 2, 'a', 'b', 'c', 'd', [], 5, 6, 7, 8, 9]
x[3:5] = ["a", "b", "c", "d", yy]
y[3:5:1] = ["a", "b", "c", "d", yy]
assert x == [0, 1, 2, "a", "b", "c", "d", [], 5, 6, 7, 8, 9]
assert x == y
yy.append(100)
assert x == [0, 1, 2, 'a', 'b', 'c', 'd', [100], 5, 6, 7, 8, 9]
assert x == [0, 1, 2, "a", "b", "c", "d", [100], 5, 6, 7, 8, 9]
assert x == y
assert x[7] == yy
assert x[7] == [100]
assert y[7] == yy
assert y[7] == [100]
# no zero step
def no_zero_step_set():
x = [1, 2, 3, 4, 5]
x[0:4:0] = [11, 12, 13, 14, 15]
x = [1, 2, 3, 4, 5]
x[0:4:0] = [11, 12, 13, 14, 15]
assert_raises(ValueError, no_zero_step_set)
# stepped slice index
# forward slice
x = a[:]
x[2:8:2] = ['a', 'b', 'c']
assert x == [0, 1, 'a', 3, 'b', 5, 'c', 7, 8, 9]
x[2:8:2] = ["a", "b", "c"]
assert x == [0, 1, "a", 3, "b", 5, "c", 7, 8, 9]
x = a[:]
y = a[:]
z = a[:]
zz = a[:]
c = ['a', 'b', 'c', 'd', 'e']
c = ["a", "b", "c", "d", "e"]
x[::2] = c
y[-10::2] = c
z[0:10:2] = c
zz[-13:13:2] = c # slice indexes will be truncated to bounds
assert x == ['a', 1, 'b', 3, 'c', 5, 'd', 7, 'e', 9]
zz[-13:13:2] = c # slice indexes will be truncated to bounds
assert x == ["a", 1, "b", 3, "c", 5, "d", 7, "e", 9]
assert x == y
assert x == z
assert x == zz
# backward slice
x = a[:]
x[8:2:-2] = ['a', 'b', 'c']
assert x == [0, 1, 2, 3, 'c', 5, 'b', 7, 'a', 9]
x[8:2:-2] = ["a", "b", "c"]
assert x == [0, 1, 2, 3, "c", 5, "b", 7, "a", 9]
x = a[:]
y = a[:]
z = a[:]
zz = a[:]
c = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
c = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]
x[::-1] = c
y[9:-11:-1] = c
z[9::-1] = c
zz[11:-13:-1] = c # slice indexes will be truncated to bounds
assert x == ['j', 'i', 'h', 'g', 'f', 'e', 'd', 'c', 'b', 'a']
zz[11:-13:-1] = c # slice indexes will be truncated to bounds
assert x == ["j", "i", "h", "g", "f", "e", "d", "c", "b", "a"]
assert x == y
assert x == z
assert x == zz
# step size bigger than len
x = a[:]
x[::200] = ['a']
assert x == ['a', 1, 2, 3, 4, 5, 6, 7, 8, 9]
x[::200] = ["a"]
assert x == ["a", 1, 2, 3, 4, 5, 6, 7, 8, 9]
x = a[:]
x[5::200] = ['a']
assert x == [0, 1, 2, 3, 4, 'a', 6, 7, 8, 9]
x[5::200] = ["a"]
assert x == [0, 1, 2, 3, 4, "a", 6, 7, 8, 9]
# bad stepped slices
def stepped_slice_assign_too_big():
x = [0, 1, 2, 3, 4]
x[::2] = ['a', 'b', 'c', 'd']
x = [0, 1, 2, 3, 4]
x[::2] = ["a", "b", "c", "d"]
assert_raises(ValueError, stepped_slice_assign_too_big)
def stepped_slice_assign_too_small():
x = [0, 1, 2, 3, 4]
x[::2] = ['a', 'b']
x = [0, 1, 2, 3, 4]
x[::2] = ["a", "b"]
assert_raises(ValueError, stepped_slice_assign_too_small)
# must assign iter t0 slice
def must_assign_iter_to_slice():
x = [0, 1, 2, 3, 4]
x[::2] = 42
x = [0, 1, 2, 3, 4]
x[::2] = 42
assert_raises(TypeError, must_assign_iter_to_slice)
@@ -446,74 +534,87 @@ a = list(range(10))
# string
x = a[:]
x[3:8] = "abcdefghi"
assert x == [0, 1, 2, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 8, 9]
assert x == [0, 1, 2, "a", "b", "c", "d", "e", "f", "g", "h", "i", 8, 9]
# tuple
x = a[:]
x[3:8] = (11, 12, 13, 14, 15)
assert x == [0, 1, 2, 11, 12, 13, 14, 15, 8, 9]
# class
# __next__
class CIterNext:
def __init__(self, sec=(1, 2, 3)):
self.sec = sec
self.index = 0
def __iter__(self):
return self
def __next__(self):
if self.index >= len(self.sec):
raise StopIteration
v = self.sec[self.index]
self.index += 1
return v
def __init__(self, sec=(1, 2, 3)):
self.sec = sec
self.index = 0
def __iter__(self):
return self
def __next__(self):
if self.index >= len(self.sec):
raise StopIteration
v = self.sec[self.index]
self.index += 1
return v
x = list(range(10))
x[3:8] = CIterNext()
assert x == [0, 1, 2, 1, 2, 3, 8, 9]
# __iter__ yield
class CIter:
def __init__(self, sec=(1, 2, 3)):
self.sec = sec
def __iter__(self):
for n in self.sec:
yield n
def __init__(self, sec=(1, 2, 3)):
self.sec = sec
def __iter__(self):
for n in self.sec:
yield n
x = list(range(10))
x[3:8] = CIter()
assert x == [0, 1, 2, 1, 2, 3, 8, 9]
# __getitem but no __iter__ sequence
class CGetItem:
def __init__(self, sec=(1, 2, 3)):
self.sec = sec
def __getitem__(self, sub):
return self.sec[sub]
def __init__(self, sec=(1, 2, 3)):
self.sec = sec
def __getitem__(self, sub):
return self.sec[sub]
x = list(range(10))
x[3:8] = CGetItem()
assert x == [0, 1, 2, 1, 2, 3, 8, 9]
# iter raises error
class CIterError:
def __iter__(self):
for i in range(10):
if i > 5:
raise RuntimeError
yield i
def __iter__(self):
for i in range(10):
if i > 5:
raise RuntimeError
yield i
def bad_iter_assign():
x = list(range(10))
x[3:8] = CIterError()
x = list(range(10))
x[3:8] = CIterError()
assert_raises(RuntimeError, bad_iter_assign)
# slice assign when step or stop is -1
a = list(range(10))
x = a[:]
x[-1:-5:-1] = ['a', 'b', 'c', 'd']
assert x == [0, 1, 2, 3, 4, 5, 'd', 'c', 'b', 'a']
x[-1:-5:-1] = ["a", "b", "c", "d"]
assert x == [0, 1, 2, 3, 4, 5, "d", "c", "b", "a"]
x = a[:]
x[-5:-1:-1] = []
assert x == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
@@ -557,17 +658,17 @@ assert [0, 0] <= [0, 0]
assert not [0, 0] > [0, 0]
assert not [0, 0] < [0, 0]
assert not [float('nan'), float('nan')] <= [float('nan'), 1]
assert not [float('nan'), float('nan')] <= [float('nan'), float('nan')]
assert not [float('nan'), float('nan')] >= [float('nan'), float('nan')]
assert not [float('nan'), float('nan')] < [float('nan'), float('nan')]
assert not [float('nan'), float('nan')] > [float('nan'), float('nan')]
assert not [float("nan"), float("nan")] <= [float("nan"), 1]
assert not [float("nan"), float("nan")] <= [float("nan"), float("nan")]
assert not [float("nan"), float("nan")] >= [float("nan"), float("nan")]
assert not [float("nan"), float("nan")] < [float("nan"), float("nan")]
assert not [float("nan"), float("nan")] > [float("nan"), float("nan")]
assert [float('inf'), float('inf')] >= [float('inf'), 1]
assert [float('inf'), float('inf')] <= [float('inf'), float('inf')]
assert [float('inf'), float('inf')] >= [float('inf'), float('inf')]
assert not [float('inf'), float('inf')] < [float('inf'), float('inf')]
assert not [float('inf'), float('inf')] > [float('inf'), float('inf')]
assert [float("inf"), float("inf")] >= [float("inf"), 1]
assert [float("inf"), float("inf")] <= [float("inf"), float("inf")]
assert [float("inf"), float("inf")] >= [float("inf"), float("inf")]
assert not [float("inf"), float("inf")] < [float("inf"), float("inf")]
assert not [float("inf"), float("inf")] > [float("inf"), float("inf")]
# list __iadd__
a = []
@@ -575,62 +676,111 @@ a += [1, 2, 3]
assert a == [1, 2, 3]
a = []
a += (1,2,3,4)
a += (1, 2, 3, 4)
assert a == [1, 2, 3, 4]
a += 'abcdefg'
assert a == [1, 2, 3, 4, 'a', 'b', 'c', 'd', 'e', 'f', 'g']
a += "abcdefg"
assert a == [1, 2, 3, 4, "a", "b", "c", "d", "e", "f", "g"]
a += range(10)
assert a == [1, 2, 3, 4, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
assert a == [
1,
2,
3,
4,
"a",
"b",
"c",
"d",
"e",
"f",
"g",
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
]
a = []
a += {1,2,3,4}
a += {1, 2, 3, 4}
assert a == [1, 2, 3, 4]
a += {'a': 1, 'b': 2, 'z': 51}
assert a == [1, 2, 3, 4, 'a', 'b', 'z']
a += {"a": 1, "b": 2, "z": 51}
assert a == [1, 2, 3, 4, "a", "b", "z"]
class Iter:
def __iter__(self):
yield 12
yield 28
a += Iter()
assert a == [1, 2, 3, 4, 'a', 'b', 'z', 12, 28]
a += bytes(b'hello world')
assert a == [1, 2, 3, 4, 'a', 'b', 'z', 12, 28, 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]
a += Iter()
assert a == [1, 2, 3, 4, "a", "b", "z", 12, 28]
a += bytes(b"hello world")
assert a == [
1,
2,
3,
4,
"a",
"b",
"z",
12,
28,
104,
101,
108,
108,
111,
32,
119,
111,
114,
108,
100,
]
class Next:
def __next__(self):
yield 12
yield 28
def iadd_int():
a = []
a += 3
def iadd_slice():
a = []
a += slice(0, 10, 1)
assert_raises(TypeError, iadd_int)
assert_raises(TypeError, iadd_slice)
it = iter([1,2,3,4])
it = iter([1, 2, 3, 4])
assert it.__length_hint__() == 4
assert next(it) == 1
assert it.__length_hint__() == 3
assert list(it) == [2,3,4]
assert list(it) == [2, 3, 4]
assert it.__length_hint__() == 0
it = reversed([1,2,3,4])
it = reversed([1, 2, 3, 4])
assert it.__length_hint__() == 4
assert next(it) == 4
assert it.__length_hint__() == 3
assert list(it) == [3,2,1]
assert list(it) == [3, 2, 1]
assert it.__length_hint__() == 0
a = [*[1, 2], 3, *[4, 5]]
@@ -648,21 +798,25 @@ for base in object, list, tuple:
class C(base):
def __iter__(self):
a.append(2)
def inner():
yield 3
a.append(4)
return inner()
a = [1]
b = [*a, *C(), *a.copy()]
assert b == [1, 3, 1, 2, 4]
# Test for list entering daedlock or not (https://github.com/RustPython/RustPython/pull/2933)
class MutatingCompare:
def __eq__(self, other):
self.list.pop()
return True
m = MutatingCompare()
l = [1, 2, 3, m, 4]
@@ -675,18 +829,21 @@ assert l.index(4) == 3
l = [1, 2, 3, m, 4]
m.list = l
l.remove(4)
assert_raises(ValueError, lambda: l.index(4)) # element 4 must not be in the list
l.remove(4)
assert_raises(ValueError, lambda: l.index(4)) # element 4 must not be in the list
# Test no panic occurred when list elements was deleted in __eq__
class rewrite_list_eq(list):
pass
class poc:
def __eq__(self, other):
list1.clear()
return self
list1 = rewrite_list_eq([poc()])
list1.remove(list1)
assert list1 == []

View File

@@ -1,19 +1,18 @@
a = 5
b = 6
loc = locals()
assert loc['a'] == 5
assert loc['b'] == 6
assert loc["a"] == 5
assert loc["b"] == 6
def f():
c = 4
a = 7
c = 4
a = 7
loc = locals()
assert loc['a'] == 4
assert loc['c'] == 7
assert not 'b' in loc
loc = locals()
assert loc["a"] == 4
assert loc["c"] == 7
assert not "b" in loc

View File

@@ -1,5 +1,5 @@
a = list(map(str, [1, 2, 3]))
assert a == ['1', '2', '3']
assert a == ["1", "2", "3"]
b = list(map(lambda x, y: x + y, [1, 2, 4], [3, 5]))
@@ -20,7 +20,7 @@ class Counter(object):
return self
it = map(lambda x: x+1, Counter())
it = map(lambda x: x + 1, Counter())
assert next(it) == 2
assert next(it) == 3

View File

@@ -1,5 +1,6 @@
from testutils import assert_raises
class A(dict):
def a():
pass
@@ -8,16 +9,16 @@ class A(dict):
pass
assert A.__dict__['a'] == A.a
assert A.__dict__["a"] == A.a
with assert_raises(KeyError) as cm:
A.__dict__['not here']
A.__dict__["not here"]
assert cm.exception.args[0] == "not here"
assert 'b' in A.__dict__
assert 'c' not in A.__dict__
assert "b" in A.__dict__
assert "c" not in A.__dict__
assert '__dict__' in A.__dict__
assert "__dict__" in A.__dict__
assert A.__dict__.get("not here", "default") == "default"
assert A.__dict__.get("a", "default") is A.a

View File

@@ -3,17 +3,22 @@ from testutils import assert_raises
# simple values
assert max(0, 0) == 0
assert max(1, 0) == 1
assert max(1., 0.) == 1.
assert max(1.0, 0.0) == 1.0
assert max(-1, 0) == 0
assert max(1, 2, 3) == 3
# iterables
assert max([1, 2, 3]) == 3
assert max((1, 2, 3)) == 3
assert max({
"a": 0,
"b": 1,
}) == "b"
assert (
max(
{
"a": 0,
"b": 1,
}
)
== "b"
)
assert max([1, 2], default=0) == 2
assert max([], default=0) == 0
assert_raises(ValueError, max, [])
@@ -30,7 +35,7 @@ assert_raises(TypeError, max, 1)
# custom class
class MyComparable():
class MyComparable:
nb = 0
def __init__(self):
@@ -47,7 +52,7 @@ assert max(first, second) == second
assert max([first, second]) == second
class MyNotComparable():
class MyNotComparable:
pass

View File

@@ -10,48 +10,52 @@ assert a[2:3] == b"c"
assert hash(obj) == hash(a)
class A(array.array):
...
class B(bytes):
...
class A(array.array): ...
class C():
...
memoryview(bytearray('abcde', encoding='utf-8'))
memoryview(array.array('i', [1, 2, 3]))
memoryview(A('b', [0]))
memoryview(B('abcde', encoding='utf-8'))
class B(bytes): ...
class C: ...
memoryview(bytearray("abcde", encoding="utf-8"))
memoryview(array.array("i", [1, 2, 3]))
memoryview(A("b", [0]))
memoryview(B("abcde", encoding="utf-8"))
assert_raises(TypeError, lambda: memoryview([1, 2, 3]))
assert_raises(TypeError, lambda: memoryview((1, 2, 3)))
assert_raises(TypeError, lambda: memoryview({}))
assert_raises(TypeError, lambda: memoryview('string'))
assert_raises(TypeError, lambda: memoryview("string"))
assert_raises(TypeError, lambda: memoryview(C()))
def test_slice():
b = b'123456789'
b = b"123456789"
m = memoryview(b)
m2 = memoryview(b)
assert m == m
assert m == m2
assert m.tobytes() == b'123456789'
assert m.tobytes() == b"123456789"
assert m == b
assert m[::2].tobytes() == b'13579'
assert m[::2] == b'13579'
assert m[1::2].tobytes() == b'2468'
assert m[::2][1:].tobytes() == b'3579'
assert m[::2][1:-1].tobytes() == b'357'
assert m[::2][::2].tobytes() == b'159'
assert m[::2][1::2].tobytes() == b'37'
assert m[::-1].tobytes() == b'987654321'
assert m[::-2].tobytes() == b'97531'
assert m[::2].tobytes() == b"13579"
assert m[::2] == b"13579"
assert m[1::2].tobytes() == b"2468"
assert m[::2][1:].tobytes() == b"3579"
assert m[::2][1:-1].tobytes() == b"357"
assert m[::2][::2].tobytes() == b"159"
assert m[::2][1::2].tobytes() == b"37"
assert m[::-1].tobytes() == b"987654321"
assert m[::-2].tobytes() == b"97531"
test_slice()
def test_resizable():
b = bytearray(b'123')
b = bytearray(b"123")
b.append(4)
m = memoryview(b)
assert_raises(BufferError, lambda: b.append(5))
@@ -68,18 +72,21 @@ def test_resizable():
m4.release()
b.append(7)
test_resizable()
def test_delitem():
a = b'abc'
b = memoryview(a)
assert_raises(TypeError, lambda : b.__delitem__())
assert_raises(TypeError, lambda : b.__delitem__(0))
assert_raises(TypeError, lambda : b.__delitem__(10))
a = bytearray(b'abc')
b = memoryview(a)
assert_raises(TypeError, lambda : b.__delitem__())
assert_raises(TypeError, lambda : b.__delitem__(1))
assert_raises(TypeError, lambda : b.__delitem__(12))
test_delitem()
def test_delitem():
a = b"abc"
b = memoryview(a)
assert_raises(TypeError, lambda: b.__delitem__())
assert_raises(TypeError, lambda: b.__delitem__(0))
assert_raises(TypeError, lambda: b.__delitem__(10))
a = bytearray(b"abc")
b = memoryview(a)
assert_raises(TypeError, lambda: b.__delitem__())
assert_raises(TypeError, lambda: b.__delitem__(1))
assert_raises(TypeError, lambda: b.__delitem__(12))
test_delitem()

View File

@@ -3,17 +3,22 @@ from testutils import assert_raises
# simple values
assert min(0, 0) == 0
assert min(1, 0) == 0
assert min(1., 0.) == 0.
assert min(1.0, 0.0) == 0.0
assert min(-1, 0) == -1
assert min(1, 2, 3) == 1
# iterables
assert min([1, 2, 3]) == 1
assert min((1, 2, 3)) == 1
assert min({
"a": 0,
"b": 1,
}) == "a"
assert (
min(
{
"a": 0,
"b": 1,
}
)
== "a"
)
assert min([1, 2], default=0) == 1
assert min([], default=0) == 0
@@ -31,7 +36,7 @@ assert_raises(TypeError, min, 1)
# custom class
class MyComparable():
class MyComparable:
nb = 0
def __init__(self):
@@ -48,7 +53,7 @@ assert min(first, second) == first
assert min([first, second]) == first
class MyNotComparable():
class MyNotComparable:
pass

View File

@@ -4,19 +4,22 @@ y = None
x = None
assert x is y
def none():
pass
def none2():
return None
assert none() is none()
assert none() is x
assert none() is none2()
assert str(None) == 'None'
assert repr(None) == 'None'
assert str(None) == "None"
assert repr(None) == "None"
assert type(None)() is None
assert None.__eq__(3) is NotImplemented

View File

@@ -1,6 +1,7 @@
class MyObject:
pass
assert not MyObject() == MyObject()
assert MyObject() != MyObject()
myobj = MyObject()
@@ -21,8 +22,8 @@ obj = MyObject()
assert obj.__eq__(obj) is True
assert obj.__ne__(obj) is False
assert not hasattr(obj, 'a')
obj.__dict__ = {'a': 1}
assert not hasattr(obj, "a")
obj.__dict__ = {"a": 1}
assert obj.a == 1
# Value inside the formatter goes through a different path of resolution.

View File

@@ -1,19 +1,19 @@
from testutils import assert_raises
fd = open('README.md')
assert 'RustPython' in fd.read()
fd = open("README.md")
assert "RustPython" in fd.read()
assert_raises(FileNotFoundError, open, 'DoesNotExist')
assert_raises(FileNotFoundError, open, "DoesNotExist")
# Use open as a context manager
with open('README.md', 'rt') as fp:
with open("README.md", "rt") as fp:
contents = fp.read()
assert type(contents) == str, "type is " + str(type(contents))
with open('README.md', 'r') as fp:
with open("README.md", "r") as fp:
contents = fp.read()
assert type(contents) == str, "type is " + str(type(contents))
with open('README.md', 'rb') as fp:
with open("README.md", "rb") as fp:
contents = fp.read()
assert type(contents) == bytes, "type is " + str(type(contents))

View File

@@ -3,11 +3,18 @@ from testutils import assert_raises
assert ord("a") == 97
assert ord("é") == 233
assert ord("🤡") == 129313
assert ord(b'a') == 97
assert ord(bytearray(b'a')) == 97
assert ord(b"a") == 97
assert ord(bytearray(b"a")) == 97
assert_raises(TypeError, ord, _msg='ord() is called with no argument')
assert_raises(TypeError, ord, "", _msg='ord() is called with an empty string')
assert_raises(TypeError, ord, "ab", _msg='ord() is called with more than one character')
assert_raises(TypeError, ord, b"ab", _msg='ord() expected a character, but string of length 2 found')
assert_raises(TypeError, ord, 1, _msg='ord() expected a string, bytes or bytearray, but found int')
assert_raises(TypeError, ord, _msg="ord() is called with no argument")
assert_raises(TypeError, ord, "", _msg="ord() is called with an empty string")
assert_raises(TypeError, ord, "ab", _msg="ord() is called with more than one character")
assert_raises(
TypeError,
ord,
b"ab",
_msg="ord() expected a character, but string of length 2 found",
)
assert_raises(
TypeError, ord, 1, _msg="ord() expected a string, bytes or bytearray, but found int"
)

View File

@@ -12,7 +12,7 @@ assert pow(1, 2.0) == 1.0
assert pow(2.0, 1) == 2.0
assert pow(0, 10**1000) == 0
assert pow(1, 10**1000) == 1
assert pow(-1, 10**1000+1) == -1
assert pow(-1, 10**1000 + 1) == -1
assert pow(-1, 10**1000) == 1
assert pow(2, 4, 5) == 1
@@ -59,7 +59,7 @@ def powtest(type):
assert_raises(ZeroDivisionError, pow, zero, exp)
il, ih = -20, 20
jl, jh = -5, 5
jl, jh = -5, 5
kl, kh = -10, 10
asseq = assert_equal
if type == float:
@@ -76,10 +76,7 @@ def powtest(type):
if type == float or j < 0:
assert_raises(TypeError, pow, type(i), j, k)
continue
asseq(
pow(type(i), j, k),
pow(type(i), j) % type(k)
)
asseq(pow(type(i), j, k), pow(type(i), j) % type(k))
def test_powint():
@@ -92,40 +89,35 @@ def test_powfloat():
def test_other():
# Other tests-- not very systematic
assert_equal(pow(3,3) % 8, pow(3,3,8))
assert_equal(pow(3,3) % -8, pow(3,3,-8))
assert_equal(pow(3,2) % -2, pow(3,2,-2))
assert_equal(pow(-3,3) % 8, pow(-3,3,8))
assert_equal(pow(-3,3) % -8, pow(-3,3,-8))
assert_equal(pow(5,2) % -8, pow(5,2,-8))
assert_equal(pow(3, 3) % 8, pow(3, 3, 8))
assert_equal(pow(3, 3) % -8, pow(3, 3, -8))
assert_equal(pow(3, 2) % -2, pow(3, 2, -2))
assert_equal(pow(-3, 3) % 8, pow(-3, 3, 8))
assert_equal(pow(-3, 3) % -8, pow(-3, 3, -8))
assert_equal(pow(5, 2) % -8, pow(5, 2, -8))
assert_equal(pow(3,3) % 8, pow(3,3,8))
assert_equal(pow(3,3) % -8, pow(3,3,-8))
assert_equal(pow(3,2) % -2, pow(3,2,-2))
assert_equal(pow(-3,3) % 8, pow(-3,3,8))
assert_equal(pow(-3,3) % -8, pow(-3,3,-8))
assert_equal(pow(5,2) % -8, pow(5,2,-8))
assert_equal(pow(3, 3) % 8, pow(3, 3, 8))
assert_equal(pow(3, 3) % -8, pow(3, 3, -8))
assert_equal(pow(3, 2) % -2, pow(3, 2, -2))
assert_equal(pow(-3, 3) % 8, pow(-3, 3, 8))
assert_equal(pow(-3, 3) % -8, pow(-3, 3, -8))
assert_equal(pow(5, 2) % -8, pow(5, 2, -8))
for i in range(-10, 11):
for j in range(0, 6):
for k in range(-7, 11):
if j >= 0 and k != 0:
assert_equal(
pow(i,j) % k,
pow(i,j,k)
)
assert_equal(pow(i, j) % k, pow(i, j, k))
if j >= 0 and k != 0:
assert_equal(
pow(int(i),j) % k,
pow(int(i),j,k)
)
assert_equal(pow(int(i), j) % k, pow(int(i), j, k))
def test_bug643260():
class TestRpow:
def __rpow__(self, other):
return None
None ** TestRpow() # Won't fail when __rpow__ invoked. SF bug #643260.
None ** TestRpow() # Won't fail when __rpow__ invoked. SF bug #643260.
def test_bug705231():
@@ -141,15 +133,15 @@ def test_bug705231():
for b in range(-10, 11):
eq(pow(a, float(b)), b & 1 and -1.0 or 1.0)
for n in range(0, 100):
fiveto = float(5 ** n)
fiveto = float(5**n)
# For small n, fiveto will be odd. Eventually we run out of
# mantissa bits, though, and thereafer fiveto will be even.
expected = fiveto % 2.0 and -1.0 or 1.0
eq(pow(a, fiveto), expected)
eq(pow(a, -fiveto), expected)
eq(expected, 1.0) # else we didn't push fiveto to evenness
eq(expected, 1.0) # else we didn't push fiveto to evenness
tests = [f for name, f in locals().items() if name.startswith('test_')]
tests = [f for name, f in locals().items() if name.startswith("test_")]
for f in tests:
f()

View File

@@ -3,14 +3,14 @@ import io
print(2 + 3)
assert_raises(TypeError, print, 'test', end=4, _msg='wrong type passed to end')
assert_raises(TypeError, print, 'test', sep=['a'], _msg='wrong type passed to sep')
assert_raises(TypeError, print, "test", end=4, _msg="wrong type passed to end")
assert_raises(TypeError, print, "test", sep=["a"], _msg="wrong type passed to sep")
try:
print('test', end=None, sep=None, flush=None)
print("test", end=None, sep=None, flush=None)
except:
assert False, 'Expected None passed to end, sep, and flush to not raise errors'
assert False, "Expected None passed to end, sep, and flush to not raise errors"
buf = io.StringIO()
print('hello, world', file=buf)
assert buf.getvalue() == 'hello, world\n', buf.getvalue()
print("hello, world", file=buf)
assert buf.getvalue() == "hello, world\n", buf.getvalue()

View File

@@ -62,8 +62,8 @@ with assert_raises(TypeError):
assert p.__doc__ is None
# Test property instance __doc__ attribute:
p.__doc__ = '222'
assert p.__doc__ == '222'
p.__doc__ = "222"
assert p.__doc__ == "222"
p1 = property("a", "b", "c")
@@ -83,5 +83,5 @@ assert p1.deleter(None).fdel == "c"
assert p1.__get__(None, object) is p1
# assert p1.__doc__ is 'a'.__doc__
p2 = property('a', doc='pdoc')
p2 = property("a", doc="pdoc")
# assert p2.__doc__ == 'pdoc'

View File

@@ -1,11 +1,11 @@
from testutils import assert_raises
assert range(2**63+1)[2**63] == 9223372036854775808
assert range(2**63 + 1)[2**63] == 9223372036854775808
# len tests
assert len(range(10, 5)) == 0, 'Range with no elements should have length = 0'
assert len(range(10, 5, -2)) == 3, 'Expected length 3, for elements: 10, 8, 6'
assert len(range(5, 10, 2)) == 3, 'Expected length 3, for elements: 5, 7, 9'
assert len(range(10, 5)) == 0, "Range with no elements should have length = 0"
assert len(range(10, 5, -2)) == 3, "Expected length 3, for elements: 10, 8, 6"
assert len(range(5, 10, 2)) == 3, "Expected length 3, for elements: 5, 7, 9"
# index tests
assert range(10).index(6) == 6
@@ -13,18 +13,18 @@ assert range(4, 10).index(6) == 2
assert range(4, 10, 2).index(6) == 1
assert range(10, 4, -2).index(8) == 1
assert_raises(ValueError, lambda: range(10).index(-1), _msg='out of bounds')
assert_raises(ValueError, lambda: range(10).index(10), _msg='out of bounds')
assert_raises(ValueError, lambda: range(4, 10, 2).index(5), _msg='out of step')
assert_raises(ValueError, lambda: range(10).index('foo'), _msg='not an int')
assert_raises(ValueError, lambda: range(1, 10, 0), _msg='step is zero')
assert_raises(ValueError, lambda: range(10).index(-1), _msg="out of bounds")
assert_raises(ValueError, lambda: range(10).index(10), _msg="out of bounds")
assert_raises(ValueError, lambda: range(4, 10, 2).index(5), _msg="out of step")
assert_raises(ValueError, lambda: range(10).index("foo"), _msg="not an int")
assert_raises(ValueError, lambda: range(1, 10, 0), _msg="step is zero")
# get tests
assert range(10)[0] == 0
assert range(10)[9] == 9
assert range(10, 0, -1)[0] == 10
assert range(10, 0, -1)[9] == 1
assert_raises(IndexError, lambda: range(10)[10], _msg='out of bound')
assert_raises(IndexError, lambda: range(10)[10], _msg="out of bound")
# slice tests
assert range(10)[0:3] == range(3)
@@ -34,13 +34,17 @@ assert range(10)[-15:3] == range(0, 3)
assert range(10, 100, 3)[4:1000:5] == range(22, 100, 15)
assert range(10)[:] == range(10)
assert range(10, 0, -2)[0:5:2] == range(10, 0, -4)
assert range(10)[10:11] == range(10,10)
assert range(10)[10:11] == range(10, 10)
assert range(0, 10, -1)[::-1] == range(1, 1)
assert range(0, 10)[::-1] == range(9, -1, -1)
assert range(0, -10)[::-1] == range(-1, -1, -1)
assert range(0, -10)[::-1][::-1] == range(0, 0)
assert_raises(ValueError, lambda: range(0, 10)[::0], _msg='slice step cannot be zero')
assert_raises(TypeError, lambda: range(0, 10)['a':], _msg='slice indices must be integers or None or have an __index__ method')
assert_raises(ValueError, lambda: range(0, 10)[::0], _msg="slice step cannot be zero")
assert_raises(
TypeError,
lambda: range(0, 10)["a":],
_msg="slice indices must be integers or None or have an __index__ method",
)
# count tests
assert range(10).count(2) == 1
@@ -64,22 +68,22 @@ assert range(10).__eq__(range(0, 11, 1)) is False
assert range(10).__ne__(range(0, 11, 1)) is True
assert range(0, 10, 3).__eq__(range(0, 11, 3)) is True
assert range(0, 10, 3).__ne__(range(0, 11, 3)) is False
#__lt__
# __lt__
assert range(1, 2, 3).__lt__(range(1, 2, 3)) == NotImplemented
assert range(1, 2, 1).__lt__(range(1, 2)) == NotImplemented
assert range(2).__lt__(range(0, 2)) == NotImplemented
#__gt__
# __gt__
assert range(1, 2, 3).__gt__(range(1, 2, 3)) == NotImplemented
assert range(1, 2, 1).__gt__(range(1, 2)) == NotImplemented
assert range(2).__gt__(range(0, 2)) == NotImplemented
#__le__
# __le__
assert range(1, 2, 3).__le__(range(1, 2, 3)) == NotImplemented
assert range(1, 2, 1).__le__(range(1, 2)) == NotImplemented
assert range(2).__le__(range(0, 2)) == NotImplemented
#__ge__
# __ge__
assert range(1, 2, 3).__ge__(range(1, 2, 3)) == NotImplemented
assert range(1, 2, 1).__ge__(range(1, 2)) == NotImplemented
assert range(2).__ge__(range(0, 2)) == NotImplemented
@@ -101,12 +105,12 @@ assert 8 in range(10, 4, -2)
assert -1 not in range(10)
assert 9 not in range(10, 4, -2)
assert 4 not in range(10, 4, -2)
assert 'foo' not in range(10)
assert "foo" not in range(10)
# __reversed__
assert list(reversed(range(5))) == [4, 3, 2, 1, 0]
assert list(reversed(range(5, 0, -1))) == [1, 2, 3, 4, 5]
assert list(reversed(range(1,10,5))) == [6, 1]
assert list(reversed(range(1, 10, 5))) == [6, 1]
# __reduce__
assert range(10).__reduce__()[0] == range
@@ -120,7 +124,7 @@ assert range(i).stop is i
# negative index
assert range(10)[-1] == 9
assert_raises(IndexError, lambda: range(10)[-11], _msg='out of bound')
assert_raises(IndexError, lambda: range(10)[-11], _msg="out of bound")
assert range(10)[-2:4] == range(8, 4)
assert range(10)[-6:-2] == range(4, 8)
assert range(50, 0, -2)[-5] == 10

View File

@@ -1,4 +1,4 @@
assert list(reversed(range(5))) == [4, 3, 2, 1, 0]
l = [5,4,3,2,1]
assert list(reversed(l)) == [1,2,3,4,5]
l = [5, 4, 3, 2, 1]
assert list(reversed(l)) == [1, 2, 3, 4, 5]

View File

@@ -8,11 +8,11 @@ assert round(-0.5) == 0
assert round(-1.5) == -2
# ValueError: cannot convert float NaN to integer
assert_raises(ValueError, round, float('nan'))
assert_raises(ValueError, round, float("nan"))
# OverflowError: cannot convert float infinity to integer
assert_raises(OverflowError, round, float('inf'))
assert_raises(OverflowError, round, float("inf"))
# OverflowError: cannot convert float infinity to integer
assert_raises(OverflowError, round, -float('inf'))
assert_raises(OverflowError, round, -float("inf"))
assert round(0) == 0
assert isinstance(round(0), int)

View File

@@ -1,38 +1,54 @@
from testutils import assert_raises
assert set([1,2]) == set([1,2])
assert not set([1,2,3]) == set([1,2])
assert set([1, 2]) == set([1, 2])
assert not set([1, 2, 3]) == set([1, 2])
assert set([1,2,3]) >= set([1,2])
assert set([1,2]) >= set([1,2])
assert not set([1,3]) >= set([1,2])
assert set([1, 2, 3]) >= set([1, 2])
assert set([1, 2]) >= set([1, 2])
assert not set([1, 3]) >= set([1, 2])
assert set([1,2,3]).issuperset(set([1,2]))
assert set([1,2]).issuperset(set([1,2]))
assert not set([1,3]).issuperset(set([1,2]))
assert set([1, 2, 3]).issuperset(set([1, 2]))
assert set([1, 2]).issuperset(set([1, 2]))
assert not set([1, 3]).issuperset(set([1, 2]))
assert set([1,2,3]) > set([1,2])
assert not set([1,2]) > set([1,2])
assert not set([1,3]) > set([1,2])
assert set([1, 2, 3]) > set([1, 2])
assert not set([1, 2]) > set([1, 2])
assert not set([1, 3]) > set([1, 2])
assert set([1,2]) <= set([1,2,3])
assert set([1,2]) <= set([1,2])
assert not set([1,3]) <= set([1,2])
assert set([1, 2]) <= set([1, 2, 3])
assert set([1, 2]) <= set([1, 2])
assert not set([1, 3]) <= set([1, 2])
assert set([1,2]).issubset(set([1,2,3]))
assert set([1,2]).issubset(set([1,2]))
assert not set([1,3]).issubset(set([1,2]))
assert set([1, 2]).issubset(set([1, 2, 3]))
assert set([1, 2]).issubset(set([1, 2]))
assert not set([1, 3]).issubset(set([1, 2]))
assert set([1,2]) < set([1,2,3])
assert not set([1,2]) < set([1,2])
assert not set([1,3]) < set([1,2])
assert set([1, 2]) < set([1, 2, 3])
assert not set([1, 2]) < set([1, 2])
assert not set([1, 3]) < set([1, 2])
assert (set() == []) is False
assert set().__eq__([]) == NotImplemented
assert_raises(TypeError, lambda: set() < [], _msg="'<' not supported between instances of 'set' and 'list'")
assert_raises(TypeError, lambda: set() <= [], _msg="'<=' not supported between instances of 'set' and 'list'")
assert_raises(TypeError, lambda: set() > [], _msg="'>' not supported between instances of 'set' and 'list'")
assert_raises(TypeError, lambda: set() >= [], _msg="'>=' not supported between instances of 'set' and 'list'")
assert_raises(
TypeError,
lambda: set() < [],
_msg="'<' not supported between instances of 'set' and 'list'",
)
assert_raises(
TypeError,
lambda: set() <= [],
_msg="'<=' not supported between instances of 'set' and 'list'",
)
assert_raises(
TypeError,
lambda: set() > [],
_msg="'>' not supported between instances of 'set' and 'list'",
)
assert_raises(
TypeError,
lambda: set() >= [],
_msg="'>=' not supported between instances of 'set' and 'list'",
)
assert set().issuperset([])
assert set().issubset([])
assert not set().issuperset([1, 2, 3])
@@ -47,6 +63,7 @@ assert_raises(TypeError, lambda: set() >= 3, _msg="'int' object is not iterable"
assert_raises(TypeError, set().issuperset, 3, _msg="'int' object is not iterable")
assert_raises(TypeError, set().issubset, 3, _msg="'int' object is not iterable")
class Hashable(object):
def __init__(self, obj):
self.obj = obj
@@ -57,6 +74,7 @@ class Hashable(object):
def __hash__(self):
return id(self)
assert repr(set()) == "set()"
assert repr(set([1, 2, 3])) == "{1, 2, 3}"
@@ -64,9 +82,11 @@ recursive = set()
recursive.add(Hashable(recursive))
assert repr(recursive) == "{set(...)}"
class S(set):
pass
assert repr(S()) == "S()"
assert repr(S([1, 2, 3])) == "S({1, 2, 3})"
@@ -79,44 +99,44 @@ assert len(a) == 3
a.clear()
assert len(a) == 0
assert set([1,2,3]).union(set([4,5])) == set([1,2,3,4,5])
assert set([1,2,3]).union(set([1,2,3,4,5])) == set([1,2,3,4,5])
assert set([1,2,3]).union([1,2,3,4,5]) == set([1,2,3,4,5])
assert set([1, 2, 3]).union(set([4, 5])) == set([1, 2, 3, 4, 5])
assert set([1, 2, 3]).union(set([1, 2, 3, 4, 5])) == set([1, 2, 3, 4, 5])
assert set([1, 2, 3]).union([1, 2, 3, 4, 5]) == set([1, 2, 3, 4, 5])
assert set([1,2,3]) | set([4,5]) == set([1,2,3,4,5])
assert set([1,2,3]) | set([1,2,3,4,5]) == set([1,2,3,4,5])
assert_raises(TypeError, lambda: set([1,2,3]) | [1,2,3,4,5])
assert set([1, 2, 3]) | set([4, 5]) == set([1, 2, 3, 4, 5])
assert set([1, 2, 3]) | set([1, 2, 3, 4, 5]) == set([1, 2, 3, 4, 5])
assert_raises(TypeError, lambda: set([1, 2, 3]) | [1, 2, 3, 4, 5])
assert set([1,2,3]).intersection(set([1,2])) == set([1,2])
assert set([1,2,3]).intersection(set([5,6])) == set([])
assert set([1,2,3]).intersection([1,2]) == set([1,2])
assert set([1, 2, 3]).intersection(set([1, 2])) == set([1, 2])
assert set([1, 2, 3]).intersection(set([5, 6])) == set([])
assert set([1, 2, 3]).intersection([1, 2]) == set([1, 2])
assert set([1,2,3]) & set([4,5]) == set([])
assert set([1,2,3]) & set([1,2,3,4,5]) == set([1,2,3])
assert_raises(TypeError, lambda: set([1,2,3]) & [1,2,3,4,5])
assert set([1, 2, 3]) & set([4, 5]) == set([])
assert set([1, 2, 3]) & set([1, 2, 3, 4, 5]) == set([1, 2, 3])
assert_raises(TypeError, lambda: set([1, 2, 3]) & [1, 2, 3, 4, 5])
assert set([1,2,3]).difference(set([1,2])) == set([3])
assert set([1,2,3]).difference(set([5,6])) == set([1,2,3])
assert set([1,2,3]).difference([1,2]) == set([3])
assert set([1, 2, 3]).difference(set([1, 2])) == set([3])
assert set([1, 2, 3]).difference(set([5, 6])) == set([1, 2, 3])
assert set([1, 2, 3]).difference([1, 2]) == set([3])
assert set([1,2,3]) - set([4,5]) == set([1,2,3])
assert set([1,2,3]) - set([1,2,3,4,5]) == set([])
assert_raises(TypeError, lambda: set([1,2,3]) - [1,2,3,4,5])
assert set([1, 2, 3]) - set([4, 5]) == set([1, 2, 3])
assert set([1, 2, 3]) - set([1, 2, 3, 4, 5]) == set([])
assert_raises(TypeError, lambda: set([1, 2, 3]) - [1, 2, 3, 4, 5])
assert set([1,2]).__sub__(set([2,3])) == set([1])
assert set([1,2]).__rsub__(set([2,3])) == set([3])
assert set([1, 2]).__sub__(set([2, 3])) == set([1])
assert set([1, 2]).__rsub__(set([2, 3])) == set([3])
assert set([1,2,3]).symmetric_difference(set([1,2])) == set([3])
assert set([1,2,3]).symmetric_difference(set([5,6])) == set([1,2,3,5,6])
assert set([1,2,3]).symmetric_difference([1,2]) == set([3])
assert set([1, 2, 3]).symmetric_difference(set([1, 2])) == set([3])
assert set([1, 2, 3]).symmetric_difference(set([5, 6])) == set([1, 2, 3, 5, 6])
assert set([1, 2, 3]).symmetric_difference([1, 2]) == set([3])
assert set([1,2,3]) ^ set([4,5]) == set([1,2,3,4,5])
assert set([1,2,3]) ^ set([1,2,3,4,5]) == set([4,5])
assert_raises(TypeError, lambda: set([1,2,3]) ^ [1,2,3,4,5])
assert set([1, 2, 3]) ^ set([4, 5]) == set([1, 2, 3, 4, 5])
assert set([1, 2, 3]) ^ set([1, 2, 3, 4, 5]) == set([4, 5])
assert_raises(TypeError, lambda: set([1, 2, 3]) ^ [1, 2, 3, 4, 5])
assert set([1,2,3]).isdisjoint(set([5,6])) == True
assert set([1,2,3]).isdisjoint(set([2,5,6])) == False
assert set([1,2,3]).isdisjoint([5,6]) == True
assert set([1, 2, 3]).isdisjoint(set([5, 6])) == True
assert set([1, 2, 3]).isdisjoint(set([2, 5, 6])) == False
assert set([1, 2, 3]).isdisjoint([5, 6]) == True
assert_raises(TypeError, lambda: set() & [])
assert_raises(TypeError, lambda: set() | [])
@@ -132,7 +152,7 @@ assert a.discard(1) is None
assert not 1 in a
assert a.discard(42) is None
a = set([1,2,3])
a = set([1, 2, 3])
b = a.copy()
assert len(a) == 3
assert len(b) == 3
@@ -140,71 +160,71 @@ b.clear()
assert len(a) == 3
assert len(b) == 0
a = set([1,2])
a = set([1, 2])
b = a.pop()
assert b in [1,2]
assert b in [1, 2]
c = a.pop()
assert (c in [1,2] and c != b)
assert c in [1, 2] and c != b
assert_raises(KeyError, lambda: a.pop())
a = set([1,2,3])
a.update([3,4,5])
assert a == set([1,2,3,4,5])
a = set([1, 2, 3])
a.update([3, 4, 5])
assert a == set([1, 2, 3, 4, 5])
assert_raises(TypeError, lambda: a.update(1))
a = set([1,2,3])
a = set([1, 2, 3])
b = set()
for e in a:
assert e == 1 or e == 2 or e == 3
b.add(e)
assert e == 1 or e == 2 or e == 3
b.add(e)
assert a == b
a = set([1,2,3])
a |= set([3,4,5])
assert a == set([1,2,3,4,5])
a = set([1, 2, 3])
a |= set([3, 4, 5])
assert a == set([1, 2, 3, 4, 5])
with assert_raises(TypeError):
a |= 1
a |= 1
with assert_raises(TypeError):
a |= [1,2,3]
a |= [1, 2, 3]
a = set([1,2,3])
a.intersection_update([2,3,4,5])
assert a == set([2,3])
a = set([1, 2, 3])
a.intersection_update([2, 3, 4, 5])
assert a == set([2, 3])
assert_raises(TypeError, lambda: a.intersection_update(1))
a = set([1,2,3])
a &= set([2,3,4,5])
assert a == set([2,3])
a = set([1, 2, 3])
a &= set([2, 3, 4, 5])
assert a == set([2, 3])
with assert_raises(TypeError):
a &= 1
a &= 1
with assert_raises(TypeError):
a &= [1,2,3]
a &= [1, 2, 3]
a = set([1,2,3])
a.difference_update([3,4,5])
assert a == set([1,2])
a = set([1, 2, 3])
a.difference_update([3, 4, 5])
assert a == set([1, 2])
assert_raises(TypeError, lambda: a.difference_update(1))
a = set([1,2,3])
a -= set([3,4,5])
assert a == set([1,2])
a = set([1, 2, 3])
a -= set([3, 4, 5])
assert a == set([1, 2])
with assert_raises(TypeError):
a -= 1
a -= 1
with assert_raises(TypeError):
a -= [1,2,3]
a -= [1, 2, 3]
a = set([1,2,3])
a.symmetric_difference_update([3,4,5])
assert a == set([1,2,4,5])
a = set([1, 2, 3])
a.symmetric_difference_update([3, 4, 5])
assert a == set([1, 2, 4, 5])
assert_raises(TypeError, lambda: a.difference_update(1))
a = set([1,2,3])
a ^= set([3,4,5])
assert a == set([1,2,4,5])
a = set([1, 2, 3])
a ^= set([3, 4, 5])
assert a == set([1, 2, 4, 5])
with assert_raises(TypeError):
a ^= 1
a ^= 1
with assert_raises(TypeError):
a ^= [1,2,3]
a ^= [1, 2, 3]
a = set([1, 2, 3])
i = iter(a)
@@ -218,142 +238,154 @@ a.remove(4)
# frozen set
assert frozenset([1,2]) == frozenset([1,2])
assert not frozenset([1,2,3]) == frozenset([1,2])
assert frozenset([1, 2]) == frozenset([1, 2])
assert not frozenset([1, 2, 3]) == frozenset([1, 2])
assert frozenset([1,2,3]) >= frozenset([1,2])
assert frozenset([1,2]) >= frozenset([1,2])
assert not frozenset([1,3]) >= frozenset([1,2])
assert frozenset([1, 2, 3]) >= frozenset([1, 2])
assert frozenset([1, 2]) >= frozenset([1, 2])
assert not frozenset([1, 3]) >= frozenset([1, 2])
assert frozenset([1,2,3]).issuperset(frozenset([1,2]))
assert frozenset([1,2]).issuperset(frozenset([1,2]))
assert not frozenset([1,3]).issuperset(frozenset([1,2]))
assert frozenset([1, 2, 3]).issuperset(frozenset([1, 2]))
assert frozenset([1, 2]).issuperset(frozenset([1, 2]))
assert not frozenset([1, 3]).issuperset(frozenset([1, 2]))
assert frozenset([1,2,3]) > frozenset([1,2])
assert not frozenset([1,2]) > frozenset([1,2])
assert not frozenset([1,3]) > frozenset([1,2])
assert frozenset([1, 2, 3]) > frozenset([1, 2])
assert not frozenset([1, 2]) > frozenset([1, 2])
assert not frozenset([1, 3]) > frozenset([1, 2])
assert frozenset([1,2]) <= frozenset([1,2,3])
assert frozenset([1,2]) <= frozenset([1,2])
assert not frozenset([1,3]) <= frozenset([1,2])
assert frozenset([1, 2]) <= frozenset([1, 2, 3])
assert frozenset([1, 2]) <= frozenset([1, 2])
assert not frozenset([1, 3]) <= frozenset([1, 2])
assert frozenset([1,2]).issubset(frozenset([1,2,3]))
assert frozenset([1,2]).issubset(frozenset([1,2]))
assert not frozenset([1,3]).issubset(frozenset([1,2]))
assert frozenset([1, 2]).issubset(frozenset([1, 2, 3]))
assert frozenset([1, 2]).issubset(frozenset([1, 2]))
assert not frozenset([1, 3]).issubset(frozenset([1, 2]))
assert frozenset([1,2]) < frozenset([1,2,3])
assert not frozenset([1,2]) < frozenset([1,2])
assert not frozenset([1,3]) < frozenset([1,2])
assert frozenset([1, 2]) < frozenset([1, 2, 3])
assert not frozenset([1, 2]) < frozenset([1, 2])
assert not frozenset([1, 3]) < frozenset([1, 2])
a = frozenset([1, 2, 3])
assert len(a) == 3
b = a.copy()
assert b == a
assert frozenset([1,2,3]).union(frozenset([4,5])) == frozenset([1,2,3,4,5])
assert frozenset([1,2,3]).union(frozenset([1,2,3,4,5])) == frozenset([1,2,3,4,5])
assert frozenset([1,2,3]).union([1,2,3,4,5]) == frozenset([1,2,3,4,5])
assert frozenset([1, 2, 3]).union(frozenset([4, 5])) == frozenset([1, 2, 3, 4, 5])
assert frozenset([1, 2, 3]).union(frozenset([1, 2, 3, 4, 5])) == frozenset(
[1, 2, 3, 4, 5]
)
assert frozenset([1, 2, 3]).union([1, 2, 3, 4, 5]) == frozenset([1, 2, 3, 4, 5])
assert frozenset([1,2,3]) | frozenset([4,5]) == frozenset([1,2,3,4,5])
assert frozenset([1,2,3]) | frozenset([1,2,3,4,5]) == frozenset([1,2,3,4,5])
assert_raises(TypeError, lambda: frozenset([1,2,3]) | [1,2,3,4,5])
assert frozenset([1, 2, 3]) | frozenset([4, 5]) == frozenset([1, 2, 3, 4, 5])
assert frozenset([1, 2, 3]) | frozenset([1, 2, 3, 4, 5]) == frozenset([1, 2, 3, 4, 5])
assert_raises(TypeError, lambda: frozenset([1, 2, 3]) | [1, 2, 3, 4, 5])
assert frozenset([1,2,3]).intersection(frozenset([1,2])) == frozenset([1,2])
assert frozenset([1,2,3]).intersection(frozenset([5,6])) == frozenset([])
assert frozenset([1,2,3]).intersection([1,2]) == frozenset([1,2])
assert frozenset([1, 2, 3]).intersection(frozenset([1, 2])) == frozenset([1, 2])
assert frozenset([1, 2, 3]).intersection(frozenset([5, 6])) == frozenset([])
assert frozenset([1, 2, 3]).intersection([1, 2]) == frozenset([1, 2])
assert frozenset([1,2,3]) & frozenset([4,5]) == frozenset([])
assert frozenset([1,2,3]) & frozenset([1,2,3,4,5]) == frozenset([1,2,3])
assert_raises(TypeError, lambda: frozenset([1,2,3]) & [1,2,3,4,5])
assert frozenset([1, 2, 3]) & frozenset([4, 5]) == frozenset([])
assert frozenset([1, 2, 3]) & frozenset([1, 2, 3, 4, 5]) == frozenset([1, 2, 3])
assert_raises(TypeError, lambda: frozenset([1, 2, 3]) & [1, 2, 3, 4, 5])
assert frozenset([1,2,3]).difference(frozenset([1,2])) == frozenset([3])
assert frozenset([1,2,3]).difference(frozenset([5,6])) == frozenset([1,2,3])
assert frozenset([1,2,3]).difference([1,2]) == frozenset([3])
assert frozenset([1, 2, 3]).difference(frozenset([1, 2])) == frozenset([3])
assert frozenset([1, 2, 3]).difference(frozenset([5, 6])) == frozenset([1, 2, 3])
assert frozenset([1, 2, 3]).difference([1, 2]) == frozenset([3])
assert frozenset([1,2,3]) - frozenset([4,5]) == frozenset([1,2,3])
assert frozenset([1,2,3]) - frozenset([1,2,3,4,5]) == frozenset([])
assert_raises(TypeError, lambda: frozenset([1,2,3]) - [1,2,3,4,5])
assert frozenset([1, 2, 3]) - frozenset([4, 5]) == frozenset([1, 2, 3])
assert frozenset([1, 2, 3]) - frozenset([1, 2, 3, 4, 5]) == frozenset([])
assert_raises(TypeError, lambda: frozenset([1, 2, 3]) - [1, 2, 3, 4, 5])
assert frozenset([1,2]).__sub__(frozenset([2,3])) == frozenset([1])
assert frozenset([1,2]).__rsub__(frozenset([2,3])) == frozenset([3])
assert frozenset([1, 2]).__sub__(frozenset([2, 3])) == frozenset([1])
assert frozenset([1, 2]).__rsub__(frozenset([2, 3])) == frozenset([3])
assert frozenset([1,2,3]).symmetric_difference(frozenset([1,2])) == frozenset([3])
assert frozenset([1,2,3]).symmetric_difference(frozenset([5,6])) == frozenset([1,2,3,5,6])
assert frozenset([1,2,3]).symmetric_difference([1,2]) == frozenset([3])
assert frozenset([1, 2, 3]).symmetric_difference(frozenset([1, 2])) == frozenset([3])
assert frozenset([1, 2, 3]).symmetric_difference(frozenset([5, 6])) == frozenset(
[1, 2, 3, 5, 6]
)
assert frozenset([1, 2, 3]).symmetric_difference([1, 2]) == frozenset([3])
assert frozenset([1,2,3]) ^ frozenset([4,5]) == frozenset([1,2,3,4,5])
assert frozenset([1,2,3]) ^ frozenset([1,2,3,4,5]) == frozenset([4,5])
assert_raises(TypeError, lambda: frozenset([1,2,3]) ^ [1,2,3,4,5])
assert frozenset([1, 2, 3]) ^ frozenset([4, 5]) == frozenset([1, 2, 3, 4, 5])
assert frozenset([1, 2, 3]) ^ frozenset([1, 2, 3, 4, 5]) == frozenset([4, 5])
assert_raises(TypeError, lambda: frozenset([1, 2, 3]) ^ [1, 2, 3, 4, 5])
assert frozenset([1,2,3]).isdisjoint(frozenset([5,6])) == True
assert frozenset([1,2,3]).isdisjoint(frozenset([2,5,6])) == False
assert frozenset([1,2,3]).isdisjoint([5,6]) == True
assert frozenset([1, 2, 3]).isdisjoint(frozenset([5, 6])) == True
assert frozenset([1, 2, 3]).isdisjoint(frozenset([2, 5, 6])) == False
assert frozenset([1, 2, 3]).isdisjoint([5, 6]) == True
assert_raises(TypeError, frozenset, [[]])
a = frozenset([1,2,3])
a = frozenset([1, 2, 3])
b = set()
for e in a:
assert e == 1 or e == 2 or e == 3
b.add(e)
assert e == 1 or e == 2 or e == 3
b.add(e)
assert a == b
# set and frozen set
assert frozenset([1,2,3]).union(set([4,5])) == frozenset([1,2,3,4,5])
assert set([1,2,3]).union(frozenset([4,5])) == set([1,2,3,4,5])
assert frozenset([1, 2, 3]).union(set([4, 5])) == frozenset([1, 2, 3, 4, 5])
assert set([1, 2, 3]).union(frozenset([4, 5])) == set([1, 2, 3, 4, 5])
assert frozenset([1,2,3]) | set([4,5]) == frozenset([1,2,3,4,5])
assert set([1,2,3]) | frozenset([4,5]) == set([1,2,3,4,5])
assert frozenset([1, 2, 3]) | set([4, 5]) == frozenset([1, 2, 3, 4, 5])
assert set([1, 2, 3]) | frozenset([4, 5]) == set([1, 2, 3, 4, 5])
assert frozenset([1,2,3]).intersection(set([5,6])) == frozenset([])
assert set([1,2,3]).intersection(frozenset([5,6])) == set([])
assert frozenset([1, 2, 3]).intersection(set([5, 6])) == frozenset([])
assert set([1, 2, 3]).intersection(frozenset([5, 6])) == set([])
assert frozenset([1,2,3]) & set([1,2,3,4,5]) == frozenset([1,2,3])
assert set([1,2,3]) & frozenset([1,2,3,4,5]) == set([1,2,3])
assert frozenset([1, 2, 3]) & set([1, 2, 3, 4, 5]) == frozenset([1, 2, 3])
assert set([1, 2, 3]) & frozenset([1, 2, 3, 4, 5]) == set([1, 2, 3])
assert frozenset([1,2,3]).difference(set([5,6])) == frozenset([1,2,3])
assert set([1,2,3]).difference(frozenset([5,6])) == set([1,2,3])
assert frozenset([1, 2, 3]).difference(set([5, 6])) == frozenset([1, 2, 3])
assert set([1, 2, 3]).difference(frozenset([5, 6])) == set([1, 2, 3])
assert frozenset([1,2,3]) - set([4,5]) == frozenset([1,2,3])
assert set([1,2,3]) - frozenset([4,5]) == frozenset([1,2,3])
assert frozenset([1, 2, 3]) - set([4, 5]) == frozenset([1, 2, 3])
assert set([1, 2, 3]) - frozenset([4, 5]) == frozenset([1, 2, 3])
assert frozenset([1,2]).__sub__(set([2,3])) == frozenset([1])
assert frozenset([1,2]).__rsub__(set([2,3])) == set([3])
assert set([1,2]).__sub__(frozenset([2,3])) == set([1])
assert set([1,2]).__rsub__(frozenset([2,3])) == frozenset([3])
assert frozenset([1, 2]).__sub__(set([2, 3])) == frozenset([1])
assert frozenset([1, 2]).__rsub__(set([2, 3])) == set([3])
assert set([1, 2]).__sub__(frozenset([2, 3])) == set([1])
assert set([1, 2]).__rsub__(frozenset([2, 3])) == frozenset([3])
assert frozenset([1,2,3]).symmetric_difference(set([1,2])) == frozenset([3])
assert set([1,2,3]).symmetric_difference(frozenset([1,2])) == set([3])
assert frozenset([1, 2, 3]).symmetric_difference(set([1, 2])) == frozenset([3])
assert set([1, 2, 3]).symmetric_difference(frozenset([1, 2])) == set([3])
assert frozenset([1, 2, 3]) ^ set([4, 5]) == frozenset([1, 2, 3, 4, 5])
assert set([1, 2, 3]) ^ frozenset([4, 5]) == set([1, 2, 3, 4, 5])
assert frozenset([1,2,3]) ^ set([4,5]) == frozenset([1,2,3,4,5])
assert set([1,2,3]) ^ frozenset([4,5]) == set([1,2,3,4,5])
class A:
def __hash__(self):
return 1
class B:
def __hash__(self):
return 1
s = {1, A(), B()}
assert len(s) == 3
s = {True}
s.add(1.0)
assert str(s) == '{True}'
assert str(s) == "{True}"
class EqObject:
def __init__(self, eq):
self.eq = eq
def __eq__(self, other):
return self.eq
def __hash__(self):
return bool(self.eq)
assert 'x' == (EqObject('x') == EqObject('x'))
s = {EqObject('x')}
assert EqObject('x') in s
assert '[]' == (EqObject('[]') == EqObject('[]'))
assert "x" == (EqObject("x") == EqObject("x"))
s = {EqObject("x")}
assert EqObject("x") in s
assert "[]" == (EqObject("[]") == EqObject("[]"))
s = {EqObject([])}
assert EqObject([]) not in s
x = object()
@@ -372,8 +404,8 @@ assert not frozenset([1, 2]).__ne__(frozenset([2, 1]))
assert frozenset().__ne__(1) == NotImplemented
empty_set = set()
non_empty_set = set([1,2,3])
set_from_literal = {1,2,3}
non_empty_set = set([1, 2, 3])
set_from_literal = {1, 2, 3}
assert 1 in non_empty_set
assert 4 not in non_empty_set
@@ -382,8 +414,8 @@ assert 1 in set_from_literal
assert 4 not in set_from_literal
# TODO: Assert that empty aruguments raises exception.
non_empty_set.add('a')
assert 'a' in non_empty_set
non_empty_set.add("a")
assert "a" in non_empty_set
# TODO: Assert that empty arguments, or item not in set raises exception.
non_empty_set.remove(1)
@@ -394,8 +426,10 @@ assert 1 not in non_empty_set
assert repr(frozenset()) == "frozenset()"
assert repr(frozenset([1, 2, 3])) == "frozenset({1, 2, 3})"
class FS(frozenset):
pass
assert repr(FS()) == "FS()"
assert repr(FS([1, 2, 3])) == "FS({1, 2, 3})"

View File

@@ -10,16 +10,16 @@ assert a.start == 0
assert a.stop == 10
assert a.step == 1
assert slice(10).__repr__() == 'slice(None, 10, None)'
assert slice(None).__repr__() == 'slice(None, None, None)'
assert slice(0, 10, 13).__repr__() == 'slice(0, 10, 13)'
assert slice('0', 1.1, 2+3j).__repr__() == "slice('0', 1.1, (2+3j))"
assert slice(10).__repr__() == "slice(None, 10, None)"
assert slice(None).__repr__() == "slice(None, None, None)"
assert slice(0, 10, 13).__repr__() == "slice(0, 10, 13)"
assert slice("0", 1.1, 2 + 3j).__repr__() == "slice('0', 1.1, (2+3j))"
assert slice(10) == slice(10)
assert slice(-1) != slice(1)
assert slice(0, 10, 3) != slice(0, 11, 3)
assert slice(0, None, 3) != slice(0, 'a', 3)
assert slice(0, 'a', 3) == slice(0, 'a', 3)
assert slice(0, None, 3) != slice(0, "a", 3)
assert slice(0, "a", 3) == slice(0, "a", 3)
assert slice(0, 0, 0).__eq__(slice(0, 0, 0))
assert not slice(0, 0, 1).__eq__(slice(0, 0, 0))
@@ -65,29 +65,29 @@ assert slice(0, 0, 0) <= slice(0, 0, 0)
assert not slice(0, 0, 0) > slice(0, 0, 0)
assert not slice(0, 0, 0) < slice(0, 0, 0)
assert not slice(0, float('nan'), float('nan')) <= slice(0, float('nan'), 1)
assert not slice(0, float('nan'), float('nan')) <= slice(0, float('nan'), float('nan'))
assert not slice(0, float('nan'), float('nan')) >= slice(0, float('nan'), float('nan'))
assert not slice(0, float('nan'), float('nan')) < slice(0, float('nan'), float('nan'))
assert not slice(0, float('nan'), float('nan')) > slice(0, float('nan'), float('nan'))
assert not slice(0, float("nan"), float("nan")) <= slice(0, float("nan"), 1)
assert not slice(0, float("nan"), float("nan")) <= slice(0, float("nan"), float("nan"))
assert not slice(0, float("nan"), float("nan")) >= slice(0, float("nan"), float("nan"))
assert not slice(0, float("nan"), float("nan")) < slice(0, float("nan"), float("nan"))
assert not slice(0, float("nan"), float("nan")) > slice(0, float("nan"), float("nan"))
assert slice(0, float('inf'), float('inf')) >= slice(0, float('inf'), 1)
assert slice(0, float('inf'), float('inf')) <= slice(0, float('inf'), float('inf'))
assert slice(0, float('inf'), float('inf')) >= slice(0, float('inf'), float('inf'))
assert not slice(0, float('inf'), float('inf')) < slice(0, float('inf'), float('inf'))
assert not slice(0, float('inf'), float('inf')) > slice(0, float('inf'), float('inf'))
assert slice(0, float("inf"), float("inf")) >= slice(0, float("inf"), 1)
assert slice(0, float("inf"), float("inf")) <= slice(0, float("inf"), float("inf"))
assert slice(0, float("inf"), float("inf")) >= slice(0, float("inf"), float("inf"))
assert not slice(0, float("inf"), float("inf")) < slice(0, float("inf"), float("inf"))
assert not slice(0, float("inf"), float("inf")) > slice(0, float("inf"), float("inf"))
assert_raises(TypeError, lambda: slice(0) < 3)
assert_raises(TypeError, lambda: slice(0) > 3)
assert_raises(TypeError, lambda: slice(0) <= 3)
assert_raises(TypeError, lambda: slice(0) >= 3)
assert slice(None ).indices(10) == (0, 10, 1)
assert slice(None, None, 2).indices(10) == (0, 10, 2)
assert slice(1, None, 2).indices(10) == (1, 10, 2)
assert slice(None, None, -1).indices(10) == (9, -1, -1)
assert slice(None, None, -2).indices(10) == (9, -1, -2)
assert slice(3, None, -2).indices(10) == (3, -1, -2)
assert slice(None).indices(10) == (0, 10, 1)
assert slice(None, None, 2).indices(10) == (0, 10, 2)
assert slice(1, None, 2).indices(10) == (1, 10, 2)
assert slice(None, None, -1).indices(10) == (9, -1, -1)
assert slice(None, None, -2).indices(10) == (9, -1, -2)
assert slice(3, None, -2).indices(10) == (3, -1, -2)
# issue 3004 tests
assert slice(None, -9).indices(10) == (0, 1, 1)
@@ -103,21 +103,17 @@ assert slice(None, 8, -1).indices(10) == (9, 8, -1)
assert slice(None, 9, -1).indices(10) == (9, 9, -1)
assert slice(None, 10, -1).indices(10) == (9, 9, -1)
assert \
slice(-100, 100).indices(10) == \
slice(None ).indices(10)
assert slice(-100, 100).indices(10) == slice(None).indices(10)
assert \
slice(100, -100, -1).indices(10) == \
slice(None, None, -1).indices(10)
assert slice(100, -100, -1).indices(10) == slice(None, None, -1).indices(10)
assert slice(-100, 100, 2).indices(10) == (0, 10, 2)
assert slice(-100, 100, 2).indices(10) == (0, 10, 2)
try:
slice(None, None, 0)
assert "zero step" == "throws an exception"
slice(None, None, 0)
assert "zero step" == "throws an exception"
except:
pass
pass
a = []
b = [1, 2]
@@ -167,8 +163,8 @@ class CustomIndex:
return self.x
assert c[CustomIndex(1):CustomIndex(3)] == [1, 2]
assert d[CustomIndex(1):CustomIndex(3)] == "23"
assert c[CustomIndex(1) : CustomIndex(3)] == [1, 2]
assert d[CustomIndex(1) : CustomIndex(3)] == "23"
def test_all_slices():
@@ -176,7 +172,7 @@ def test_all_slices():
test all possible slices except big number
"""
mod = __import__('cpython_generated_slices')
mod = __import__("cpython_generated_slices")
ll = mod.LL
start = mod.START

File diff suppressed because it is too large Load Diff

View File

@@ -10,11 +10,13 @@ else:
assert_raises(UnicodeEncodeError, "¿como estás?".encode, "ascii")
def round_trip(s, encoding="utf-8"):
encoded = s.encode(encoding)
decoded = encoded.decode(encoding)
assert s == decoded
round_trip("👺♦ 𝐚Şđƒ ☆☝")
round_trip("☢🐣 ᖇ𝓤𝕊тⓟ𝕐𝕥卄σ𝔫 ♬👣")
round_trip("💀👌 ק𝔂t𝓷 🔥👤")

View File

@@ -3,6 +3,7 @@ from testutils import assert_raises
x = "An interesting piece of text"
assert x is str(x)
class Stringy(str):
def __new__(cls, value=""):
return str.__new__(cls, value)
@@ -10,6 +11,7 @@ class Stringy(str):
def __init__(self, value):
self.x = "substr"
y = Stringy(1)
assert type(y) is Stringy, "Type of Stringy should be stringy"
assert type(str(y)) is str, "Str of a str-subtype should be a str."

View File

@@ -1,29 +1,29 @@
# Test the unicode support! 👋
=2
= 2
assert *8 == 16
assert * 8 == 16
="👋"
= "👋"
c = *3
c = * 3
assert c == '👋👋👋'
assert c == "👋👋👋"
import unicodedata
assert unicodedata.category('a') == 'Ll'
assert unicodedata.category('A') == 'Lu'
assert unicodedata.name('a') == 'LATIN SMALL LETTER A'
assert unicodedata.lookup('LATIN SMALL LETTER A') == 'a'
assert unicodedata.bidirectional('a') == 'L'
assert unicodedata.east_asian_width('\u231a') == 'W'
assert unicodedata.normalize('NFC', 'bla') == 'bla'
assert unicodedata.category("a") == "Ll"
assert unicodedata.category("A") == "Lu"
assert unicodedata.name("a") == "LATIN SMALL LETTER A"
assert unicodedata.lookup("LATIN SMALL LETTER A") == "a"
assert unicodedata.bidirectional("a") == "L"
assert unicodedata.east_asian_width("\u231a") == "W"
assert unicodedata.normalize("NFC", "bla") == "bla"
# testing unicodedata.ucd_3_2_0 for idna
assert "abcСĤ".encode("idna") == b'xn--abc-7sa390b'
assert "abc䄣IJ".encode("idna") == b'xn--abcij-zb5f'
assert "abcСĤ".encode("idna") == b"xn--abc-7sa390b"
assert "abc䄣IJ".encode("idna") == b"xn--abcij-zb5f"
# from CPython tests
assert "python.org".encode("idna") == b"python.org"

View File

@@ -1,13 +1,14 @@
def test_slice_bounds(s):
# End out of range
assert s[0:100] == s
assert s[0:-100] == ''
assert s[0:-100] == ""
# Start out of range
assert s[100:1] == ''
assert s[100:1] == ""
# Out of range both sides
# This is the behaviour in cpython
# assert s[-100:100] == s
def expect_index_error(s, index):
try:
s[index]
@@ -16,6 +17,7 @@ def expect_index_error(s, index):
else:
assert False
unicode_str = "∀∂"
assert unicode_str[0] == ""
assert unicode_str[1] == ""
@@ -35,25 +37,25 @@ assert ascii_str[-1] == "d"
hebrew_text = "בְּרֵאשִׁית, בָּרָא אֱלֹהִים, אֵת הַשָּׁמַיִם, וְאֵת הָאָרֶץ"
assert len(hebrew_text) == 60
assert len(hebrew_text[:]) == 60
assert hebrew_text[0] == 'ב'
assert hebrew_text[1] == 'ְ'
assert hebrew_text[2] == 'ּ'
assert hebrew_text[3] == 'ר'
assert hebrew_text[4] == 'ֵ'
assert hebrew_text[5] == 'א'
assert hebrew_text[6] == 'ש'
assert hebrew_text[5:10] == 'אשִׁי'
assert hebrew_text[0] == "ב"
assert hebrew_text[1] == "ְ"
assert hebrew_text[2] == "ּ"
assert hebrew_text[3] == "ר"
assert hebrew_text[4] == "ֵ"
assert hebrew_text[5] == "א"
assert hebrew_text[6] == "ש"
assert hebrew_text[5:10] == "אשִׁי"
assert len(hebrew_text[5:10]) == 5
assert hebrew_text[-20:50] == 'מַיִם, וְא'
assert hebrew_text[-20:50] == "מַיִם, וְא"
assert len(hebrew_text[-20:50]) == 10
assert hebrew_text[:-30:1] == 'בְּרֵאשִׁית, בָּרָא אֱלֹהִים, '
assert hebrew_text[:-30:1] == "בְּרֵאשִׁית, בָּרָא אֱלֹהִים, "
assert len(hebrew_text[:-30:1]) == 30
assert hebrew_text[10:-30] == 'ת, בָּרָא אֱלֹהִים, '
assert hebrew_text[10:-30] == "ת, בָּרָא אֱלֹהִים, "
assert len(hebrew_text[10:-30]) == 20
assert hebrew_text[10:30:3] == 'תבר לִ,'
assert hebrew_text[10:30:3] == "תבר לִ,"
assert len(hebrew_text[10:30:3]) == 7
assert hebrew_text[10:30:-3] == ''
assert hebrew_text[30:10:-3] == 'אםהֱאּ '
assert hebrew_text[10:30:-3] == ""
assert hebrew_text[30:10:-3] == "אםהֱאּ "
assert len(hebrew_text[30:10:-3]) == 7
assert hebrew_text[30:10:-1] == 'א ,םיִהֹלֱא אָרָּב ,'
assert hebrew_text[30:10:-1] == "א ,םיִהֹלֱא אָרָּב ,"
assert len(hebrew_text[30:10:-1]) == 20

View File

@@ -1,8 +1,8 @@
from testutils import assert_raises
assert (1,2) == (1,2)
assert (1, 2) == (1, 2)
x = (1,2)
x = (1, 2)
assert x[0] == 1
y = (1,)
@@ -19,7 +19,7 @@ assert y < x, "tuple __lt__ failed"
assert x > y, "tuple __gt__ failed"
b = (1,2,3)
b = (1, 2, 3)
assert b.index(2) == 1
recursive_list = []
@@ -30,15 +30,17 @@ assert repr(recursive) == "([(...)],)"
assert (None, "", 1).index(1) == 2
assert 1 in (None, "", 1)
class Foo(object):
def __eq__(self, x):
return False
foo = Foo()
assert (foo,) == (foo,)
a = (1, 2, 3)
a += 1,
a += (1,)
assert a == (1, 2, 3, 1)
b = (55, *a)
@@ -80,14 +82,14 @@ assert (0, 0) <= (0, 0)
assert not (0, 0) > (0, 0)
assert not (0, 0) < (0, 0)
assert not (float('nan'), float('nan')) <= (float('nan'), 1)
assert not (float('nan'), float('nan')) <= (float('nan'), float('nan'))
assert not (float('nan'), float('nan')) >= (float('nan'), float('nan'))
assert not (float('nan'), float('nan')) < (float('nan'), float('nan'))
assert not (float('nan'), float('nan')) > (float('nan'), float('nan'))
assert not (float("nan"), float("nan")) <= (float("nan"), 1)
assert not (float("nan"), float("nan")) <= (float("nan"), float("nan"))
assert not (float("nan"), float("nan")) >= (float("nan"), float("nan"))
assert not (float("nan"), float("nan")) < (float("nan"), float("nan"))
assert not (float("nan"), float("nan")) > (float("nan"), float("nan"))
assert (float('inf'), float('inf')) >= (float('inf'), 1)
assert (float('inf'), float('inf')) <= (float('inf'), float('inf'))
assert (float('inf'), float('inf')) >= (float('inf'), float('inf'))
assert not (float('inf'), float('inf')) < (float('inf'), float('inf'))
assert not (float('inf'), float('inf')) > (float('inf'), float('inf'))
assert (float("inf"), float("inf")) >= (float("inf"), 1)
assert (float("inf"), float("inf")) <= (float("inf"), float("inf"))
assert (float("inf"), float("inf")) >= (float("inf"), float("inf"))
assert not (float("inf"), float("inf")) < (float("inf"), float("inf"))
assert not (float("inf"), float("inf")) > (float("inf"), float("inf"))

View File

@@ -13,9 +13,9 @@ print(1.1)
print("abc")
# print(u"abc")
# Structural below
print((1, 2)) # Tuple can be any length, but fixed after declared
x = (1,2)
print(x[0]) # Tuple can be any length, but fixed after declared
print((1, 2)) # Tuple can be any length, but fixed after declared
x = (1, 2)
print(x[0]) # Tuple can be any length, but fixed after declared
print([1, 2, 3])
# print({"first":1,"second":2})
@@ -52,25 +52,25 @@ assert int() == 0
a = complex(2, 4)
assert type(a) is complex
assert type(a + a) is complex
assert repr(a) == '(2+4j)'
assert repr(a) == "(2+4j)"
a = 10j
assert repr(a) == '10j'
assert repr(a) == "10j"
a = 1
assert a.conjugate() == a
a = 12345
b = a*a*a*a*a*a*a*a
b = a * a * a * a * a * a * a * a
assert b.bit_length() == 109
assert type.__module__ == 'builtins'
assert type.__qualname__ == 'type'
assert type.__name__ == 'type'
assert type.__module__ == "builtins"
assert type.__qualname__ == "type"
assert type.__name__ == "type"
assert isinstance(type.__doc__, str)
assert object.__qualname__ == 'object'
assert int.__qualname__ == 'int'
assert object.__qualname__ == "object"
assert int.__qualname__ == "int"
class A(type):
@@ -78,8 +78,8 @@ class A(type):
class B(type):
__module__ = 'b'
__qualname__ = 'BB'
__module__ = "b"
__qualname__ = "BB"
class C:
@@ -87,23 +87,23 @@ class C:
class D:
__module__ = 'd'
__qualname__ = 'DD'
__module__ = "d"
__qualname__ = "DD"
assert A.__module__ == '__main__'
assert A.__qualname__ == 'A'
assert B.__module__ == 'b'
assert B.__qualname__ == 'BB'
assert C.__module__ == '__main__'
assert C.__qualname__ == 'C'
assert D.__module__ == 'd'
assert D.__qualname__ == 'DD'
assert A.__module__ == "__main__"
assert A.__qualname__ == "A"
assert B.__module__ == "b"
assert B.__qualname__ == "BB"
assert C.__module__ == "__main__"
assert C.__qualname__ == "C"
assert D.__module__ == "d"
assert D.__qualname__ == "DD"
A.__qualname__ = 'AA'
B.__qualname__ = 'b'
assert A.__qualname__ == 'AA'
assert B.__qualname__ == 'b'
A.__qualname__ = "AA"
B.__qualname__ = "b"
assert A.__qualname__ == "AA"
assert B.__qualname__ == "b"
with assert_raises(TypeError):
del D.__qualname__
with assert_raises(TypeError):
@@ -114,7 +114,8 @@ with assert_raises(TypeError):
from testutils import assert_raises
import platform
if platform.python_implementation() == 'RustPython':
if platform.python_implementation() == "RustPython":
gc = None
else:
import gc
@@ -123,13 +124,13 @@ assert type(type) is type
assert type(object) is type
assert type(object()) is object
new_type = type('New', (object,), {})
new_type = type("New", (object,), {})
assert type(new_type) is type
assert type(new_type()) is new_type
metaclass = type('MCl', (type,), {})
cls = metaclass('Cls', (object,), {})
metaclass = type("MCl", (type,), {})
cls = metaclass("Cls", (object,), {})
inst = cls()
assert type(inst) is cls
@@ -154,10 +155,22 @@ assert isinstance(type, (int, object))
assert not issubclass(type, (int, float))
assert issubclass(type, (int, type))
class A: pass
class B(A): pass
class C(A): pass
class D(B, C): pass
class A:
pass
class B(A):
pass
class C(A):
pass
class D(B, C):
pass
assert A.__subclasses__() == [B, C]
assert B.__subclasses__() == [D]
@@ -174,7 +187,7 @@ del D
if gc:
# gc sweep is needed here for CPython...
gc.collect()
# ...while RustPython doesn't have `gc` yet.
# ...while RustPython doesn't have `gc` yet.
if gc:
# D.__new__ is a method bound to the D type, so just deleting D
@@ -185,43 +198,53 @@ if gc:
assert type in object.__subclasses__()
assert cls.__name__ == 'Cls'
assert cls.__name__ == "Cls"
# mro
assert int.mro() == [int, object]
assert bool.mro() == [bool, int, object]
assert object.mro() == [object]
class A:
pass
class B(A):
pass
assert A.mro() == [A, object]
assert B.mro() == [B, A, object]
class AA:
pass
class BB(AA):
pass
class C(B, BB):
pass
assert C.mro() == [C, B, A, BB, AA, object]
assert type(Exception.args).__name__ == 'getset_descriptor'
assert type(Exception.args).__name__ == "getset_descriptor"
assert type(None).__bool__(None) is False
class A:
pass
class B:
pass
a = A()
a.__class__ = B
assert isinstance(a, B)
@@ -234,30 +257,33 @@ with assert_raises(TypeError):
# Regression to
# https://github.com/RustPython/RustPython/issues/2310
import builtins
assert builtins.iter.__class__.__module__ == 'builtins'
assert builtins.iter.__class__.__qualname__ == 'builtin_function_or_method'
assert iter.__class__.__module__ == 'builtins'
assert iter.__class__.__qualname__ == 'builtin_function_or_method'
assert type(iter).__module__ == 'builtins'
assert type(iter).__qualname__ == 'builtin_function_or_method'
assert builtins.iter.__class__.__module__ == "builtins"
assert builtins.iter.__class__.__qualname__ == "builtin_function_or_method"
assert iter.__class__.__module__ == "builtins"
assert iter.__class__.__qualname__ == "builtin_function_or_method"
assert type(iter).__module__ == "builtins"
assert type(iter).__qualname__ == "builtin_function_or_method"
# Regression to
# https://github.com/RustPython/RustPython/issues/2767
# Marked as `#[pymethod]`:
assert str.replace.__qualname__ == 'str.replace'
assert str().replace.__qualname__ == 'str.replace'
assert int.to_bytes.__qualname__ == 'int.to_bytes'
assert int().to_bytes.__qualname__ == 'int.to_bytes'
assert str.replace.__qualname__ == "str.replace"
assert str().replace.__qualname__ == "str.replace"
assert int.to_bytes.__qualname__ == "int.to_bytes"
assert int().to_bytes.__qualname__ == "int.to_bytes"
# Marked as `#[pyclassmethod]`:
assert dict.fromkeys.__qualname__ == 'dict.fromkeys'
assert object.__init_subclass__.__qualname__ == 'object.__init_subclass__'
assert dict.fromkeys.__qualname__ == "dict.fromkeys"
assert object.__init_subclass__.__qualname__ == "object.__init_subclass__"
# Dynamic with `#[extend_class]`:
assert bytearray.maketrans.__qualname__ == 'bytearray.maketrans', bytearray.maketrans.__qualname__
assert bytearray.maketrans.__qualname__ == "bytearray.maketrans", (
bytearray.maketrans.__qualname__
)
# Third-party:
@@ -285,47 +311,48 @@ class MyTypeWithMethod:
def s():
pass
assert MyTypeWithMethod.method.__name__ == 'method'
assert MyTypeWithMethod().method.__name__ == 'method'
assert MyTypeWithMethod.clsmethod.__name__ == 'clsmethod'
assert MyTypeWithMethod().clsmethod.__name__ == 'clsmethod'
assert MyTypeWithMethod.stmethod.__name__ == 'stmethod'
assert MyTypeWithMethod().stmethod.__name__ == 'stmethod'
assert MyTypeWithMethod.method.__qualname__ == 'MyTypeWithMethod.method'
assert MyTypeWithMethod().method.__qualname__ == 'MyTypeWithMethod.method'
assert MyTypeWithMethod.clsmethod.__qualname__ == 'MyTypeWithMethod.clsmethod'
assert MyTypeWithMethod().clsmethod.__qualname__ == 'MyTypeWithMethod.clsmethod'
assert MyTypeWithMethod.stmethod.__qualname__ == 'MyTypeWithMethod.stmethod'
assert MyTypeWithMethod().stmethod.__qualname__ == 'MyTypeWithMethod.stmethod'
assert MyTypeWithMethod.method.__name__ == "method"
assert MyTypeWithMethod().method.__name__ == "method"
assert MyTypeWithMethod.clsmethod.__name__ == "clsmethod"
assert MyTypeWithMethod().clsmethod.__name__ == "clsmethod"
assert MyTypeWithMethod.stmethod.__name__ == "stmethod"
assert MyTypeWithMethod().stmethod.__name__ == "stmethod"
assert MyTypeWithMethod.N.m.__name__ == 'm'
assert MyTypeWithMethod().N.m.__name__ == 'm'
assert MyTypeWithMethod.N.c.__name__ == 'c'
assert MyTypeWithMethod().N.c.__name__ == 'c'
assert MyTypeWithMethod.N.s.__name__ == 's'
assert MyTypeWithMethod().N.s.__name__ == 's'
assert MyTypeWithMethod.method.__qualname__ == "MyTypeWithMethod.method"
assert MyTypeWithMethod().method.__qualname__ == "MyTypeWithMethod.method"
assert MyTypeWithMethod.clsmethod.__qualname__ == "MyTypeWithMethod.clsmethod"
assert MyTypeWithMethod().clsmethod.__qualname__ == "MyTypeWithMethod.clsmethod"
assert MyTypeWithMethod.stmethod.__qualname__ == "MyTypeWithMethod.stmethod"
assert MyTypeWithMethod().stmethod.__qualname__ == "MyTypeWithMethod.stmethod"
assert MyTypeWithMethod.N.m.__qualname__ == 'MyTypeWithMethod.N.m'
assert MyTypeWithMethod().N.m.__qualname__ == 'MyTypeWithMethod.N.m'
assert MyTypeWithMethod.N.c.__qualname__ == 'MyTypeWithMethod.N.c'
assert MyTypeWithMethod().N.c.__qualname__ == 'MyTypeWithMethod.N.c'
assert MyTypeWithMethod.N.s.__qualname__ == 'MyTypeWithMethod.N.s'
assert MyTypeWithMethod().N.s.__qualname__ == 'MyTypeWithMethod.N.s'
assert MyTypeWithMethod.N.m.__name__ == "m"
assert MyTypeWithMethod().N.m.__name__ == "m"
assert MyTypeWithMethod.N.c.__name__ == "c"
assert MyTypeWithMethod().N.c.__name__ == "c"
assert MyTypeWithMethod.N.s.__name__ == "s"
assert MyTypeWithMethod().N.s.__name__ == "s"
assert MyTypeWithMethod.N().m.__name__ == 'm'
assert MyTypeWithMethod().N().m.__name__ == 'm'
assert MyTypeWithMethod.N().c.__name__ == 'c'
assert MyTypeWithMethod().N().c.__name__ == 'c'
assert MyTypeWithMethod.N().s.__name__ == 's'
assert MyTypeWithMethod().N.s.__name__ == 's'
assert MyTypeWithMethod.N.m.__qualname__ == "MyTypeWithMethod.N.m"
assert MyTypeWithMethod().N.m.__qualname__ == "MyTypeWithMethod.N.m"
assert MyTypeWithMethod.N.c.__qualname__ == "MyTypeWithMethod.N.c"
assert MyTypeWithMethod().N.c.__qualname__ == "MyTypeWithMethod.N.c"
assert MyTypeWithMethod.N.s.__qualname__ == "MyTypeWithMethod.N.s"
assert MyTypeWithMethod().N.s.__qualname__ == "MyTypeWithMethod.N.s"
assert MyTypeWithMethod.N().m.__qualname__ == 'MyTypeWithMethod.N.m'
assert MyTypeWithMethod().N().m.__qualname__ == 'MyTypeWithMethod.N.m'
assert MyTypeWithMethod.N().c.__qualname__ == 'MyTypeWithMethod.N.c'
assert MyTypeWithMethod().N().c.__qualname__ == 'MyTypeWithMethod.N.c'
assert MyTypeWithMethod.N().s.__qualname__ == 'MyTypeWithMethod.N.s'
assert MyTypeWithMethod().N().s.__qualname__ == 'MyTypeWithMethod.N.s'
assert MyTypeWithMethod.N().m.__name__ == "m"
assert MyTypeWithMethod().N().m.__name__ == "m"
assert MyTypeWithMethod.N().c.__name__ == "c"
assert MyTypeWithMethod().N().c.__name__ == "c"
assert MyTypeWithMethod.N().s.__name__ == "s"
assert MyTypeWithMethod().N.s.__name__ == "s"
assert MyTypeWithMethod.N().m.__qualname__ == "MyTypeWithMethod.N.m"
assert MyTypeWithMethod().N().m.__qualname__ == "MyTypeWithMethod.N.m"
assert MyTypeWithMethod.N().c.__qualname__ == "MyTypeWithMethod.N.c"
assert MyTypeWithMethod().N().c.__qualname__ == "MyTypeWithMethod.N.c"
assert MyTypeWithMethod.N().s.__qualname__ == "MyTypeWithMethod.N.s"
assert MyTypeWithMethod().N().s.__qualname__ == "MyTypeWithMethod.N.s"
# Regresesion to
@@ -339,26 +366,27 @@ assert repr(int.to_bytes) == "<method 'to_bytes' of 'int' objects>"
# Regression to
# https://github.com/RustPython/RustPython/issues/2788
assert iter.__qualname__ == iter.__name__ == 'iter'
assert max.__qualname__ == max.__name__ == 'max'
assert min.__qualname__ == min.__name__ == 'min'
assert iter.__qualname__ == iter.__name__ == "iter"
assert max.__qualname__ == max.__name__ == "max"
assert min.__qualname__ == min.__name__ == "min"
def custom_func():
pass
assert custom_func.__qualname__ == 'custom_func'
assert custom_func.__qualname__ == "custom_func"
# Regression to
# https://github.com/RustPython/RustPython/issues/2786
assert object.__new__.__name__ == '__new__'
assert object.__new__.__qualname__ == 'object.__new__'
assert object.__subclasshook__.__name__ == '__subclasshook__'
assert object.__subclasshook__.__qualname__ == 'object.__subclasshook__'
assert type.__new__.__name__ == '__new__'
assert type.__new__.__qualname__ == 'type.__new__'
assert object.__new__.__name__ == "__new__"
assert object.__new__.__qualname__ == "object.__new__"
assert object.__subclasshook__.__name__ == "__subclasshook__"
assert object.__subclasshook__.__qualname__ == "object.__subclasshook__"
assert type.__new__.__name__ == "__new__"
assert type.__new__.__qualname__ == "type.__new__"
class AQ:
@@ -414,75 +442,76 @@ class BQ(AQ):
def three_st():
pass
assert AQ.one.__name__ == 'one'
assert AQ().one.__name__ == 'one'
assert AQ.one_cls.__name__ == 'one_cls'
assert AQ().one_cls.__name__ == 'one_cls'
assert AQ.one_st.__name__ == 'one_st'
assert AQ().one_st.__name__ == 'one_st'
assert AQ.one.__qualname__ == 'AQ.one'
assert AQ().one.__qualname__ == 'AQ.one'
assert AQ.one_cls.__qualname__ == 'AQ.one_cls'
assert AQ().one_cls.__qualname__ == 'AQ.one_cls'
assert AQ.one_st.__qualname__ == 'AQ.one_st'
assert AQ().one_st.__qualname__ == 'AQ.one_st'
assert AQ.one.__name__ == "one"
assert AQ().one.__name__ == "one"
assert AQ.one_cls.__name__ == "one_cls"
assert AQ().one_cls.__name__ == "one_cls"
assert AQ.one_st.__name__ == "one_st"
assert AQ().one_st.__name__ == "one_st"
assert AQ.two.__name__ == 'two'
assert AQ().two.__name__ == 'two'
assert AQ.two_cls.__name__ == 'two_cls'
assert AQ().two_cls.__name__ == 'two_cls'
assert AQ.two_st.__name__ == 'two_st'
assert AQ().two_st.__name__ == 'two_st'
assert AQ.one.__qualname__ == "AQ.one"
assert AQ().one.__qualname__ == "AQ.one"
assert AQ.one_cls.__qualname__ == "AQ.one_cls"
assert AQ().one_cls.__qualname__ == "AQ.one_cls"
assert AQ.one_st.__qualname__ == "AQ.one_st"
assert AQ().one_st.__qualname__ == "AQ.one_st"
assert AQ.two.__qualname__ == 'AQ.two'
assert AQ().two.__qualname__ == 'AQ.two'
assert AQ.two_cls.__qualname__ == 'AQ.two_cls'
assert AQ().two_cls.__qualname__ == 'AQ.two_cls'
assert AQ.two_st.__qualname__ == 'AQ.two_st'
assert AQ().two_st.__qualname__ == 'AQ.two_st'
assert AQ.two.__name__ == "two"
assert AQ().two.__name__ == "two"
assert AQ.two_cls.__name__ == "two_cls"
assert AQ().two_cls.__name__ == "two_cls"
assert AQ.two_st.__name__ == "two_st"
assert AQ().two_st.__name__ == "two_st"
assert BQ.one.__name__ == 'one'
assert BQ().one.__name__ == 'one'
assert BQ.one_cls.__name__ == 'one_cls'
assert BQ().one_cls.__name__ == 'one_cls'
assert BQ.one_st.__name__ == 'one_st'
assert BQ().one_st.__name__ == 'one_st'
assert AQ.two.__qualname__ == "AQ.two"
assert AQ().two.__qualname__ == "AQ.two"
assert AQ.two_cls.__qualname__ == "AQ.two_cls"
assert AQ().two_cls.__qualname__ == "AQ.two_cls"
assert AQ.two_st.__qualname__ == "AQ.two_st"
assert AQ().two_st.__qualname__ == "AQ.two_st"
assert BQ.one.__qualname__ == 'BQ.one'
assert BQ().one.__qualname__ == 'BQ.one'
assert BQ.one_cls.__qualname__ == 'BQ.one_cls'
assert BQ().one_cls.__qualname__ == 'BQ.one_cls'
assert BQ.one_st.__qualname__ == 'BQ.one_st'
assert BQ().one_st.__qualname__ == 'BQ.one_st'
assert BQ.one.__name__ == "one"
assert BQ().one.__name__ == "one"
assert BQ.one_cls.__name__ == "one_cls"
assert BQ().one_cls.__name__ == "one_cls"
assert BQ.one_st.__name__ == "one_st"
assert BQ().one_st.__name__ == "one_st"
assert BQ.two.__name__ == 'two'
assert BQ().two.__name__ == 'two'
assert BQ.two_cls.__name__ == 'two_cls'
assert BQ().two_cls.__name__ == 'two_cls'
assert BQ.two_st.__name__ == 'two_st'
assert BQ().two_st.__name__ == 'two_st'
assert BQ.one.__qualname__ == "BQ.one"
assert BQ().one.__qualname__ == "BQ.one"
assert BQ.one_cls.__qualname__ == "BQ.one_cls"
assert BQ().one_cls.__qualname__ == "BQ.one_cls"
assert BQ.one_st.__qualname__ == "BQ.one_st"
assert BQ().one_st.__qualname__ == "BQ.one_st"
assert BQ.two.__qualname__ == 'AQ.two'
assert BQ().two.__qualname__ == 'AQ.two'
assert BQ.two_cls.__qualname__ == 'AQ.two_cls'
assert BQ().two_cls.__qualname__ == 'AQ.two_cls'
assert BQ.two_st.__qualname__ == 'AQ.two_st'
assert BQ().two_st.__qualname__ == 'AQ.two_st'
assert BQ.two.__name__ == "two"
assert BQ().two.__name__ == "two"
assert BQ.two_cls.__name__ == "two_cls"
assert BQ().two_cls.__name__ == "two_cls"
assert BQ.two_st.__name__ == "two_st"
assert BQ().two_st.__name__ == "two_st"
assert BQ.three.__name__ == 'three'
assert BQ().three.__name__ == 'three'
assert BQ.three_cls.__name__ == 'three_cls'
assert BQ().three_cls.__name__ == 'three_cls'
assert BQ.three_st.__name__ == 'three_st'
assert BQ().three_st.__name__ == 'three_st'
assert BQ.two.__qualname__ == "AQ.two"
assert BQ().two.__qualname__ == "AQ.two"
assert BQ.two_cls.__qualname__ == "AQ.two_cls"
assert BQ().two_cls.__qualname__ == "AQ.two_cls"
assert BQ.two_st.__qualname__ == "AQ.two_st"
assert BQ().two_st.__qualname__ == "AQ.two_st"
assert BQ.three.__qualname__ == 'BQ.three'
assert BQ().three.__qualname__ == 'BQ.three'
assert BQ.three_cls.__qualname__ == 'BQ.three_cls'
assert BQ().three_cls.__qualname__ == 'BQ.three_cls'
assert BQ.three_st.__qualname__ == 'BQ.three_st'
assert BQ().three_st.__qualname__ == 'BQ.three_st'
assert BQ.three.__name__ == "three"
assert BQ().three.__name__ == "three"
assert BQ.three_cls.__name__ == "three_cls"
assert BQ().three_cls.__name__ == "three_cls"
assert BQ.three_st.__name__ == "three_st"
assert BQ().three_st.__name__ == "three_st"
assert BQ.three.__qualname__ == "BQ.three"
assert BQ().three.__qualname__ == "BQ.three"
assert BQ.three_cls.__qualname__ == "BQ.three_cls"
assert BQ().three_cls.__qualname__ == "BQ.three_cls"
assert BQ.three_st.__qualname__ == "BQ.three_st"
assert BQ().three_st.__qualname__ == "BQ.three_st"
class ClassWithNew:
@@ -494,73 +523,74 @@ class ClassWithNew:
return super().__new__(cls, *args, **kwargs)
assert ClassWithNew.__new__.__qualname__ == 'ClassWithNew.__new__'
assert ClassWithNew().__new__.__qualname__ == 'ClassWithNew.__new__'
assert ClassWithNew.__new__.__name__ == '__new__'
assert ClassWithNew().__new__.__name__ == '__new__'
assert ClassWithNew.__new__.__qualname__ == "ClassWithNew.__new__"
assert ClassWithNew().__new__.__qualname__ == "ClassWithNew.__new__"
assert ClassWithNew.__new__.__name__ == "__new__"
assert ClassWithNew().__new__.__name__ == "__new__"
assert ClassWithNew.N.__new__.__qualname__ == 'ClassWithNew.N.__new__'
assert ClassWithNew().N.__new__.__qualname__ == 'ClassWithNew.N.__new__'
assert ClassWithNew.N.__new__.__name__ == '__new__'
assert ClassWithNew().N.__new__.__name__ == '__new__'
assert ClassWithNew.N().__new__.__qualname__ == 'ClassWithNew.N.__new__'
assert ClassWithNew().N().__new__.__qualname__ == 'ClassWithNew.N.__new__'
assert ClassWithNew.N().__new__.__name__ == '__new__'
assert ClassWithNew().N().__new__.__name__ == '__new__'
assert ClassWithNew.N.__new__.__qualname__ == "ClassWithNew.N.__new__"
assert ClassWithNew().N.__new__.__qualname__ == "ClassWithNew.N.__new__"
assert ClassWithNew.N.__new__.__name__ == "__new__"
assert ClassWithNew().N.__new__.__name__ == "__new__"
assert ClassWithNew.N().__new__.__qualname__ == "ClassWithNew.N.__new__"
assert ClassWithNew().N().__new__.__qualname__ == "ClassWithNew.N.__new__"
assert ClassWithNew.N().__new__.__name__ == "__new__"
assert ClassWithNew().N().__new__.__name__ == "__new__"
# Regression to:
# https://github.com/RustPython/RustPython/issues/2762
assert type.__prepare__() == {}
assert type.__prepare__('name') == {}
assert type.__prepare__('name', object) == {}
assert type.__prepare__('name', (bytes, str)) == {}
assert type.__prepare__("name") == {}
assert type.__prepare__("name", object) == {}
assert type.__prepare__("name", (bytes, str)) == {}
assert type.__prepare__(a=1, b=2) == {}
assert type.__prepare__('name', (object, int), kw=True) == {}
assert type.__prepare__("name", (object, int), kw=True) == {}
# Previously we needed `name` to be `str`:
assert type.__prepare__(1) == {}
assert int.__prepare__() == {}
assert int.__prepare__('name', (object, int), kw=True) == {}
assert int.__prepare__("name", (object, int), kw=True) == {}
# Regression to
# https://github.com/RustPython/RustPython/issues/2790
# `#[pyproperty]`
assert BaseException.args.__qualname__ == 'BaseException.args'
assert BaseException.args.__qualname__ == "BaseException.args"
# class extension without `#[pyproperty]` override
assert Exception.args.__qualname__ == 'BaseException.args'
assert Exception.args.__qualname__ == "BaseException.args"
# dynamic with `.new_readonly_getset`
assert SyntaxError.msg.__qualname__ == 'SyntaxError.msg'
assert SyntaxError.msg.__qualname__ == "SyntaxError.msg"
# Regression to
# https://github.com/RustPython/RustPython/issues/2794
assert type.__subclasshook__.__qualname__ == 'type.__subclasshook__'
assert object.__subclasshook__.__qualname__ == 'object.__subclasshook__'
assert type.__subclasshook__.__qualname__ == "type.__subclasshook__"
assert object.__subclasshook__.__qualname__ == "object.__subclasshook__"
# Regression to
# https://github.com/RustPython/RustPython/issues/2776
assert repr(BQ.one).startswith('<function BQ.one at 0x')
assert repr(BQ.one_st).startswith('<function BQ.one_st at 0x')
assert repr(BQ.one).startswith("<function BQ.one at 0x")
assert repr(BQ.one_st).startswith("<function BQ.one_st at 0x")
assert repr(BQ.two).startswith('<function AQ.two at 0x')
assert repr(BQ.two_st).startswith('<function AQ.two_st at 0x')
assert repr(BQ.two).startswith("<function AQ.two at 0x")
assert repr(BQ.two_st).startswith("<function AQ.two_st at 0x")
assert repr(BQ.three).startswith('<function BQ.three at 0x')
assert repr(BQ.three_st).startswith('<function BQ.three_st at 0x')
assert repr(BQ.three).startswith("<function BQ.three at 0x")
assert repr(BQ.three_st).startswith("<function BQ.three_st at 0x")
def my_repr_func():
pass
assert repr(my_repr_func).startswith('<function my_repr_func at 0x')
assert repr(my_repr_func).startswith("<function my_repr_func at 0x")
# https://github.com/RustPython/RustPython/issues/3100

View File

@@ -1,22 +1,29 @@
class X():
class X:
pass
class Y():
class Y:
pass
class A(X, Y):
pass
assert (A, X, Y, object) == A.__mro__
class B(X, Y):
pass
assert (B, X, Y, object) == B.__mro__
class C(A, B):
pass
assert (C, A, B, X, Y, object) == C.__mro__
assert type.__mro__ == (type, object)

View File

@@ -1,9 +1,13 @@
assert list(zip(['a', 'b', 'c'], range(3), [9, 8, 7, 99])) == [('a', 0, 9), ('b', 1, 8), ('c', 2, 7)]
assert list(zip(["a", "b", "c"], range(3), [9, 8, 7, 99])) == [
("a", 0, 9),
("b", 1, 8),
("c", 2, 7),
]
assert list(zip(['a', 'b', 'c'])) == [('a',), ('b',), ('c',)]
assert list(zip(["a", "b", "c"])) == [("a",), ("b",), ("c",)]
assert list(zip()) == []
assert list(zip(*zip(['a', 'b', 'c'], range(1, 4)))) == [('a', 'b', 'c'), (1, 2, 3)]
assert list(zip(*zip(["a", "b", "c"], range(1, 4)))) == [("a", "b", "c"), (1, 2, 3)]
# test infinite iterator

View File

@@ -1,25 +1,26 @@
from testutils import assert_raises
assert '__builtins__' in globals()
assert "__builtins__" in globals()
# assert type(__builtins__).__name__ == 'module'
with assert_raises(AttributeError):
__builtins__.__builtins__
assert __builtins__.__name__ == "builtins"
import builtins
assert builtins.__name__ == "builtins"
__builtins__.x = 'new'
assert x == 'new' # noqa: F821
__builtins__.x = "new"
assert x == "new" # noqa: F821
exec('assert "__builtins__" in globals()', dict())
exec('assert __builtins__ == 7', {'__builtins__': 7})
exec('assert not isinstance(__builtins__, dict)')
exec('assert isinstance(__builtins__, dict)', {})
exec("assert __builtins__ == 7", {"__builtins__": 7})
exec("assert not isinstance(__builtins__, dict)")
exec("assert isinstance(__builtins__, dict)", {})
namespace = {}
exec('', namespace)
assert namespace['__builtins__'] == __builtins__.__dict__
exec("", namespace)
assert namespace["__builtins__"] == __builtins__.__dict__
# with assert_raises(NameError):
# exec('print(__builtins__)', {'__builtins__': {}})

View File

@@ -1,5 +1,6 @@
from asyncio import sleep
def f():
def g():
return 1
@@ -7,25 +8,32 @@ def f():
assert g.__code__.co_consts[0] == None
return 2
assert f.__code__.co_consts[0] == None
def generator():
yield 1
yield 2
yield 1
yield 2
assert generator().gi_code.co_consts[0] == None
async def async_f():
await sleep(1)
return 1
await sleep(1)
return 1
assert async_f.__code__.co_consts[0] == None
lambda_f = lambda: 0
assert lambda_f.__code__.co_consts[0] == None
class cls:
def f():
return 1
assert cls().f.__code__.co_consts[0] == None

View File

@@ -1 +1 @@
print('Hello')
print("Hello")

View File

@@ -8,6 +8,7 @@ def fizzbuzz(n):
else:
return str(n)
n = 1
while n < 10:
print(fizzbuzz(n))

View File

@@ -1,12 +1,14 @@
c1 = compile("1 + 1", "", 'eval')
c1 = compile("1 + 1", "", "eval")
code_class = type(c1)
def f(x, y, *args, power=1, **kwargs):
print("Constant String", 2, None, (2, 4))
assert code_class == type(c1)
z = x * y
return z ** power
return z**power
c2 = f.__code__
# print(c2)
@@ -19,12 +21,12 @@ assert "Constant String" in c2.co_consts, c2.co_consts
print(c2.co_consts)
assert 2 in c2.co_consts, c2.co_consts
assert "example_interactive.py" in c2.co_filename
assert c2.co_firstlineno == 5, str(c2.co_firstlineno)
assert c2.co_firstlineno == 6, str(c2.co_firstlineno)
# assert isinstance(c2.co_flags, int) # 'OPTIMIZED, NEWLOCALS, NOFREE'
# assert c2.co_freevars == (), str(c2.co_freevars)
assert c2.co_kwonlyargcount == 1, (c2.co_kwonlyargcount)
assert c2.co_kwonlyargcount == 1, c2.co_kwonlyargcount
# assert c2.co_lnotab == 0, c2.co_lnotab # b'\x00\x01' # Line number table
assert c2.co_name == 'f', c2.co_name
assert c2.co_name == "f", c2.co_name
# assert c2.co_names == ('code_class', 'type', 'c1', 'AssertionError'), c2.co_names # , c2.co_names
# assert c2.co_nlocals == 4, c2.co_nlocals #
# assert c2.co_stacksize == 2, 'co_stacksize',

View File

@@ -1,19 +1,41 @@
from typing import Type
from types import (
GeneratorType, CoroutineType, AsyncGeneratorType, BuiltinFunctionType,
BuiltinMethodType, WrapperDescriptorType, MethodWrapperType, MethodDescriptorType,
ClassMethodDescriptorType, FrameType, GetSetDescriptorType, MemberDescriptorType
GeneratorType,
CoroutineType,
AsyncGeneratorType,
BuiltinFunctionType,
BuiltinMethodType,
WrapperDescriptorType,
MethodWrapperType,
MethodDescriptorType,
ClassMethodDescriptorType,
FrameType,
GetSetDescriptorType,
MemberDescriptorType,
)
from testutils import assert_raises
def check_forbidden_instantiation(typ, reverse=False):
f = reversed if reverse else iter
with assert_raises(TypeError):
type(f(typ()))()
dict_values, dict_items = lambda: {}.values(), lambda: {}.items()
# types with custom forward iterators
iter_types = [list, set, str, bytearray, bytes, dict, tuple, lambda: range(0), dict_items, dict_values]
iter_types = [
list,
set,
str,
bytearray,
bytes,
dict,
tuple,
lambda: range(0),
dict_items,
dict_values,
]
# types with custom backwards iterators
reviter_types = [list, dict, lambda: range(0), dict_values, dict_items]
# internal types:
@@ -22,14 +44,14 @@ internal_types = [
CoroutineType,
AsyncGeneratorType,
BuiltinFunctionType,
BuiltinMethodType, # same as MethodWrapperType
BuiltinMethodType, # same as MethodWrapperType
WrapperDescriptorType,
MethodWrapperType,
MethodDescriptorType,
ClassMethodDescriptorType,
FrameType,
GetSetDescriptorType, # same as MemberDescriptorType
MemberDescriptorType
GetSetDescriptorType, # same as MemberDescriptorType
MemberDescriptorType,
]
for typ in iter_types:
@@ -38,4 +60,4 @@ for typ in reviter_types:
check_forbidden_instantiation(typ, reverse=True)
for typ in internal_types:
with assert_raises(TypeError):
typ()
typ()

View File

@@ -1,2 +1,3 @@
import __hello__
assert __hello__.initialized == True

View File

@@ -4,6 +4,7 @@ from import_target import func as aliased_func, other_func as aliased_other_func
from import_star import *
import import_mutual1
assert import_target.X == import_target.func()
assert import_target.X == func()
@@ -17,56 +18,60 @@ assert import_target.Y == aliased.Y
assert import_target.X == aliased_func()
assert import_target.Y == aliased_other_func()
assert STAR_IMPORT == '123'
assert STAR_IMPORT == "123"
try:
from import_target import func, unknown_name
raise AssertionError('`unknown_name` does not cause an exception')
raise AssertionError("`unknown_name` does not cause an exception")
except ImportError:
pass
try:
import mymodule
except ModuleNotFoundError as exc:
assert exc.name == 'mymodule'
assert exc.name == "mymodule"
test = __import__("import_target")
assert test.X == import_target.X
import builtins
class OverrideImportContext():
def __enter__(self):
self.original_import = builtins.__import__
def __exit__(self, exc_type, exc_val, exc_tb):
builtins.__import__ = self.original_import
class OverrideImportContext:
def __enter__(self):
self.original_import = builtins.__import__
def __exit__(self, exc_type, exc_val, exc_tb):
builtins.__import__ = self.original_import
with OverrideImportContext():
def fake_import(name, globals=None, locals=None, fromlist=(), level=0):
return len(name)
builtins.__import__ = fake_import
import test
assert test == 4
def fake_import(name, globals=None, locals=None, fromlist=(), level=0):
return len(name)
builtins.__import__ = fake_import
import test
assert test == 4
# TODO: Once we can determine current directory, use that to construct this
# path:
#import sys
#sys.path.append("snippets/import_directory")
#import nested_target
# import sys
# sys.path.append("snippets/import_directory")
# import nested_target
#try:
# try:
# X
#except NameError:
# except NameError:
# pass
#else:
# else:
# raise AssertionError('X should not be imported')
from testutils import assert_raises
with assert_raises(SyntaxError):
exec('import')
exec("import")

View File

@@ -1,4 +1,5 @@
import os
def import_file():
assert os.path.basename(__file__) == "import_file.py"
assert os.path.basename(__file__) == "import_file.py"

View File

@@ -1,4 +1,2 @@
# Mutual recursive import:
import import_mutual2

View File

@@ -1,3 +1,2 @@
# Mutual recursive import:
import import_mutual1

View File

@@ -1,3 +1,3 @@
# This is used by import.py; the two should be modified in concert
STAR_IMPORT = '123'
STAR_IMPORT = "123"

View File

@@ -1,10 +1,12 @@
# This is used by import.py; the two should be modified in concert
X = '123'
Y = 'abc'
X = "123"
Y = "abc"
def func():
return X
def other_func():
return Y

View File

@@ -1,8 +1,8 @@
assert 2 + 2 == 4
assert 50 - 5*6 == 20
assert 50 - 5 * 6 == 20
assert (50 - 5*6) / 4 == 5 # This will crash
assert (50 - 5*6) / 4 == 5.0
assert (50 - 5 * 6) / 4 == 5 # This will crash
assert (50 - 5 * 6) / 4 == 5.0
assert 8 / 5 == 1.6 # division always returns a floating point number
assert 8 / 5 == 1.6 # division always returns a floating point number

View File

@@ -1,3 +1,3 @@
assert 25 == 5 ** 2 # 5 squared
assert 25 == 5**2 # 5 squared
assert 128 == 2 ** 7 # 2 to the power of 7
assert 128 == 2**7 # 2 to the power of 7

View File

@@ -1,7 +1,6 @@
assert 'spam eggs' == 'spam eggs' # single quotes
assert "doesn't" == 'doesn\'t' # use \' to escape the single quote...
assert "spam eggs" == "spam eggs" # single quotes
assert "doesn't" == "doesn't" # use \' to escape the single quote...
assert "doesn't" == "doesn't" # ...or use double quotes instead
assert '"Yes," he said.' == '"Yes," he said.'
assert '"Yes," he said.' == "\"Yes,\" he said."
assert '"Yes," he said.' == '"Yes," he said.'
assert '"Isn\'t," she said.' == '"Isn\'t," she said.'

View File

@@ -1,6 +1,6 @@
word = 'Python'
assert 'P' == word[0] # character in position 0
assert 'n' == word[5] # character in position 5
assert 'n' == word[-1] # last character
assert 'o' == word[-2] # second-last character
assert 'P' == word[-6]
word = "Python"
assert "P" == word[0] # character in position 0
assert "n" == word[5] # character in position 5
assert "n" == word[-1] # last character
assert "o" == word[-2] # second-last character
assert "P" == word[-6]

Some files were not shown because too many files have changed in this diff Show More