Skip to content

Mutable default argument in _SharedMemoryTracker.__init__ causes shared state between instances #153141

Description

@whyvineet

Bug report

Bug description:

_SharedMemoryTracker.__init__ uses a mutable default argument for segment_names:

def __init__(self, name, segment_names=[]):

Because the default list is created only once, multiple _SharedMemoryTracker instances created without explicitly passing segment_names unexpectedly share the same list.

Minimal reproducer:

from multiprocessing.managers import _SharedMemoryTracker

t1 = _SharedMemoryTracker("ctx1")
t1.register_segment("seg1")

t2 = _SharedMemoryTracker("ctx2")

print(t2.segment_names)
print(t1.segment_names is t2.segment_names)

Output:

['seg1']
True

Expected behavior:

[]
False

Right now, this bug is hidden because _SharedMemoryTracker is usually created just once for each SharedMemoryServer process, so the shared state does not usually show up. But if you create more than one tracker in the same interpreter, they end up sharing bookkeeping state by accident because of the mutable default list.

To fix this, we can make the constructor safer by using None as the default value and creating a new list for each instance if one is not provided.

CPython versions tested on:

3.15

Operating systems tested on:

Windows

Linked PRs

Metadata

Metadata

Assignees

Labels

stdlibStandard Library Python modules in the Lib/ directorytopic-multiprocessingtype-refactorCode refactoring (with no changes in behavior)

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions