Iteration strategies
_iter_instances controls which instances take part in a merge and in what
order. pleroma ships four ready-made strategies in pleroma.iteration so you
rarely need to write that override from scratch.
Available strategies
| Function | Yields |
|---|---|
iter_all |
Every instance in original order (default behaviour) |
iter_reversed |
Every instance in reverse order |
iter_first |
The first two instances only |
iter_last |
The first and last instances only |
All four accept any Collection and return an Iterator, making them safe to
use with lists, tuples, and other sequences. An empty collection always
produces an empty iterator without raising.
Using a strategy
Import the function and call it from your _iter_instances override:
import dataclasses
from pleroma import MergeableMixin, iter_reversed
@dataclasses.dataclass
class Config(MergeableMixin):
host: str | None = None
port: int | None = None
@classmethod
def _iter_instances(cls, instances):
return iter_reversed(instances)
a = Config(host="a", port=8080)
b = Config(host="b", port=None)
c = Config(host="c", port=9090)
Config.merge([a, b, c])
# Traversal order: c → b → a
# host: 'a' (last non-None going c→b→a is 'a')
# port: 9090 (last non-None going c→b→a is 9090)
# Config(host='a', port=9090)
iter_first — merge only the first two
Use iter_first when only the earliest entries in a collection should be
considered and the rest discarded:
import dataclasses
from pleroma import MergeableMixin, iter_first
@dataclasses.dataclass
class Event(MergeableMixin):
source: str | None = None
value: int | None = None
@classmethod
def _iter_instances(cls, instances):
return iter_first(instances)
a = Event(source="a", value=1)
b = Event(source="b", value=2)
c = Event(source="c", value=100)
Event.merge([a, b, c])
# Only a and b are merged; c is ignored.
# Event(source='b', value=2)
iter_last — merge base with tail
Use iter_last when only the first and last entries matter:
import dataclasses
from pleroma import MergeableMixin, iter_last
@dataclasses.dataclass
class Snapshot(MergeableMixin):
label: str | None = None
value: int | None = None
@classmethod
def _iter_instances(cls, instances):
return iter_last(instances)
first = Snapshot(label="init", value=0)
middle = Snapshot(label="ignored", value=50)
last = Snapshot(label="final", value=99)
Snapshot.merge([first, middle, last])
# Only first and last are merged; middle is skipped.
# Snapshot(label='final', value=99)
Works with MergeableModel too
All strategies work identically with MergeableModel:
from pleroma import iter_last
from pleroma.contrib.pydantic import MergeableModel
class Setting(MergeableModel):
value: int | None = None
@classmethod
def _iter_instances(cls, instances):
return iter_last(instances)