-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TC003’s rewritten annotations have syntax errors and type-checking problems #14538
Comments
This looks to be the culprit, instead of properly handling 1 and 0 element tuples, 0 element tuples get skipped by ruff/crates/ruff_linter/src/rules/flake8_type_checking/helpers.rs Lines 397 to 410 in 4ba847f
Should be a fairly easy fix, but I won't have time to get around to it today. So if someone else wants to write a couple of test cases and handling for those two cases, go right ahead. For 0 element tuples you just have to |
There are probably additional corner cases though, i.e. the ones where the tuple needs to be enclosed in parentheses in order to be syntactically distinguishable. So something like However it's somewhat questionable to quote anything containing But we could make certain we avoid bad cases by marking the fix invalid, as soon as we see an |
I'm gonna take a stab at this. It shouldn't actually be too hard to fix the other corner-cases either, since most nodes aren't traversed manually and just rely on There's still a larger of issue of whether or not we should allow any of the references inside type definitions to be quoted, when that type definition contains an |
The longer I look at this the more subtle problems stick out at me. The approach with a custom visitor that tries to get away with handling just a small subset of nodes is never going to be sound and by the time it is sound we may just have duplicated all the code of We will either need to extend |
@charliermarsh Would you be opposed to adding a boolean field to But it also seems like the most efficient way to detect and expand forward references in It might also be possible to leverage the cache of parsed forward references to detect whether or not Or my least favorite way: Copy Or we just give up for now and only provide a naïve fix, that either doesn't expand nested quotes, that are safe to expand or only provides a fix in fewer cases where we don't have to worry about the complexity of nested quotes (which would essentially mean reverting to what we had before switching to this more powerful but broken version or something even more simple). |
Actually, tagging wouldn't handle nested forward references properly either, unless the forward reference is already sitting parsed in the cache and has already been visited by the semantic model. So it's probably not worth adding this to the AST after all. Maybe it would be better to add a separate opinionated rule about nested forward references and the fix for that would remove one level of nesting at a time. Then we could rely on repeated fixes eventually giving us the desired result. |
It might also not be possible because you would have to mutate the tree in the semantic model, or use a
The challenge is that there's no guarantee that this rule is enabled or that the rule is run and fixed first. I haven't studied the problem in detail but is the rewrite a common problem? Could we just not emit a fix in those cases? |
That's pretty much how it worked previously IIRC, if there were any quotes at all in the unparsed expression no fix would be emitted. But since I assume it would be easy to write a fix that always works, all you'd have to do is put the unparsed expression into a new The major drawback to this version of the fix would be that you would introduce nested quotes for existing forward references, which usually is undesirable (I can imagine that there are some corner cases in runtime typing where nested forward references are the only way to make some code work, but that should be rare, I certainly have never seen it out in the wild). Nested quotes for
I can see how it would be a problem for a type expression that already contains nested forward references, but now needs to be quoted as a whole. In which case the two fixes would overlap. I don't really know how Ruff deals with overlapping edits. But the other way around it seems unproblematic to me. If quoting the annotation introduces nested annotations, then if someone cares about getting rid of those they will be flagged by the other rule and subsequently fixed. The fixes should always stabilize this way. |
@MichaReiser I guess the most sensible approach would be to extract My only concern would be that the trait would look a bit arbitrary, since it would be tailored exactly for this use-case, when there may well be other |
Actually, one common hook at the start of Edit: Looks like this doesn't quite work either, since we would also need a post-traversal hook, so we can pop the current annotation state off the stack. But those two hooks together should be able to do a lot of different things. |
The fix for TC003 sometimes makes Ruff fail or introduces type-checking problems when
lint.flake8-type-checking.quote-annotations = true
in Ruff 0.8.0.Here are some examples of type-checking problems. The first two make the types invalid. The rest change the types’ metadata. Metadata can be any Python expression and can be interpreted by any arbitrary tool, so Ruff should not make any assumptions about it or modify it beyond simple syntactic transformations like switching quotation marks.
Here is an example of a failure.
The text was updated successfully, but these errors were encountered: