Portable code: __import__ demands different string types between 2 and 3

Steven D'Aprano steve+comp.lang.python at pearwood.info
Mon Dec 15 07:02:03 EST 2014


Ben Finney wrote:

> Howdy all,
> 
> What should I do, in a world where all text literals are Unicode by
> default, to make ‘__import__’ work in both Python 2 and 3?

One approach I frequently use is a conditional import. Off the top of my
head, I'd do something like this:


try:
    import builtins  # Python 3.x.
except ImportError:
    # We're probably running Python 2.x.
    import __builtin__ as builtins

# Untested, just to give you an idea of what I mean.
try:
    _ = __import__("sys", fromlist=["version"])
except TypeError:
    # Shadow the built-in with a patched version.
    def __import__(*args, **kwargs):
        if "fromlist" in kwargs:
            kwargs["fromlist"] = [str(name) for name in kwargs["fromlist"]]
        return builtins.__import__(*args, **kwargs)

If you're really brave, you can even monkey-patch builtins with your own
version. Obviously you still need to keep the old version somewhere. A
closure would be perfect for that:

# Again, untested.
def patch_import(original_import=__import__):
    def __import__(*args, **kwargs):
        if "fromlist" in kwargs:
            kwargs["fromlist"] = [str(name) for name in kwargs["fromlist"]]
        return original_import(*args, **kwargs)
    builtins.__import__ = __import__

Monkey-patching builtins.__import__ is one of the few
not-completely-frowned-upon uses of monkey-patching.

Perhaps a better approach might be to eschew the use of __import__ and see
whether the functions in imputil (deprecated) or importlib do what you
need.

https://docs.python.org/2/library/imputil.html
https://docs.python.org/3/library/importlib.html

Aside: __import__ is not recommended for user code.

"Direct use of __import__() is also discouraged in favor of
importlib.import_module()."

https://docs.python.org/3/library/functions.html#__import__



-- 
Steven




More information about the Python-list mailing list