Skip to content
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

gh-108851: Fix tomllib recursion tests #108853

Merged
merged 2 commits into from
Sep 6, 2023
Merged

Conversation

vstinner
Copy link
Member

@vstinner vstinner commented Sep 3, 2023

  • sys.setrecursionlimit() now allows setting the limit to the current recursion depth.
  • Add get_recursion_available() and get_recursion_depth() functions to the test.support module.
  • Change infinite_recursion() default max_depth from 75 to 100.
  • Fix test_tomllib recursion tests for WASI buildbots: reduce the recursion limit and compute the maximum nested array/dict depending on the current available recursion limit.

@vstinner
Copy link
Member Author

vstinner commented Sep 3, 2023

This PR combines 3 changes at once. IMO it's better to change all of them at the same time to ease backports, rather than having 3 commits (more work for little benefits).

cc @serhiy-storchaka

@vstinner
Copy link
Member Author

vstinner commented Sep 3, 2023

The test_tomllib failure can be reproduced on Linux by reducing the recursion limit. Use this patch:

diff --git a/Lib/test/test_tomllib/test_misc.py b/Lib/test/test_tomllib/test_misc.py
index a477a219fd..43357f2064 100644
--- a/Lib/test/test_tomllib/test_misc.py
+++ b/Lib/test/test_tomllib/test_misc.py
@@ -10,6 +10,8 @@
 import tempfile
 import unittest

+sys.setrecursionlimit(250)
+
 from . import tomllib


On the main branch, I reproduce the issue:

$ ./python -m test test_tomllib -v
(...)
======================================================================
ERROR: test_inline_array_recursion_limit (test.test_tomllib.test_misc.TestMiscellaneous.test_inline_array_recursion_limit)
----------------------------------------------------------------------
(...)
RecursionError: maximum recursion depth exceeded

======================================================================
ERROR: test_inline_table_recursion_limit (test.test_tomllib.test_misc.TestMiscellaneous.test_inline_table_recursion_limit)
----------------------------------------------------------------------
(...)
RecursionError: maximum recursion depth exceeded
(...)

With this PR and the patch to trigger the bug: test_tomllib pass successfully.

Lib/test/support/__init__.py Outdated Show resolved Hide resolved
Lib/test/support/__init__.py Outdated Show resolved Hide resolved
Lib/test/support/__init__.py Outdated Show resolved Hide resolved
Lib/test/support/__init__.py Outdated Show resolved Hide resolved
# it can raise RecursionError
return
get_depth = support.get_recursion_depth()
print(f"test_recursive: {depth}/{limit}: "
Copy link
Member

Choose a reason for hiding this comment

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

Should subTest() used instead of printing out the values?

Copy link
Member Author

Choose a reason for hiding this comment

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

This is a script run by test_get_recursion_depth(). You should not see the output unless the test crash or fails. It's not written with unittest.

Lib/test/test_support.py Outdated Show resolved Hide resolved
Lib/test/test_support.py Outdated Show resolved Hide resolved
Lib/test/test_support.py Outdated Show resolved Hide resolved
Lib/test/test_support.py Outdated Show resolved Hide resolved
Lib/test/test_support.py Show resolved Hide resolved
* Add get_recursion_available() and get_recursion_depth() functions
  to the test.support module.
* Change infinite_recursion() default max_depth from 75 to 100.
* Fix test_tomllib recursion tests for WASI buildbots: reduce the
  recursion limit and compute the maximum nested array/dict depending
  on the current available recursion limit.
* test.pythoninfo logs sys.getrecursionlimit()
* Enhance test_sys tests on sys.getrecursionlimit()
  and sys.setrecursionlimit().
@vstinner
Copy link
Member Author

vstinner commented Sep 5, 2023

I rebased my PR and I revert the sys.setrecursionlimit().

The sys.setrecursionlimit() change was fun to do, play with the bare minimum. But it introduces a weird behavior (you can no longer call any Python function, not great.) Instead of I changed the support.infinite_recursion() minimum to 3, instead of 2. In practice, this function should be called at least with 50 (default is 100 with my change).

@vstinner
Copy link
Member Author

vstinner commented Sep 5, 2023

@brettcannon: Would you mind to review the updated PR?

Copy link
Member

@serhiy-storchaka serhiy-storchaka left a comment

Choose a reason for hiding this comment

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

LGTM.

You may also add simple docstrings for new functions. Just one line would be enough.

@vstinner
Copy link
Member Author

vstinner commented Sep 6, 2023

You may also add simple docstrings for new functions. Just one line would be enough.

@vstinner
Copy link
Member Author

vstinner commented Sep 6, 2023

You may also add simple docstrings for new functions. Just one line would be enough.

I added docstrings to the 2 newly added test.support functions.

@vstinner vstinner merged commit 8ff1142 into python:main Sep 6, 2023
17 checks passed
@vstinner vstinner deleted the support_recursive branch September 6, 2023 15:34
@bedevere-bot
Copy link

There's a new commit after the PR has been approved.

@serhiy-storchaka: please review the changes made to this pull request.

@vstinner vstinner added needs backport to 3.11 only security fixes needs backport to 3.12 bug and security fixes labels Sep 6, 2023
@miss-islington
Copy link
Contributor

Thanks @vstinner for the PR 🌮🎉.. I'm working now to backport this PR to: 3.12.
🐍🍒⛏🤖

@miss-islington
Copy link
Contributor

Thanks @vstinner for the PR 🌮🎉.. I'm working now to backport this PR to: 3.11.
🐍🍒⛏🤖

@miss-islington
Copy link
Contributor

Sorry, @vstinner, I could not cleanly backport this to 3.11 due to a conflict.
Please backport using cherry_picker on command line.
cherry_picker 8ff11425783806f8cb78e99f667546b1f7f3428e 3.11

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Sep 6, 2023
* Add get_recursion_available() and get_recursion_depth() functions
  to the test.support module.
* Change infinite_recursion() default max_depth from 75 to 100.
* Fix test_tomllib recursion tests for WASI buildbots: reduce the
  recursion limit and compute the maximum nested array/dict depending
  on the current available recursion limit.
* test.pythoninfo logs sys.getrecursionlimit().
* Enhance test_sys tests on sys.getrecursionlimit()
  and sys.setrecursionlimit().
(cherry picked from commit 8ff1142)

Co-authored-by: Victor Stinner <[email protected]>
@bedevere-bot
Copy link

GH-109012 is a backport of this pull request to the 3.12 branch.

@bedevere-bot bedevere-bot removed the needs backport to 3.12 bug and security fixes label Sep 6, 2023
vstinner added a commit to vstinner/cpython that referenced this pull request Sep 6, 2023
* Add get_recursion_available() and get_recursion_depth() functions
  to the test.support module.
* Change infinite_recursion() default max_depth from 75 to 100.
* Fix test_tomllib recursion tests for WASI buildbots: reduce the
  recursion limit and compute the maximum nested array/dict depending
  on the current available recursion limit.
* test.pythoninfo logs sys.getrecursionlimit().
* Enhance test_sys tests on sys.getrecursionlimit()
  and sys.setrecursionlimit().

Backport notes:

* Set support.infinite_recursion() minimumum to 4 frames.
* test_support.test_get_recursion_depth() uses limit-2, apparently
  f-string counts for 2 frames in Python 3.11.
* test_sys.test_setrecursionlimit_to_depth() tests depth+2 instead of
  depth+1.

(cherry picked from commit 8ff1142)
vstinner added a commit to vstinner/cpython that referenced this pull request Sep 6, 2023
* Add get_recursion_available() and get_recursion_depth() functions
  to the test.support module.
* Change infinite_recursion() default max_depth from 75 to 100.
* Fix test_tomllib recursion tests for WASI buildbots: reduce the
  recursion limit and compute the maximum nested array/dict depending
  on the current available recursion limit.
* test.pythoninfo logs sys.getrecursionlimit().
* Enhance test_sys tests on sys.getrecursionlimit()
  and sys.setrecursionlimit().

Backport notes:

* Set support.infinite_recursion() minimum to 4 frames.
* test_support.test_get_recursion_depth() uses limit-2, apparently
  f-string counts for 2 frames in Python 3.11.
* test_sys.test_setrecursionlimit_to_depth() tests depth+2 instead of
  depth+1.

(cherry picked from commit 8ff1142)
@bedevere-bot
Copy link

GH-109013 is a backport of this pull request to the 3.11 branch.

@bedevere-bot bedevere-bot removed the needs backport to 3.11 only security fixes label Sep 6, 2023
@vstinner
Copy link
Member Author

vstinner commented Sep 6, 2023

Thanks for the review @brettcannon and @serhiy-storchaka. I will try to keep an eye on the WASI buildbots ;-)

vstinner added a commit that referenced this pull request Sep 6, 2023
gh-108851: Fix tomllib recursion tests (#108853)

* Add get_recursion_available() and get_recursion_depth() functions
  to the test.support module.
* Change infinite_recursion() default max_depth from 75 to 100.
* Fix test_tomllib recursion tests for WASI buildbots: reduce the
  recursion limit and compute the maximum nested array/dict depending
  on the current available recursion limit.
* test.pythoninfo logs sys.getrecursionlimit().
* Enhance test_sys tests on sys.getrecursionlimit()
  and sys.setrecursionlimit().

Backport notes:

* Set support.infinite_recursion() minimum to 4 frames.
* test_support.test_get_recursion_depth() uses limit-2, apparently
  f-string counts for 2 frames in Python 3.11.
* test_sys.test_setrecursionlimit_to_depth() tests depth+2 instead of
  depth+1.

(cherry picked from commit 8ff1142)
@brettcannon
Copy link
Member

Thanks for the fix!

@vstinner
Copy link
Member Author

vstinner commented Sep 7, 2023

The fix works as expected: wasm32-wasi 3.11917 buildbot is back to green (success).

first successful build: https://buildbot.python.org/all/#/builders/1047/builds/908

By the way, I added sys.getrecursionlimit to test.pythoninfo. On WASI, the limit is lower, as you can now see on test.pythoninfo:

sys.getrecursionlimit: 600

On other platforms, the default is 1,000 frames:

$ make pythoninfo|grep getrecursionlimit
sys.getrecursionlimit: 1000

@vstinner
Copy link
Member Author

vstinner commented Sep 8, 2023

Oh, I was sure that I removed #self.assertEqual(available, 2) commented code from test_support.py but it back from death in the merged commit! Well, I will remove it in a following change :-)

Yhg1s pushed a commit that referenced this pull request Sep 8, 2023
gh-108851: Fix tomllib recursion tests (GH-108853)

* Add get_recursion_available() and get_recursion_depth() functions
  to the test.support module.
* Change infinite_recursion() default max_depth from 75 to 100.
* Fix test_tomllib recursion tests for WASI buildbots: reduce the
  recursion limit and compute the maximum nested array/dict depending
  on the current available recursion limit.
* test.pythoninfo logs sys.getrecursionlimit().
* Enhance test_sys tests on sys.getrecursionlimit()
  and sys.setrecursionlimit().
(cherry picked from commit 8ff1142)

Co-authored-by: Victor Stinner <[email protected]>
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.

5 participants