[pyflakes] Fix preview-mode bugs in F401 when attempting to autofix unused first-party submodule imports in an __init__.py file#12569
Conversation
pyflakes] Fix preview-mode infinite loop when attempting to autofix unused first-party submodule import in an __init__.py file that has an __all__ definitionpyflakes] Fix preview-mode infinite loop in F401 when attempting to autofix unused first-party submodule import in an __init__.py file that has an __all__ definition
|
|
Will this fix #12570 ? |
Doesn't look like it (not as the PR currently stands, anyway). I can still repro that infinite loop even with this PR branch. |
|
I'm still looking into it, but it looks like #12570 is a distinct bug from the one this PR is fixing. So we'll fix it, but not in this PR 👍 |
MichaReiser
left a comment
There was a problem hiding this comment.
LGTM.
What's the reason that you decided not to add sub imports (by adding a) to __ALL__? Is it because that's not what sub imports are commonly used for?
Submodule imports have... odd semantics in Python. Here's what happens if I import a regular module: the >>> globals().keys()
dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__'])
>>> import email
>>> globals().keys()
dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', 'email'])
<module 'email' from '/Users/alexw/.pyenv/versions/3.12.4/lib/python3.12/email/__init__.py'>That's not what happens with a submodule import, however: Python 3.12.4 (main, Jun 12 2024, 09:54:41) [Clang 15.0.0 (clang-1500.3.9.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import email.utils
>>> globals().keys()
dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', 'email'])
>>> email
<module 'email' from '/Users/alexw/.pyenv/versions/3.12.4/lib/python3.12/email/__init__.py'>
>>> email.utils
<module 'email.utils' from '/Users/alexw/.pyenv/versions/3.12.4/lib/python3.12/email/utils.py'>In the REPL snippet above, the
Possibly we could autofix this by adding |
|
I might be missing some context here, but if we autofix this: to this: Then I think we should also autofix this: to this: It doesn't make sense to me that we would remove |
|
I don't think you're missing something! I think I just spent too long tracking down the source of the bug, and didn't think hard enough about what the correct autofix should be. I'll make that change. |
|
I found another bug! If you have |
c12ec11 to
670c0b5
Compare
670c0b5 to
0a74bc8
Compare
|
I pushed some updates. They required a bit of refactoring as the code for this rule is quite complex. To summarise, if you have an unused first-party submodule import (e.g.
The error message has also changed slightly if you have an unused import in an
I think that's an improvement. If it's not a first-party import, there's very little chance that the user wants it to be reexported, either by adding it to |
pyflakes] Fix preview-mode infinite loop in F401 when attempting to autofix unused first-party submodule import in an __init__.py file that has an __all__ definitionpyflakes] Fix preview-mode bugs in F401 when attempting to autofix unused first-party submodule imports in an __init__.py file
Summary
Fixes #12513.
To summarise, if you have an unused first-party submodule import (e.g.
import submodule.a) in an__init__.pyfile:__all__definition:import submodule.a as submodule.a.__all__definition:"submodule"to__all__in our autofixThe error message has also changed slightly if you have an unused import in an
__init__.pyfile that isn't a first-party import. This was a side effect of the refactoring, but I think it's for the better. Forimport sysin an__init__.pyfile:I think that's an improvement. If it's not a first-party import, there's very little chance that the user wants it to be reexported, either by adding it to
__all__or by using a redundant alias, so the more concise error message feels like an improvement to me.Test Plan
cargo test -p ruff_linter --lib