Source code for calendaring_sync.objects.change_set

# SPDX-FileCopyrightText: 2026 calendaring-sync contributors
# SPDX-License-Identifier: AGPL-3.0-or-later

"""What an :term:`adapter` hands the core after asking the server what changed."""

from __future__ import annotations

from collections.abc import Mapping
from dataclasses import dataclass

from calendaring_sync._text import check_text
from calendaring_sync.objects.change import Change


[docs] @dataclass(frozen=True) class ChangeSet: """One :term:`change set`, or one :term:`truncated page` of it, for one :term:`scope`. Attributes: scope: The id of the scope it covers. since: The :term:`sync token` it was fetched from, ``None`` for a scope that has none. Every page of a :term:`full listing` carries the scope's token from before the listing. token: The token the scope moves to. On a truncated page of an :term:`incremental change set` that's the page's :term:`checkpoint`. Every page of a full listing carries the same token, the one the listing read before it started, and the scope moves to it when the last page is ingested. changes: Each object id mapped to how the object changed. An object appears once. full_listing: Whether it lists every object in the scope, rather than only what changed. truncated: Whether more pages follow it. Raises: ValueError: If the scope id, a token or an object id holds a :ref:`lone surrogate <lone-surrogates>`. """ scope: str since: str | None token: str changes: Mapping[str, Change] full_listing: bool = False truncated: bool = False def __post_init__(self) -> None: check_text(scope=self.scope, since=self.since, token=self.token, object_ids=self.changes)