tonghuaroot · GitHub

Bug report

marshal cannot round-trip a frozendict that appears more than once in the
data. Loading fails with ValueError, while frozenset in the same shape
works:

>>> import marshal
>>> fd = frozendict({'a': 1, 'b': 2})
>>> marshal.loads(marshal.dumps([fd, fd]))
Traceback (most recent call last):
  ...
ValueError: bad marshal data (invalid reference)
>>> fs = frozenset({1, 2})
>>> marshal.loads(marshal.dumps([fs, fs]))
[frozenset({1, 2}), frozenset({1, 2})]

The reader's TYPE_FROZENDICT branch reserves a back-reference slot with
r_ref_reserve but never fills it with r_ref_insert, unlike TYPE_FROZENSET,
so a later reference to the shared frozendict resolves to an empty slot.

CPython versions tested on:

3.16 (main)

Operating systems tested on:

Linux, macOS

Linked PRs

Read the original on github.com ↗