You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I encountered this when attempting to lint my own project which is using the simplekml package (pip install simplekml).
simplekml has functionality to monkey-patch xml.dom.minidom.Element with a special class, simplekml.KmlElement, which provides a special writexml method, while inheriting the monkey-patched Element class.
Apparently, astroid does not like this monkey patching behavior, and appears to enter an infinite loop when trying to infer the parent class. This is probably due to KmlElement overwriting what is already declared as it's parent?
Anyway, I've reduced the test down to the two files in the attached zip file, extracting those should be enough.
extract the files from the monkeypatch.zip file
pylint monkeypatch.py
Current behavior
monkeypatch.py:8:52: C0303: Trailing whitespace (trailing-whitespace)
monkeypatch.py:1:0: C0114: Missing module docstring (missing-module-docstring)
monkeypatch.py:3:0: C0115: Missing class docstring (missing-class-docstring)
Traceback (most recent call last):
File "/usr/lib/python3.6/runpy.py", line 193, in _run_module_as_main
"main", mod_spec)
File "/usr/lib/python3.6/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/usr/local/lib/python3.6/dist-packages/pylint/main.py", line 7, in
pylint.run_pylint()
File "/usr/local/lib/python3.6/dist-packages/pylint/init.py", line 23, in run_pylint
PylintRun(sys.argv[1:])
File "/usr/local/lib/python3.6/dist-packages/pylint/lint.py", line 1731, in init
linter.check(args)
File "/usr/local/lib/python3.6/dist-packages/pylint/lint.py", line 1004, in check
self._do_check(files_or_modules)
File "/usr/local/lib/python3.6/dist-packages/pylint/lint.py", line 1165, in _do_check
self.check_astroid_module(ast_node, walker, rawcheckers, tokencheckers)
File "/usr/local/lib/python3.6/dist-packages/pylint/lint.py", line 1252, in check_astroid_module
walker.walk(ast_node)
File "/usr/local/lib/python3.6/dist-packages/pylint/utils/ast_walker.py", line 77, in walk
self.walk(child)
File "/usr/local/lib/python3.6/dist-packages/pylint/utils/ast_walker.py", line 74, in walk
callback(astroid)
File "/usr/local/lib/python3.6/dist-packages/pylint/checkers/typecheck.py", line 845, in visit_classdef
metaclass = node.declared_metaclass()
File "/usr/local/lib/python3.6/dist-packages/astroid/scoped_nodes.py", line 2594, in declared_metaclass
for baseobj in base.infer(context=context):
File "/usr/local/lib/python3.6/dist-packages/astroid/decorators.py", line 141, in raise_if_nothing_inferred
yield from generator
File "/usr/local/lib/python3.6/dist-packages/astroid/decorators.py", line 95, in wrapped
res = next(generator)
File "/usr/local/lib/python3.6/dist-packages/astroid/inference.py", line 311, in infer_attribute
yield from owner.igetattr(self.attrname, context)
File "/usr/local/lib/python3.6/dist-packages/astroid/bases.py", line 133, in _infer_stmts
for inferred in stmt.infer(context=context):
File "/usr/local/lib/python3.6/dist-packages/astroid/util.py", line 160, in limit_inference
yield from islice(iterator, size)
File "/usr/local/lib/python3.6/dist-packages/astroid/context.py", line 113, in cache_generator
for result in generator:
.....
File "/usr/local/lib/python3.6/dist-packages/astroid/decorators.py", line 95, in wrapped
res = next(generator)
File "/usr/local/lib/python3.6/dist-packages/astroid/inference.py", line 287, in infer_attribute
for owner in self.expr.infer(context):
File "/usr/local/lib/python3.6/dist-packages/astroid/util.py", line 160, in limit_inference
yield from islice(iterator, size)
File "/usr/local/lib/python3.6/dist-packages/astroid/context.py", line 113, in cache_generator
for result in generator:
File "/usr/local/lib/python3.6/dist-packages/astroid/decorators.py", line 131, in raise_if_nothing_inferred
yield next(generator)
File "/usr/local/lib/python3.6/dist-packages/astroid/decorators.py", line 92, in wrapped
generator = _func(node, context, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/astroid/inference.py", line 197, in infer_name
context = contextmod.copy_context(context)
File "/usr/local/lib/python3.6/dist-packages/astroid/context.py", line 155, in copy_context
return context.clone()
File "/usr/local/lib/python3.6/dist-packages/astroid/context.py", line 102, in clone
clone = InferenceContext(self.path, inferred=self.inferred)
RecursionError: maximum recursion depth exceeded while calling a Python object
Expected behavior
Ideally this weird monkeypatch behavior should be tolerated (perhaps with a warning from pylint?).
Thanks for the report! I'd have to dive deep to figure out why the recursion happens, but as you mentioned it's definitely related to the monkeypatching overwriting an existing attribute.
Steps to reproduce
monkeypatch.zip
I encountered this when attempting to lint my own project which is using the simplekml package (pip install simplekml).
simplekml has functionality to monkey-patch xml.dom.minidom.Element with a special class, simplekml.KmlElement, which provides a special writexml method, while inheriting the monkey-patched Element class.
Apparently, astroid does not like this monkey patching behavior, and appears to enter an infinite loop when trying to infer the parent class. This is probably due to KmlElement overwriting what is already declared as it's parent?
Anyway, I've reduced the test down to the two files in the attached zip file, extracting those should be enough.
Current behavior
monkeypatch.py:8:52: C0303: Trailing whitespace (trailing-whitespace)
monkeypatch.py:1:0: C0114: Missing module docstring (missing-module-docstring)
monkeypatch.py:3:0: C0115: Missing class docstring (missing-class-docstring)
Traceback (most recent call last):
File "/usr/lib/python3.6/runpy.py", line 193, in _run_module_as_main
"main", mod_spec)
File "/usr/lib/python3.6/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/usr/local/lib/python3.6/dist-packages/pylint/main.py", line 7, in
pylint.run_pylint()
File "/usr/local/lib/python3.6/dist-packages/pylint/init.py", line 23, in run_pylint
PylintRun(sys.argv[1:])
File "/usr/local/lib/python3.6/dist-packages/pylint/lint.py", line 1731, in init
linter.check(args)
File "/usr/local/lib/python3.6/dist-packages/pylint/lint.py", line 1004, in check
self._do_check(files_or_modules)
File "/usr/local/lib/python3.6/dist-packages/pylint/lint.py", line 1165, in _do_check
self.check_astroid_module(ast_node, walker, rawcheckers, tokencheckers)
File "/usr/local/lib/python3.6/dist-packages/pylint/lint.py", line 1252, in check_astroid_module
walker.walk(ast_node)
File "/usr/local/lib/python3.6/dist-packages/pylint/utils/ast_walker.py", line 77, in walk
self.walk(child)
File "/usr/local/lib/python3.6/dist-packages/pylint/utils/ast_walker.py", line 74, in walk
callback(astroid)
File "/usr/local/lib/python3.6/dist-packages/pylint/checkers/typecheck.py", line 845, in visit_classdef
metaclass = node.declared_metaclass()
File "/usr/local/lib/python3.6/dist-packages/astroid/scoped_nodes.py", line 2594, in declared_metaclass
for baseobj in base.infer(context=context):
File "/usr/local/lib/python3.6/dist-packages/astroid/decorators.py", line 141, in raise_if_nothing_inferred
yield from generator
File "/usr/local/lib/python3.6/dist-packages/astroid/decorators.py", line 95, in wrapped
res = next(generator)
File "/usr/local/lib/python3.6/dist-packages/astroid/inference.py", line 311, in infer_attribute
yield from owner.igetattr(self.attrname, context)
File "/usr/local/lib/python3.6/dist-packages/astroid/bases.py", line 133, in _infer_stmts
for inferred in stmt.infer(context=context):
File "/usr/local/lib/python3.6/dist-packages/astroid/util.py", line 160, in limit_inference
yield from islice(iterator, size)
File "/usr/local/lib/python3.6/dist-packages/astroid/context.py", line 113, in cache_generator
for result in generator:
.....
File "/usr/local/lib/python3.6/dist-packages/astroid/decorators.py", line 95, in wrapped
res = next(generator)
File "/usr/local/lib/python3.6/dist-packages/astroid/inference.py", line 287, in infer_attribute
for owner in self.expr.infer(context):
File "/usr/local/lib/python3.6/dist-packages/astroid/util.py", line 160, in limit_inference
yield from islice(iterator, size)
File "/usr/local/lib/python3.6/dist-packages/astroid/context.py", line 113, in cache_generator
for result in generator:
File "/usr/local/lib/python3.6/dist-packages/astroid/decorators.py", line 131, in raise_if_nothing_inferred
yield next(generator)
File "/usr/local/lib/python3.6/dist-packages/astroid/decorators.py", line 92, in wrapped
generator = _func(node, context, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/astroid/inference.py", line 197, in infer_name
context = contextmod.copy_context(context)
File "/usr/local/lib/python3.6/dist-packages/astroid/context.py", line 155, in copy_context
return context.clone()
File "/usr/local/lib/python3.6/dist-packages/astroid/context.py", line 102, in clone
clone = InferenceContext(self.path, inferred=self.inferred)
RecursionError: maximum recursion depth exceeded while calling a Python object
Expected behavior
Ideally this weird monkeypatch behavior should be tolerated (perhaps with a warning from pylint?).
python -c "from astroid import __pkginfo__; print(__pkginfo__.version)"
output2.3.3, also 1.6.6
The text was updated successfully, but these errors were encountered: