Skip to content

plistlib binary writer leaves large formats in the struct cache #161106

Closed

Description

@gpshead

Bug report

Bug description:

The binary plist writer builds its struct formats for the object references of every array and dict, and for the offset table, as one format code per item ('>' + code * n). The struct module caches compiled formats, and a format with one code per item compiles to about 33 bytes per item, so after plistlib.dumps() returns, memory proportional to the largest containers written stays allocated in the cache (up to 100 such formats).

import plistlib, struct, tracemalloc

tracemalloc.start()
for i in range(40):
    plistlib.dumps([True] * (250_000 - i), fmt=plistlib.FMT_BINARY)
print(tracemalloc.get_traced_memory()[0])  # ~330 MB
struct._clearcache()
print(tracemalloc.get_traced_memory()[0])  # < 1 kB

The reader already uses repeat-count formats (f'>{n}{code}', gh-86269), which compile to a constant size; the writer should do the same. The output bytes are unchanged.

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Linked PRs

Activity

  1. self-assigned this
    on Nov 1, 2026
  2. added
    type-bugAn unexpected behavior, bug, or error
    stdlibStandard Library Python modules in the Lib/ directory
    on Nov 1, 2026
  3. added a commit that references this issue on Nov 1, 2026
  4. added 2 commits that reference this issue on Nov 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

stdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions