Repository navigation
Closed
Labels
3.10 (EOL)end of lifeend of life3.11only security fixesonly security fixes3.12only security fixesonly security fixesinterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Description
| BPO | 45687 |
|---|---|
| Nosy | @serhiy-storchaka, @embe |
| Files |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee = None
closed_at = None
created_at = <Date 2021-11-02.08:21:56.849>
labels = ['interpreter-core', 'type-bug', '3.9', '3.10', '3.11', 'library']
title = 'Infinite recursion in Pickler.persistent_id'
updated_at = <Date 2021-11-02.09:16:16.272>
user = 'https://github.com/embe'bugs.python.org fields:
activity = <Date 2021-11-02.09:16:16.272>
actor = 'serhiy.storchaka'
assignee = 'none'
closed = False
closed_date = None
closer = None
components = ['Interpreter Core', 'Library (Lib)']
creation = <Date 2021-11-02.08:21:56.849>
creator = 'embe-navalgo'
dependencies = []
files = ['50418']
hgrepos = []
issue_num = 45687
keywords = []
message_count = 1.0
messages = ['405494']
nosy_count = 2.0
nosy_names = ['serhiy.storchaka', 'embe-navalgo']
pr_nums = []
priority = 'normal'
resolution = None
stage = None
status = 'open'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue45687'
versions = ['Python 3.9', 'Python 3.10', 'Python 3.11']Linked PRs
Metadata
Metadata
Assignees
Labels
3.10 (EOL)end of lifeend of life3.11only security fixesonly security fixes3.12only security fixesonly security fixesinterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Activity
embe commentedon Nov 2, 2021
The following code, which seems reasonable:
crashes with:
RecursionError: maximum recursion depth exceeded while calling a Python object
It works perfectly when inheriting from pickle._Pickler (the Python implementation).
4 remaining items
iritkatriel commentedon Jun 1, 2022
I think it's because in the C version persistent_id can be NULL (but it's still in dir()):
on the other hand:
furkanonder commentedon Dec 20, 2022
The refcount of
self->pers_funcappears to be increasing which causes the recursion error. I tried to decrease the refcount (I reverted the changes for this function on this PR, by the way, I didn't see any reference cycles @serhiy-storchaka ) Recursion error is fixed but I am gettingTypeErrorpythongh-89850: Add default C implementations of persistent_id() and …
serhiy-storchaka commentedon Dec 30, 2023
The C implementation saves references to
persistent_idandpersistent_loadmethods for performance reason. It saves a method lookup and creation. Also, since the C implementation ofPicklerdoes not have thepersistent_idmethod by default, it allows to avoid calling the trivial method at all.Since saving a reference to a method creates a reference loop, it uses a trick: deconstruct it if it is a bound method and save only reference to an unbound method. When read the
persistent_idattribute, the bound method is reconstructed back.But it does not work with
super().super()simply skips the current class when looks up the attribute in the MRO. But in this case it cames to thepersistent_iddescriptor in the base class which returns a bound method created from an unbound method of the subclass. So calling it leads to an infinite recursion.There is the same issue with
persistent_loadmethod.PR #113579 uses a different approach, similar to the one used for
reducer_override. It removespersistent_idandpersistent_loaddescriptors and caches the bound methods, but only for the time of executiondump()andload()methods. It also adds the default implementations ofpersistent_idandpersistent_loadmethods in the C classes as well as in the Python classes.This approach may have disadvantage: calling
dump()andload()for small objects may now be slower due to added constant overhead. But I hope that the overhead is insignificant in comparison with other operations (IO, memory management).gh-89850: Add default C implementations of persistent_id() and persis…
pythongh-89850: Add default C implementations of persistent_id() and …
pythongh-89850: Add default C implementations of persistent_id() and …
pythongh-89850: Add default C implementations of persistent_id() and …