gh-146059: Call fast_save_leave() in pickle save_frozenset()#146173
gh-146059: Call fast_save_leave() in pickle save_frozenset()#146173vstinner merged 3 commits intopython:mainfrom
Conversation
Lib/test/pickletester.py
Outdated
| buf = io.BytesIO() | ||
| pickler = self.pickler(buf, protocol=proto) | ||
| # Enable fast mode (disables memo, enables cycle detection) | ||
| pickler.fast = 1 |
There was a problem hiding this comment.
Would it be also worth it to test non-fast mode? The bug only triggers in fast mode.
serhiy-storchaka
left a comment
There was a problem hiding this comment.
Please add also tests for list, set, dict, tuple and frozendict.
serhiy-storchaka
left a comment
There was a problem hiding this comment.
Also, this mechanism is used to guard against deeply nested structures, so it would be worth to test deeply nested structures.
There are sets of tests for recursive structures. We can use similar tests for limited but deep recursion.
|
@serhiy-storchaka: Please review the updated PR. Is it what you expected?
I added deep_nested_struct() tests for the 6 types.
Good idea, I rewrote tests like that. |
|
Ping @serhiy-storchaka. |
|
Thanks @vstinner for the PR 🌮🎉.. I'm working now to backport this PR to: 3.13, 3.14. |
…ythonGH-146173) Add more pickle tests: test also nested structures. (cherry picked from commit 5c0dcb3e0d817bd8c28e8efcdb97103cd9210989) Co-authored-by: Victor Stinner <[email protected]>
…ythonGH-146173) Add more pickle tests: test also nested structures. (cherry picked from commit 5c0dcb3) Co-authored-by: Victor Stinner <[email protected]>
|
GH-146473 is a backport of this pull request to the 3.14 branch. |
|
GH-146474 is a backport of this pull request to the 3.13 branch. |
serhiy-storchaka
left a comment
There was a problem hiding this comment.
LGTM. 👍
I only have some minor questions.
| self.skipTest("need Pickler class") | ||
|
|
||
| data = [create_data(i) for i in range(FAST_NESTING_LIMIT * 2)] | ||
| data = {"key": data} |
There was a problem hiding this comment.
Ah, it comes from the initial reproducer. But I confirm that I can still reproduce the bug/crash without {"key": data}. I removed fast_save_leave() from save_list(), save_dict() and save_frozenset(), and the test fails or crash.
| self.assertIn(expected, str(e)) | ||
|
|
||
| def fast_save_enter(self, create_data, minprotocol=0): | ||
| # gh-146059: Check that fast_save() is called when |
There was a problem hiding this comment.
Did you mean fast_save_leave()?
| data = seed | ||
| for i in range(depth): | ||
| data = create_nested(data) | ||
| data = {"key": data} |
| def test_fast_save_enter_dict(self): | ||
| self.fast_save_enter(lambda i: {"key": i}) | ||
|
|
||
| def deep_nested_struct(self, seed, create_nested, |
There was a problem hiding this comment.
Why is the seed parameter used? Can't we use the same seed (None) for all tests?
There was a problem hiding this comment.
I looked nice to me to have a seed of the same type than the nested structure, but you're right, it makes the test too complex, it's not worth it. Also, I confirm that I can still trigger the bug (when removing fast_save_leave() manually in pickle) with None seed.
Thanks for your review. I created #146481 to address your review. |
Fatal Python errorwhen using_picklewith manyfrozensetobjects #146059