utils/crdt-sync/tool/interop_seed.py
Krzysztof kuhy Rudnicki 6154dc09bf Pin pre-commit's ruff to 0.16.7 and satisfy the CPY001 it brings
The three Python packages pinned ruff twice at different versions:
requirements.txt at 0.16.7, .pre-commit-config.yaml at v0.15.2. Only the
older one ever ran, so `select = ["ALL"]` was enforced two minor versions
behind. Measured before aligning: v0.15.2 reports 0 findings, every 0.16.x
reports CPY001 on each file -- 70 crdt-sync, 23 freedays, 71 gatelock, and
no other rule.

Resolved by adding the notice rather than ignoring the rule, so the gate
keeps its teeth.

Two gatelock modules sat at exactly the 250-line cap, so a one-line header
tipped them to 251. Both are split along a real seam rather than shaved:

  _widget_fills.py    colour arithmetic over LockConfig, no tkinter import
  _surfaces_focus.py  selects among existing surfaces, never mutates them

The focus split keeps _surfaces.py's documented containment (it stays the
only module that creates, moves or destroys windows), and the static guard
in test_recovery_invariants.py globs _surfaces*.py, so the new sibling is
covered with no list to extend. widgets.py re-exports the fills helpers,
which keeps gatelock.widgets the single public surface its tests import.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019kMvSMtsVMB3d2uoZ56pbp
2026-09-12 18:11:24 +02:00

91 lines
2.5 KiB
Python

# Copyright (c) 2026 Krzysztof Rudnicki
"""Write the Python half of the live cross-language interop check.
``crdt_sync_dart/tool/interop_check.dart`` merges a Dart record into
``_interop/devices`` and then asserts it can also see a record written by the
*Python* client -- but nothing wrote that record, so the check could only ever
fail. This is the missing half: it pushes ``py-rec`` through the real
:class:`FirebaseSyncClient`, so the Dart tool has something to find.
The two implementations must agree byte-for-byte, or a phone running Dart
would silently not see a PC running Python. That is the failure this pair of
tools exists to catch before any real data depends on it.
Run this first, then the Dart checker::
python3 tool/interop_seed.py
dart run tool/interop_check.dart
Writes only under ``_interop/``; the Dart side deletes both devices' data on
its way out.
"""
from __future__ import annotations
import logging
import sys
from crdt_sync import (
FirebaseConfig,
Hlc,
LogCodec,
MemorySyncStateStore,
Record,
RevisionTracking,
SyncTarget,
dump_log,
firebase_client_for,
load_log,
sync_log,
)
_PATH_PREFIX = "_interop/devices"
_DEVICE_ID = "pydev"
_logger = logging.getLogger("interop-seed")
# The library's canonical serializers, deliberately -- the point of the check
# is that what the real apps write is what the other language reads, so
# reimplementing the encoding here would test the wrong thing.
def main() -> int:
"""Push the Python-side record, returning a process exit code."""
logging.basicConfig(stream=sys.stdout, level=logging.INFO, format="%(message)s")
client = firebase_client_for("interop", config=FirebaseConfig.load())
merged = sync_log(
SyncTarget(
client=client,
device_id=_DEVICE_ID,
path_prefix=_PATH_PREFIX,
),
{
"py-rec": Record(
id="py-rec",
fields={
"value": (
"written-by-python",
Hlc(wall_time_ms=1000, counter=0, node_id="node-py"),
)
},
)
},
LogCodec(
decode=load_log,
encode=dump_log,
),
RevisionTracking(
state_store=MemorySyncStateStore(),
),
)
_logger.info("python sees records: %s", sorted(merged))
_logger.info("seeded %s; now run: dart run tool/interop_check.dart", _DEVICE_ID)
return 0
if __name__ == "__main__":
raise SystemExit(main())