cultcache-py: the record decode applies a slot default in one place; plain field helper, SlotCodec and field immutability pinned

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-10-11 04:47:52 +02:00
commit eae7207df5
2 changed files with 19 additions and 3 deletions

View file

@ -398,12 +398,12 @@ def _record_codec(type: str, normalized: list[DatabaseEntryField], cls: type[Any
for field in normalized:
if field.key < len(raw):
value = decode_slot(field, raw[field.key])
elif field.default is not MISSING:
value = field.default() if callable(field.default) else field.default
else:
elif field.default is MISSING:
raise ValueError(
f"DatabaseEntry document type {type!r} is missing required slot {field.key}"
)
else:
value = None
if value is None and field.default is not MISSING:
value = field.default() if callable(field.default) else field.default
values[field.name] = value

View file

@ -353,6 +353,22 @@ class RecordCodecTests(unittest.TestCase):
define_record_codec("Nothing", [])
self.assertEqual(str(empty.exception), "DatabaseEntry document types require at least one field")
def test_a_plain_field_helper_makes_a_required_slot_with_no_codec(self) -> None:
plain = define_record_codec("Plain", [database_entry_field("id", 0), database_entry_field("label", 1)])
self.assertEqual(plain.decode(plain.encode({"id": "a", "label": "b"})), {"id": "a", "label": "b"})
with self.assertRaises(ValueError) as caught:
plain.decode(["a"])
self.assertEqual(str(caught.exception), "DatabaseEntry document type 'Plain' is missing required slot 1")
field = database_entry_field("id", 0)
self.assertIsNone(field.codec)
self.assertFalse(field.many)
def test_slot_codecs_and_fields_are_immutable(self) -> None:
with self.assertRaises(dataclasses.FrozenInstanceError):
node.encode = None # type: ignore[misc]
with self.assertRaises(dataclasses.FrozenInstanceError):
database_entry_field("id", 0).key = 1 # type: ignore[misc]
def test_a_negative_slot_key_is_refused_but_zero_is_not(self) -> None:
database_entry_field("zero", 0)
with self.assertRaises(ValueError) as caught: