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