Skip to content

gh-47369: Make the pure-Python pickler avoid recursion limit on deeply nested objects - #160157

Open
coreythompson643-lang wants to merge 1 commit into
python:mainfrom
coreythompson643-lang:gh-47369-stackless-pickler
Open

coreythompson643-lang wants to merge 1 commit into
python:mainfrom
coreythompson643-lang:gh-47369-stackless-pickler

Conversation

@coreythompson643-lang

Copy link
Copy Markdown

Fixes gh-47369.

Problem

The pure-Python pickler (pickle._Pickler) saves nested containers through recursive save() calls, so pickling deeply nested lists, tuples, dicts, sets, frozensets or object states raises RecursionError well before memory is a concern.

Approach

save() now drives the save methods as generators on an explicit stack. A save method that needs a child object saved yields a request instead of calling save() recursively; exceptions are thrown back into the requesting generator so they propagate (and collect notes) as they did with recursion. Subclass overrides of save(), save_reduce() and dispatch table entries are still honoured. The C pickler (_pickle) is not changed.

Tests

Added tests in Lib/test/pickletester.py for deeply nested structures with the pure-Python pickler. ./python -m test test_pickle test_pickletools test_copyreg test_shelve passes on a local build of main (1,538 tests run, 96 skipped).

Performance

The pure-Python pickler is about 1.5–1.9x slower in my measurements because of the generator machinery. The C pickler, which is what pickle.dumps uses by default, is unaffected. Feedback on whether this trade-off is acceptable is welcome.

… deeply nested objects

Save containers using an explicit stack of generators instead of
recursive calls in pickle._Pickler.
@python-cla-bot

python-cla-bot Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

All commit authors signed the Contributor License Agreement.

CLA signed

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.

pickle.py is limited by python's call stack

1 participant