py2/py3: Fix __import__ fromlist argument.
__import__ `fromlist` argument was wrong. It was working anyway with Python2 but
not anymore with Python3, raising a `ModuleNotFoundError` exception. According
to Python `__import__(name, globals, locals, fromlist)` documentation:
When the `name` variable is of the form `package.module`, normally, the
top-level package (the `name` up till the first dot) is returned, *not* the
module named by `name`. However, when a non-empty `fromlist` argument is
given, the module named by `name` is returned.
Thus, the following patterns were wrong:
* __import__(MODULE_NAME, globals(), locals(), MODULE_NAME)
=> Iterate through each character of MODULE_NAME as fromlist is expected to
be a list/tuple.
* __import__(MODULE_NAME, globals(), locals(), [MODULE_NAME])
=> This works but actually tries to import MODULE_NAME object from
MODULE_NAME module (no error if it cannot).
The goal of such __import__ calls were for __import__ to return the right-end
module instead of the top-level package. In such case, `fromlist=['']` is the
way to go as it __import__ does not check if the object exists in the module if
it's an empty string. However, it is even better and easier to read to use
importlib.import_module() for that...
Also, add `from __future__ import absolute_import` because python2 tries both
relative and absolute import (level=-1 __import__ parameter) whereas python3
does absolute import by default (level=0).
Co-authored-by: Kazuhiko SHIOZAKI <kazuhiko@nexedi.com>
Showing
Please register or sign in to comment