Skip to content

gh-134935: Use RecursionError to check for circular references #134937

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from

Conversation

aivarsk
Copy link
Contributor

@aivarsk aivarsk commented May 30, 2025

Other fast JSON encoders rely on RecursionError to detect circular references:

  • ultrajson -- OverflowError: Maximum recursion level reached
  • orjson -- TypeError: Recursion limit reached

Python's json module kept a dictionary with visited objects. It is too much work for a nicer error message. Instead raise a ValueError on RecursionError to keep the API but do not track the objects.

Other fast JSON encoders rely on RecursionError to detect circular
references:

- ultrajson -- OverflowError: Maximum recursion level reached
- orjson -- TypeError: Recursion limit reached

Python's json module kept a dictionary with visited objects. It is too
much work for a nicer error message. Instead raise a ValueError on
RecursionError to keep the API but do not track the objects.
@nineteendo
Copy link
Contributor

It's not guaranteed that Python will recover:

check_circular (bool) – If False, the circular reference check for container types is skipped and a circular reference will result in a RecursionError (or worse).

And I would argue it's not backwards compatible, because it no longer checks for circular references, simply relying on the recursion limit.

Does this improve the performance in any way compared to check_circular=False? Otherwise it's safer to keep the code as is.

@@ -22,7 +22,7 @@ def test_listrecursion(self):
try:
self.dumps(x)
except ValueError as exc:
self.assertEqual(exc.__notes__, ["when serializing list item 0"]*2)
self.assertEqual(exc.__notes__[:2], ["when serializing list item 0"]*2)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what consequences of this change led to the need to limit how many notes we assert on?

what additional notes are now added?

@aivarsk
Copy link
Contributor Author

aivarsk commented May 30, 2025 via email

@gpshead
Copy link
Member

gpshead commented May 30, 2025

having notes grow huge with the stack depth destroys the value of the notes as the error message produced when the exception is seen will be huge. perhaps something like this to constrain the notes growth: 971abd2

@serhiy-storchaka
Copy link
Member

I do not think this is correct. See reasons on the issue.

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

Successfully merging this pull request may close these issues.

4 participants