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

Don't report unused imports in __init__.py #162

Closed
pyflakes-bot opened this issue May 11, 2013 · 15 comments
Closed

Don't report unused imports in __init__.py #162

pyflakes-bot opened this issue May 11, 2013 · 15 comments

Comments

@pyflakes-bot
Copy link

Original report by asmeurer (@asmeurer?) on Launchpad:


__init__.py files are full of unused import warnings, because all they are are imports. But this is one instance where it is correct to import something and not "use" it.

@pyflakes-bot
Copy link
Author

Original comment by asmeurer (@asmeurer?) on Launchpad:


I see. It is trying to do this, but it only works if the module uses __all__. Isn't it more correct to just ignore all undefined names at the module level scope in an __init__.py file?

@pyflakes-bot
Copy link
Author

Original comment by icordasc (@sigmavirus24?) on Launchpad:


@asmeurer no it shouldn't. There are people who write actually classes and functions in __init__.py. Those people are expecting these errors. There is probably no really good way to ignore some and not others.

@pyflakes-bot
Copy link
Author

Original comment by asmeurer (@asmeurer?) on Launchpad:


But even if you do that, all imported names are going to be used for import purposes. And there will be so many false positives that no one will ever notice a mistake from pyflakes anyway.

@pyflakes-bot
Copy link
Author

Original comment by icordasc (@sigmavirus24?) on Launchpad:


With the same exact example above you can not be certain of that. I could write something that imports a module, refactor and completely forget to remove the import were I to not have pyflakes reporting for it. Why should pyflakes just assume that I'm leaving it there for someone else to import into their library?

In short, the best way to really do this is to use __all__. It's the only reliable way to avoid the unused import warnings since it clearly shows the intent of the module author. If you're using submodules instead and don't wish to have to do:

from sub_module import (exported, names)

etc.

all = [exported, names, ...]

Then do

import sub_module1
import sub_module2

etc.

import sub_modulen

all = []

for i in range(1, n + 1):
all.extend(globals()['sub_module%d' % i].all)

Obviously that's a bit contrived, but you get the point. You can be guaranteed it will execute only once and it won't cause you other troubles with pyflakes.

@pyflakes-bot
Copy link
Author

Original comment by asmeurer (@asmeurer?) on Launchpad:


Why should pyflakes just assume that I'm leaving it there for someone else to import into their library?

Because you're writing it in __init__.py. That's exactly what that file is for. Besides, writing extensive code in __init__.py is (IMO) bad style, and you shouldn't be surprised if pyflakes misses errors because of it.

By the way, what is the general stance for pyflakes aboud false positives vs. false negatives?

@pyflakes-bot
Copy link
Author

Original comment by icordasc (@sigmavirus24?) on Launchpad:


It's bad style in my opinion too, but is far more common than I like.

You're still going to have push back from plenty of people though that there's no checking on __init__.py and they should feel surprised that pyflakes missed errors in it.

@pyflakes-bot
Copy link
Author

Original comment by florent.x (@florentx?) on Launchpad:


IMHO, the __all__ declaration is the only safe way to prevent this warning. I agree with Ian.

http://docs.python.org/3.4/tutorial/modules.html#importing-from-a-package

If you need more flexibility, Flake8 "# noqa" should help.

@pyflakes-bot
Copy link
Author

Original comment by asmeurer (@asmeurer?) on Launchpad:


Today's update to PEP 8 says, "Wildcard imports (from import *) should be avoided, as they make it unclear which names are present in the namespace, confusing both readers and many automated tools. There is one defensible use case for a wildcard import, which is to republish an internal interface as part of a public API (for example, overwriting a pure Python implementation of an interface with the definitions from an optional accelerator module and exactly which definitions will be overwritten isn't known in advance).

"When republishing names this way, the guidelines below regarding public and internal interfaces still apply."

Is that argument enough to change this behavior?

@pyflakes-bot
Copy link
Author

Original comment by exarkun (@exarkun?) on Launchpad:


No. Be explicit about the names you want to export. Define an __all__ on your package.

@pyflakes-bot
Copy link
Author

Original comment by asmeurer (@asmeurer?) on Launchpad:


It seems like __all__ is unnecessary complexity for most packages, and may make the import time unnecessarily slower (I haven't timed it, though, so I could be wrong about the speed).

@pyflakes-bot
Copy link
Author

Original comment by bjodah on Launchpad:


I completely agree with @asmeurer on this. It has always been and still is my biggest concern with pyflakes.

@pyflakes-bot
Copy link
Author

Original comment by pierre-sassoulas on Launchpad:


Maybe flake could give a different more explicit warning message and not F401, when there is unused import in an __init__ file. Something like "x imported but unused, declare with __all__ if you want to explicitly export this name".

@pyflakes-bot
Copy link
Author

Original comment by alevis on Launchpad:


Still an inconvenience.

@vbrozik
Copy link

vbrozik commented Feb 13, 2022

I think that in case __init__.py contains only imports an no other commands, pyflakes should not complain.

@asottile
Copy link
Member

use __all__ to indicate the exported members and pyflakes will not complain

@PyCQA PyCQA locked as resolved and limited conversation to collaborators Feb 13, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants