Skip to content
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

UP035 autofix breaks code when a typing-module alias is used in a PEP-604 union in combination with a string #15937

Open
PhilipVinc opened this issue Feb 4, 2025 · 9 comments
Labels
bug Something isn't working fixes Related to suggested fixes for violations

Comments

@PhilipVinc
Copy link

PhilipVinc commented Feb 4, 2025

Description

The following code is correct

from typing import Iterable
a = Iterable['ciao'] | 'ciao'

However it gets tagged as wrong by UP35 and automatically fixed to

from collections.abc import Iterable
a = Iterable['ciao'] | 'ciao'

And the fixed code is wrong.

@AlexWaygood AlexWaygood added bug Something isn't working fixes Related to suggested fixes for violations labels Feb 4, 2025
@AlexWaygood
Copy link
Member

AlexWaygood commented Feb 4, 2025

I'm marking this issue as a bug since it's true that the autofix changes behaviour here, and ideally we should fix that. FWIW, though, I'd recommend always quoting the entire union if you're using forward references in a PEP-604 union, e.g.

from collections.abc import Iterable
a = 'Iterable[ciao] | ciao'

You can get unpredictable results (like this) otherwise. This is the official advice given at https://docs.python.org/3/library/stdtypes.html#types-union

@Daverball
Copy link
Contributor

The original code is wrong as well, see runtime-string-union for why.

However, since you're using an implicit type alias, ruff can't know that using | here is not allowed. If you want ruff to be able to detect TC010 here, then you need to switch to an explicit type alias: https://play.ruff.rs/9bd2d888-0d78-43af-bc0e-2e7b8da5d5dc

@AlexWaygood
Copy link
Member

The original code is wrong as well

I'd say that the original code is "ill-advised" @Daverball, but it's true that it does work at runtime :-)

@Daverball
Copy link
Contributor

You're right. I didn't know the aliases in the typing module had some special magic to convert strings to ForwardRef.

@AlexWaygood
Copy link
Member

I didn't know the aliases in the typing module had some special magic to convert strings to ForwardRef.

Yeah... and it's arguably somewhat regrettable that they do, since it leads to highly confusing situationsn like this :/ but it can't realistically be reversed now

@PhilipVinc
Copy link
Author

Ah, I was not aware that even my code was 'ill-advised' wrong!
Thanks for letting me know!

However my point stands...
I had some 'working' (albeit incorrect) code that ruff broke when I added UP rules.
I was not aware of TC rules.
I imagine you'd like to avoid this happening.

It might be a good idea to suggest turning on TC010 with UP035 and some other UP rules as well?

@PhilipVinc
Copy link
Author

(Yeah, I acknowledge that the 'right' and 'wrong' adjectives I used in the original post was a bit strong. Sorry, I was just trying to open the issue quickly because I had some other things to attend to)

@AlexWaygood
Copy link
Member

However my point stands...
I had some 'working' (albeit incorrect) code that ruff broke when I added UP rules.
I was not aware of TC rules.
I imagine you'd like to avoid this happening.

Yes, we agree that this is a bug in Ruff that should be fixed :-) The autofix for this rule isn't meant to change the behaviour of your code!

It might be a good idea to suggest turning on TC010 with UP035 and some other UP rules as well?

Hmm, not sure -- this is the first time I've seen this come up, so I don't think many people run into this issue.

@Daverball
Copy link
Contributor

Daverball commented Feb 4, 2025

The easiest way to address this would probably be to mark the fix as unsafe if the parent node to any of the references is a union BinOp and either the node directly to the left or directly to the right is a string.

Eventually if #15222 or #15635 gets merged, we could reuse that fix to extend the quotes and make the fix safe again if it doesn't get rid of any comments.

@AlexWaygood AlexWaygood changed the title UP035 may leads to broken code UP035 autofix breaks code when a typing-module alias is used in a PEP-604 union in combination with a string Feb 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working fixes Related to suggested fixes for violations
Projects
None yet
Development

No branches or pull requests

3 participants