Use immutabledict instead of frozendict (#15113)

Additionally:

* Consistently use `freeze()` in test

---------

Co-authored-by: Patrick Cloke <clokep@users.noreply.github.com>
Co-authored-by: 6543 <6543@obermui.de>
This commit is contained in:
David Robertson 2023-03-22 17:15:34 +00:00 committed by GitHub
parent cabe4a3005
commit 3b0083c92a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 123 additions and 243 deletions

View file

@ -18,7 +18,7 @@ import typing
from typing import Any, Callable, Dict, Generator, Optional, Sequence
import attr
from frozendict import frozendict
from immutabledict import immutabledict
from matrix_common.versionstring import get_distribution_version_string
from typing_extensions import ParamSpec
@ -41,22 +41,18 @@ def _reject_invalid_json(val: Any) -> None:
raise ValueError("Invalid JSON value: '%s'" % val)
def _handle_frozendict(obj: Any) -> Dict[Any, Any]:
"""Helper for json_encoder. Makes frozendicts serializable by returning
def _handle_immutabledict(obj: Any) -> Dict[Any, Any]:
"""Helper for json_encoder. Makes immutabledicts serializable by returning
the underlying dict
"""
if type(obj) is frozendict:
if type(obj) is immutabledict:
# fishing the protected dict out of the object is a bit nasty,
# but we don't really want the overhead of copying the dict.
try:
# Safety: we catch the AttributeError immediately below.
# See https://github.com/matrix-org/python-canonicaljson/issues/36#issuecomment-927816293
# for discussion on how frozendict's internals have changed over time.
return obj._dict # type: ignore[attr-defined]
return obj._dict
except AttributeError:
# When the C implementation of frozendict is used,
# there isn't a `_dict` attribute with a dict
# so we resort to making a copy of the frozendict
# If all else fails, resort to making a copy of the immutabledict
return dict(obj)
raise TypeError(
"Object of type %s is not JSON serializable" % obj.__class__.__name__
@ -64,11 +60,11 @@ def _handle_frozendict(obj: Any) -> Dict[Any, Any]:
# A custom JSON encoder which:
# * handles frozendicts
# * handles immutabledicts
# * produces valid JSON (no NaNs etc)
# * reduces redundant whitespace
json_encoder = json.JSONEncoder(
allow_nan=False, separators=(",", ":"), default=_handle_frozendict
allow_nan=False, separators=(",", ":"), default=_handle_immutabledict
)
# Create a custom decoder to reject Python extensions to JSON.