diff --git a/Cargo.lock b/Cargo.lock index cef898addd..53b4f96922 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,7 +21,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", - "getrandom 0.3.3", + "getrandom 0.3.4", "once_cell", "version_check", "zerocopy", @@ -143,6 +143,36 @@ dependencies = [ "bytemuck", ] +[[package]] +name = "attribute-derive" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05832cdddc8f2650cc2cc187cc2e952b8c133a48eb055f35211f61ee81502d77" +dependencies = [ + "attribute-derive-macro", + "derive-where", + "manyhow", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "attribute-derive-macro" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a7cdbbd4bd005c5d3e2e9c885e6fa575db4f4a3572335b974d8db853b6beb61" +dependencies = [ + "collection_literals", + "interpolator", + "manyhow", + "proc-macro-utils", + "proc-macro2", + "quote", + "quote-use", + "syn", +] + [[package]] name = "autocfg" version = "1.5.0" @@ -233,9 +263,9 @@ checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" [[package]] name = "bzip2" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bea8dcd42434048e4f7a304411d9273a411f647446c1234a65ce0554923f4cff" +checksum = "f3a53fac24f34a81bc9954b5d6cfce0c21e18ec6959f44f56e8e90e4bb7c346c" dependencies = [ "libbz2-rs-sys", ] @@ -266,9 +296,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.40" +version = "1.2.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d05d92f4b1fd76aad469d46cdd858ca761576082cd37df81416691e50199fb" +checksum = "ac9fe6cdbb24b6ade63616c0a0688e45bb56732262c158df3c0c4bea4ca47cb7" dependencies = [ "find-msvc-tools", "shlex", @@ -285,9 +315,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cfg_aliases" @@ -348,18 +378,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.48" +version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae" +checksum = "f4512b90fa68d3a9932cea5184017c5d200f5921df706d45e853537dea51508f" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.48" +version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9" +checksum = "0025e98baa12e766c67ba13ff4695a887a1eba19569aad00a472546795bd6730" dependencies = [ "anstyle", "clap_lex", @@ -367,9 +397,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "clipboard-win" @@ -380,6 +410,12 @@ dependencies = [ "error-code", ] +[[package]] +name = "collection_literals" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2550f75b8cfac212855f6b1885455df8eaee8fe8e246b647d69146142e016084" + [[package]] name = "colorchoice" version = "1.0.4" @@ -388,9 +424,9 @@ checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" [[package]] name = "compact_str" -version = "0.8.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b79c4069c6cad78e2e0cdfcbd26275770669fb39fd308a752dc110e83b9af32" +checksum = "3fdb1325a1cece981e8a296ab8f0f9b63ae357bd0784a9faaf548cc7b480707a" dependencies = [ "castaway", "cfg-if", @@ -708,13 +744,24 @@ dependencies = [ [[package]] name = "csv-core" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d02f3b0da4c6504f86e9cd789d8dbafab48c2321be74e9987593de5a894d93d" +checksum = "704a3c26996a80471189265814dbc2c257598b96b8a7feae2d31ace646bb9782" dependencies = [ "memchr", ] +[[package]] +name = "derive-where" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef941ded77d15ca19b40374869ac6000af1c9f2a4c0f3d4c70926287e6364a8f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "digest" version = "0.10.7" @@ -785,9 +832,9 @@ checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" [[package]] name = "env_filter" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" +checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2" dependencies = [ "log", "regex", @@ -859,9 +906,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0399f9d26e5191ce32c498bebd31e7a3ceabc2745f0ac54af3f335126c3f24b3" +checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" [[package]] name = "flame" @@ -933,22 +980,45 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "generic-array" -version = "0.14.7" +version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" dependencies = [ "typenum", "version_check", ] +[[package]] +name = "get-size-derive2" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3814abc7da8ab18d2fd820f5b540b5e39b6af0a32de1bdd7c47576693074843" +dependencies = [ + "attribute-derive", + "quote", + "syn", +] + +[[package]] +name = "get-size2" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfe2cec5b5ce8fb94dcdb16a1708baa4d0609cc3ce305ca5d3f6f2ffb59baed" +dependencies = [ + "compact_str", + "get-size-derive2", + "hashbrown 0.16.0", + "smallvec", +] + [[package]] name = "gethostname" -version = "1.0.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc257fdb4038301ce4b9cd1b3b51704509692bb3ff716a410cbd07925d9dae55" +checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8" dependencies = [ "rustix", - "windows-targets 0.52.6", + "windows-link", ] [[package]] @@ -968,20 +1038,20 @@ checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "libc", - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi", ] [[package]] name = "getrandom" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "js-sys", "libc", "r-efi", - "wasi 0.14.7+wasi-0.2.4", + "wasip2", "wasm-bindgen", ] @@ -1004,12 +1074,13 @@ checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] name = "half" -version = "2.6.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" dependencies = [ "cfg-if", "crunchy", + "zerocopy", ] [[package]] @@ -1086,9 +1157,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.11.4" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" +checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" dependencies = [ "equivalent", "hashbrown 0.16.0", @@ -1111,6 +1182,12 @@ dependencies = [ "similar", ] +[[package]] +name = "interpolator" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71dd52191aae121e8611f1e8dc3e324dd0dd1dee1e6dd91d10ee07a3cfb4d9d8" + [[package]] name = "is-macro" version = "0.3.7" @@ -1251,9 +1328,9 @@ checksum = "2c4a545a15244c7d945065b5d392b2d2d7f21526fba56ce51467b06ed445e8f7" [[package]] name = "libc" -version = "0.2.176" +version = "0.2.177" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174" +checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" [[package]] name = "libffi" @@ -1428,6 +1505,29 @@ dependencies = [ "malachite-nz", ] +[[package]] +name = "manyhow" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b33efb3ca6d3b07393750d4030418d594ab1139cee518f0dc88db70fec873587" +dependencies = [ + "manyhow-macros", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "manyhow-macros" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46fce34d199b78b6e6073abf984c9cf5fd3e9330145a93ee0738a7443e371495" +dependencies = [ + "proc-macro-utils", + "proc-macro2", + "quote", +] + [[package]] name = "maplit" version = "1.0.2" @@ -1622,9 +1722,9 @@ checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" [[package]] name = "openssl" -version = "0.10.73" +version = "0.10.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" +checksum = "24ad14dd45412269e1a30f52ad8f0664f0f4f4a89ee8fe28c3b3527021ebb654" dependencies = [ "bitflags 2.9.4", "cfg-if", @@ -1663,9 +1763,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.109" +version = "0.9.110" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" +checksum = "0a9f0075ba3c21b09f8e8b2026584b1d18d49388648f2fbbf3c97ea8deced8e2" dependencies = [ "cc", "libc", @@ -1836,6 +1936,17 @@ dependencies = [ "syn", ] +[[package]] +name = "proc-macro-utils" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eeaf08a13de400bc215877b5bdc088f241b12eb42f0a548d3390dc1c56bb7071" +dependencies = [ + "proc-macro2", + "quote", + "smallvec", +] + [[package]] name = "proc-macro2" version = "1.0.101" @@ -1924,6 +2035,28 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "quote-use" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9619db1197b497a36178cfc736dc96b271fe918875fbf1344c436a7e93d0321e" +dependencies = [ + "quote", + "quote-use-macros", +] + +[[package]] +name = "quote-use-macros" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82ebfb7faafadc06a7ab141a6f67bcfb24cb8beb158c6fe933f2f035afa99f35" +dependencies = [ + "proc-macro-utils", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "r-efi" version = "5.3.0" @@ -2005,7 +2138,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", ] [[package]] @@ -2070,9 +2203,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.3" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b5288124840bee7b386bc413c487869b360b2b4ec421ea56425128692f2a82c" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ "aho-corasick", "memchr", @@ -2082,9 +2215,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.11" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", @@ -2093,9 +2226,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "region" @@ -2133,11 +2266,12 @@ dependencies = [ [[package]] name = "ruff_python_ast" version = "0.0.0" -source = "git+https://github.com/astral-sh/ruff.git?tag=0.11.0#2cd25ef6410fb5fca96af1578728a3d828d2d53a" +source = "git+https://github.com/astral-sh/ruff.git?tag=0.14.1#2bffef59665ce7d2630dfd72ee99846663660db8" dependencies = [ "aho-corasick", "bitflags 2.9.4", "compact_str", + "get-size2", "is-macro", "itertools 0.14.0", "memchr", @@ -2145,16 +2279,18 @@ dependencies = [ "ruff_source_file", "ruff_text_size", "rustc-hash", + "thiserror 2.0.17", ] [[package]] name = "ruff_python_parser" version = "0.0.0" -source = "git+https://github.com/astral-sh/ruff.git?tag=0.11.0#2cd25ef6410fb5fca96af1578728a3d828d2d53a" +source = "git+https://github.com/astral-sh/ruff.git?tag=0.14.1#2bffef59665ce7d2630dfd72ee99846663660db8" dependencies = [ "bitflags 2.9.4", "bstr", "compact_str", + "get-size2", "memchr", "ruff_python_ast", "ruff_python_trivia", @@ -2169,7 +2305,7 @@ dependencies = [ [[package]] name = "ruff_python_trivia" version = "0.0.0" -source = "git+https://github.com/astral-sh/ruff.git?tag=0.11.0#2cd25ef6410fb5fca96af1578728a3d828d2d53a" +source = "git+https://github.com/astral-sh/ruff.git?tag=0.14.1#2bffef59665ce7d2630dfd72ee99846663660db8" dependencies = [ "itertools 0.14.0", "ruff_source_file", @@ -2180,7 +2316,7 @@ dependencies = [ [[package]] name = "ruff_source_file" version = "0.0.0" -source = "git+https://github.com/astral-sh/ruff.git?tag=0.11.0#2cd25ef6410fb5fca96af1578728a3d828d2d53a" +source = "git+https://github.com/astral-sh/ruff.git?tag=0.14.1#2bffef59665ce7d2630dfd72ee99846663660db8" dependencies = [ "memchr", "ruff_text_size", @@ -2189,7 +2325,10 @@ dependencies = [ [[package]] name = "ruff_text_size" version = "0.0.0" -source = "git+https://github.com/astral-sh/ruff.git?tag=0.11.0#2cd25ef6410fb5fca96af1578728a3d828d2d53a" +source = "git+https://github.com/astral-sh/ruff.git?tag=0.14.1#2bffef59665ce7d2630dfd72ee99846663660db8" +dependencies = [ + "get-size2", +] [[package]] name = "rustc-hash" @@ -2264,7 +2403,7 @@ dependencies = [ "ascii", "bitflags 2.9.4", "cfg-if", - "getrandom 0.3.3", + "getrandom 0.3.4", "itertools 0.14.0", "libc", "lock_api", @@ -2483,7 +2622,7 @@ dependencies = [ "exitcode", "flame", "flamer", - "getrandom 0.3.3", + "getrandom 0.3.4", "glob", "half", "hex", @@ -2779,19 +2918,19 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "socket2" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] name = "stable_deref_trait" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "static_assertions" @@ -2825,9 +2964,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.106" +version = "2.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +checksum = "2a26dbd934e5451d21ef060c018dae56fc073894c5a7896f882928a76e6d081b" dependencies = [ "proc-macro2", "quote", @@ -3301,15 +3440,6 @@ version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" -[[package]] -name = "wasi" -version = "0.14.7+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" -dependencies = [ - "wasip2", -] - [[package]] name = "wasip2" version = "1.0.1+wasi-0.2.4" @@ -3436,9 +3566,9 @@ dependencies = [ [[package]] name = "widestring" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd7cf3379ca1aac9eea11fba24fd7e315d621f8dfe35c8d7d2be8b793726e07d" +checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471" [[package]] name = "winapi" @@ -3757,9 +3887,9 @@ checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "xml" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72e6e0a83ae73d886ab66fc2f82b598fbbb8f373357d5f2f9f783e50e4d06435" +checksum = "58a4274c410d957424a1502b21126915b45d9956b2f80a88d4f6f906af29facc" [[package]] name = "xz2" diff --git a/Cargo.toml b/Cargo.toml index ab055f6a36..3cdc471dc3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -158,10 +158,10 @@ rustpython-sre_engine = { path = "vm/sre_engine", version = "0.4.0" } rustpython-wtf8 = { path = "wtf8", version = "0.4.0" } rustpython-doc = { git = "https://github.com/RustPython/__doc__", tag = "0.3.0", version = "0.3.0" } -ruff_python_parser = { git = "https://github.com/astral-sh/ruff.git", tag = "0.11.0" } -ruff_python_ast = { git = "https://github.com/astral-sh/ruff.git", tag = "0.11.0" } -ruff_text_size = { git = "https://github.com/astral-sh/ruff.git", tag = "0.11.0" } -ruff_source_file = { git = "https://github.com/astral-sh/ruff.git", tag = "0.11.0" } +ruff_python_parser = { git = "https://github.com/astral-sh/ruff.git", tag = "0.14.1" } +ruff_python_ast = { git = "https://github.com/astral-sh/ruff.git", tag = "0.14.1" } +ruff_text_size = { git = "https://github.com/astral-sh/ruff.git", tag = "0.14.1" } +ruff_source_file = { git = "https://github.com/astral-sh/ruff.git", tag = "0.14.1" } ahash = "0.8.12" ascii = "1.1" diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index cc9f066b14..229f16393f 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -1826,7 +1826,6 @@ def test_gh129093(self): self.assertEqual(f'{f'{1!=2=}'=}', "f'{1!=2=}'='1!=2=True'") self.assertEqual(f'{f'{1 != 2=}'=}', "f'{1 != 2=}'='1 != 2=True'") - @unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: "f-string: newlines are not allowed in format specifiers" does not match "'unexpected EOF while parsing' (, line 2)" def test_newlines_in_format_specifiers(self): cases = [ """f'{1:d\n}'""", diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index 7e46773047..29dd04995e 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -259,6 +259,36 @@ Traceback (most recent call last): SyntaxError: invalid syntax +Comprehensions without 'in' keyword: + +>>> [x for x if range(1)] +Traceback (most recent call last): +SyntaxError: 'in' expected after for-loop variables + +>>> tuple(x for x if range(1)) +Traceback (most recent call last): +SyntaxError: 'in' expected after for-loop variables + +>>> [x for x() in a] +Traceback (most recent call last): +SyntaxError: cannot assign to function call + +>>> [x for a, b, (c + 1, d()) in y] +Traceback (most recent call last): +SyntaxError: cannot assign to expression + +>>> [x for a, b, (c + 1, d()) if y] +Traceback (most recent call last): +SyntaxError: 'in' expected after for-loop variables + +>>> [x for x+1 in y] +Traceback (most recent call last): +SyntaxError: cannot assign to expression + +>>> [x for x+1, x() in y] +Traceback (most recent call last): +SyntaxError: cannot assign to expression + Comprehensions creating tuples without parentheses should produce a specialized error message: @@ -322,6 +352,13 @@ Traceback (most recent call last): SyntaxError: invalid syntax +# But prefixes of soft keywords should +# still raise specialized errors + +>>> (mat x) +Traceback (most recent call last): +SyntaxError: invalid syntax. Perhaps you forgot a comma? + From compiler_complex_args(): >>> def f(None=1): @@ -334,7 +371,12 @@ >>> def f(x, y=1, z): ... pass Traceback (most recent call last): -SyntaxError: non-default argument follows default argument +SyntaxError: parameter without a default follows parameter with a default + +>>> def f(x, /, y=1, z): +... pass +Traceback (most recent call last): +SyntaxError: parameter without a default follows parameter with a default >>> def f(x, None): ... pass @@ -555,8 +597,16 @@ Traceback (most recent call last): SyntaxError: expected default value expression -# TODO: RUSTPYTHON NameError: name 'PyCF_TYPE_COMMENTS' is not defined ->>> import ast; ast.parse(''' # doctest: +SKIP +>>> lambda a,d=3,c: None +Traceback (most recent call last): +SyntaxError: parameter without a default follows parameter with a default + +>>> lambda a,/,d=3,c: None +Traceback (most recent call last): +SyntaxError: parameter without a default follows parameter with a default + +>>> # TODO: RUSTPYTHON +>>> import ast; ast.parse(''' # doctest: +SKIP ... def f( ... *, # type: int ... a, # type: int @@ -582,46 +632,31 @@ >>> L = range(10) >>> f(x for x in L) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - -# TODO: RUSTPYTHON does not raise. ->>> f(x for x in L, 1) # doctest: +SKIP +>>> f(x for x in L, 1) Traceback (most recent call last): SyntaxError: Generator expression must be parenthesized - -# TODO: RUSTPYTHON does not raise. ->>> f(x for x in L, y=1) # doctest: +SKIP +>>> f(x for x in L, y=1) Traceback (most recent call last): SyntaxError: Generator expression must be parenthesized - -# TODO: RUSTPYTHON does not raise. ->>> f(x for x in L, *[]) # doctest: +SKIP +>>> f(x for x in L, *[]) Traceback (most recent call last): SyntaxError: Generator expression must be parenthesized - -# TODO: RUSTPYTHON does not raise. ->>> f(x for x in L, **{}) # doctest: +SKIP +>>> f(x for x in L, **{}) Traceback (most recent call last): SyntaxError: Generator expression must be parenthesized - -# TODO: RUSTPYTHON does not raise. ->>> f(L, x for x in L) # doctest: +SKIP +>>> f(L, x for x in L) Traceback (most recent call last): SyntaxError: Generator expression must be parenthesized - -# TODO: RUSTPYTHON does not raise. ->>> f(x for x in L, y for y in L) # doctest: +SKIP +>>> f(x for x in L, y for y in L) Traceback (most recent call last): SyntaxError: Generator expression must be parenthesized - -# TODO: RUSTPYTHON does not raise. ->>> f(x for x in L,) # doctest: +SKIP +>>> f(x for x in L,) Traceback (most recent call last): SyntaxError: Generator expression must be parenthesized >>> f((x for x in L), 1) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - -# TODO: RUSTPYTHON TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases ->>> class C(x for x in L): # doctest: +SKIP +>>> # TODO: RUSTPYTHON +>>> class C(x for x in L): # doctest: +SKIP ... pass Traceback (most recent call last): SyntaxError: invalid syntax @@ -742,8 +777,8 @@ >>> f(x.y=1) Traceback (most recent call last): SyntaxError: expression cannot contain assignment, perhaps you meant "=="? -# TODO: RUSTPYTHON ->>> f((x)=2) # doctest: +SKIP +>>> # TODO: RUSTPYTHON +>>> f((x)=2) # doctest: +SKIP Traceback (most recent call last): SyntaxError: expression cannot contain assignment, perhaps you meant "=="? >>> f(True=1) @@ -758,11 +793,31 @@ >>> f(__debug__=1) Traceback (most recent call last): SyntaxError: cannot assign to __debug__ - -# TODO: RUSTPYTHON NameError: name '__annotations__' is not defined ->>> __debug__: int # doctest: +SKIP +>>> # TODO: RUSTPYTHON +>>> __debug__: int # doctest: +SKIP Traceback (most recent call last): SyntaxError: cannot assign to __debug__ +>>> f(a=) +Traceback (most recent call last): +SyntaxError: expected argument value expression +>>> f(a, b, c=) +Traceback (most recent call last): +SyntaxError: expected argument value expression +>>> f(a, b, c=, d) +Traceback (most recent call last): +SyntaxError: expected argument value expression +>>> f(*args=[0]) +Traceback (most recent call last): +SyntaxError: cannot assign to iterable argument unpacking +>>> f(a, b, *args=[0]) +Traceback (most recent call last): +SyntaxError: cannot assign to iterable argument unpacking +>>> f(**kwargs={'a': 1}) +Traceback (most recent call last): +SyntaxError: cannot assign to keyword argument unpacking +>>> f(a, b, *args, **kwargs={'a': 1}) +Traceback (most recent call last): +SyntaxError: cannot assign to keyword argument unpacking More set_context(): @@ -990,11 +1045,26 @@ Traceback (most recent call last): SyntaxError: expected ':' + >>> def f[T]() + ... pass + Traceback (most recent call last): + SyntaxError: expected ':' + >>> class A ... pass Traceback (most recent call last): SyntaxError: expected ':' + >>> class A[T] + ... pass + Traceback (most recent call last): + SyntaxError: expected ':' + + >>> class A[T]() + ... pass + Traceback (most recent call last): + SyntaxError: expected ':' + >>> class R&D: ... pass Traceback (most recent call last): @@ -1154,6 +1224,22 @@ Traceback (most recent call last): SyntaxError: expected '(' + >>> def f -> int: + Traceback (most recent call last): + SyntaxError: expected '(' + + >>> async def f -> int: # type: int + Traceback (most recent call last): + SyntaxError: expected '(' + + >>> async def f[T]: + Traceback (most recent call last): + SyntaxError: expected '(' + + >>> def f[T] -> str: + Traceback (most recent call last): + SyntaxError: expected '(' + Parenthesized arguments in function definitions >>> def f(x, (y, z), w): @@ -1432,11 +1518,21 @@ Traceback (most recent call last): IndentationError: expected an indented block after function definition on line 1 + >>> def foo[T](x, /, y, *, z=2): + ... pass + Traceback (most recent call last): + IndentationError: expected an indented block after function definition on line 1 + >>> class Blech(A): ... pass Traceback (most recent call last): IndentationError: expected an indented block after class definition on line 1 + >>> class Blech[T](A): + ... pass + Traceback (most recent call last): + IndentationError: expected an indented block after class definition on line 1 + >>> match something: ... pass Traceback (most recent call last): @@ -1469,14 +1565,16 @@ Check that an multiple exception types with missing parentheses raise a custom exception - >>> try: + >>> # TODO: RUSTPYTHON + >>> try: # doctest: +SKIP ... pass ... except A, B: ... pass Traceback (most recent call last): SyntaxError: multiple exception types must be parenthesized - >>> try: + >>> # TODO: RUSTPYTHON + >>> try: # doctest: +SKIP ... pass ... except A, B, C: ... pass @@ -1591,30 +1689,113 @@ Traceback (most recent call last): SyntaxError: trailing comma not allowed without surrounding parentheses +>>> import a from b +Traceback (most recent call last): +SyntaxError: Did you mean to use 'from ... import ...' instead? + +>>> import a.y.z from b.y.z +Traceback (most recent call last): +SyntaxError: Did you mean to use 'from ... import ...' instead? + +>>> import a from b as bar +Traceback (most recent call last): +SyntaxError: Did you mean to use 'from ... import ...' instead? + +>>> import a.y.z from b.y.z as bar +Traceback (most recent call last): +SyntaxError: Did you mean to use 'from ... import ...' instead? + +>>> import a, b,c from b +Traceback (most recent call last): +SyntaxError: Did you mean to use 'from ... import ...' instead? + +>>> import a.y.z, b.y.z, c.y.z from b.y.z +Traceback (most recent call last): +SyntaxError: Did you mean to use 'from ... import ...' instead? + +>>> import a,b,c from b as bar +Traceback (most recent call last): +SyntaxError: Did you mean to use 'from ... import ...' instead? + +>>> import a.y.z, b.y.z, c.y.z from b.y.z as bar +Traceback (most recent call last): +SyntaxError: Did you mean to use 'from ... import ...' instead? + # Check that we dont raise the "trailing comma" error if there is more # input to the left of the valid part that we parsed. ->>> from t import x,y, and 3 +>>> from t import x,y, and 3 Traceback (most recent call last): SyntaxError: invalid syntax -# TODO: RUSTPYTHON nothing raised. ->>> (): int # doctest: +SKIP +>>> from i import +Traceback (most recent call last): +SyntaxError: Expected one or more names after 'import' + +>>> from .. import +Traceback (most recent call last): +SyntaxError: Expected one or more names after 'import' + +>>> import +Traceback (most recent call last): +SyntaxError: Expected one or more names after 'import' + +>>> (): int Traceback (most recent call last): SyntaxError: only single target (not tuple) can be annotated -# TODO: RUSTPYTHON nothing raised. ->>> []: int # doctest: +SKIP +>>> []: int Traceback (most recent call last): SyntaxError: only single target (not list) can be annotated -# TODO: RUSTPYTHON nothing raised. ->>> (()): int # doctest: +SKIP +>>> (()): int Traceback (most recent call last): SyntaxError: only single target (not tuple) can be annotated -# TODO: RUSTPYTHON nothing raised. ->>> ([]): int # doctest: +SKIP +>>> ([]): int Traceback (most recent call last): SyntaxError: only single target (not list) can be annotated +# 'not' after operators: + +>>> 3 + not 3 +Traceback (most recent call last): +SyntaxError: 'not' after an operator must be parenthesized + +>>> 3 * not 3 +Traceback (most recent call last): +SyntaxError: 'not' after an operator must be parenthesized + +>>> + not 3 +Traceback (most recent call last): +SyntaxError: 'not' after an operator must be parenthesized + +>>> - not 3 +Traceback (most recent call last): +SyntaxError: 'not' after an operator must be parenthesized + +>>> ~ not 3 +Traceback (most recent call last): +SyntaxError: 'not' after an operator must be parenthesized + +>>> 3 + - not 3 +Traceback (most recent call last): +SyntaxError: 'not' after an operator must be parenthesized + +>>> 3 + not -1 +Traceback (most recent call last): +SyntaxError: 'not' after an operator must be parenthesized + +# Check that we don't introduce misleading errors +>>> not 1 */ 2 +Traceback (most recent call last): +SyntaxError: invalid syntax + +>>> not 1 + +Traceback (most recent call last): +SyntaxError: invalid syntax + +>>> not + 1 + +Traceback (most recent call last): +SyntaxError: invalid syntax + Corner-cases that used to fail to raise the correct error: >>> def f(*, x=lambda __debug__:0): pass @@ -1635,8 +1816,7 @@ Corner-cases that used to crash: - # TODO: RUSTPYTHON nothing raised. - >>> def f(**__debug__): pass # doctest: +SKIP + >>> def f(**__debug__): pass Traceback (most recent call last): SyntaxError: cannot assign to __debug__ @@ -1650,8 +1830,8 @@ Invalid pattern matching constructs: - # TODO: RUSTPYTHON nothing raised. - >>> match ...: # doctest: +SKIP + >>> # TODO: RUSTPYTHON + >>> match ...: # doctest: +SKIP ... case 42 as _: ... ... Traceback (most recent call last): @@ -1751,22 +1931,22 @@ >>> A[*(1:2)] Traceback (most recent call last): ... - SyntaxError: invalid syntax + SyntaxError: Invalid star expression >>> A[*(1:2)] = 1 Traceback (most recent call last): ... - SyntaxError: invalid syntax + SyntaxError: Invalid star expression >>> del A[*(1:2)] Traceback (most recent call last): ... - SyntaxError: invalid syntax + SyntaxError: Invalid star expression A[*:] and A[:*] >>> A[*:] Traceback (most recent call last): ... - SyntaxError: invalid syntax + SyntaxError: Invalid star expression >>> A[:*] Traceback (most recent call last): ... @@ -1777,7 +1957,7 @@ >>> A[*] Traceback (most recent call last): ... - SyntaxError: invalid syntax + SyntaxError: Invalid star expression A[**] @@ -1829,10 +2009,246 @@ def f(x: *b) Traceback (most recent call last): ... SyntaxError: invalid syntax + +Invalid bytes literals: + + >>> b"Ā" + Traceback (most recent call last): + ... + b"Ā" + ^^^ + SyntaxError: bytes can only contain ASCII literal characters + + >>> b"абвгде" + Traceback (most recent call last): + ... + b"абвгде" + ^^^^^^^^ + SyntaxError: bytes can only contain ASCII literal characters + + >>> b"abc ъющый" # first 3 letters are ascii + Traceback (most recent call last): + ... + b"abc ъющый" + ^^^^^^^^^^^ + SyntaxError: bytes can only contain ASCII literal characters + +Invalid expressions in type scopes: + + >>> type A[] = int + Traceback (most recent call last): + ... + SyntaxError: Type parameter list cannot be empty + + >>> class A[]: ... + Traceback (most recent call last): + ... + SyntaxError: Type parameter list cannot be empty + + >>> def some[](): ... + Traceback (most recent call last): + ... + SyntaxError: Type parameter list cannot be empty + + >>> def some[]() + Traceback (most recent call last): + ... + SyntaxError: Type parameter list cannot be empty + + >>> async def some[]: # type: int + Traceback (most recent call last): + ... + SyntaxError: Type parameter list cannot be empty + + >>> def f[T: (x:=3)](): pass + Traceback (most recent call last): + ... + SyntaxError: named expression cannot be used within a TypeVar bound + + >>> def f[T: ((x:= 3), int)](): pass + Traceback (most recent call last): + ... + SyntaxError: named expression cannot be used within a TypeVar constraint + + >>> def f[T = ((x:=3))](): pass + Traceback (most recent call last): + ... + SyntaxError: named expression cannot be used within a TypeVar default + + >>> async def f[T: (x:=3)](): pass + Traceback (most recent call last): + ... + SyntaxError: named expression cannot be used within a TypeVar bound + + >>> async def f[T: ((x:= 3), int)](): pass + Traceback (most recent call last): + ... + SyntaxError: named expression cannot be used within a TypeVar constraint + + >>> async def f[T = ((x:=3))](): pass + Traceback (most recent call last): + ... + SyntaxError: named expression cannot be used within a TypeVar default + + >>> type A[T: (x:=3)] = int + Traceback (most recent call last): + ... + SyntaxError: named expression cannot be used within a TypeVar bound + + >>> type A[T: ((x:= 3), int)] = int + Traceback (most recent call last): + ... + SyntaxError: named expression cannot be used within a TypeVar constraint + + >>> type A[T = ((x:=3))] = int + Traceback (most recent call last): + ... + SyntaxError: named expression cannot be used within a TypeVar default + + >>> def f[T: (yield)](): pass + Traceback (most recent call last): + ... + SyntaxError: yield expression cannot be used within a TypeVar bound + + >>> def f[T: (int, (yield))](): pass + Traceback (most recent call last): + ... + SyntaxError: yield expression cannot be used within a TypeVar constraint + + >>> def f[T = (yield)](): pass + Traceback (most recent call last): + ... + SyntaxError: yield expression cannot be used within a TypeVar default + + >>> def f[*Ts = (yield)](): pass + Traceback (most recent call last): + ... + SyntaxError: yield expression cannot be used within a TypeVarTuple default + + >>> def f[**P = [(yield), int]](): pass + Traceback (most recent call last): + ... + SyntaxError: yield expression cannot be used within a ParamSpec default + + >>> type A[T: (yield 3)] = int + Traceback (most recent call last): + ... + SyntaxError: yield expression cannot be used within a TypeVar bound + + >>> type A[T: (int, (yield 3))] = int + Traceback (most recent call last): + ... + SyntaxError: yield expression cannot be used within a TypeVar constraint + + >>> type A[T = (yield 3)] = int + Traceback (most recent call last): + ... + SyntaxError: yield expression cannot be used within a TypeVar default + + >>> type A[T: (await 3)] = int + Traceback (most recent call last): + ... + SyntaxError: await expression cannot be used within a TypeVar bound + + >>> type A[T: (yield from [])] = int + Traceback (most recent call last): + ... + SyntaxError: yield expression cannot be used within a TypeVar bound + + >>> class A[T: (yield 3)]: pass + Traceback (most recent call last): + ... + SyntaxError: yield expression cannot be used within a TypeVar bound + + >>> class A[T: (int, (yield 3))]: pass + Traceback (most recent call last): + ... + SyntaxError: yield expression cannot be used within a TypeVar constraint + + >>> class A[T = (yield)]: pass + Traceback (most recent call last): + ... + SyntaxError: yield expression cannot be used within a TypeVar default + + >>> class A[*Ts = (yield)]: pass + Traceback (most recent call last): + ... + SyntaxError: yield expression cannot be used within a TypeVarTuple default + + >>> class A[**P = [(yield), int]]: pass + Traceback (most recent call last): + ... + SyntaxError: yield expression cannot be used within a ParamSpec default + + >>> # TODO: RUSTPYTHON + >>> type A = (x := 3) # doctest: +SKIP + Traceback (most recent call last): + ... + SyntaxError: named expression cannot be used within a type alias + + >>> type A = (yield 3) + Traceback (most recent call last): + ... + SyntaxError: yield expression cannot be used within a type alias + + >>> type A = (await 3) + Traceback (most recent call last): + ... + SyntaxError: await expression cannot be used within a type alias + + >>> type A = (yield from []) + Traceback (most recent call last): + ... + SyntaxError: yield expression cannot be used within a type alias + + >>> class A[T]((x := 3)): ... + Traceback (most recent call last): + ... + SyntaxError: named expression cannot be used within the definition of a generic + + >>> class A[T]((yield 3)): ... + Traceback (most recent call last): + ... + SyntaxError: yield expression cannot be used within the definition of a generic + + >>> class A[T]((await 3)): ... + Traceback (most recent call last): + ... + SyntaxError: await expression cannot be used within the definition of a generic + + >>> class A[T]((yield from [])): ... + Traceback (most recent call last): + ... + SyntaxError: yield expression cannot be used within the definition of a generic + + >>> f(**x, *y) + Traceback (most recent call last): + SyntaxError: iterable argument unpacking follows keyword argument unpacking + + >>> f(**x, *) + Traceback (most recent call last): + SyntaxError: Invalid star expression + + >>> f(x, *:) + Traceback (most recent call last): + SyntaxError: Invalid star expression + + >>> f(x, *) + Traceback (most recent call last): + SyntaxError: Invalid star expression + + >>> f(x = 5, *) + Traceback (most recent call last): + SyntaxError: Invalid star expression + + >>> f(x = 5, *:) + Traceback (most recent call last): + SyntaxError: Invalid star expression """ import re import doctest +import textwrap import unittest from test import support @@ -1869,8 +2285,7 @@ def _check_error(self, code, errtext, else: self.fail("compile() did not raise SyntaxError") - # TODO: RUSTPYTHON - @unittest.expectedFailure + @unittest.expectedFailure # TODO: RUSTPYTHON def test_expression_with_assignment(self): self._check_error( "print(end1 + end2 = ' ')", @@ -1878,16 +2293,14 @@ def test_expression_with_assignment(self): offset=7 ) - # TODO: RUSTPYTHON - @unittest.expectedFailure + @unittest.expectedFailure # TODO: RUSTPYTHON def test_curly_brace_after_primary_raises_immediately(self): self._check_error("f{}", "invalid syntax", mode="single") def test_assign_call(self): self._check_error("f() = 1", "assign") - # TODO: RUSTPYTHON - @unittest.expectedFailure + @unittest.expectedFailure # TODO: RUSTPYTHON def test_assign_del(self): self._check_error("del (,)", "invalid syntax") self._check_error("del 1", "cannot delete literal") @@ -1939,9 +2352,6 @@ def error2(): """ self._check_error(source, "parameter and nonlocal", lineno=3) - def test_break_outside_loop(self): - self._check_error("break", "outside loop") - def test_yield_outside_function(self): self._check_error("if 0: yield", "outside function") self._check_error("if 0: yield\nelse: x=1", "outside function") @@ -1970,22 +2380,28 @@ def test_return_outside_function(self): "outside function") def test_break_outside_loop(self): - self._check_error("if 0: break", "outside loop") - self._check_error("if 0: break\nelse: x=1", "outside loop") - self._check_error("if 1: pass\nelse: break", "outside loop") - self._check_error("class C:\n if 0: break", "outside loop") + msg = "outside loop" + self._check_error("break", msg, lineno=1) + self._check_error("if 0: break", msg, lineno=1) + self._check_error("if 0: break\nelse: x=1", msg, lineno=1) + self._check_error("if 1: pass\nelse: break", msg, lineno=2) + self._check_error("class C:\n if 0: break", msg, lineno=2) self._check_error("class C:\n if 1: pass\n else: break", - "outside loop") + msg, lineno=3) + self._check_error("with object() as obj:\n break", + msg, lineno=2) - # TODO: RUSTPYTHON - @unittest.expectedFailure + @unittest.expectedFailure # TODO: RUSTPYTHON def test_continue_outside_loop(self): - self._check_error("if 0: continue", "not properly in loop") - self._check_error("if 0: continue\nelse: x=1", "not properly in loop") - self._check_error("if 1: pass\nelse: continue", "not properly in loop") - self._check_error("class C:\n if 0: continue", "not properly in loop") + msg = "not properly in loop" + self._check_error("if 0: continue", msg, lineno=1) + self._check_error("if 0: continue\nelse: x=1", msg, lineno=1) + self._check_error("if 1: pass\nelse: continue", msg, lineno=2) + self._check_error("class C:\n if 0: continue", msg, lineno=2) self._check_error("class C:\n if 1: pass\n else: continue", - "not properly in loop") + msg, lineno=3) + self._check_error("with object() as obj:\n continue", + msg, lineno=2) def test_unexpected_indent(self): self._check_error("foo()\n bar()\n", "unexpected indent", @@ -2000,35 +2416,42 @@ def test_bad_outdent(self): "unindent does not match .* level", subclass=IndentationError) - # TODO: RUSTPYTHON - @unittest.expectedFailure + @unittest.expectedFailure # TODO: RUSTPYTHON def test_kwargs_last(self): self._check_error("int(base=10, '2')", "positional argument follows keyword argument") - # TODO: RUSTPYTHON - @unittest.expectedFailure + @unittest.expectedFailure # TODO: RUSTPYTHON def test_kwargs_last2(self): self._check_error("int(**{'base': 10}, '2')", "positional argument follows " "keyword argument unpacking") - # TODO: RUSTPYTHON - @unittest.expectedFailure + @unittest.expectedFailure # TODO: RUSTPYTHON def test_kwargs_last3(self): self._check_error("int(**{'base': 10}, *['2'])", "iterable argument unpacking follows " "keyword argument unpacking") - # TODO: RUSTPYTHON - @unittest.expectedFailure + @unittest.expectedFailure # TODO: RUSTPYTHON def test_generator_in_function_call(self): self._check_error("foo(x, y for y in range(3) for z in range(2) if z , p)", "Generator expression must be parenthesized", lineno=1, end_lineno=1, offset=11, end_offset=53) - # TODO: RUSTPYTHON - @unittest.expectedFailure + @unittest.expectedFailure # TODO: RUSTPYTHON + def test_except_then_except_star(self): + self._check_error("try: pass\nexcept ValueError: pass\nexcept* TypeError: pass", + r"cannot have both 'except' and 'except\*' on the same 'try'", + lineno=3, end_lineno=3, offset=1, end_offset=8) + + @unittest.expectedFailure # TODO: RUSTPYTHON + def test_except_star_then_except(self): + self._check_error("try: pass\nexcept* ValueError: pass\nexcept TypeError: pass", + r"cannot have both 'except' and 'except\*' on the same 'try'", + lineno=3, end_lineno=3, offset=1, end_offset=7) + + @unittest.expectedFailure # TODO: RUSTPYTHON def test_empty_line_after_linecont(self): # See issue-40847 s = r"""\ @@ -2073,6 +2496,25 @@ def test_continuation_bad_indentation(self): self.assertRaises(IndentationError, exec, code) + @support.cpython_only + def test_disallowed_type_param_names(self): + # See gh-128632 + + self._check_error(f"class A[__classdict__]: pass", + f"reserved name '__classdict__' cannot be used for type parameter") + self._check_error(f"def f[__classdict__](): pass", + f"reserved name '__classdict__' cannot be used for type parameter") + self._check_error(f"type T[__classdict__] = tuple[__classdict__]", + f"reserved name '__classdict__' cannot be used for type parameter") + + # These compilations are here to make sure __class__, __classcell__ and __classdictcell__ + # don't break in the future like __classdict__ did in this case. + for name in ('__class__', '__classcell__', '__classdictcell__'): + compile(f""" +class A: + class B[{name}]: pass + """, "", mode="exec") + @support.cpython_only def test_nested_named_except_blocks(self): code = "" @@ -2083,6 +2525,58 @@ def test_nested_named_except_blocks(self): code += f"{' '*4*12}pass" self._check_error(code, "too many statically nested blocks") + @support.cpython_only + def test_with_statement_many_context_managers(self): + # See gh-113297 + + def get_code(n): + code = textwrap.dedent(""" + def bug(): + with ( + a + """) + for i in range(n): + code += f" as a{i}, a\n" + code += "): yield a" + return code + + CO_MAXBLOCKS = 21 # static nesting limit of the compiler + MAX_MANAGERS = CO_MAXBLOCKS - 1 # One for the StopIteration block + + for n in range(MAX_MANAGERS): + with self.subTest(f"within range: {n=}"): + compile(get_code(n), "", "exec") + + for n in range(MAX_MANAGERS, MAX_MANAGERS + 5): + with self.subTest(f"out of range: {n=}"): + self._check_error(get_code(n), "too many statically nested blocks") + + @support.cpython_only + def test_async_with_statement_many_context_managers(self): + # See gh-116767 + + def get_code(n): + code = [ textwrap.dedent(""" + async def bug(): + async with ( + a + """) ] + for i in range(n): + code.append(f" as a{i}, a\n") + code.append("): yield a") + return "".join(code) + + CO_MAXBLOCKS = 21 # static nesting limit of the compiler + MAX_MANAGERS = CO_MAXBLOCKS - 1 # One for the StopIteration block + + for n in range(MAX_MANAGERS): + with self.subTest(f"within range: {n=}"): + compile(get_code(n), "", "exec") + + for n in range(MAX_MANAGERS, MAX_MANAGERS + 5): + with self.subTest(f"out of range: {n=}"): + self._check_error(get_code(n), "too many statically nested blocks") + def test_barry_as_flufl_with_syntax_errors(self): # The "barry_as_flufl" rule can produce some "bugs-at-a-distance" if # is reading the wrong token in the presence of syntax errors later @@ -2100,8 +2594,7 @@ def func2(): """ self._check_error(code, "expected ':'") - # TODO: RUSTPYTHON - @unittest.expectedFailure + @unittest.expectedFailure # TODO: RUSTPYTHON def test_invalid_line_continuation_error_position(self): self._check_error(r"a = 3 \ 4", "unexpected character after line continuation character", @@ -2113,8 +2606,7 @@ def test_invalid_line_continuation_error_position(self): "unexpected character after line continuation character", lineno=3, offset=4) - # TODO: RUSTPYTHON - @unittest.expectedFailure + @unittest.expectedFailure # TODO: RUSTPYTHON def test_invalid_line_continuation_left_recursive(self): # Check bpo-42218: SyntaxErrors following left-recursive rules # (t_primary_raw in this case) need to be tested explicitly @@ -2123,8 +2615,7 @@ def test_invalid_line_continuation_left_recursive(self): self._check_error("A.\u03bc\\\n", "unexpected EOF while parsing") - # TODO: RUSTPYTHON - @unittest.expectedFailure + @unittest.expectedFailure # TODO: RUSTPYTHON def test_error_parenthesis(self): for paren in "([{": self._check_error(paren + "1 + 2", f"\\{paren}' was never closed") @@ -2135,10 +2626,39 @@ def test_error_parenthesis(self): for paren in ")]}": self._check_error(paren + "1 + 2", f"unmatched '\\{paren}'") - # TODO: RUSTPYTHON - @unittest.expectedFailure + # Some more complex examples: + code = """\ +func( + a=["unclosed], # Need a quote in this comment: " + b=2, +) +""" + self._check_error(code, "parenthesis '\\)' does not match opening parenthesis '\\['") + + self._check_error("match y:\n case e(e=v,v,", " was never closed") + + # Examples with dencodings + s = b'# coding=latin\n(aaaaaaaaaaaaaaaaa\naaaaaaaaaaa\xb5' + self._check_error(s, r"'\(' was never closed") + + @unittest.expectedFailure # TODO: RUSTPYTHON + def test_error_string_literal(self): + + self._check_error("'blech", r"unterminated string literal \(.*\)$") + self._check_error('"blech', r"unterminated string literal \(.*\)$") + self._check_error( + r'"blech\"', r"unterminated string literal \(.*\); perhaps you escaped the end quote" + ) + self._check_error( + r'r"blech\"', r"unterminated string literal \(.*\); perhaps you escaped the end quote" + ) + self._check_error("'''blech", "unterminated triple-quoted string literal") + self._check_error('"""blech', "unterminated triple-quoted string literal") + + @unittest.expectedFailure # TODO: RUSTPYTHON def test_invisible_characters(self): self._check_error('print\x17("Hello")', "invalid non-printable character") + self._check_error(b"with(0,,):\n\x01", "invalid non-printable character") def test_match_call_does_not_raise_syntax_error(self): code = """ @@ -2158,8 +2678,7 @@ def case(x): """ compile(code, "", "exec") - # TODO: RUSTPYTHON - @unittest.expectedFailure + @unittest.expectedFailure # TODO: RUSTPYTHON def test_multiline_compiler_error_points_to_the_end(self): self._check_error( "call(\na=1,\na=1\n)", @@ -2198,7 +2717,8 @@ def test_syntax_error_on_deeply_nested_blocks(self): while 20: while 21: while 22: - break + while 23: + break """ self._check_error(source, "too many statically nested blocks") @@ -2207,7 +2727,7 @@ def test_error_on_parser_stack_overflow(self): source = "-" * 100000 + "4" for mode in ["exec", "eval", "single"]: with self.subTest(mode=mode): - with self.assertRaises(MemoryError): + with self.assertRaisesRegex(MemoryError, r"too complex"): compile(source, "", mode) @support.cpython_only diff --git a/compiler/codegen/src/compile.rs b/compiler/codegen/src/compile.rs index c509052a56..5f8caebf27 100644 --- a/compiler/codegen/src/compile.rs +++ b/compiler/codegen/src/compile.rs @@ -24,23 +24,23 @@ use ruff_python_ast::{ Alias, Arguments, BoolOp, CmpOp, Comprehension, ConversionFlag, DebugText, Decorator, DictItem, ExceptHandler, ExceptHandlerExceptHandler, Expr, ExprAttribute, ExprBoolOp, ExprContext, ExprFString, ExprList, ExprName, ExprSlice, ExprStarred, ExprSubscript, ExprTuple, ExprUnaryOp, - FString, FStringElement, FStringElements, FStringFlags, FStringPart, Identifier, Int, Keyword, - MatchCase, ModExpression, ModModule, Operator, Parameters, Pattern, PatternMatchAs, - PatternMatchClass, PatternMatchMapping, PatternMatchOr, PatternMatchSequence, - PatternMatchSingleton, PatternMatchStar, PatternMatchValue, Singleton, Stmt, StmtExpr, - TypeParam, TypeParamParamSpec, TypeParamTypeVar, TypeParamTypeVarTuple, TypeParams, UnaryOp, - WithItem, + FString, FStringFlags, FStringPart, Identifier, Int, InterpolatedElement, + InterpolatedStringElement, InterpolatedStringElements, Keyword, MatchCase, ModExpression, + ModModule, Operator, Parameters, Pattern, PatternMatchAs, PatternMatchClass, + PatternMatchMapping, PatternMatchOr, PatternMatchSequence, PatternMatchSingleton, + PatternMatchStar, PatternMatchValue, Singleton, Stmt, StmtExpr, TypeParam, TypeParamParamSpec, + TypeParamTypeVar, TypeParamTypeVarTuple, TypeParams, UnaryOp, WithItem, }; use ruff_text_size::{Ranged, TextRange}; use rustpython_compiler_core::{ - Mode, OneIndexed, SourceFile, SourceLocation, + Mode, OneIndexed, PositionEncoding, SourceFile, SourceLocation, bytecode::{ self, Arg as OpArgMarker, BinaryOperator, CodeObject, ComparisonOperator, ConstantData, Instruction, OpArg, OpArgType, UnpackExArgs, }, }; use rustpython_wtf8::Wtf8Buf; -use std::borrow::Cow; +use std::{borrow::Cow, collections::HashSet}; const MAXBLOCKS: usize = 20; @@ -147,6 +147,20 @@ enum ComprehensionType { Dict, } +fn validate_duplicate_params(params: &Parameters) -> Result<(), CodegenErrorType> { + let mut seen_params = HashSet::new(); + for param in params { + let param_name = param.name().as_str(); + if !seen_params.insert(param_name) { + return Err(CodegenErrorType::SyntaxError(format!( + r#"Duplicate parameter "{param_name}""# + ))); + } + } + + Ok(()) +} + /// Compile an Mod produced from ruff parser pub fn compile_top( ast: ruff_python_ast::Mod, @@ -240,18 +254,18 @@ fn eprint_location(zelf: &Compiler) { let start = zelf .source_file .to_source_code() - .source_location(zelf.current_source_range.start()); + .source_location(zelf.current_source_range.start(), PositionEncoding::Utf8); let end = zelf .source_file .to_source_code() - .source_location(zelf.current_source_range.end()); + .source_location(zelf.current_source_range.end(), PositionEncoding::Utf8); eprintln!( "LOCATION: {} from {}:{} to {}:{}", zelf.source_file.name(), - start.row, - start.column, - end.row, - end.column + start.line, + start.character_offset, + end.line, + end.character_offset ); } @@ -531,7 +545,7 @@ impl Compiler { let location = self .source_file .to_source_code() - .source_location(range.start()); + .source_location(range.start(), PositionEncoding::Utf8); CodegenError { error, location: Some(location), @@ -631,8 +645,8 @@ impl Compiler { ) -> CompileResult<()> { // Create location let location = SourceLocation { - row: OneIndexed::new(lineno as usize).unwrap_or(OneIndexed::MIN), - column: OneIndexed::new(1).unwrap(), + line: OneIndexed::new(lineno as usize).unwrap_or(OneIndexed::MIN), + character_offset: OneIndexed::MIN, }; // Allocate a new compiler unit @@ -769,8 +783,8 @@ impl Compiler { let _resume_loc = if scope_type == CompilerScope::Module { // Module scope starts with lineno 0 SourceLocation { - row: OneIndexed::MIN, - column: OneIndexed::MIN, + line: OneIndexed::MIN, + character_offset: OneIndexed::MIN, } } else { location @@ -1500,15 +1514,19 @@ impl Compiler { type_params, is_async, .. - }) => self.compile_function_def( - name.as_str(), - parameters, - body, - decorator_list, - returns.as_deref(), - *is_async, - type_params.as_deref(), - )?, + }) => { + validate_duplicate_params(parameters).map_err(|e| self.error(e))?; + + self.compile_function_def( + name.as_str(), + parameters, + body, + decorator_list, + returns.as_deref(), + *is_async, + type_params.as_deref(), + )? + } Stmt::ClassDef(StmtClassDef { name, body, @@ -3579,7 +3597,7 @@ impl Compiler { // Step 2: If we have keys to match if size > 0 { // Validate and compile keys - let mut seen = std::collections::HashSet::new(); + let mut seen = HashSet::new(); for key in keys { let is_attribute = matches!(key, Expr::Attribute(_)); let is_literal = matches!( @@ -4656,10 +4674,12 @@ impl Compiler { Expr::Lambda(ExprLambda { parameters, body, .. }) => { - let prev_ctx = self.ctx; - let name = "".to_owned(); let default_params = Parameters::default(); let params = parameters.as_deref().unwrap_or(&default_params); + validate_duplicate_params(params).map_err(|e| self.error(e))?; + + let prev_ctx = self.ctx; + let name = "".to_owned(); // Prepare defaults before entering function let defaults: Vec<_> = std::iter::empty() @@ -4872,6 +4892,7 @@ impl Compiler { Expr::Named(ExprNamed { target, value, + node_index: _, range: _, }) => { self.compile_expression(value)?; @@ -4881,6 +4902,9 @@ impl Compiler { Expr::FString(fstring) => { self.compile_expr_fstring(fstring)?; } + Expr::TString(_) => { + return Err(self.error(CodegenErrorType::NotImplementedYet)); + } Expr::StringLiteral(string) => { let value = string.value.to_str(); if value.contains(char::REPLACEMENT_CHARACTER) { @@ -5334,7 +5358,7 @@ impl Compiler { let location = self .source_file .to_source_code() - .source_location(range.start()); + .source_location(range.start(), PositionEncoding::Utf8); // TODO: insert source filename self.current_block().instructions.push(ir::InstructionInfo { instr, @@ -5524,27 +5548,14 @@ impl Compiler { Expr::Named(ExprNamed { target, value, + node_index: _, range: _, }) => Self::contains_await(target) || Self::contains_await(value), - Expr::FString(ExprFString { value, range: _ }) => { - fn expr_element_contains_await bool>( - expr_element: &FStringExpressionElement, - contains_await: F, - ) -> bool { - contains_await(&expr_element.expression) - || expr_element - .format_spec - .iter() - .flat_map(|spec| spec.elements.expressions()) - .any(|element| expr_element_contains_await(element, contains_await)) - } - - value.elements().any(|element| match element { - FStringElement::Expression(expr_element) => { - expr_element_contains_await(expr_element, Self::contains_await) - } - FStringElement::Literal(_) => false, - }) + Expr::FString(fstring) => { + Self::interpolated_string_contains_await(fstring.value.elements()) + } + Expr::TString(tstring) => { + Self::interpolated_string_contains_await(tstring.value.elements()) } Expr::StringLiteral(_) | Expr::BytesLiteral(_) @@ -5556,6 +5567,29 @@ impl Compiler { } } + fn interpolated_string_contains_await<'a>( + mut elements: impl Iterator, + ) -> bool { + fn interpolated_element_contains_await bool>( + expr_element: &InterpolatedElement, + contains_await: F, + ) -> bool { + contains_await(&expr_element.expression) + || expr_element + .format_spec + .iter() + .flat_map(|spec| spec.elements.interpolations()) + .any(|element| interpolated_element_contains_await(element, contains_await)) + } + + elements.any(|element| match element { + InterpolatedStringElement::Interpolation(expr_element) => { + interpolated_element_contains_await(expr_element, Self::contains_await) + } + InterpolatedStringElement::Literal(_) => false, + }) + } + fn compile_expr_fstring(&mut self, fstring: &ExprFString) -> CompileResult<()> { let fstring = &fstring.value; for part in fstring { @@ -5602,13 +5636,13 @@ impl Compiler { fn compile_fstring_elements( &mut self, flags: FStringFlags, - fstring_elements: &FStringElements, + fstring_elements: &InterpolatedStringElements, ) -> CompileResult<()> { let mut element_count = 0; for element in fstring_elements { element_count += 1; match element { - FStringElement::Literal(string) => { + InterpolatedStringElement::Literal(string) => { if string.value.contains(char::REPLACEMENT_CHARACTER) { // might have a surrogate literal; should reparse to be sure let source = self.source_file.slice(string.range); @@ -5625,7 +5659,7 @@ impl Compiler { }); } } - FStringElement::Expression(fstring_expr) => { + InterpolatedStringElement::Interpolation(fstring_expr) => { let mut conversion = fstring_expr.conversion; if let Some(DebugText { leading, trailing }) = &fstring_expr.debug_text { @@ -5858,21 +5892,27 @@ mod ruff_tests { // f'{x}' let expr_x = Expr::Name(ExprName { + node_index: AtomicNodeIndex::NONE, range, id: Name::new("x"), ctx: ExprContext::Load, }); let not_present = &Expr::FString(ExprFString { + node_index: AtomicNodeIndex::NONE, range, value: FStringValue::single(FString { + node_index: AtomicNodeIndex::NONE, range, - elements: vec![FStringElement::Expression(FStringExpressionElement { - range, - expression: Box::new(expr_x), - debug_text: None, - conversion: ConversionFlag::None, - format_spec: None, - })] + elements: vec![InterpolatedStringElement::Interpolation( + InterpolatedElement { + node_index: AtomicNodeIndex::NONE, + range, + expression: Box::new(expr_x), + debug_text: None, + conversion: ConversionFlag::None, + format_spec: None, + }, + )] .into(), flags, }), @@ -5881,24 +5921,31 @@ mod ruff_tests { // f'{await x}' let expr_await_x = Expr::Await(ExprAwait { + node_index: AtomicNodeIndex::NONE, range, value: Box::new(Expr::Name(ExprName { + node_index: AtomicNodeIndex::NONE, range, id: Name::new("x"), ctx: ExprContext::Load, })), }); let present = &Expr::FString(ExprFString { + node_index: AtomicNodeIndex::NONE, range, value: FStringValue::single(FString { + node_index: AtomicNodeIndex::NONE, range, - elements: vec![FStringElement::Expression(FStringExpressionElement { - range, - expression: Box::new(expr_await_x), - debug_text: None, - conversion: ConversionFlag::None, - format_spec: None, - })] + elements: vec![InterpolatedStringElement::Interpolation( + InterpolatedElement { + node_index: AtomicNodeIndex::NONE, + range, + expression: Box::new(expr_await_x), + debug_text: None, + conversion: ConversionFlag::None, + format_spec: None, + }, + )] .into(), flags, }), @@ -5907,39 +5954,51 @@ mod ruff_tests { // f'{x:{await y}}' let expr_x = Expr::Name(ExprName { + node_index: AtomicNodeIndex::NONE, range, id: Name::new("x"), ctx: ExprContext::Load, }); let expr_await_y = Expr::Await(ExprAwait { + node_index: AtomicNodeIndex::NONE, range, value: Box::new(Expr::Name(ExprName { + node_index: AtomicNodeIndex::NONE, range, id: Name::new("y"), ctx: ExprContext::Load, })), }); let present = &Expr::FString(ExprFString { + node_index: AtomicNodeIndex::NONE, range, value: FStringValue::single(FString { + node_index: AtomicNodeIndex::NONE, range, - elements: vec![FStringElement::Expression(FStringExpressionElement { - range, - expression: Box::new(expr_x), - debug_text: None, - conversion: ConversionFlag::None, - format_spec: Some(Box::new(FStringFormatSpec { + elements: vec![InterpolatedStringElement::Interpolation( + InterpolatedElement { + node_index: AtomicNodeIndex::NONE, range, - elements: vec![FStringElement::Expression(FStringExpressionElement { + expression: Box::new(expr_x), + debug_text: None, + conversion: ConversionFlag::None, + format_spec: Some(Box::new(InterpolatedStringFormatSpec { + node_index: AtomicNodeIndex::NONE, range, - expression: Box::new(expr_await_y), - debug_text: None, - conversion: ConversionFlag::None, - format_spec: None, - })] - .into(), - })), - })] + elements: vec![InterpolatedStringElement::Interpolation( + InterpolatedElement { + node_index: AtomicNodeIndex::NONE, + range, + expression: Box::new(expr_await_y), + debug_text: None, + conversion: ConversionFlag::None, + format_spec: None, + }, + )] + .into(), + })), + }, + )] .into(), flags, }), diff --git a/compiler/codegen/src/ir.rs b/compiler/codegen/src/ir.rs index 31c8926091..7cd173c821 100644 --- a/compiler/codegen/src/ir.rs +++ b/compiler/codegen/src/ir.rs @@ -182,7 +182,7 @@ impl CodeInfo { *arg = new_arg; } let (extras, lo_arg) = arg.split(); - locations.extend(std::iter::repeat_n(info.location.clone(), arg.instr_size())); + locations.extend(std::iter::repeat_n(info.location, arg.instr_size())); instructions.extend( extras .map(|byte| CodeUnit::new(Instruction::ExtendedArg, byte)) @@ -422,8 +422,8 @@ fn generate_linetable(locations: &[SourceLocation], first_line: i32) -> Box<[u8] // Get line and column information // SourceLocation always has row and column (both are OneIndexed) - let line = loc.row.get() as i32; - let col = (loc.column.get() as i32) - 1; // Convert 1-based to 0-based + let line = loc.line.get() as i32; + let col = loc.character_offset.to_zero_indexed() as i32; let line_delta = line - prev_line; diff --git a/compiler/codegen/src/lib.rs b/compiler/codegen/src/lib.rs index 9b444de994..291b57d7f6 100644 --- a/compiler/codegen/src/lib.rs +++ b/compiler/codegen/src/lib.rs @@ -56,6 +56,7 @@ impl ToPythonName for Expr { Self::Starred { .. } => "starred", Self::Slice { .. } => "slice", Self::FString { .. } => "f-string expression", + Self::TString { .. } => "t-string expression", Self::Name { .. } => "name", Self::Lambda { .. } => "lambda", Self::If { .. } => "conditional expression", diff --git a/compiler/codegen/src/symboltable.rs b/compiler/codegen/src/symboltable.rs index 16e88ad690..0464e09c13 100644 --- a/compiler/codegen/src/symboltable.rs +++ b/compiler/codegen/src/symboltable.rs @@ -19,7 +19,7 @@ use ruff_python_ast::{ Stmt, TypeParam, TypeParamParamSpec, TypeParamTypeVar, TypeParamTypeVarTuple, TypeParams, }; use ruff_text_size::{Ranged, TextRange}; -use rustpython_compiler_core::{SourceFile, SourceLocation}; +use rustpython_compiler_core::{PositionEncoding, SourceFile, SourceLocation}; use std::{borrow::Cow, fmt}; /// Captures all symbols in the current scope, and has a list of sub-scopes in this scope. @@ -793,6 +793,7 @@ impl SymbolTableBuilder { decorator_list, type_params, range, + node_index: _, }) => { if let Some(type_params) = type_params { self.enter_type_param_block( @@ -910,6 +911,7 @@ impl SymbolTableBuilder { value, simple, range, + node_index: _, }) => { // https://github.com/python/cpython/blob/main/Python/symtable.c#L1233 match &**target { @@ -1046,7 +1048,7 @@ impl SymbolTableBuilder { location: Some( self.source_file .to_source_code() - .source_location(expression.range().start()), + .source_location(expression.range().start(), PositionEncoding::Utf8), ), }); } @@ -1089,7 +1091,11 @@ impl SymbolTableBuilder { }) => { self.scan_expression(value, ExpressionContext::Load)?; } - Expr::Dict(ExprDict { items, range: _ }) => { + Expr::Dict(ExprDict { + items, + node_index: _, + range: _, + }) => { for item in items { if let Some(key) = &item.key { self.scan_expression(key, context)?; @@ -1097,15 +1103,27 @@ impl SymbolTableBuilder { self.scan_expression(&item.value, context)?; } } - Expr::Await(ExprAwait { value, range: _ }) => { + Expr::Await(ExprAwait { + value, + node_index: _, + range: _, + }) => { self.scan_expression(value, context)?; } - Expr::Yield(ExprYield { value, range: _ }) => { + Expr::Yield(ExprYield { + value, + node_index: _, + range: _, + }) => { if let Some(expression) = value { self.scan_expression(expression, context)?; } } - Expr::YieldFrom(ExprYieldFrom { value, range: _ }) => { + Expr::YieldFrom(ExprYieldFrom { + value, + node_index: _, + range: _, + }) => { self.scan_expression(value, context)?; } Expr::UnaryOp(ExprUnaryOp { @@ -1127,6 +1145,7 @@ impl SymbolTableBuilder { lower, upper, step, + node_index: _, range: _, }) => { if let Some(lower) = lower { @@ -1151,6 +1170,7 @@ impl SymbolTableBuilder { elt, generators, range, + node_index: _, }) => { self.scan_comprehension("genexpr", elt, None, generators, *range)?; } @@ -1158,6 +1178,7 @@ impl SymbolTableBuilder { elt, generators, range, + node_index: _, }) => { self.scan_comprehension("genexpr", elt, None, generators, *range)?; } @@ -1166,12 +1187,14 @@ impl SymbolTableBuilder { value, generators, range, + node_index: _, }) => { self.scan_comprehension("genexpr", key, Some(value), generators, *range)?; } Expr::Call(ExprCall { func, arguments, + node_index: _, range: _, }) => { match context { @@ -1218,6 +1241,7 @@ impl SymbolTableBuilder { Expr::Lambda(ExprLambda { body, parameters, + node_index: _, range: _, }) => { if let Some(parameters) = parameters { @@ -1244,15 +1268,25 @@ impl SymbolTableBuilder { self.leave_scope(); } Expr::FString(ExprFString { value, .. }) => { - for expr in value.elements().filter_map(|x| x.as_expression()) { + for expr in value.elements().filter_map(|x| x.as_interpolation()) { self.scan_expression(&expr.expression, ExpressionContext::Load)?; if let Some(format_spec) = &expr.format_spec { - for element in format_spec.elements.expressions() { + for element in format_spec.elements.interpolations() { self.scan_expression(&element.expression, ExpressionContext::Load)? } } } } + Expr::TString(tstring) => { + return Err(SymbolTableError { + error: "not yet implemented".into(), + location: Some( + self.source_file + .to_source_code() + .source_location(tstring.range.start(), PositionEncoding::Utf8), + ), + }); + } // Constants Expr::StringLiteral(_) | Expr::BytesLiteral(_) @@ -1265,6 +1299,7 @@ impl SymbolTableBuilder { test, body, orelse, + node_index: _, range: _, }) => { self.scan_expression(test, ExpressionContext::Load)?; @@ -1276,13 +1311,14 @@ impl SymbolTableBuilder { target, value, range, + node_index: _, }) => { // named expressions are not allowed in the definition of // comprehension iterator definitions if let ExpressionContext::IterDefinitionExp = context { return Err(SymbolTableError { error: "assignment expression cannot be used in a comprehension iterable expression".to_string(), - location: Some(self.source_file.to_source_code().source_location(target.range().start())), + location: Some(self.source_file.to_source_code().source_location(target.range().start(), PositionEncoding::Utf8)), }); } @@ -1393,6 +1429,7 @@ impl SymbolTableBuilder { bound, range: type_var_range, default, + node_index: _, }) => { self.register_name(name.as_str(), SymbolUsage::TypeParam, *type_var_range)?; @@ -1416,6 +1453,7 @@ impl SymbolTableBuilder { name, range: param_spec_range, default, + node_index: _, }) => { self.register_name(name, SymbolUsage::TypeParam, *param_spec_range)?; @@ -1429,6 +1467,7 @@ impl SymbolTableBuilder { name, range: type_var_tuple_range, default, + node_index: _, }) => { self.register_name(name, SymbolUsage::TypeParam, *type_var_tuple_range)?; @@ -1565,7 +1604,7 @@ impl SymbolTableBuilder { let location = self .source_file .to_source_code() - .source_location(range.start()); + .source_location(range.start(), PositionEncoding::Utf8); let location = Some(location); let scope_depth = self.tables.len(); let table = self.tables.last_mut().unwrap(); diff --git a/compiler/codegen/src/unparse.rs b/compiler/codegen/src/unparse.rs index f2fb86ed4e..7f2bcf16b4 100644 --- a/compiler/codegen/src/unparse.rs +++ b/compiler/codegen/src/unparse.rs @@ -85,6 +85,7 @@ impl<'a, 'b, 'c> Unparser<'a, 'b, 'c> { Expr::BoolOp(ruff::ExprBoolOp { op, values, + node_index: _, range: _range, }) => { let (op, prec) = op_prec!(bin, op, BoolOp, And("and", AND), Or("or", OR)); @@ -99,6 +100,7 @@ impl<'a, 'b, 'c> Unparser<'a, 'b, 'c> { Expr::Named(ruff::ExprNamed { target, value, + node_index: _, range: _range, }) => { group_if!(precedence::TUPLE, { @@ -111,6 +113,7 @@ impl<'a, 'b, 'c> Unparser<'a, 'b, 'c> { left, op, right, + node_index: _, range: _range, }) => { let right_associative = matches!(op, Operator::Pow); @@ -141,6 +144,7 @@ impl<'a, 'b, 'c> Unparser<'a, 'b, 'c> { Expr::UnaryOp(ruff::ExprUnaryOp { op, operand, + node_index: _, range: _range, }) => { let (op, prec) = op_prec!( @@ -160,6 +164,7 @@ impl<'a, 'b, 'c> Unparser<'a, 'b, 'c> { Expr::Lambda(ruff::ExprLambda { parameters, body, + node_index: _, range: _range, }) => { group_if!(precedence::TEST, { @@ -176,6 +181,7 @@ impl<'a, 'b, 'c> Unparser<'a, 'b, 'c> { test, body, orelse, + node_index: _, range: _range, }) => { group_if!(precedence::TEST, { @@ -188,6 +194,7 @@ impl<'a, 'b, 'c> Unparser<'a, 'b, 'c> { } Expr::Dict(ruff::ExprDict { items, + node_index: _, range: _range, }) => { self.p("{")?; @@ -205,6 +212,7 @@ impl<'a, 'b, 'c> Unparser<'a, 'b, 'c> { } Expr::Set(ruff::ExprSet { elts, + node_index: _, range: _range, }) => { self.p("{")?; @@ -218,6 +226,7 @@ impl<'a, 'b, 'c> Unparser<'a, 'b, 'c> { Expr::ListComp(ruff::ExprListComp { elt, generators, + node_index: _, range: _range, }) => { self.p("[")?; @@ -228,6 +237,7 @@ impl<'a, 'b, 'c> Unparser<'a, 'b, 'c> { Expr::SetComp(ruff::ExprSetComp { elt, generators, + node_index: _, range: _range, }) => { self.p("{")?; @@ -239,6 +249,7 @@ impl<'a, 'b, 'c> Unparser<'a, 'b, 'c> { key, value, generators, + node_index: _, range: _range, }) => { self.p("{")?; @@ -252,6 +263,7 @@ impl<'a, 'b, 'c> Unparser<'a, 'b, 'c> { parenthesized: _, elt, generators, + node_index: _, range: _range, }) => { self.p("(")?; @@ -261,6 +273,7 @@ impl<'a, 'b, 'c> Unparser<'a, 'b, 'c> { } Expr::Await(ruff::ExprAwait { value, + node_index: _, range: _range, }) => { group_if!(precedence::AWAIT, { @@ -270,6 +283,7 @@ impl<'a, 'b, 'c> Unparser<'a, 'b, 'c> { } Expr::Yield(ruff::ExprYield { value, + node_index: _, range: _range, }) => { if let Some(value) = value { @@ -280,6 +294,7 @@ impl<'a, 'b, 'c> Unparser<'a, 'b, 'c> { } Expr::YieldFrom(ruff::ExprYieldFrom { value, + node_index: _, range: _range, }) => { write!( @@ -292,6 +307,7 @@ impl<'a, 'b, 'c> Unparser<'a, 'b, 'c> { left, ops, comparators, + node_index: _, range: _range, }) => { group_if!(precedence::CMP, { @@ -308,6 +324,7 @@ impl<'a, 'b, 'c> Unparser<'a, 'b, 'c> { Expr::Call(ruff::ExprCall { func, arguments: Arguments { args, keywords, .. }, + node_index: _, range: _range, }) => { self.unparse_expr(func, precedence::ATOM)?; @@ -317,6 +334,7 @@ impl<'a, 'b, 'c> Unparser<'a, 'b, 'c> { Expr::Generator(ruff::ExprGenerator { elt, generators, + node_index: _, range: _range, .. }), @@ -347,6 +365,7 @@ impl<'a, 'b, 'c> Unparser<'a, 'b, 'c> { self.p(")")?; } Expr::FString(ruff::ExprFString { value, .. }) => self.unparse_fstring(value)?, + Expr::TString(_) => self.p("t\"\"")?, Expr::StringLiteral(ruff::ExprStringLiteral { value, .. }) => { if value.is_unicode() { self.p("u")? @@ -435,6 +454,7 @@ impl<'a, 'b, 'c> Unparser<'a, 'b, 'c> { lower, upper, step, + node_index: _, range: _range, }) => { if let Some(lower) = lower { @@ -513,7 +533,10 @@ impl<'a, 'b, 'c> Unparser<'a, 'b, 'c> { Ok(()) } - fn unparse_fstring_body(&mut self, elements: &[ruff::FStringElement]) -> fmt::Result { + fn unparse_fstring_body( + &mut self, + elements: &[ruff::InterpolatedStringElement], + ) -> fmt::Result { for elem in elements { self.unparse_fstring_elem(elem)?; } @@ -525,7 +548,7 @@ impl<'a, 'b, 'c> Unparser<'a, 'b, 'c> { val: &Expr, debug_text: Option<&ruff::DebugText>, conversion: ConversionFlag, - spec: Option<&ruff::FStringFormatSpec>, + spec: Option<&ruff::InterpolatedStringFormatSpec>, ) -> fmt::Result { let buffered = to_string_fmt(|f| { Unparser::new(f, self.source).unparse_expr(val, precedence::TEST + 1) @@ -562,9 +585,9 @@ impl<'a, 'b, 'c> Unparser<'a, 'b, 'c> { Ok(()) } - fn unparse_fstring_elem(&mut self, elem: &ruff::FStringElement) -> fmt::Result { + fn unparse_fstring_elem(&mut self, elem: &ruff::InterpolatedStringElement) -> fmt::Result { match elem { - ruff::FStringElement::Expression(ruff::FStringExpressionElement { + ruff::InterpolatedStringElement::Interpolation(ruff::InterpolatedElement { expression, debug_text, conversion, @@ -576,9 +599,10 @@ impl<'a, 'b, 'c> Unparser<'a, 'b, 'c> { *conversion, format_spec.as_deref(), ), - ruff::FStringElement::Literal(ruff::FStringLiteralElement { value, .. }) => { - self.unparse_fstring_str(value) - } + ruff::InterpolatedStringElement::Literal(ruff::InterpolatedStringLiteralElement { + value, + .. + }) => self.unparse_fstring_str(value), } } diff --git a/compiler/core/src/bytecode.rs b/compiler/core/src/bytecode.rs index 1088dd9848..4ab666da99 100644 --- a/compiler/core/src/bytecode.rs +++ b/compiler/core/src/bytecode.rs @@ -1196,14 +1196,14 @@ impl CodeObject { level: usize, ) -> fmt::Result { let label_targets = self.label_targets(); - let line_digits = (3).max(self.locations.last().unwrap().row.to_string().len()); - let offset_digits = (4).max(self.instructions.len().to_string().len()); + let line_digits = (3).max(self.locations.last().unwrap().line.digits().get()); + let offset_digits = (4).max(1 + self.instructions.len().ilog10() as usize); let mut last_line = OneIndexed::MAX; let mut arg_state = OpArgState::default(); for (offset, &instruction) in self.instructions.iter().enumerate() { let (instruction, arg) = arg_state.get(instruction); // optional line number - let line = self.locations[offset].row; + let line = self.locations[offset].line; if line != last_line { if last_line != OneIndexed::MAX { writeln!(f)?; diff --git a/compiler/core/src/lib.rs b/compiler/core/src/lib.rs index 0ce4a9defb..08cdc0ec21 100644 --- a/compiler/core/src/lib.rs +++ b/compiler/core/src/lib.rs @@ -8,4 +8,6 @@ mod mode; pub use mode::Mode; -pub use ruff_source_file::{LineIndex, OneIndexed, SourceFile, SourceFileBuilder, SourceLocation}; +pub use ruff_source_file::{ + LineIndex, OneIndexed, PositionEncoding, SourceFile, SourceFileBuilder, SourceLocation, +}; diff --git a/compiler/core/src/marshal.rs b/compiler/core/src/marshal.rs index b8044a1ab9..5e16e59102 100644 --- a/compiler/core/src/marshal.rs +++ b/compiler/core/src/marshal.rs @@ -198,8 +198,8 @@ pub fn deserialize_code( let locations = (0..len) .map(|_| { Ok(SourceLocation { - row: OneIndexed::new(rdr.read_u32()? as _).ok_or(MarshalError::InvalidLocation)?, - column: OneIndexed::from_zero_indexed(rdr.read_u32()? as _), + line: OneIndexed::new(rdr.read_u32()? as _).ok_or(MarshalError::InvalidLocation)?, + character_offset: OneIndexed::from_zero_indexed(rdr.read_u32()? as _), }) }) .collect::>>()?; @@ -656,8 +656,8 @@ pub fn serialize_code(buf: &mut W, code: &CodeObject) write_len(buf, code.locations.len()); for loc in &*code.locations { - buf.write_u32(loc.row.get() as _); - buf.write_u32(loc.column.to_zero_indexed() as _); + buf.write_u32(loc.line.get() as _); + buf.write_u32(loc.character_offset.to_zero_indexed() as _); } buf.write_u16(code.flags.bits()); diff --git a/compiler/src/lib.rs b/compiler/src/lib.rs index 111b9aec2e..84e64f3c27 100644 --- a/compiler/src/lib.rs +++ b/compiler/src/lib.rs @@ -1,4 +1,4 @@ -use ruff_source_file::{SourceFile, SourceFileBuilder, SourceLocation}; +use ruff_source_file::{PositionEncoding, SourceFile, SourceFileBuilder, SourceLocation}; use rustpython_codegen::{compile, symboltable}; pub use rustpython_codegen::compile::CompileOpts; @@ -46,7 +46,7 @@ impl CompileError { pub fn from_ruff_parse_error(error: parser::ParseError, source_file: &SourceFile) -> Self { let location = source_file .to_source_code() - .source_location(error.location.start()); + .source_location(error.location.start(), PositionEncoding::Utf8); Self::Parse(ParseError { error: error.error, raw_location: error.location, @@ -55,26 +55,18 @@ impl CompileError { }) } - pub fn location(&self) -> Option { + pub const fn location(&self) -> Option { match self { - Self::Codegen(codegen_error) => codegen_error.location.clone(), - Self::Parse(parse_error) => Some(parse_error.location.clone()), + Self::Codegen(codegen_error) => codegen_error.location, + Self::Parse(parse_error) => Some(parse_error.location), } } pub const fn python_location(&self) -> (usize, usize) { - match self { - Self::Codegen(codegen_error) => { - if let Some(location) = &codegen_error.location { - (location.row.get(), location.column.get()) - } else { - (0, 0) - } - } - Self::Parse(parse_error) => ( - parse_error.location.row.get(), - parse_error.location.column.get(), - ), + if let Some(location) = self.location() { + (location.line.get(), location.character_offset.get()) + } else { + (0, 0) } } diff --git a/src/shell.rs b/src/shell.rs index c0ae508b01..d2e54c490a 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -1,7 +1,7 @@ mod helper; use rustpython_compiler::{ - CompileError, ParseError, parser::FStringErrorType, parser::LexicalErrorType, + CompileError, ParseError, parser::InterpolatedStringErrorType, parser::LexicalErrorType, parser::ParseErrorType, }; use rustpython_vm::{ @@ -52,7 +52,7 @@ fn shell_exec( Err(CompileError::Parse(ParseError { error: ParseErrorType::Lexical(LexicalErrorType::FStringError( - FStringErrorType::UnterminatedTripleQuotedString, + InterpolatedStringErrorType::UnterminatedTripleQuotedString, )), .. })) => ShellExecResult::ContinueLine, diff --git a/stdlib/src/faulthandler.rs b/stdlib/src/faulthandler.rs index f358129c87..5c9196ad33 100644 --- a/stdlib/src/faulthandler.rs +++ b/stdlib/src/faulthandler.rs @@ -10,7 +10,7 @@ mod decl { stderr, " File \"{}\", line {} in {}", frame.code.source_path, - frame.current_location().row, + frame.current_location().line, frame.code.obj_name ) } diff --git a/vm/src/builtins/frame.rs b/vm/src/builtins/frame.rs index 65ac3e798d..17dc88ac04 100644 --- a/vm/src/builtins/frame.rs +++ b/vm/src/builtins/frame.rs @@ -60,7 +60,7 @@ impl Frame { #[pygetset] pub fn f_lineno(&self) -> usize { - self.current_location().row.get() + self.current_location().line.get() } #[pygetset] diff --git a/vm/src/frame.rs b/vm/src/frame.rs index ba9abffc6e..fa5860244f 100644 --- a/vm/src/frame.rs +++ b/vm/src/frame.rs @@ -171,7 +171,7 @@ impl Frame { } pub fn current_location(&self) -> SourceLocation { - self.code.locations[self.lasti() as usize - 1].clone() + self.code.locations[self.lasti() as usize - 1] } pub fn lasti(&self) -> u32 { @@ -388,11 +388,15 @@ impl ExecutingFrame<'_> { // 2. Add new entry with current execution position (filename, lineno, code_object) to traceback. // 3. Unwind block stack till appropriate handler is found. - let loc = frame.code.locations[idx].clone(); + let loc = frame.code.locations[idx]; let next = exception.__traceback__(); - let new_traceback = - PyTraceback::new(next, frame.object.to_owned(), frame.lasti(), loc.row); - vm_trace!("Adding to traceback: {:?} {:?}", new_traceback, loc.row); + let new_traceback = PyTraceback::new( + next, + frame.object.to_owned(), + frame.lasti(), + loc.line, + ); + vm_trace!("Adding to traceback: {:?} {:?}", new_traceback, loc.line); exception.set_traceback_typed(Some(new_traceback.into_ref(&vm.ctx))); vm.contextualize_exception(&exception); diff --git a/vm/src/stdlib/ast.rs b/vm/src/stdlib/ast.rs index 1533f903c5..00aad0213f 100644 --- a/vm/src/stdlib/ast.rs +++ b/vm/src/stdlib/ast.rs @@ -23,7 +23,7 @@ use node::Node; use ruff_python_ast as ruff; use ruff_text_size::{Ranged, TextRange, TextSize}; use rustpython_compiler_core::{ - LineIndex, OneIndexed, SourceFile, SourceFileBuilder, SourceLocation, + LineIndex, OneIndexed, PositionEncoding, SourceFile, SourceFileBuilder, SourceLocation, }; #[cfg(feature = "parser")] @@ -92,8 +92,8 @@ pub struct PySourceLocation { impl PySourceLocation { const fn to_source_location(&self) -> SourceLocation { SourceLocation { - row: self.row.get_one_indexed(), - column: self.column.get_one_indexed(), + line: self.row.get_one_indexed(), + character_offset: self.column.get_one_indexed(), } } } @@ -194,14 +194,14 @@ fn source_range_to_text_range(source_file: &SourceFile, location: PySourceRange) } let start = index.offset( - location.start.row.get_one_indexed(), - location.start.column.get_one_indexed(), + location.start.to_source_location(), source, + PositionEncoding::Utf8, ); let end = index.offset( - location.end.row.get_one_indexed(), - location.end.column.get_one_indexed(), + location.end.to_source_location(), source, + PositionEncoding::Utf8, ); TextRange::new(start, end) @@ -273,9 +273,11 @@ pub(crate) fn compile( let ast: Mod = Node::ast_from_object(vm, &source_file, object)?; let ast = match ast { Mod::Module(m) => ruff::Mod::Module(m), - Mod::Interactive(ModInteractive { range, body }) => { - ruff::Mod::Module(ruff::ModModule { range, body }) - } + Mod::Interactive(ModInteractive { range, body }) => ruff::Mod::Module(ruff::ModModule { + node_index: Default::default(), + range, + body, + }), Mod::Expression(e) => ruff::Mod::Expression(e), Mod::FunctionType(_) => todo!(), }; diff --git a/vm/src/stdlib/ast/argument.rs b/vm/src/stdlib/ast/argument.rs index a1207f2c05..a13200e650 100644 --- a/vm/src/stdlib/ast/argument.rs +++ b/vm/src/stdlib/ast/argument.rs @@ -57,6 +57,7 @@ pub(super) fn merge_function_call_arguments( let range = pos_args.range.cover(key_args.range); ruff::Arguments { + node_index: Default::default(), range, args: pos_args.args, keywords: key_args.keywords, @@ -67,6 +68,7 @@ pub(super) fn split_function_call_arguments( args: ruff::Arguments, ) -> (PositionalArguments, KeywordArguments) { let ruff::Arguments { + node_index: _, range: _, args, keywords, @@ -105,6 +107,7 @@ pub(super) fn split_class_def_args( Some(args) => *args, }; let ruff::Arguments { + node_index: _, range: _, args, keywords, @@ -155,6 +158,7 @@ pub(super) fn merge_class_def_args( }; Some(Box::new(ruff::Arguments { + node_index: Default::default(), range: Default::default(), // TODO args, keywords, diff --git a/vm/src/stdlib/ast/constant.rs b/vm/src/stdlib/ast/constant.rs index b6c3e9596b..83b2a7f701 100644 --- a/vm/src/stdlib/ast/constant.rs +++ b/vm/src/stdlib/ast/constant.rs @@ -247,14 +247,21 @@ impl Node for ConstantLiteral { fn constant_to_ruff_expr(value: Constant) -> ruff::Expr { let Constant { value, range } = value; match value { - ConstantLiteral::None => ruff::Expr::NoneLiteral(ruff::ExprNoneLiteral { range }), - ConstantLiteral::Bool(value) => { - ruff::Expr::BooleanLiteral(ruff::ExprBooleanLiteral { range, value }) - } + ConstantLiteral::None => ruff::Expr::NoneLiteral(ruff::ExprNoneLiteral { + node_index: Default::default(), + range, + }), + ConstantLiteral::Bool(value) => ruff::Expr::BooleanLiteral(ruff::ExprBooleanLiteral { + node_index: Default::default(), + range, + value, + }), ConstantLiteral::Str { value, prefix } => { ruff::Expr::StringLiteral(ruff::ExprStringLiteral { + node_index: Default::default(), range, value: ruff::StringLiteralValue::single(ruff::StringLiteral { + node_index: Default::default(), range, value, flags: ruff::StringLiteralFlags::empty().with_prefix(prefix), @@ -263,8 +270,10 @@ fn constant_to_ruff_expr(value: Constant) -> ruff::Expr { } ConstantLiteral::Bytes(value) => { ruff::Expr::BytesLiteral(ruff::ExprBytesLiteral { + node_index: Default::default(), range, value: ruff::BytesLiteralValue::single(ruff::BytesLiteral { + node_index: Default::default(), range, value, flags: ruff::BytesLiteralFlags::empty(), // TODO @@ -272,10 +281,12 @@ fn constant_to_ruff_expr(value: Constant) -> ruff::Expr { }) } ConstantLiteral::Int(value) => ruff::Expr::NumberLiteral(ruff::ExprNumberLiteral { + node_index: Default::default(), range, value: ruff::Number::Int(value), }), ConstantLiteral::Tuple(value) => ruff::Expr::Tuple(ruff::ExprTuple { + node_index: Default::default(), range, elts: value .into_iter() @@ -291,14 +302,17 @@ fn constant_to_ruff_expr(value: Constant) -> ruff::Expr { parenthesized: true, }), ConstantLiteral::FrozenSet(value) => ruff::Expr::Call(ruff::ExprCall { + node_index: Default::default(), range, // idk lol func: Box::new(ruff::Expr::Name(ruff::ExprName { + node_index: Default::default(), range: TextRange::default(), id: ruff::name::Name::new_static("frozenset"), ctx: ruff::ExprContext::Load, })), arguments: ruff::Arguments { + node_index: Default::default(), range, args: value .into_iter() @@ -313,18 +327,21 @@ fn constant_to_ruff_expr(value: Constant) -> ruff::Expr { }, }), ConstantLiteral::Float(value) => ruff::Expr::NumberLiteral(ruff::ExprNumberLiteral { + node_index: Default::default(), range, value: ruff::Number::Float(value), }), ConstantLiteral::Complex { real, imag } => { ruff::Expr::NumberLiteral(ruff::ExprNumberLiteral { + node_index: Default::default(), range, value: ruff::Number::Complex { real, imag }, }) } - ConstantLiteral::Ellipsis => { - ruff::Expr::EllipsisLiteral(ruff::ExprEllipsisLiteral { range }) - } + ConstantLiteral::Ellipsis => ruff::Expr::EllipsisLiteral(ruff::ExprEllipsisLiteral { + node_index: Default::default(), + range, + }), } } @@ -333,7 +350,11 @@ pub(super) fn number_literal_to_object( source_file: &SourceFile, constant: ruff::ExprNumberLiteral, ) -> PyObjectRef { - let ruff::ExprNumberLiteral { range, value } = constant; + let ruff::ExprNumberLiteral { + node_index: _, + range, + value, + } = constant; let c = match value { ruff::Number::Int(n) => Constant::new_int(n, range), ruff::Number::Float(n) => Constant::new_float(n, range), @@ -347,7 +368,11 @@ pub(super) fn string_literal_to_object( source_file: &SourceFile, constant: ruff::ExprStringLiteral, ) -> PyObjectRef { - let ruff::ExprStringLiteral { range, value } = constant; + let ruff::ExprStringLiteral { + node_index: _, + range, + value, + } = constant; let prefix = value .iter() .next() @@ -361,7 +386,11 @@ pub(super) fn bytes_literal_to_object( source_file: &SourceFile, constant: ruff::ExprBytesLiteral, ) -> PyObjectRef { - let ruff::ExprBytesLiteral { range, value } = constant; + let ruff::ExprBytesLiteral { + node_index: _, + range, + value, + } = constant; let bytes = value.as_slice().iter().flat_map(|b| b.value.iter()); let c = Constant::new_bytes(bytes.copied().collect(), range); c.ast_to_object(vm, source_file) @@ -372,7 +401,11 @@ pub(super) fn boolean_literal_to_object( source_file: &SourceFile, constant: ruff::ExprBooleanLiteral, ) -> PyObjectRef { - let ruff::ExprBooleanLiteral { range, value } = constant; + let ruff::ExprBooleanLiteral { + node_index: _, + range, + value, + } = constant; let c = Constant::new_bool(value, range); c.ast_to_object(vm, source_file) } @@ -382,7 +415,10 @@ pub(super) fn none_literal_to_object( source_file: &SourceFile, constant: ruff::ExprNoneLiteral, ) -> PyObjectRef { - let ruff::ExprNoneLiteral { range } = constant; + let ruff::ExprNoneLiteral { + node_index: _, + range, + } = constant; let c = Constant::new_none(range); c.ast_to_object(vm, source_file) } @@ -392,7 +428,10 @@ pub(super) fn ellipsis_literal_to_object( source_file: &SourceFile, constant: ruff::ExprEllipsisLiteral, ) -> PyObjectRef { - let ruff::ExprEllipsisLiteral { range } = constant; + let ruff::ExprEllipsisLiteral { + node_index: _, + range, + } = constant; let c = Constant::new_ellipsis(range); c.ast_to_object(vm, source_file) } diff --git a/vm/src/stdlib/ast/elif_else_clause.rs b/vm/src/stdlib/ast/elif_else_clause.rs index 2b427b1ec1..581fc499b8 100644 --- a/vm/src/stdlib/ast/elif_else_clause.rs +++ b/vm/src/stdlib/ast/elif_else_clause.rs @@ -7,7 +7,12 @@ pub(super) fn ast_to_object( vm: &VirtualMachine, source_file: &SourceFile, ) -> PyObjectRef { - let ruff::ElifElseClause { range, test, body } = clause; + let ruff::ElifElseClause { + node_index: _, + range, + test, + body, + } = clause; let Some(test) = test else { assert!(rest.len() == 0); return body.ast_to_object(vm, source_file); @@ -55,6 +60,7 @@ pub(super) fn ast_from_object( let elif_else_clauses = if let [ruff::Stmt::If(_)] = &*orelse { let Some(ruff::Stmt::If(ruff::StmtIf { + node_index: _, range, test, body, @@ -66,6 +72,7 @@ pub(super) fn ast_from_object( elif_else_clauses.insert( 0, ruff::ElifElseClause { + node_index: Default::default(), range, test: Some(*test), body, @@ -74,6 +81,7 @@ pub(super) fn ast_from_object( elif_else_clauses } else { vec![ruff::ElifElseClause { + node_index: Default::default(), range, test: None, body: orelse, @@ -81,6 +89,7 @@ pub(super) fn ast_from_object( }; Ok(ruff::StmtIf { + node_index: Default::default(), test, body, elif_else_clauses, diff --git a/vm/src/stdlib/ast/exception.rs b/vm/src/stdlib/ast/exception.rs index df6b391aa1..b5b3ca2709 100644 --- a/vm/src/stdlib/ast/exception.rs +++ b/vm/src/stdlib/ast/exception.rs @@ -35,6 +35,7 @@ impl Node for ruff::ExceptHandler { impl Node for ruff::ExceptHandlerExceptHandler { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, type_, name, body, @@ -63,6 +64,7 @@ impl Node for ruff::ExceptHandlerExceptHandler { _object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), type_: get_node_field_opt(_vm, &_object, "type")? .map(|obj| Node::ast_from_object(_vm, source_file, obj)) .transpose()?, diff --git a/vm/src/stdlib/ast/expression.rs b/vm/src/stdlib/ast/expression.rs index 31b65bd13a..83d7737438 100644 --- a/vm/src/stdlib/ast/expression.rs +++ b/vm/src/stdlib/ast/expression.rs @@ -36,6 +36,7 @@ impl Node for ruff::Expr { Self::NumberLiteral(cons) => constant::number_literal_to_object(vm, source_file, cons), Self::StringLiteral(cons) => constant::string_literal_to_object(vm, source_file, cons), Self::FString(cons) => string::fstring_to_object(vm, source_file, cons), + Self::TString(_) => unimplemented!(), Self::BytesLiteral(cons) => constant::bytes_literal_to_object(vm, source_file, cons), Self::BooleanLiteral(cons) => { constant::boolean_literal_to_object(vm, source_file, cons) @@ -145,7 +146,12 @@ impl Node for ruff::Expr { // constructor impl Node for ruff::ExprBoolOp { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { - let Self { op, values, range } = self; + let Self { + node_index: _, + op, + values, + range, + } = self; let node = NodeAst .into_ref_with_type(vm, pyast::NodeExprBoolOp::static_type().to_owned()) .unwrap(); @@ -164,6 +170,7 @@ impl Node for ruff::ExprBoolOp { object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), op: Node::ast_from_object( vm, source_file, @@ -183,6 +190,7 @@ impl Node for ruff::ExprBoolOp { impl Node for ruff::ExprNamed { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, target, value, range, @@ -205,6 +213,7 @@ impl Node for ruff::ExprNamed { object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), target: Node::ast_from_object( vm, source_file, @@ -224,6 +233,7 @@ impl Node for ruff::ExprNamed { impl Node for ruff::ExprBinOp { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, left, op, right, @@ -249,6 +259,7 @@ impl Node for ruff::ExprBinOp { object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), left: Node::ast_from_object( vm, source_file, @@ -272,7 +283,12 @@ impl Node for ruff::ExprBinOp { // constructor impl Node for ruff::ExprUnaryOp { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { - let Self { op, operand, range } = self; + let Self { + node_index: _, + op, + operand, + range, + } = self; let node = NodeAst .into_ref_with_type(vm, pyast::NodeExprUnaryOp::static_type().to_owned()) .unwrap(); @@ -290,6 +306,7 @@ impl Node for ruff::ExprUnaryOp { object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), op: Node::ast_from_object( vm, source_file, @@ -309,6 +326,7 @@ impl Node for ruff::ExprUnaryOp { impl Node for ruff::ExprLambda { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, parameters, body, range: _range, @@ -331,6 +349,7 @@ impl Node for ruff::ExprLambda { object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), parameters: Node::ast_from_object( vm, source_file, @@ -350,6 +369,7 @@ impl Node for ruff::ExprLambda { impl Node for ruff::ExprIf { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, test, body, orelse, @@ -375,6 +395,7 @@ impl Node for ruff::ExprIf { object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), test: Node::ast_from_object( vm, source_file, @@ -398,7 +419,11 @@ impl Node for ruff::ExprIf { // constructor impl Node for ruff::ExprDict { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { - let Self { items, range } = self; + let Self { + node_index: _, + items, + range, + } = self; let (keys, values) = items .into_iter() @@ -440,6 +465,7 @@ impl Node for ruff::ExprDict { .map(|(key, value)| ruff::DictItem { key, value }) .collect(); Ok(Self { + node_index: Default::default(), items, range: range_from_object(vm, source_file, object, "Dict")?, }) @@ -449,7 +475,11 @@ impl Node for ruff::ExprDict { // constructor impl Node for ruff::ExprSet { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { - let Self { elts, range } = self; + let Self { + node_index: _, + elts, + range, + } = self; let node = NodeAst .into_ref_with_type(vm, pyast::NodeExprSet::static_type().to_owned()) .unwrap(); @@ -465,6 +495,7 @@ impl Node for ruff::ExprSet { object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), elts: Node::ast_from_object( vm, source_file, @@ -479,6 +510,7 @@ impl Node for ruff::ExprSet { impl Node for ruff::ExprListComp { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, elt, generators, range, @@ -501,6 +533,7 @@ impl Node for ruff::ExprListComp { object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), elt: Node::ast_from_object( vm, source_file, @@ -520,6 +553,7 @@ impl Node for ruff::ExprListComp { impl Node for ruff::ExprSetComp { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, elt, generators, range, @@ -542,6 +576,7 @@ impl Node for ruff::ExprSetComp { object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), elt: Node::ast_from_object( vm, source_file, @@ -561,6 +596,7 @@ impl Node for ruff::ExprSetComp { impl Node for ruff::ExprDictComp { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, key, value, generators, @@ -586,6 +622,7 @@ impl Node for ruff::ExprDictComp { object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), key: Node::ast_from_object( vm, source_file, @@ -610,6 +647,7 @@ impl Node for ruff::ExprDictComp { impl Node for ruff::ExprGenerator { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, elt, generators, range, @@ -633,6 +671,7 @@ impl Node for ruff::ExprGenerator { object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), elt: Node::ast_from_object( vm, source_file, @@ -653,7 +692,11 @@ impl Node for ruff::ExprGenerator { // constructor impl Node for ruff::ExprAwait { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { - let Self { value, range } = self; + let Self { + node_index: _, + value, + range, + } = self; let node = NodeAst .into_ref_with_type(vm, pyast::NodeExprAwait::static_type().to_owned()) .unwrap(); @@ -669,6 +712,7 @@ impl Node for ruff::ExprAwait { object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), value: Node::ast_from_object( vm, source_file, @@ -682,7 +726,11 @@ impl Node for ruff::ExprAwait { // constructor impl Node for ruff::ExprYield { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { - let Self { value, range } = self; + let Self { + node_index: _, + value, + range, + } = self; let node = NodeAst .into_ref_with_type(vm, pyast::NodeExprYield::static_type().to_owned()) .unwrap(); @@ -699,6 +747,7 @@ impl Node for ruff::ExprYield { object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), value: get_node_field_opt(vm, &object, "value")? .map(|obj| Node::ast_from_object(vm, source_file, obj)) .transpose()?, @@ -710,7 +759,11 @@ impl Node for ruff::ExprYield { // constructor impl Node for ruff::ExprYieldFrom { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { - let Self { value, range } = self; + let Self { + node_index: _, + value, + range, + } = self; let node = NodeAst .into_ref_with_type(vm, pyast::NodeExprYieldFrom::static_type().to_owned()) .unwrap(); @@ -727,6 +780,7 @@ impl Node for ruff::ExprYieldFrom { object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), value: Node::ast_from_object( vm, source_file, @@ -741,6 +795,7 @@ impl Node for ruff::ExprYieldFrom { impl Node for ruff::ExprCompare { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, left, ops, comparators, @@ -770,6 +825,7 @@ impl Node for ruff::ExprCompare { object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), left: Node::ast_from_object( vm, source_file, @@ -800,6 +856,7 @@ impl Node for ruff::ExprCompare { impl Node for ruff::ExprCall { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, func, arguments, range, @@ -833,6 +890,7 @@ impl Node for ruff::ExprCall { object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), func: Node::ast_from_object( vm, source_file, @@ -859,6 +917,7 @@ impl Node for ruff::ExprCall { impl Node for ruff::ExprAttribute { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, value, attr, ctx, @@ -884,6 +943,7 @@ impl Node for ruff::ExprAttribute { object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), value: Node::ast_from_object( vm, source_file, @@ -908,6 +968,7 @@ impl Node for ruff::ExprAttribute { impl Node for ruff::ExprSubscript { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, value, slice, ctx, @@ -932,6 +993,7 @@ impl Node for ruff::ExprSubscript { object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), value: Node::ast_from_object( vm, source_file, @@ -955,7 +1017,12 @@ impl Node for ruff::ExprSubscript { // constructor impl Node for ruff::ExprStarred { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { - let Self { value, ctx, range } = self; + let Self { + node_index: _, + value, + ctx, + range, + } = self; let node = NodeAst .into_ref_with_type(vm, pyast::NodeExprStarred::static_type().to_owned()) .unwrap(); @@ -973,6 +1040,7 @@ impl Node for ruff::ExprStarred { object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), value: Node::ast_from_object( vm, source_file, @@ -991,7 +1059,12 @@ impl Node for ruff::ExprStarred { // constructor impl Node for ruff::ExprName { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { - let Self { id, ctx, range } = self; + let Self { + node_index: _, + id, + ctx, + range, + } = self; let node = NodeAst .into_ref_with_type(vm, pyast::NodeExprName::static_type().to_owned()) .unwrap(); @@ -1009,6 +1082,7 @@ impl Node for ruff::ExprName { object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), id: Node::ast_from_object(vm, source_file, get_node_field(vm, &object, "id", "Name")?)?, ctx: Node::ast_from_object( vm, @@ -1023,7 +1097,12 @@ impl Node for ruff::ExprName { // constructor impl Node for ruff::ExprList { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { - let Self { elts, ctx, range } = self; + let Self { + node_index: _, + elts, + ctx, + range, + } = self; let node = NodeAst .into_ref_with_type(vm, pyast::NodeExprList::static_type().to_owned()) .unwrap(); @@ -1042,6 +1121,7 @@ impl Node for ruff::ExprList { object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), elts: Node::ast_from_object( vm, source_file, @@ -1061,6 +1141,7 @@ impl Node for ruff::ExprList { impl Node for ruff::ExprTuple { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, elts, ctx, range: _range, @@ -1084,6 +1165,7 @@ impl Node for ruff::ExprTuple { object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), elts: Node::ast_from_object( vm, source_file, @@ -1104,6 +1186,7 @@ impl Node for ruff::ExprTuple { impl Node for ruff::ExprSlice { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, lower, upper, step, @@ -1129,6 +1212,7 @@ impl Node for ruff::ExprSlice { object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), lower: get_node_field_opt(vm, &object, "lower")? .map(|obj| Node::ast_from_object(vm, source_file, obj)) .transpose()?, @@ -1185,6 +1269,7 @@ impl Node for ruff::ExprContext { impl Node for ruff::Comprehension { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, target, iter, ifs, @@ -1212,6 +1297,7 @@ impl Node for ruff::Comprehension { object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), target: Node::ast_from_object( vm, source_file, diff --git a/vm/src/stdlib/ast/module.rs b/vm/src/stdlib/ast/module.rs index 33ee4c567b..6fae8f10a3 100644 --- a/vm/src/stdlib/ast/module.rs +++ b/vm/src/stdlib/ast/module.rs @@ -66,6 +66,7 @@ impl Node for Mod { impl Node for ruff::ModModule { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, body, // type_ignores, range, @@ -95,6 +96,7 @@ impl Node for ruff::ModModule { object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), body: Node::ast_from_object( vm, source_file, @@ -147,7 +149,11 @@ impl Node for ModInteractive { // constructor impl Node for ruff::ModExpression { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { - let Self { body, range } = self; + let Self { + node_index: _, + body, + range, + } = self; let node = NodeAst .into_ref_with_type(vm, pyast::NodeModExpression::static_type().to_owned()) .unwrap(); @@ -164,6 +170,7 @@ impl Node for ruff::ModExpression { object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), body: Node::ast_from_object( vm, source_file, diff --git a/vm/src/stdlib/ast/other.rs b/vm/src/stdlib/ast/other.rs index eddbef9748..780d7cc712 100644 --- a/vm/src/stdlib/ast/other.rs +++ b/vm/src/stdlib/ast/other.rs @@ -55,7 +55,11 @@ impl Node for ruff::Decorator { ) -> PyResult { let expression = ruff::Expr::ast_from_object(vm, source_file, object)?; let range = expression.range(); - Ok(Self { expression, range }) + Ok(Self { + node_index: Default::default(), + expression, + range, + }) } } @@ -63,6 +67,7 @@ impl Node for ruff::Decorator { impl Node for ruff::Alias { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, name, asname, range: _range, @@ -85,6 +90,7 @@ impl Node for ruff::Alias { object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), name: Node::ast_from_object( vm, source_file, @@ -102,6 +108,7 @@ impl Node for ruff::Alias { impl Node for ruff::WithItem { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, context_expr, optional_vars, range: _range, @@ -131,6 +138,7 @@ impl Node for ruff::WithItem { object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), context_expr: Node::ast_from_object( vm, source_file, diff --git a/vm/src/stdlib/ast/parameter.rs b/vm/src/stdlib/ast/parameter.rs index 347b3b4ec0..87fa736687 100644 --- a/vm/src/stdlib/ast/parameter.rs +++ b/vm/src/stdlib/ast/parameter.rs @@ -5,6 +5,7 @@ use rustpython_compiler_core::SourceFile; impl Node for ruff::Parameters { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, posonlyargs, args, vararg, @@ -80,6 +81,7 @@ impl Node for ruff::Parameters { let (posonlyargs, args) = merge_positional_parameter_defaults(posonlyargs, args, defaults); Ok(Self { + node_index: Default::default(), posonlyargs, args, vararg: get_node_field_opt(vm, &object, "vararg")? @@ -102,6 +104,7 @@ impl Node for ruff::Parameters { impl Node for ruff::Parameter { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, name, annotation, // type_comment, @@ -135,6 +138,7 @@ impl Node for ruff::Parameter { _object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), name: Node::ast_from_object( _vm, source_file, @@ -155,6 +159,7 @@ impl Node for ruff::Parameter { impl Node for ruff::Keyword { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, arg, value, range: _range, @@ -176,6 +181,7 @@ impl Node for ruff::Keyword { _object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), arg: get_node_field_opt(_vm, &_object, "arg")? .map(|obj| Node::ast_from_object(_vm, source_file, obj)) .transpose()?, @@ -328,6 +334,7 @@ fn merge_positional_parameter_defaults( let mut posonlyargs: Vec<_> = as IntoIterator>::into_iter(posonlyargs) .map(|parameter| ruff::ParameterWithDefault { + node_index: Default::default(), range: Default::default(), parameter, default: None, @@ -335,6 +342,7 @@ fn merge_positional_parameter_defaults( .collect(); let mut args: Vec<_> = as IntoIterator>::into_iter(args) .map(|parameter| ruff::ParameterWithDefault { + node_index: Default::default(), range: Default::default(), parameter, default: None, @@ -397,6 +405,7 @@ fn merge_keyword_parameter_defaults( ) -> Vec { std::iter::zip(kw_only_args.keywords, defaults.defaults) .map(|(parameter, default)| ruff::ParameterWithDefault { + node_index: Default::default(), parameter, default, range: Default::default(), diff --git a/vm/src/stdlib/ast/pattern.rs b/vm/src/stdlib/ast/pattern.rs index 0c484d6787..9567ed38d4 100644 --- a/vm/src/stdlib/ast/pattern.rs +++ b/vm/src/stdlib/ast/pattern.rs @@ -5,6 +5,7 @@ use rustpython_compiler_core::SourceFile; impl Node for ruff::MatchCase { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, pattern, guard, body, @@ -29,6 +30,7 @@ impl Node for ruff::MatchCase { _object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), pattern: Node::ast_from_object( _vm, source_file, @@ -127,6 +129,7 @@ impl Node for ruff::Pattern { impl Node for ruff::PatternMatchValue { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, value, range: _range, } = self; @@ -146,6 +149,7 @@ impl Node for ruff::PatternMatchValue { _object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), value: Node::ast_from_object( _vm, source_file, @@ -160,6 +164,7 @@ impl Node for ruff::PatternMatchValue { impl Node for ruff::PatternMatchSingleton { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, value, range: _range, } = self; @@ -182,6 +187,7 @@ impl Node for ruff::PatternMatchSingleton { _object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), value: Node::ast_from_object( _vm, source_file, @@ -210,6 +216,7 @@ impl Node for ruff::Singleton { impl Node for ruff::PatternMatchSequence { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, patterns, range: _range, } = self; @@ -232,6 +239,7 @@ impl Node for ruff::PatternMatchSequence { _object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), patterns: Node::ast_from_object( _vm, source_file, @@ -246,6 +254,7 @@ impl Node for ruff::PatternMatchSequence { impl Node for ruff::PatternMatchMapping { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, keys, patterns, rest, @@ -274,6 +283,7 @@ impl Node for ruff::PatternMatchMapping { _object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), keys: Node::ast_from_object( _vm, source_file, @@ -296,6 +306,7 @@ impl Node for ruff::PatternMatchMapping { impl Node for ruff::PatternMatchClass { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, cls, arguments, range: _range, @@ -344,6 +355,7 @@ impl Node for ruff::PatternMatchClass { let (patterns, keywords) = merge_pattern_match_class(patterns, kwd_attrs, kwd_patterns); Ok(Self { + node_index: Default::default(), cls: Node::ast_from_object( vm, source_file, @@ -351,6 +363,7 @@ impl Node for ruff::PatternMatchClass { )?, range: range_from_object(vm, source_file, object, "MatchClass")?, arguments: ruff::PatternArguments { + node_index: Default::default(), range: Default::default(), patterns, keywords, @@ -416,6 +429,7 @@ impl Node for PatternMatchClassKeywordPatterns { impl Node for ruff::PatternMatchStar { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, name, range: _range, } = self; @@ -435,6 +449,7 @@ impl Node for ruff::PatternMatchStar { _object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), name: get_node_field_opt(_vm, &_object, "name")? .map(|obj| Node::ast_from_object(_vm, source_file, obj)) .transpose()?, @@ -447,6 +462,7 @@ impl Node for ruff::PatternMatchStar { impl Node for ruff::PatternMatchAs { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, pattern, name, range: _range, @@ -469,6 +485,7 @@ impl Node for ruff::PatternMatchAs { _object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), pattern: get_node_field_opt(_vm, &_object, "pattern")? .map(|obj| Node::ast_from_object(_vm, source_file, obj)) .transpose()?, @@ -484,6 +501,7 @@ impl Node for ruff::PatternMatchAs { impl Node for ruff::PatternMatchOr { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, patterns, range: _range, } = self; @@ -502,6 +520,7 @@ impl Node for ruff::PatternMatchOr { _object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), patterns: Node::ast_from_object( _vm, source_file, diff --git a/vm/src/stdlib/ast/statement.rs b/vm/src/stdlib/ast/statement.rs index fab7ea7696..5925ca1fc2 100644 --- a/vm/src/stdlib/ast/statement.rs +++ b/vm/src/stdlib/ast/statement.rs @@ -172,6 +172,7 @@ impl Node for ruff::Stmt { impl Node for ruff::StmtFunctionDef { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, name, parameters, body, @@ -225,6 +226,7 @@ impl Node for ruff::StmtFunctionDef { let _cls = _object.class(); let is_async = _cls.is(pyast::NodeStmtAsyncFunctionDef::static_type()); Ok(Self { + node_index: Default::default(), name: Node::ast_from_object( _vm, source_file, @@ -267,6 +269,7 @@ impl Node for ruff::StmtFunctionDef { impl Node for ruff::StmtClassDef { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, name, arguments, body, @@ -318,6 +321,7 @@ impl Node for ruff::StmtClassDef { get_node_field(_vm, &_object, "keywords", "ClassDef")?, )?; Ok(Self { + node_index: Default::default(), name: Node::ast_from_object( _vm, source_file, @@ -347,6 +351,7 @@ impl Node for ruff::StmtClassDef { impl Node for ruff::StmtReturn { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, value, range: _range, } = self; @@ -365,6 +370,7 @@ impl Node for ruff::StmtReturn { _object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), value: get_node_field_opt(_vm, &_object, "value")? .map(|obj| Node::ast_from_object(_vm, source_file, obj)) .transpose()?, @@ -376,6 +382,7 @@ impl Node for ruff::StmtReturn { impl Node for ruff::StmtDelete { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, targets, range: _range, } = self; @@ -394,6 +401,7 @@ impl Node for ruff::StmtDelete { _object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), targets: Node::ast_from_object( _vm, source_file, @@ -408,6 +416,7 @@ impl Node for ruff::StmtDelete { impl Node for ruff::StmtAssign { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, targets, value, // type_comment, @@ -432,6 +441,7 @@ impl Node for ruff::StmtAssign { object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), targets: Node::ast_from_object( vm, source_file, @@ -454,6 +464,7 @@ impl Node for ruff::StmtAssign { impl Node for ruff::StmtTypeAlias { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, name, type_params, value, @@ -483,6 +494,7 @@ impl Node for ruff::StmtTypeAlias { _object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), name: Node::ast_from_object( _vm, source_file, @@ -507,6 +519,7 @@ impl Node for ruff::StmtTypeAlias { impl Node for ruff::StmtAugAssign { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, target, op, value, @@ -531,6 +544,7 @@ impl Node for ruff::StmtAugAssign { _object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), target: Node::ast_from_object( _vm, source_file, @@ -555,6 +569,7 @@ impl Node for ruff::StmtAugAssign { impl Node for ruff::StmtAnnAssign { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, target, annotation, value, @@ -586,6 +601,7 @@ impl Node for ruff::StmtAnnAssign { _object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), target: Node::ast_from_object( _vm, source_file, @@ -613,6 +629,7 @@ impl Node for ruff::StmtAnnAssign { impl Node for ruff::StmtFor { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, is_async, target, iter, @@ -656,6 +673,7 @@ impl Node for ruff::StmtFor { ); let is_async = _cls.is(pyast::NodeStmtAsyncFor::static_type()); Ok(Self { + node_index: Default::default(), target: Node::ast_from_object( _vm, source_file, @@ -689,6 +707,7 @@ impl Node for ruff::StmtFor { impl Node for ruff::StmtWhile { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, test, body, orelse, @@ -714,6 +733,7 @@ impl Node for ruff::StmtWhile { _object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), test: Node::ast_from_object( _vm, source_file, @@ -737,6 +757,7 @@ impl Node for ruff::StmtWhile { impl Node for ruff::StmtIf { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, test, body, range, @@ -744,6 +765,7 @@ impl Node for ruff::StmtIf { } = self; elif_else_clause::ast_to_object( ruff::ElifElseClause { + node_index: Default::default(), range, test: Some(*test), body, @@ -765,6 +787,7 @@ impl Node for ruff::StmtIf { impl Node for ruff::StmtWith { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, is_async, items, body, @@ -801,6 +824,7 @@ impl Node for ruff::StmtWith { ); let is_async = _cls.is(pyast::NodeStmtAsyncWith::static_type()); Ok(Self { + node_index: Default::default(), items: Node::ast_from_object( _vm, source_file, @@ -823,6 +847,7 @@ impl Node for ruff::StmtWith { impl Node for ruff::StmtMatch { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, subject, cases, range: _range, @@ -844,6 +869,7 @@ impl Node for ruff::StmtMatch { _object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), subject: Node::ast_from_object( _vm, source_file, @@ -862,6 +888,7 @@ impl Node for ruff::StmtMatch { impl Node for ruff::StmtRaise { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, exc, cause, range: _range, @@ -883,6 +910,7 @@ impl Node for ruff::StmtRaise { _object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), exc: get_node_field_opt(_vm, &_object, "exc")? .map(|obj| Node::ast_from_object(_vm, source_file, obj)) .transpose()?, @@ -897,6 +925,7 @@ impl Node for ruff::StmtRaise { impl Node for ruff::StmtTry { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, body, handlers, orelse, @@ -940,6 +969,7 @@ impl Node for ruff::StmtTry { ); Ok(Self { + node_index: Default::default(), body: Node::ast_from_object( _vm, source_file, @@ -969,6 +999,7 @@ impl Node for ruff::StmtTry { impl Node for ruff::StmtAssert { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, test, msg, range: _range, @@ -990,6 +1021,7 @@ impl Node for ruff::StmtAssert { _object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), test: Node::ast_from_object( _vm, source_file, @@ -1006,6 +1038,7 @@ impl Node for ruff::StmtAssert { impl Node for ruff::StmtImport { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, names, range: _range, } = self; @@ -1024,6 +1057,7 @@ impl Node for ruff::StmtImport { _object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), names: Node::ast_from_object( _vm, source_file, @@ -1037,6 +1071,7 @@ impl Node for ruff::StmtImport { impl Node for ruff::StmtImportFrom { fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, module, names, level, @@ -1061,6 +1096,7 @@ impl Node for ruff::StmtImportFrom { _object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), module: get_node_field_opt(vm, &_object, "module")? .map(|obj| Node::ast_from_object(vm, source_file, obj)) .transpose()?, @@ -1081,6 +1117,7 @@ impl Node for ruff::StmtImportFrom { impl Node for ruff::StmtGlobal { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, names, range: _range, } = self; @@ -1099,6 +1136,7 @@ impl Node for ruff::StmtGlobal { _object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), names: Node::ast_from_object( _vm, source_file, @@ -1112,6 +1150,7 @@ impl Node for ruff::StmtGlobal { impl Node for ruff::StmtNonlocal { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, names, range: _range, } = self; @@ -1130,6 +1169,7 @@ impl Node for ruff::StmtNonlocal { _object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), names: Node::ast_from_object( _vm, source_file, @@ -1143,6 +1183,7 @@ impl Node for ruff::StmtNonlocal { impl Node for ruff::StmtExpr { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, value, range: _range, } = self; @@ -1161,6 +1202,7 @@ impl Node for ruff::StmtExpr { _object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), value: Node::ast_from_object( _vm, source_file, @@ -1173,7 +1215,10 @@ impl Node for ruff::StmtExpr { // constructor impl Node for ruff::StmtPass { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { - let Self { range: _range } = self; + let Self { + node_index: _, + range: _range, + } = self; let node = NodeAst .into_ref_with_type(_vm, pyast::NodeStmtPass::static_type().to_owned()) .unwrap(); @@ -1187,6 +1232,7 @@ impl Node for ruff::StmtPass { _object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), range: range_from_object(_vm, source_file, _object, "Pass")?, }) } @@ -1194,7 +1240,10 @@ impl Node for ruff::StmtPass { // constructor impl Node for ruff::StmtBreak { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { - let Self { range: _range } = self; + let Self { + node_index: _, + range: _range, + } = self; let node = NodeAst .into_ref_with_type(_vm, pyast::NodeStmtBreak::static_type().to_owned()) .unwrap(); @@ -1209,6 +1258,7 @@ impl Node for ruff::StmtBreak { _object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), range: range_from_object(_vm, source_file, _object, "Break")?, }) } @@ -1217,7 +1267,10 @@ impl Node for ruff::StmtBreak { // constructor impl Node for ruff::StmtContinue { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { - let Self { range: _range } = self; + let Self { + node_index: _, + range: _range, + } = self; let node = NodeAst .into_ref_with_type(_vm, pyast::NodeStmtContinue::static_type().to_owned()) .unwrap(); @@ -1231,6 +1284,7 @@ impl Node for ruff::StmtContinue { _object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), range: range_from_object(_vm, source_file, _object, "Continue")?, }) } diff --git a/vm/src/stdlib/ast/string.rs b/vm/src/stdlib/ast/string.rs index 5d8654270d..f3df8d9926 100644 --- a/vm/src/stdlib/ast/string.rs +++ b/vm/src/stdlib/ast/string.rs @@ -5,24 +5,26 @@ fn ruff_fstring_value_into_iter( mut fstring_value: ruff::FStringValue, ) -> impl Iterator + 'static { let default = ruff::FStringPart::FString(ruff::FString { + node_index: Default::default(), range: Default::default(), elements: Default::default(), flags: ruff::FStringFlags::empty(), }); (0..fstring_value.as_slice().len()).map(move |i| { - let fstring_value = &mut fstring_value; - let tmp = fstring_value.into_iter().nth(i).unwrap(); + let tmp = fstring_value.iter_mut().nth(i).unwrap(); std::mem::replace(tmp, default.clone()) }) } fn ruff_fstring_element_into_iter( - mut fstring_element: ruff::FStringElements, -) -> impl Iterator + 'static { - let default = ruff::FStringElement::Literal(ruff::FStringLiteralElement { - range: Default::default(), - value: Default::default(), - }); + mut fstring_element: ruff::InterpolatedStringElements, +) -> impl Iterator + 'static { + let default = + ruff::InterpolatedStringElement::Literal(ruff::InterpolatedStringLiteralElement { + node_index: Default::default(), + range: Default::default(), + value: Default::default(), + }); (0..fstring_element.into_iter().len()).map(move |i| { let fstring_element = &mut fstring_element; let tmp = fstring_element.into_iter().nth(i).unwrap(); @@ -36,6 +38,7 @@ fn fstring_part_to_joined_str_part(fstring_part: ruff::FStringPart) -> Vec { vec![JoinedStrPart::Constant(Constant::new_str( value, @@ -47,27 +50,33 @@ fn fstring_part_to_joined_str_part(fstring_part: ruff::FStringPart) -> Vec ruff_fstring_element_into_iter(elements) .map(ruff_fstring_element_to_joined_str_part) .collect(), } } -fn ruff_fstring_element_to_joined_str_part(element: ruff::FStringElement) -> JoinedStrPart { +fn ruff_fstring_element_to_joined_str_part( + element: ruff::InterpolatedStringElement, +) -> JoinedStrPart { match element { - ruff::FStringElement::Literal(ruff::FStringLiteralElement { range, value }) => { - JoinedStrPart::Constant(Constant::new_str( - value, - ruff::str_prefix::StringLiteralPrefix::Empty, - range, - )) - } - ruff::FStringElement::Expression(ruff::FStringExpressionElement { + ruff::InterpolatedStringElement::Literal(ruff::InterpolatedStringLiteralElement { + range, + value, + node_index: _, + }) => JoinedStrPart::Constant(Constant::new_str( + value, + ruff::str_prefix::StringLiteralPrefix::Empty, + range, + )), + ruff::InterpolatedStringElement::Interpolation(ruff::InterpolatedElement { range, expression, debug_text: _, // TODO: What is this? conversion, format_spec, + node_index: _, }) => JoinedStrPart::FormattedValue(FormattedValue { value: expression, conversion, @@ -78,12 +87,16 @@ fn ruff_fstring_element_to_joined_str_part(element: ruff::FStringElement) -> Joi } fn ruff_format_spec_to_joined_str( - format_spec: Option>, + format_spec: Option>, ) -> Option> { match format_spec { None => None, Some(format_spec) => { - let ruff::FStringFormatSpec { range, elements } = *format_spec; + let ruff::InterpolatedStringFormatSpec { + range, + elements, + node_index: _, + } = *format_spec; let values: Vec<_> = ruff_fstring_element_into_iter(elements) .map(ruff_fstring_element_to_joined_str_part) .collect(); @@ -93,45 +106,37 @@ fn ruff_format_spec_to_joined_str( } } -fn ruff_fstring_element_to_ruff_fstring_part(element: ruff::FStringElement) -> ruff::FStringPart { +fn ruff_fstring_element_to_ruff_fstring_part( + element: ruff::InterpolatedStringElement, +) -> ruff::FStringPart { match element { - ruff::FStringElement::Literal(value) => { - let ruff::FStringLiteralElement { range, value } = value; - ruff::FStringPart::Literal(ruff::StringLiteral { + ruff::InterpolatedStringElement::Literal(value) => { + let ruff::InterpolatedStringLiteralElement { + node_index, range, value, - flags: ruff::StringLiteralFlags::empty(), - }) - } - ruff::FStringElement::Expression(value) => { - let ruff::FStringExpressionElement { - range, - expression, - debug_text, - conversion, - format_spec, } = value; - ruff::FStringPart::FString(ruff::FString { + ruff::FStringPart::Literal(ruff::StringLiteral { + node_index, range, - elements: vec![ruff::FStringElement::Expression( - ruff::FStringExpressionElement { - range, - expression, - debug_text, - conversion, - format_spec, - }, - )] - .into(), - flags: ruff::FStringFlags::empty(), + value, + flags: ruff::StringLiteralFlags::empty(), }) } + ruff::InterpolatedStringElement::Interpolation(ruff::InterpolatedElement { + range, .. + }) => ruff::FStringPart::FString(ruff::FString { + node_index: Default::default(), + range, + elements: vec![element].into(), + flags: ruff::FStringFlags::empty(), + }), } } fn joined_str_to_ruff_format_spec( joined_str: Option>, -) -> Option> { +) -> Option> { match joined_str { None => None, Some(joined_str) => { @@ -139,7 +144,8 @@ fn joined_str_to_ruff_format_spec( let elements: Vec<_> = Box::into_iter(values) .map(joined_str_part_to_ruff_fstring_element) .collect(); - let format_spec = ruff::FStringFormatSpec { + let format_spec = ruff::InterpolatedStringFormatSpec { + node_index: Default::default(), range, elements: elements.into(), }; @@ -158,10 +164,12 @@ impl JoinedStr { pub(super) fn into_expr(self) -> ruff::Expr { let Self { range, values } = self; ruff::Expr::FString(ruff::ExprFString { + node_index: Default::default(), range: Default::default(), value: match values.len() { // ruff represents an empty fstring like this: 0 => ruff::FStringValue::single(ruff::FString { + node_index: Default::default(), range, elements: vec![].into(), flags: ruff::FStringFlags::empty(), @@ -170,6 +178,7 @@ impl JoinedStr { Box::<[_]>::into_iter(values) .map(joined_str_part_to_ruff_fstring_element) .map(|element| ruff::FString { + node_index: Default::default(), range, elements: vec![element].into(), flags: ruff::FStringFlags::empty(), @@ -188,10 +197,11 @@ impl JoinedStr { } } -fn joined_str_part_to_ruff_fstring_element(part: JoinedStrPart) -> ruff::FStringElement { +fn joined_str_part_to_ruff_fstring_element(part: JoinedStrPart) -> ruff::InterpolatedStringElement { match part { JoinedStrPart::FormattedValue(value) => { - ruff::FStringElement::Expression(ruff::FStringExpressionElement { + ruff::InterpolatedStringElement::Interpolation(ruff::InterpolatedElement { + node_index: Default::default(), range: value.range, expression: value.value.clone(), debug_text: None, // TODO: What is this? @@ -200,7 +210,8 @@ fn joined_str_part_to_ruff_fstring_element(part: JoinedStrPart) -> ruff::FString }) } JoinedStrPart::Constant(value) => { - ruff::FStringElement::Literal(ruff::FStringLiteralElement { + ruff::InterpolatedStringElement::Literal(ruff::InterpolatedStringLiteralElement { + node_index: Default::default(), range: value.range, value: match value.value { ConstantLiteral::Str { value, .. } => value, @@ -344,7 +355,11 @@ pub(super) fn fstring_to_object( source_file: &SourceFile, expression: ruff::ExprFString, ) -> PyObjectRef { - let ruff::ExprFString { range, value } = expression; + let ruff::ExprFString { + range, + value, + node_index: _, + } = expression; let values: Vec<_> = ruff_fstring_value_into_iter(value) .flat_map(fstring_part_to_joined_str_part) .collect(); diff --git a/vm/src/stdlib/ast/type_parameters.rs b/vm/src/stdlib/ast/type_parameters.rs index 505cd04d28..017470f7e6 100644 --- a/vm/src/stdlib/ast/type_parameters.rs +++ b/vm/src/stdlib/ast/type_parameters.rs @@ -15,7 +15,11 @@ impl Node for ruff::TypeParams { let range = Option::zip(type_params.first(), type_params.last()) .map(|(first, last)| first.range().cover(last.range())) .unwrap_or_default(); - Ok(Self { type_params, range }) + Ok(Self { + node_index: Default::default(), + type_params, + range, + }) } fn is_none(&self) -> bool { @@ -70,6 +74,7 @@ impl Node for ruff::TypeParam { impl Node for ruff::TypeParamTypeVar { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, name, bound, range: _range, @@ -93,6 +98,7 @@ impl Node for ruff::TypeParamTypeVar { _object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), name: Node::ast_from_object( _vm, source_file, @@ -115,6 +121,7 @@ impl Node for ruff::TypeParamTypeVar { impl Node for ruff::TypeParamParamSpec { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, name, range: _range, default, @@ -141,6 +148,7 @@ impl Node for ruff::TypeParamParamSpec { _object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), name: Node::ast_from_object( _vm, source_file, @@ -160,6 +168,7 @@ impl Node for ruff::TypeParamParamSpec { impl Node for ruff::TypeParamTypeVarTuple { fn ast_to_object(self, _vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef { let Self { + node_index: _, name, range: _range, default, @@ -189,6 +198,7 @@ impl Node for ruff::TypeParamTypeVarTuple { _object: PyObjectRef, ) -> PyResult { Ok(Self { + node_index: Default::default(), name: Node::ast_from_object( _vm, source_file, diff --git a/vm/src/vm/vm_new.rs b/vm/src/vm/vm_new.rs index cf8d682ec2..d0b78cfe5b 100644 --- a/vm/src/vm/vm_new.rs +++ b/vm/src/vm/vm_new.rs @@ -321,7 +321,7 @@ impl VirtualMachine { error: ruff_python_parser::ParseErrorType::Lexical( ruff_python_parser::LexicalErrorType::FStringError( - ruff_python_parser::FStringErrorType::UnterminatedTripleQuotedString, + ruff_python_parser::InterpolatedStringErrorType::UnterminatedTripleQuotedString, ), ), .. @@ -412,7 +412,7 @@ impl VirtualMachine { fn get_statement(source: &str, loc: Option) -> Option { let line = source .split('\n') - .nth(loc?.row.to_zero_indexed())? + .nth(loc?.line.to_zero_indexed())? .to_owned(); Some(line + "\n") } diff --git a/wasm/lib/src/convert.rs b/wasm/lib/src/convert.rs index 9f4add0708..d1821f2e73 100644 --- a/wasm/lib/src/convert.rs +++ b/wasm/lib/src/convert.rs @@ -251,12 +251,12 @@ pub fn syntax_err(err: CompileError) -> SyntaxError { let _ = Reflect::set( &js_err, &"row".into(), - &(err.location().unwrap().row.get()).into(), + &(err.location().unwrap().line.get()).into(), ); let _ = Reflect::set( &js_err, &"col".into(), - &(err.location().unwrap().column.get()).into(), + &(err.location().unwrap().character_offset.get()).into(), ); // | ParseErrorType::UnrecognizedToken(Token::Dedent, _) let can_continue = matches!(