mirror of
https://github.com/kucherenko/jscpd.git
synced 2026-09-19 08:11:03 +08:00
d47d2dc38a
Two defects found by checking every finding on the ten trending Python repositories against an import graph rebuilt independently of the tool. They accounted for 280 wrong findings out of 1,915; 4 remain, both in cases where the checker is the generous one. A quoted type annotation is a forward reference, not data. `def f(m: "torch.nn.Conv1d")` reads `torch` exactly as surely as the unquoted form does, and the `if TYPE_CHECKING:` idiom exists so that it *is* quoted — the name may not be importable at run time. Without parsing them the import that supplies the name looks unused, which is what made 275 of 834 unused-import findings wrong: 36% of the category, every one of them reported at full confidence. The walk now tracks whether it is inside an annotation and parses string literals found there with ruff's own `parse_string_annotation`, which resolves in the source file's coordinates so the references keep real offsets. Outside an annotation a string stays what it was: weak evidence, never a read. Absolute imports now also resolve against the roots the tree implies, through a new optional `Analyzer::import_roots`. Python derives the parent of every top-level package, which is what makes a `src/` layout work from a file that belongs to no package: `utils/check_repo.py` importing `transformers.testing_utils` matched no scan root and no package of its own. Derived roots are tried last — a scan root is what the user asked for, this is an inference. Claude-Session: https://claude.ai/code/session_01WztdFKZAwW9b51iJe9zhtV