Open calestyo opened 1 year ago
'module names' means names in the module, at the top level, as opposed to names in classes and functions in the module. In 'from module import submod' will import 'submod' even though 'submod' is not already a module name (name in the module). Unless others think the existing doc unclear, this should be closed.
I guess one can read it like that... but I'd expect most people will understand "module names" as "the names of modules" and not "names at the top-level within modules". I personally would even understand a phrase like "a module's names" (as if the module itself could have more than one name) like that.
IMO that's especially emphasised as the example given along: https://github.com/python/cpython/blob/da98ed0aa040791ef08b24befab697038c8c9fd5/Doc/tutorial/modules.rst?plain=1#L510 uses only names that are names of modules.
Just for the records... I found numerous stackoverflow Q&As, which seem to imply just the wrong understanding of __all__
, i.e. that within __init__.py
it would only refer to modules (not any names within __init__.py
).
Take e.g. this one: https://stackoverflow.com/a/67143260 which even refers to the section of the tutorial I ways also referring to.
There was also another on which even had considerable upvotes... but I cannot find it anymore (had it on the smartphone and st**id Firefox there doesn't have a history).
I agree now that the tutorial section is confusing.
Maybe a way to improve it (i.e. explaining what happens when from foo import someName
generally) is to rather follow the "The from form uses a slightly more complex process:" in:
https://docs.python.org/3/reference/simple_stmts.html#import
That is by itself a bit confusing (at least for noobs ^^), but I'd interpret is as follows:
1st load foo
2nd look for the name someName
inside foo
3rd if not found, then "from within" foo
, try to import someName
4th repeat 2nd and if still nothing, raise
5th otherwise use whatever was found (first a name defined inside foo
, which could again be a module, then the "automatically" imported module
AFAICS, this generally applies, regardless of whether its a module or a package.
Not sure how to best write this in simple words... maybe that from
first tries to import an item (module, package, class, func, etc.) actually defined (includes imported) inside foo
, and only if that yielded nothing, there's an auto import.
Documentation
1) Forgive me if I'm wrong (still being a Python noob ^^), but testing seems to show that the following is only half the truth: https://github.com/python/cpython/blob/da98ed0aa040791ef08b24befab697038c8c9fd5/Doc/tutorial/modules.rst?plain=1#L501-L504
This says
__all__
would be module names only (well it doesn't explicitly say so, but neither does it mention anything else), but in fact (or at least from some poor man testing I've did), it first seems to take any "items" (functions, vars, etc.) defined inside the package itself (i.e. within__init__.py
and only if that doesn't exist (for a name listed in__all__
), it seems to try importing a module/subpackage thereof.Especially when considering: https://github.com/python/cpython/blob/da98ed0aa040791ef08b24befab697038c8c9fd5/Doc/tutorial/modules.rst?plain=1#L474-L478 mentioned just above, where it's explicitly told that with
from bla import *
takes first the in-package items and only then modules/subpackages... it may seem to the reader as if__all__
would be different, and really just take modules (as it says right now).2) Another thing, which could perhaps be improved is the case, when importing from a package, which contains a module/subpackage of the same name:
Consider e.g.:
foo/__init__.py
:foo/foo.py
:and then using:
AFAIU, the "local"
foo
wherefoo.bar
is0
would be overwritten byfoo.foo
, thusfoo.bar
would be1
.Now one might argue: package author's fault, if he writes stupid package/module names and
__all__
but the above, I think, would even happen with e.g.__all__ = ["somethingElse"]
when doing:as explained here: https://github.com/python/cpython/blob/da98ed0aa040791ef08b24befab697038c8c9fd5/Doc/tutorial/modules.rst?plain=1#L520-L531
Thanks, Chris.