Skip to content

Clarify pickle __reduce__() behavior when a string is returned (singleton support). #148669

@Viicos

Description

@Viicos

Documentation

The documentation about __reduce__() mentions:

If a string is returned, the string should be interpreted as the name of a
global variable. It should be the object's local name relative to its
module; the pickle module searches the module namespace to determine the
object's module. This behaviour is typically useful for singletons.

It is unclear what the pickle module searches the module namespace to determine the object's module means, in particular whether for a specific obj to be pickled, the object's __module__ is used (i.e. obj.__module__) or the module of the object's type (i.e. type(obj).__module__).

While in most cases, it would be expected to look up on the class (as the __module__ attribute is only documented as being set on a class or function), the current implementation does the attribute lookup on the object:

cpython/Lib/pickle.py

Lines 336 to 339 in 2a07ff9

def whichmodule(obj, name):
"""Find the module an object belong to."""
dotted_path = name.split('.')
module_name = getattr(obj, '__module__', None)

This behavior isn't clearly documented, but is relied on in multiple places, e.g. to pickle functions, TypeVar instances, the draft PEP 661 implementation (and I believe types themselves?)

This issue can be seen as a sub-issue of #60455.

Original discussion about PEP 611 Sentinels can be found here: https://discuss.python.org/t/9126/262.

I will have a PR up shortly.

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    docsDocumentation in the Doc dir

    Projects

    Status

    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions