Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions mccabe.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,23 @@ def _subgraph_parse(self, node, pathnode, extra_blocks):
self.tail = pathnode
self.dispatch_list(extra.body)
loose_ends.append(self.tail)
if node.orelse:
self.tail = pathnode
self.dispatch_list(node.orelse)
loose_ends.append(self.tail)
# Handle elif chains iteratively to avoid RecursionError
while node.orelse:
if (len(node.orelse) == 1
and isinstance(node.orelse[0], ast.If)):
# elif branch: process inline instead of recursing
node = node.orelse[0]
name = "If %d" % node.lineno
elif_node = self.appendPathNode(name)
self.tail = elif_node
self.dispatch_list(node.body)
loose_ends.append(self.tail)
else:
# else branch
self.tail = pathnode
self.dispatch_list(node.orelse)
loose_ends.append(self.tail)
break
else:
loose_ends.append(pathnode)
if pathnode:
Expand Down
12 changes: 12 additions & 0 deletions test_mccabe.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,18 @@ class _options(object):
def test_get_module_complexity(self):
self.assertEqual(0, mccabe.get_module_complexity("mccabe.py"))

def test_long_elif_chain(self):
"""Ensure bug #71 does not regress (RecursionError on long elif)."""
lines = ['def func(x):']
lines.append(' if x == 0:')
lines.append(' return 0')
for i in range(1, 200):
lines.append(' elif x == %d:' % i)
lines.append(' return %d' % i)
code = '\n'.join(lines) + '\n'
complexity = get_code_complexity(code, threshold=0)
self.assertEqual(complexity, 1)


# This test uses the Hypothesis and Hypothesmith libraries to generate random
# syntatically-valid Python source code and applies McCabe on it.
Expand Down