Closed BenGatewood closed 11 months ago
Custom classes are serialized by calling repr
, see: https://github.com/tophat/syrupy/blob/2ed84ea8e2b9dfa01cd4788f9787809ffc6b2648/src/syrupy/extensions/amber/serializer.py#L373
Since repr returns a string, we don't have a way to modify the result of calling repr to apply an exclude. You could extend the serializer to support msgspec.Struct:
import pytest
from typing import Any
from syrupy.filters import props
from syrupy.extensions.amber import AmberSnapshotExtension, AmberDataSerializer
import msgspec
class MySpec(msgspec.Struct):
a: str
b: int
class ExtendedAmberDataSerializer(AmberDataSerializer):
@classmethod
def serialize_unknown(cls, data: Any, *, depth: int = 0, **kwargs: Any) -> str:
if isinstance(data, (msgspec.Struct,)):
return cls.serialize_custom_iterable(
data=data,
resolve_entries=(
cls.sort(data.__struct_fields__),
lambda o, p: getattr(o, str(p)),
None
),
separator="=",
**kwargs
)
return super().serialize_unknown(data, depth=depth, **kwargs)
class ExtendedAmberSnapshotExtension(AmberSnapshotExtension):
serializer_class = ExtendedAmberDataSerializer
@pytest.fixture
def snapshot(snapshot):
return snapshot.use_extension(ExtendedAmberSnapshotExtension)
def test_case(snapshot):
assert MySpec(a="word", b=3) == snapshot(exclude=props("a"))
I acknowledge the serializer can be improved here.. I think we could expose an alternative to serialize_dict to handle repr a bit better
Note that "serialize_custom_iterable" requires syrupy v4.1.0 (just released today).
Updated my example using serialize_custom_iterable
which I've exposed in v4.1.0.
Nice one - thanks! I'll have a go with this method for the moment
Will close out this issue then. Feel free to comment and I'll re-open if there are other ways we can make this simpler.
Describe the bug
When I try and exclude attributes from a custom class that inherits from
msgspec.Struct
the syntax/approach from the docs doesn't seem to produce the desired behaviour and the excluded attributes remain in the snapshotTo reproduce
Expected behavior
From the above example, I would expect a snapshot like:
Environment (please complete the following information):
Additional context
Thanks for looking!