Nathaniel Smith wrote on 09/25/2014 07:07 AM:
Indeed. I can think of multiple places where there are compelling reasons to want to hook module attribute lookup:
Lazy loading: [...]
Module attribute deprecation: [...]
I think both of these use cases arise very commonly in long-lived projects, but right now the only ways to accomplish either of these things involve massive disgusting hacks. They are really really hard to do cleanly, and you risk all kinds of breakage in edge-cases (e.g. try reload()'ing a module that's been replaced by an object). So, we haven't dared release anything like this in production, and the above problems just hang around indefinitely.
The reason I brought implicit imports up in isolation from (well, maybe
not isolated enough) supporting a module.__getattr__ protocol
altogether, is that it's much less involved. The former can be added
without also adding the latter and already cover a lot of its use cases.
If module.__getattr__ can be added, I'm all for it. But it also suggests
to enable other class-like features in modules, which might not be so
easy anymore, conceptually.
In contrast, IMO, it is natural to expect package.module to *just work*,
regardless of whether the submodule has already been imported. At least,
if packages were only collections of modules. Maybe, this is the more
fundamental problem with packages. They are more like module/package
hybrids with a mixed-up namespace. This also causes other irritating
issues. E.g.:
package/__init__.py:
foo = "foo"
from . import foo
from . import bar
bar = "bar"
baz = "baz"
# has the following submodules:
package/foo.py: ...
package/bar.py: ...
package/baz.py: ...
user:
>>> package.foo