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 !1546 and 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