Commit 9f4dde50 authored by Kirill Smelkov's avatar Kirill Smelkov

pylint: Fix crash on LazyModules if those modules are not actually available

Pygolang installs import hooks for pytest and ipython, to add
exception-chaining support into them(*) _iff_ (if and only if) those
modules are actually used. This works via Importing[1] which
pre-installs artificial modules into sys.modules that catch
__getattribute__ and try to import corresponding module for real on
first access. Usually everything is fine.

But with pylint/astroid, if the checker code happens to run with those
LazyModules installed, and the checked code has `import sys` somewhere,
astroid eventually delves into processing sys, then sys.modules and
wants to represent that sys.modules dict as dict of constant. Then, when
e.g. sys.modules['_pytest'] is processed, corresponding module object is
checked for .__class__, which raises ImportError if pytest is not
actually available:

    ( https://erp5js.nexedi.net/#/test_result_module/20220127-129289AE2/33 )
    ...
    File ".../eggs/astroid-1.3.8-py2.7.egg/astroid/node_classes.py", line 553, in __init__
        for k, v in items.items()]
      File ".../eggs/astroid-1.3.8-py2.7.egg/astroid/node_classes.py", line 962, in const_factory
        return CONST_CLS[value.__class__](value)
      File ".../eggs/Importing-1.10-py2.7.egg/peak/util/imports.py", line 254, in __getattribute__
        _loadModule(self)
      File ".../eggs/Importing-1.10-py2.7.egg/peak/util/imports.py", line 222, in _loadModule
        reload(module)
    ImportError: No module named _pytest

-> Fix it by detecting those lazy modules and not letting them go through
normal const_factory not to crash.

/cc @jerome, @arnau
/reviewed-by @rafael
/reviewed-on nexedi/erp5!1546 and nexedi/slapos!1117

[1] https://pypi.org/project/Importing/

(*) see:
    https://lab.nexedi.com/nexedi/pygolang/blob/pygolang-0.1-0-g7b72d41/golang/_patch/__init__.py
    https://lab.nexedi.com/nexedi/pygolang/blob/pygolang-0.1-0-g7b72d41/golang/_patch/pytest_py2.py#L48-51
    https://lab.nexedi.com/nexedi/pygolang/blob/pygolang-0.1-0-g7b72d41/golang/_patch/ipython_py2.py#L45-48
parent f4c20e20
Pipeline #19509 failed with stage
in 0 seconds