• Arnaud Fontaine's avatar
    py2/py3: Fix __import__ fromlist argument. · 73c73960
    Arnaud Fontaine authored
    __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's avatarKazuhiko SHIOZAKI <kazuhiko@nexedi.com>
    73c73960
module.erp5.XMLSyncUtils.py 7.81 KB