Coverage for object_streams/sources/model.py: 92%
24 statements
« prev ^ index » next coverage.py v7.16.0, created at 2026-09-02 17:07 +0000
« prev ^ index » next coverage.py v7.16.0, created at 2026-09-02 17:07 +0000
1"""Source adapter for direct model changes."""
3from __future__ import annotations
5from collections.abc import Iterable
6from collections.abc import Sequence
7from dataclasses import dataclass
8from typing import Protocol
10from django.db import models
12from object_streams.events import ObjectRef
15__all__ = ("ModelSource", "Source")
18class Source(Protocol):
19 facet: str
21 def subjects_for_source(self, instance: models.Model) -> Iterable[ObjectRef]:
22 """Return stream subjects affected by a changed source instance."""
24 def changed_fields(self, instance: models.Model) -> Sequence[str]:
25 """Return changed subject fields when the source can report them."""
28@dataclass(frozen=True, slots=True)
29class ModelSource:
30 """Source adapter for events where the source row and subject row match."""
32 model: type[models.Model]
33 facet: str = "object"
35 def matches(self, instance: models.Model) -> bool:
36 return isinstance(instance, self.model)
38 def subjects_for_source(self, instance: models.Model) -> Iterable[ObjectRef]:
39 if not self.matches(instance): 39 ↛ 40line 39 didn't jump to line 40 because the condition on line 39 was never true
40 return ()
41 return (ObjectRef.from_instance(instance),)
43 def changed_fields(self, instance: models.Model) -> Sequence[str]:
44 return ()