[Python-ideas] Implicit submodule imports

Thomas Gläßle t_glaessle at gmx.de
Thu Sep 25 13:55:09 CEST 2014


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
        <module ...>

        >>> package.bar
        bar
        >>> import package.bar as bar
        >>> bar # not the module you might expect..
        bar

        >>> package.baz
        baz
        >>> from package import baz
        baz
        >>> import package.baz as baz
        >>> baz
        <module ...>

The "baz" case can be especially confusing. I know, you shouldn't write
code like this. But sometimes it happens, because it's just so easy.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 949 bytes
Desc: OpenPGP digital signature
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20140925/269ccc74/attachment.sig>


More information about the Python-ideas mailing list