Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Oct 4, 2025

Problem

Vulture crashes with RecursionError: maximum recursion depth exceeded when analyzing code containing deeply nested expressions, such as long chains of binary operations. This was reported when running vulture on the Bandit project, which uses AST-based static analysis patterns.

# Example code that triggers the issue
result = 1 + 1 + 1 + 1 + ... (repeated 500+ times)

The error manifests as:

RecursionError: maximum recursion depth exceeded
  File "vulture/core.py", line 628, in visit
    self.generic_visit(node)
  ...

Root Cause

Vulture's custom visit() method calls generic_visit() before processing each node to enable recursive reachability analysis. With deeply nested AST structures (500+ levels), this exhausts Python's recursion limit (default: 1000).

Solution

This PR adds graceful handling of RecursionError with minimal changes:

  1. Catch RecursionError during AST visiting - The scan() method now catches RecursionError exceptions and logs a clear, actionable error message instead of crashing.

  2. Preserve error exit codes - Fixed the report() method to ensure InvalidInput exit code is not overridden by DeadCode when both occur.

  3. Comprehensive test coverage - Added test_recursion_error() to verify the fix works correctly with deeply nested code.

Behavior

Before

$ vulture deep_code.py
Traceback (most recent call last):
  ...
RecursionError: maximum recursion depth exceeded

After

$ vulture deep_code.py
deep_code.py: RecursionError: maximum recursion depth exceeded while analyzing code. This can happen with extremely nested expressions.
deep_code.py:1: unused variable 'result' (60% confidence)

Exit code: 1 (InvalidInput)

The tool now:

  • Reports a clear, user-friendly error message
  • Reports any dead code found before hitting the recursion limit
  • Returns appropriate exit code (InvalidInput) instead of crashing
  • Continues processing other files in the project

Testing

  • All existing tests pass (297 tests)
  • New test validates RecursionError handling with 500 nested operations
  • Manual verification with various nesting depths (10, 100, 500, 1000)
  • Code passes ruff linter and formatter checks
  • Performance unchanged on normal codebases

Fixes the issue reported in the original bug report where vulture would crash when analyzing projects like Bandit.

Original prompt

This section details on the original issue you should resolve

<issue_title>RecursionError: maximum recursion depth exceeded</issue_title>
<issue_description>I tested out vulture on a project I maintain (Bandit). Unfortunately, the first result I got was a RecursionError. It's not clear to me if this is by-design or an edge case bug. Bandit itself does static analysis using an AST and vulture seems to trip up when inspecting the visitor logic.

To reproduce:

pip install vulture
git clone https://github.com/PyCQA/bandit
cd bandit
vulture .
  File "/Users/ericwb/workspace/reflex-web/venv/lib/python3.12/site-packages/vulture/core.py", line 721, in generic_visit
    self.visit(value)
  File "/Users/ericwb/workspace/reflex-web/venv/lib/python3.12/site-packages/vulture/core.py", line 687, in visit
    return self.generic_visit(node)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/ericwb/workspace/reflex-web/venv/lib/python3.12/site-packages/vulture/core.py", line 721, in generic_visit
    self.visit(value)
  File "/Users/ericwb/workspace/reflex-web/venv/lib/python3.12/site-packages/vulture/core.py", line 672, in visit
    visitor(node)
  File "/Users/ericwb/workspace/reflex-web/venv/lib/python3.12/site-packages/vulture/core.py", line 521, in visit_BinOp
    utils.is_ast_string(node.left)
RecursionError: maximum recursion depth exceeded
```</issue_description>

<agent_instructions>Also add changelog entry.</agent_instructions>

## Comments on the Issue (you are @copilot in this section)

<comments>
<comment_new><author>@jendrikseipp</author><body>
Thanks for the report! This is definitely not by design. Happy to review a PR if you take the time to tackle this.</body></comment_new>
<comment_new><author>@jendrikseipp</author><body>
Thanks for looking into this! Can you make a pull request along those lines?</body></comment_new>
<comment_new><author>@jendrikseipp</author><body>
Thanks for the report! Can you past the code that triggers this issue here?</body></comment_new>
</comments>
Fixes #358

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI changed the title [WIP] RecursionError: maximum recursion depth exceeded Fix RecursionError when analyzing deeply nested code structures Oct 4, 2025
Copilot AI requested a review from jendrikseipp October 4, 2025 05:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RecursionError: maximum recursion depth exceeded

2 participants