Skip to content

Conversation

@kelvinvelasquez-SDE
Copy link

Fixes #10630

Description

This PR prevents RecursionError when comparing Pydantic models with self-references (cycles), addressing issue #10630.

Implementation

  • Introduced a _recursion_ignore thread-local set in pydantic/main.py.
  • Modified BaseModel.__eq__ to track pairs of (id(self), id(other)) currently being compared.
  • If a cycle is detected (pair already exists in set), __eq__ returns True (assuming equality for the cycle), aligning with Python's standard recursive equality behavior.

Verification

  • Added regression test tests/test_issue_10630.py which reproduces the crash and verifies the fix.
  • Ran core tests (pytest tests/test_main.py) to ensure no regressions.

…models (pydantic#10630)

Detailed changes:
- Import threading in pydantic/main.py.
- Introduce _recursion_ignore thread-local storage.
- Wrap BaseModel.__eq__ logic with a check against _recursion_ignore.seen.
- Add regression test tests/test_issue_10630.py.
@github-actions github-actions bot added the relnotes-fix Used for bugfixes. label Dec 19, 2025
@codspeed-hq
Copy link

codspeed-hq bot commented Dec 19, 2025

CodSpeed Performance Report

Merging #12648 will improve performance by 6.73%

Comparing kelvinvelasquez-SDE:fix/recursion-issue-10630 (e602ec9) with main (5587023)

Summary

⚡ 2 improvements
✅ 209 untouched

Benchmarks breakdown

Benchmark BASE HEAD Efficiency
test_list_of_ints_core_json 780.3 µs 731.1 µs +6.73%
test_list_of_strs_json_uncached 448.7 µs 425.2 µs +5.51%

This removes the costly try/except AttributeError block in __eq__ and adds proper typing for Mypy.
@github-actions
Copy link
Contributor

Coverage report

Click to see where and how coverage changed

FileStatementsMissingCoverageCoverage
(new stmts)
Lines missing
  pydantic
  main.py 1174, 1217-1225
Project Total  

This report was generated by python-coverage-comment-action

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

relnotes-fix Used for bugfixes.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

(🐞) RecursionError in == when object has a reference to itself

2 participants