I can now demonstrate exactly where the unbound recursion happens.
The following is a debugger that warns me when the stack gets too big. It is a
subclass of pdb, but it overrides two methods in bdb.py. Here it is::
class debugger(pdb.Pdb):
def __init__(self,completekey='tab',stdin=None,stdout=None):
pdb.Pdb.__init__(self,completekey,stdin,stdout)
self.stackLimit = 200 # Found by trial and error.
# dispatch_call (override bdb)
def dispatch_call(self, frame, arg):
# XXX 'arg' is no longer used
# EKR: new code.
stack,junk = self.get_stack(frame,None)
if len(stack) > self.stackLimit:
print('(debugger.stop_here) stackCount %s' % len(stack))
self.interaction(frame,None)
# Existing code.
if self.botframe is None:
# First call of dispatch since reset()
self.botframe = frame.f_back # (CT) Note that this may also be None!
return self.trace_dispatch
if not (self.stop_here(frame) or self.break_anywhere(frame)):
# No need to trace this function
return # None
self.user_call(frame, arg)
if self.quitting: raise BdbQuit
return self.trace_dispatch
# set_continue (override bdb)
def set_continue(self):
# Don't stop except at breakpoints or when finished
self._set_stopinfo(self.botframe, None)
# EKR: Always run with overhead
if False:
if not self.breaks:
# no breakpoints; run without debugger overhead
sys.settrace(None)
frame = sys._getframe().f_back
while frame and frame is not self.botframe:
del frame.f_trace
frame = frame.f_back
And here is the stack trace when the stack limit tripped. It includes some
print statements I inserted while stepping through the code.
Breakpoint 1 at
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\node_classes.py:256
> c:\python26\lib\site-packages\pylint-0.19.0-py2.6.egg\pylint\lint.py(782)__init__()
-> self._rcfile = None
(Pdb) disable 1
(Pdb) c
manager.py: astng_from_file: not in cache: c:\leo.repo\until\pylintTest.py
manager.py: astng_from_file: calling file_build(pylintTest)
manager.py: astng_from_file: not in cache: c:\leo.repo\until\leo\__init__.py
manager.py: astng_from_file: calling file_build(leo)
manager.py: astng_from_file: not in cache:
c:\leo.repo\until\leo\core\__init__.py
manager.py: astng_from_file: calling file_build(leo.core)
manager.py: astng_from_file: not in cache:
c:\leo.repo\until\leo\core\leoGlobals.py
manager.py: astng_from_file: calling file_build(leo.core.leoGlobals)
manager.py: astng_from_file: not in cache: c:\leo.repo\until\leo\core\leoApp.py
manager.py: astng_from_file: calling file_build(leo.core.leoApp)
(debugger.stop_here) stackCount 201
> c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\inference.py(52)_set_proxied()
-> def _set_proxied(const):
(Pdb) w
('pdb.py:print_stack_trace', 201)
c:\python26\lib\bdb.py(404)runcall()
-> res = func(*args, **kwds)
c:\python26\lib\site-packages\pylint-0.19.0-py2.6.egg\pylint\lint.py(915)__init__()
-> linter.check(args)
c:\python26\lib\site-packages\pylint-0.19.0-py2.6.egg\pylint\lint.py(503)check()
-> self.check_astng_module(astng, checkers)
c:\python26\lib\site-packages\pylint-0.19.0-py2.6.egg\pylint\lint.py(583)check_astng_module()
-> self.astng_events(astng, aList,top=True)
c:\python26\lib\site-packages\pylint-0.19.0-py2.6.egg\pylint\lint.py(618)astng_events()
-> self.astng_events(child, checkers, _reversed_checkers,top=False)
c:\python26\lib\site-packages\pylint-0.19.0-py2.6.egg\pylint\lint.py(610)astng_events()
-> checker.visit(astng)
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\utils.py(323)visit()
-> method(node)
c:\python26\lib\site-packages\pylint-0.19.0-py2.6.egg\pylint\checkers\variables.py(408)visit_import()
-> self._check_module_attrs(node, module, parts[1:])
c:\python26\lib\site-packages\pylint-0.19.0-py2.6.egg\pylint\checkers\variables.py(464)_check_module_attrs()
-> module = module.getattr(name)[0].infer().next()
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\scoped_nodes.py(50)wrapper()
-> nodes = [n for n in func(*args, **kwargs) if not isinstance(n, cls)]
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\scoped_nodes.py(154)getattr()
-> return [self.import_module(name, relative_only=True)]
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\scoped_nodes.py(203)import_module()
-> return MANAGER.astng_from_module_name(absmodname)
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\manager.py(187)astng_from_module_name()
-> return self.astng_from_file(filepath, modname, fallback=False)
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\manager.py(138)astng_from_file()
-> astng = ASTNGBuilder(self).file_build(filepath, modname)
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\builder.py(118)file_build()
-> node = self.string_build(data, modname, path)
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\builder.py(128)string_build()
-> return self.ast_build(parse(data + '\n'), modname, path)
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\builder.py(147)ast_build()
-> self.rebuilder.walk(node)
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\rebuilder.py(94)walk()
-> self.delayed_visit_assattr(dnode)
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\rebuilder.py(278)delayed_visit_assattr()
-> for infered in node.expr.infer():
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\infutils.py(203)wrapped()
-> for res in _func(node, context, **kwargs):
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\infutils.py(168)_infer_stmts()
-> for infered in stmt.infer(context):
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\infutils.py(203)wrapped()
-> for res in _func(node, context, **kwargs):
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\inference.py(391)infer_ass()
-> stmts = list(self.assigned_stmts(context=context))
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\infutils.py(231)wrapper()
-> for node in func(*args, **kwargs):
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\protocols.py(251)assign_assigned_stmts()
-> for infered in _resolve_asspart(self.value.infer(context), asspath, context):
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\protocols.py(261)_resolve_asspart()
-> for part in parts:
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\infutils.py(203)wrapped()
-> for res in _func(node, context, **kwargs):
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\infutils.py(231)wrapper()
-> for node in func(*args, **kwargs):
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\inference.py(201)infer_callfunc()
-> for callee in self.func.infer(context):
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\infutils.py(203)wrapped()
-> for res in _func(node, context, **kwargs):
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\infutils.py(231)wrapper()
-> for node in func(*args, **kwargs):
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\inference.py(259)infer_getattr()
-> for obj in owner.igetattr(self.attrname, context):
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\infutils.py(273)igetattr()
-> self._wrap_attr(self.getattr(name, context, lookupclass=False), context),
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\infutils.py(248)getattr()
-> values = self._proxied.instance_attr(name, context)
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\inference.py(53)_set_proxied()
-> if not hasattr(const, '__proxied'):
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\infutils.py(44)__getattr__()
-> return getattr(self._proxied, name)
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\inference.py(53)_set_proxied()
-> if not hasattr(const, '__proxied'):
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\infutils.py(44)__getattr__()
-> return getattr(self._proxied, name)
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\inference.py(53)_set_proxied()
-> if not hasattr(const, '__proxied'):
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\infutils.py(44)__getattr__()
-> return getattr(self._proxied, name)
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\inference.py(53)_set_proxied()
-> if not hasattr(const, '__proxied'):
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\infutils.py(44)__getattr__()
-> return getattr(self._proxied, name)
c:\python26\lib\site-packages\logilab_astng-0.19.3-py2.6.egg\logilab\astng\inference.py(53)_set_proxied()
And so on...
I still don't understand the code, but now I know where the unbounded
recursion is.
Edward
--
pylint spews Exception RuntimeError: maximum recursion depth exceeded while
calling a Python object
https://bugs.launchpad.net/bugs/456870
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
--
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs