[Python-Dev] Add __exports__ to modules

Tim Peters tim.one@home.com
Mon, 8 Jan 2001 13:48:40 -0500

> Something better to do would be to use
> import foo as _foo

> It's pretty clear that nobody does this now and nobody is going
> to start doing it in the near future. It's too invasive and it
> makes the code too ugly.

Actually, this function is one of my std utilities:

def _pvt_import(globs, modname, *items):
    """globs, modname, *items -> import into globs with leading "_".

    If *items is empty, set globs["_" + modname] to module modname.
    If *items is not empty, import each item similarly but don't
    import the module into globs.
    Leave names that already begin with an underscore as-is.

    # import math as _math
    >>> _pvt_import(globals(), "math")
    >>> round(_math.pi, 0)

    # import math.sin as _sin and math.floor as _floor
    >>> _pvt_import(globals(), "math", "sin", "floor")
    >>> _floor(3.14)

    mod = __import__(modname, globals())
    if items:
        for name in items:
            xname = name
            if xname[0] != "_":
                xname = "_" + xname
            globs[xname] = getattr(mod, name)
        xname = modname
        if xname[0] != "_":
            xname = "_" + xname
        globs[xname] = mod

Note that it begins with an underscore because it's *meant* to be exported
<0.5 wink>.  That is, the module importing this does

    from utils import _pvt_import

because they don't already have _pvt_import to automate adding the
underscore, and without the underscore almost everyone would accidentally
export "pvt_import" in turn.  IOW,

    import M
    from N import M

not only import M, by default they usually export it too, but the latter is
rarely *intended*.  So, over the years, I've gone thru several phases of
naming objects I *intend* to export with a leading underscore.  That's the
only way to prevent later imports from exporting by accident.  I don't
believe I've distributed any code using _pvt_import, though, because it
fights against the language and expectations.  Metaprogramming against the
grain should be a private sin <0.9 wink>.

_metaprogramming-ly y'rs  - tim