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.
[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