ruff icon indicating copy to clipboard operation
ruff copied to clipboard

ruff incorrectly flags imports included in __all__

Open john-dupuy opened this issue 2 years ago • 2 comments

Steps to reproduce

  1. Create two files, __init__.py and blah.py.

blah.py

class MyBlahClass:
    pass

__init__.py

from blah import MyBlahClass

__all__ = ["MyBlahClass"]
  1. Run ruff

Expected results 2. ruff should not have an issue with the import in MyBlahClass as it's included in __all__.

Actual results 2. ruff reports a F401, class imported but unused

ruff output:

ruff . -v  
[2022-09-01][15:17:28][ruff][DEBUG] Identified files to lint in: 25.778µs
[2022-09-01][15:17:28][ruff::linter][DEBUG] Cache hit for: ./blah.py
[2022-09-01][15:17:28][ruff::linter][DEBUG] Cache hit for: ./__init__.py
[2022-09-01][15:17:28][ruff][DEBUG] Checked files in: 588.674µs
Found 1 error(s).

./__init__.py:1:1: F401 `blah.MyBlahClass` imported but unused

flake8 output:

flake8 . -v
flake8.checker            MainProcess     53 INFO     Making checkers
flake8.checker            MainProcess     54 INFO     Checking 2 files
flake8.main.application   MainProcess     71 INFO     Finished running
flake8.main.application   MainProcess     71 INFO     Reporting errors
flake8.main.application   MainProcess     71 INFO     Found a total of 0 violations and reported 0

john-dupuy avatar Sep 01 '22 22:09 john-dupuy

https://github.com/charliermarsh/ruff/pull/34 potentially related?

john-dupuy avatar Sep 01 '22 22:09 john-dupuy

Thanks, that's a legitimate bug, will fix :)

charliermarsh avatar Sep 02 '22 00:09 charliermarsh

Fixed in #87.

charliermarsh avatar Sep 02 '22 14:09 charliermarsh

Thanks for the quick fix @charliermarsh! :slightly_smiling_face:

john-dupuy avatar Sep 06 '22 14:09 john-dupuy

@charliermarsh I found a slight wrinkle in this fix, doesn't quite work with importing a module.

Consider:

foo/
    __init__.py
bar/
    __init__.py

Then in foo/init.py:

import bar

__all__ = ["bar"]

Ruff detects as an unused import. But if I give it an explicit name:

import bar as bar

__all__ = ["bar"]

Ruff reports no issues. Shouldn't both be detected as no issues?

phillipuniverse avatar Dec 05 '22 15:12 phillipuniverse

Yeah looks like that first case is a bug.

charliermarsh avatar Dec 05 '22 15:12 charliermarsh

(The explicit re-export (import bar as bar) is always protected.)

charliermarsh avatar Dec 05 '22 15:12 charliermarsh