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

gh-120417: Add #noqa to used imports in the stdlib #120421

Merged
merged 9 commits into from
Jun 13, 2024

Conversation

vstinner
Copy link
Member

@vstinner vstinner commented Jun 12, 2024

Tools such as ruff can ignore "imported but unused" warnings if a line ends with "# noqa". It avoids the temptation to remove an import which is used effectively.

Tools such as ruff can ignore "imported but unused" warnings if a
line ends with "# noqa". It avoids the temptation to remove an import
which is used effectively.
Copy link
Member

@AlexWaygood AlexWaygood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Looks much better now, a couple of questions though:

Lib/code.py Outdated Show resolved Hide resolved
Comment on lines 48 to 51
try:
from _collections import _deque_iterator
from _collections import _deque_iterator # noqa
except ImportError:
pass
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test_collections passes for me if I remove this import. Does it need to stay? It was added in 52f96d3

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@erlend-aasland @kumaraditya303: Do you know/recall why this symbol is exposed?

Copy link
Member

@AlexWaygood AlexWaygood Jun 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, test_deque fails if the import is removed. I expected deque to be tested as part of test_collections, but apparently it has its own test file. Could you add a comment that it is (apparently) required to expose it in the collections module in order for deque iterators to be pickled?

======================================================================
ERROR: test_iterator_pickle (test.test_deque.TestBasic.test_iterator_pickle)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/alexw/dev/cpython/Lib/test/test_deque.py", line 640, in test_iterator_pickle
    dump = pickle.dumps((itorg, orig), proto)
_pickle.PicklingError: Can't pickle <class 'collections._deque_iterator'>: attribute lookup _deque_iterator on collections failed

----------------------------------------------------------------------

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I added a comment.

Lib/pydoc.py Outdated
Comment on lines 78 to 80
from _pyrepl.pager import (get_pager, pipe_pager,
plain_pager, tempfile_pager, tty_pager,
plain) # noqa
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which is the import being flagged as unused here? Why does it need to stay?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pydoc.plain() is an alias to _pyrepl.pager.plain(). It has to stay since it's part of pydoc API, and test_pydoc fails if you remove it.

# noqa only applies to the current line, no?

Copy link
Member

@AlexWaygood AlexWaygood Jun 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pydoc.plain() is an alias to _pyrepl.pager.plain(). It has to stay since it's part of pydoc API, and test_pydoc fails if you remove it.

I see, thanks. Maybe add a comment explaining that to the code?

# noqa only applies to the current line, no?

It depends on the tool, the rule and the AST node. For example, in this:

from collections import (  # noqa: F401
    deque,
    OrderedDict,
    ChainMap,
)

the single noqa comment will cause Ruff to ignore the three unused imports deque, OrderedDict and ChainMap, because they constitute a single ImportFrom node in the AST and the noqa comment is applied on the starting line number of the AST node.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved the import to a separated statement and added a comment.

@gpshead
Copy link
Member

gpshead commented Jun 12, 2024

Instead of blanket everything # noqa comments, please make these specific to the thing being disabled. # noqa: unused-import for example. Except that ruff appears to not support human meaningful and thus maintainable suppression comments in favor of inhumane error code numbers in noqa comments? So that might read F401 today.

But at least we could fix those when ruff enters the modern era and names things to be understandable by code maintainers.

@vstinner
Copy link
Member Author

Instead of blanket everything # noqa comments, please make these specific to the thing being disabled.

On a line like import readline # noqa, it's clear that noqa suppress a warning about unused import, no?

So that might read F401 today.

So you suggest using # noqa: F401 instead?

@AlexWaygood
Copy link
Member

AlexWaygood commented Jun 12, 2024

Except that ruff appears to not support human meaningful and thus maintainable suppression comments in favor of inhumane error code numbers in noqa comments? So that might read F401 today.

But at least we could fix those when ruff enters the modern era and names things to be understandable by code maintainers.

it's on our to-do list :-)

Edit: and I see Zanie already said that on the Ruff issue tracker ;)

Copy link
Member

@AlexWaygood AlexWaygood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would also prefer that we ignore a specific linter error (F401) rather than all linter errors. But other than that, this LGTM now, thanks (though some tests seem to be failing)

@gpshead
Copy link
Member

gpshead commented Jun 12, 2024

yep, always list the specific error(s) being ignored in the comment.

@rhettinger rhettinger removed their request for review June 12, 2024 22:20
Lib/operator.py Outdated Show resolved Hide resolved
Copy link
Member

@serhiy-storchaka serhiy-storchaka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

How did you know that all these imports were necessary? Or did you just flag all the names for which you can't confirm redundant imports?

Lib/pydoc.py Outdated Show resolved Hide resolved
@vstinner
Copy link
Member Author

How did you know that all these imports were necessary? Or did you just flag all the names for which you can't confirm redundant imports?

I'm checking for unused imports for 5 years, and every year, I meet the same imports :-) Over time, I learnt which imports are done to populate an API, and which ones can be removed.

You can try to remove them and see the test suite failing.

@serhiy-storchaka
Copy link
Member

I agree with all this, I just wondering how did you find them, because the amount of the work is large, and many cases are not trivial. Removing imports unlit the code breaks is risky, not all can be covered by tests.

@vstinner
Copy link
Member Author

I modified the PR to use # noqa: F401. Hopefully, it seems like warning numbers are standardized between linters.

@vstinner
Copy link
Member Author

I agree with all this, I just wondering how did you find them, because the amount of the work is large, and many cases are not trivial. Removing imports unlit the code breaks is risky, not all can be covered by tests.

I also rely on code review to validate my work :-)

@hugovk
Copy link
Member

hugovk commented Jun 13, 2024

yep, always list the specific error(s) being ignored in the comment.

There's a rule (PGH004 blanket-noqa) to prevent noqas that are missing the specific error. We have it in https://github.com/python/cpython/blob/main/Tools/clinic/.ruff.toml:

"PGH004", # Ban blanket `# noqa` comments (only ignore specific error codes)

Shall we add it to the other one, https://github.com/python/cpython/blob/main/Lib/test/.ruff.toml ?

And maybe add another .ruff.toml for Lib/ or other directories?


I'm checking for unused imports for 5 years, and every year, I meet the same imports :-) Over time, I learnt which imports are done to populate an API, and which ones can be removed.

If we added F401 unused-import to Ruff, these would get flagged by the CI, and we'd have to label the ones we really need with noqa: F401.

@vstinner vstinner merged commit 6ae254a into python:main Jun 13, 2024
34 checks passed
@vstinner vstinner deleted the import_noqa branch June 13, 2024 14:14
@vstinner
Copy link
Member Author

I created a second PR for the 7 files which requires tons of #noqa: #120454.

@vstinner
Copy link
Member Author

Merged, thanks for reviews!

@hugovk: I'm interested by a CI checking for unused imports, it's appealing :-)

@encukou
Copy link
Member

encukou commented Jun 17, 2024

For things that are re-exported for a public API, should add them to __all__ rather than add the linter directive?

@AlexWaygood
Copy link
Member

For things that are re-exported for a public API, should add them to __all__ rather than add the linter directive?

usually IMO, yes

mrahtz pushed a commit to mrahtz/cpython that referenced this pull request Jun 30, 2024
Tools such as ruff can ignore "imported but unused" warnings if a
line ends with "# noqa: F401". It avoids the temptation to remove
an import which is used effectively.
noahbkim pushed a commit to hudson-trading/cpython that referenced this pull request Jul 11, 2024
Tools such as ruff can ignore "imported but unused" warnings if a
line ends with "# noqa: F401". It avoids the temptation to remove
an import which is used effectively.
estyxx pushed a commit to estyxx/cpython that referenced this pull request Jul 17, 2024
Tools such as ruff can ignore "imported but unused" warnings if a
line ends with "# noqa: F401". It avoids the temptation to remove
an import which is used effectively.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants