Make Binding::range() point to the range of a type parameter's name, not the full type parameter#15935
Conversation
… not the full type parameter
MichaReiser
left a comment
There was a problem hiding this comment.
Haha nice find.
Do you expect that this breaks any diagnostic range? E.g. do you know if the binding range is used in any diagnostic / fix code? I know, this is probably hard to figure out, just something that I'm slightly worried about but relying on our tests/user reports might be fine to catch this.
|
It's very hard to tell... :(
Agreed, and this is partly why I wanted to separate this out as a separate PR from #15862 (see my comment in #15862 (comment)). This is also why I worked around the bug in #15888 rather than fixing it prior to making that PR... but then @ntBre ran into exactly the same bug the next day in #15862! And I don't think it'll be so easy to workaround the bug in his PR. Plus, The fact that none of our snapshots change and the ecosystem check is clean gives me confidence that, if this does change our user-facing behaviour in some cases, they're at least rare/edge cases. And PEP-695 type parameters are anyway new syntax that are still rarely used in the real world. So I think we're good here. |
* main: (66 commits) [red-knot] Use ternary decision diagrams (TDDs) for visibility constraints (#15861) [`pyupgrade`] Rename private type parameters in PEP 695 generics (`UP049`) (#15862) Simplify the `StringFlags` trait (#15944) [`flake8-pyi`] Make `PYI019` autofixable for `.py` files in preview mode as well as stubs (#15889) Docs (`linter.md`): clarify that Python files are always searched for in subdirectories (#15882) [`flake8-pyi`] Make PEP-695 functions with multiple type parameters fixable by PYI019 again (#15938) [red-knot] Use unambiguous invalid-syntax-construct for suppression comment test (#15933) Make `Binding::range()` point to the range of a type parameter's name, not the full type parameter (#15935) Update black deviations (#15928) [red-knot] MDTest: Fix line numbers in error messages (#15932) Preserve triple quotes and prefixes for strings (#15818) [red-knot] Hand-written MDTest parser (#15926) [`pylint`] Fix missing parens in unsafe fix for `unnecessary-dunder-call` (`PLC2801`) (#15762) nit: docs for ignore & select (#15883) [airflow] `BashOperator` has been moved to `airflow.providers.standard.operators.bash.BashOperator` (AIR302) (#15922) [`flake8-logging`] `.exception()` and `exc_info=` outside exception handlers (`LOG004`, `LOG014`) (#15799) [red-knot] Enforce specifying paths for mdtest code blocks in a separate preceding line (#15890) [red-knot] Internal refactoring of visibility constraints API (#15913) [red-knot] Implicit instance attributes (#15811) [`flake8-comprehensions`] Handle extraneous parentheses around list comprehension (`C403`) (#15877) ...
Summary
A PEP-695 type parameter creates a binding that is tracked by Ruff's semantic model:
But if the type parameter has a bound or constraint, the range of the
Bindingrecorded by Ruff's semantic model includes the bounds or constraints of the type parameter:This is problematic, as
S: intis not a valid Python identifier, and nor isT: (int, str). All other bindings in Ruff's semantic model have their range point to the name that is bound, not the full expression/statement that creates the binding. A specific effect that this has is that if you have aBindingxthat points to a PEP-695 type parameter, callingx.name(source)does not actually return the name of the PEP-695 type parameter. Instead, ifxpointed to the binding forTin the example above, callingx.name(source)would return"T: int", and ifxpointed to the binding forU, callingx.name(source)would return"U: (int, str)".This PR changes the range for PEP-695 bindings so that it points to the name that is bound by the type parameter. This makes these
Bindings consistent with other bindings, makesBinding::name()work as expected in all situations, allows us to simplify some code in the implementation of the PYI019 rule, and unblocks #15862Test Plan
cargo test -p ruff_linter --libCo-authored-by: Brent Westbrook [email protected]