diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 2617c15e..fdbea30f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,7 @@ latest ------ * Drop support for Python 3.9. +* Bugfix: don't treat t-strings as syntax errors. https://github.com/python-grimp/grimp/issues/268 3.13 (2025-10-29) ----------------- diff --git a/rust/Cargo.lock b/rust/Cargo.lock index a00f0b1b..187a8041 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -12,7 +12,7 @@ dependencies = [ "encoding_rs", "getset", "indexmap 2.11.0", - "itertools 0.14.0", + "itertools", "parameterized", "pyo3", "rayon", @@ -20,7 +20,7 @@ dependencies = [ "ruff_python_ast", "ruff_python_parser", "ruff_source_file", - "rustc-hash 2.1.1", + "rustc-hash", "serde", "serde_json", "serde_yaml", @@ -40,6 +40,36 @@ dependencies = [ "memchr", ] +[[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" @@ -69,12 +99,41 @@ dependencies = [ "serde", ] +[[package]] +name = "castaway" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a" +dependencies = [ + "rustversion", +] + [[package]] name = "cfg-if" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" +[[package]] +name = "collection_literals" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2550f75b8cfac212855f6b1885455df8eaee8fe8e246b647d69146142e016084" + +[[package]] +name = "compact_str" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb1325a1cece981e8a296ab8f0f9b63ae357bd0784a9faaf548cc7b480707a" +dependencies = [ + "castaway", + "cfg-if", + "itoa", + "rustversion", + "ryu", + "static_assertions", +] + [[package]] name = "const_format" version = "0.2.34" @@ -131,6 +190,17 @@ dependencies = [ "syn", ] +[[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 = "either" version = "1.15.0" @@ -158,6 +228,29 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +[[package]] +name = "get-size-derive2" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab21d7bd2c625f2064f04ce54bcb88bc57c45724cde45cba326d784e22d3f71a" +dependencies = [ + "attribute-derive", + "quote", + "syn", +] + +[[package]] +name = "get-size2" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879272b0de109e2b67b39fcfe3d25fdbba96ac07e44a254f5a0b4d7ff55340cb" +dependencies = [ + "compact_str", + "get-size-derive2", + "hashbrown 0.16.1", + "smallvec", +] + [[package]] name = "getopts" version = "0.2.24" @@ -205,6 +298,12 @@ dependencies = [ "foldhash", ] +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + [[package]] name = "heck" version = "0.5.0" @@ -237,6 +336,12 @@ version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd" +[[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" @@ -249,15 +354,6 @@ dependencies = [ "syn", ] -[[package]] -name = "itertools" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.14.0" @@ -285,6 +381,29 @@ version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" +[[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 = "memchr" version = "2.7.5" @@ -402,6 +521,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" @@ -481,6 +611,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 = "rand" version = "0.8.5" @@ -563,31 +715,36 @@ checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" [[package]] name = "ruff_python_ast" version = "0.0.0" -source = "git+https://github.com/astral-sh/ruff.git?tag=v0.4.10#b54922fd7394c36cdc390fd21aaee99206ebc361" +source = "git+https://github.com/astral-sh/ruff.git?tag=0.14.8#9d4f1c6ae24b75642a586531f4c668213fbac3fb" dependencies = [ "aho-corasick", "bitflags", + "compact_str", + "get-size2", "is-macro", - "itertools 0.13.0", - "once_cell", + "itertools", + "memchr", "ruff_python_trivia", "ruff_source_file", "ruff_text_size", - "rustc-hash 1.1.0", + "rustc-hash", + "thiserror", ] [[package]] name = "ruff_python_parser" version = "0.0.0" -source = "git+https://github.com/astral-sh/ruff.git?tag=v0.4.10#b54922fd7394c36cdc390fd21aaee99206ebc361" +source = "git+https://github.com/astral-sh/ruff.git?tag=0.14.8#9d4f1c6ae24b75642a586531f4c668213fbac3fb" dependencies = [ "bitflags", "bstr", + "compact_str", + "get-size2", "memchr", "ruff_python_ast", "ruff_python_trivia", "ruff_text_size", - "rustc-hash 1.1.0", + "rustc-hash", "static_assertions", "unicode-ident", "unicode-normalization", @@ -597,9 +754,9 @@ dependencies = [ [[package]] name = "ruff_python_trivia" version = "0.0.0" -source = "git+https://github.com/astral-sh/ruff.git?tag=v0.4.10#b54922fd7394c36cdc390fd21aaee99206ebc361" +source = "git+https://github.com/astral-sh/ruff.git?tag=0.14.8#9d4f1c6ae24b75642a586531f4c668213fbac3fb" dependencies = [ - "itertools 0.13.0", + "itertools", "ruff_source_file", "ruff_text_size", "unicode-ident", @@ -608,29 +765,31 @@ dependencies = [ [[package]] name = "ruff_source_file" version = "0.0.0" -source = "git+https://github.com/astral-sh/ruff.git?tag=v0.4.10#b54922fd7394c36cdc390fd21aaee99206ebc361" +source = "git+https://github.com/astral-sh/ruff.git?tag=0.14.8#9d4f1c6ae24b75642a586531f4c668213fbac3fb" dependencies = [ "memchr", - "once_cell", "ruff_text_size", ] [[package]] name = "ruff_text_size" version = "0.0.0" -source = "git+https://github.com/astral-sh/ruff.git?tag=v0.4.10#b54922fd7394c36cdc390fd21aaee99206ebc361" +source = "git+https://github.com/astral-sh/ruff.git?tag=0.14.8#9d4f1c6ae24b75642a586531f4c668213fbac3fb" +dependencies = [ + "get-size2", +] [[package]] name = "rustc-hash" -version = "1.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] -name = "rustc-hash" -version = "2.1.1" +name = "rustversion" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" @@ -698,6 +857,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + [[package]] name = "static_assertions" version = "1.1.0" diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 4eb4e139..12fcd0cb 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -21,9 +21,9 @@ rustc-hash = "2.1.1" indexmap = "2.11.0" regex = "1.11.2" const_format = "0.2.34" -ruff_python_parser = { git = "https://github.com/astral-sh/ruff.git", tag = "v0.4.10" } -ruff_python_ast = { git = "https://github.com/astral-sh/ruff.git", tag = "v0.4.10" } -ruff_source_file = { git = "https://github.com/astral-sh/ruff.git", tag = "v0.4.10" } +ruff_python_parser = { git = "https://github.com/astral-sh/ruff.git", tag = "0.14.8" } +ruff_python_ast = { git = "https://github.com/astral-sh/ruff.git", tag = "0.14.8" } +ruff_source_file = { git = "https://github.com/astral-sh/ruff.git", tag = "0.14.8" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.137" serde_yaml = "0.9" diff --git a/rust/src/import_parsing.rs b/rust/src/import_parsing.rs index a43f7422..ba9d79e0 100644 --- a/rust/src/import_parsing.rs +++ b/rust/src/import_parsing.rs @@ -80,7 +80,7 @@ impl<'a> StatementVisitor<'a> for Visitor<'a> { let line_number = self.source_code.line_index(import_stmt.range.start()); for name in import_stmt.names.iter() { self.imported_objects.push(ImportedObject::new( - name.name.id.clone(), + name.name.id.to_string(), line_number.get(), self.source_code.line_text(line_number).trim().to_string(), self.typechecking_only, diff --git a/tests/unit/application/test_scanning.py b/tests/unit/application/test_scanning.py index e7cbfa54..af5fa125 100644 --- a/tests/unit/application/test_scanning.py +++ b/tests/unit/application/test_scanning.py @@ -938,6 +938,46 @@ def test_exclude_type_checking_imports( assert {module_foo_one_file: expected_result} == result +def test_t_string_syntax(): + module_file_to_scan = _module_to_module_file(Module("foo.one")) + + all_module_files = frozenset({module_file_to_scan, _module_to_module_file(Module("foo.two"))}) + file_system = rust.FakeBasicFileSystem( + content_map={ + "/path/to/foo/one.py": """ + import foo.two + # t-strings are only valid in Python 3.14+ + hello = t"Hello" + """ + } + ) + + with override_settings(FILE_SYSTEM=file_system): + result = scanning.scan_imports( + {module_file_to_scan}, + found_packages={ + FoundPackage( + name="foo", + directory="/path/to/foo", + module_files=all_module_files, + ) + }, + include_external_packages=False, + exclude_type_checking_imports=False, + ) + + assert result == { + module_file_to_scan: { + DirectImport( + importer=Module("foo.one"), + imported=Module("foo.two"), + line_number=1, + line_contents="import foo.two", + ), + } + } + + def _module_to_module_file(module: Module) -> ModuleFile: some_mtime = 100933.4 return ModuleFile(module=module, mtime=some_mtime)