-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Fix variables in __all__ being flagged by --no-implicit-reexport #7099
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
Conversation
Following @JukkaL's suggestion in #7042 (comment), I tried to look at the code for a couple of hours and this is what I came up with. I am not sure it is correct at all, or if it has any unexpected consequences, so please review carefully (once/if it passes CI) :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks solid except for the one subtlety I mentioned.
mypy/newsemanal/semanal.py
Outdated
if '__all__' in self.globals: | ||
for name, g in self.globals.items(): | ||
if name not in self.all_exports: | ||
if name in self.all_exports: | ||
g.module_hidden = False |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at the docs for module_public
and module_hidden
:
- public means that it will be picked up by an
import *
- hidden means that it can't be imported at all
So I think we need to set public = True
when the name does appear to prevent it from being spurious excluded from import *
.
@msullivan Yes, testing with If I understand
But the "cannot be imported directly, included in import *" case, I think makes no sense? That is, I think that if a symbol is imported with If true, this suggests that instead of two booleans, an enum should be used, maybe something like this: class SymbolModuleVisibility:
"""The visibility of the symbol in a module, i.e. whether and how another module can import the symbol from this module.
Only relevant for module symbol tables.
"""
# Another module cannot import this symbol.
hidden = 1
# Another module can import this symbol directly.
exported = 2
# Another module can import this symbol directly, and with `from <module> import *`.
exported_public = 3 Things which affect visibility (AFAICS) are:
Do you think it makes sense to get into that, or just do the fix you suggested and be done with it? |
Removing the potential invalid state by using defined constants seems reasonable. (Unfortunately we can't use an |
1defc19
to
6022dac
Compare
I applied @msullivan's suggestion and also adjusted the docs. I also added a second commit which switches the code to use an enum as proposed in the comment above. I want to add more test cases and probably adjust the terminology in the second commit, so marking as WIP. |
mypy/nodes.py
Outdated
Only relevant for module symbol tables. | ||
""" | ||
# Another module cannot import this symbol. | ||
hidden = 1 # type: Final |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make these names all caps
Left a comment in the issue #7042 (comment) on what's blocking this. |
@bluetech |
@ilevkivskyi Sorry for not following up. This needs some work/research, in particular spec'ing out the rules for each of these:
per each type of import and export (partial list?)
and I haven't had enough patience to do it. For now I'd like to close it, but instead I'll just try to go back to the initial commit and rebase which at least makes the |
The natural expectation is that when a variable is explicitly added to a module's `__all__`, the module explicitly means to export it. Previously, this was not the case, and a `from [..] import [..] as [..]` reexport was required by `--no-implicit-export` even if the variable is listed in `__all__`. Fixes python#7042
6022dac
to
133ba62
Compare
Updated as described above. |
I think we can keep this open (after #7361 is merged) as a place to discuss possible follow-up refactoring/clean-up that will replace |
…abled (#7361) Based on #7099. Currently, in regular files, symbols imported into module A with `from B import *` are considered explicitly exported from module A as well, i.e. they are considered part of module's A public API. This behavior makes sense in stub files as a shorthand (and is specified in PEP 484), but for regular files I think it is better to be explicit: add the symbols to `__all__`. Fixes #7042 Further discussion: #7042 (comment)
The natural expectation is that when a variable is explicitly added to a
module's
__all__
, the module explicitly means to export it.Previously, this was not the case, and a
from [..] import [..] as [..]
reexport was required by
--no-implicit-export
even if the variable islisted in
__all__
.Fixes #7042