Skip to content

Commit e7c6ca1

Browse files
Convert NodeStore from ABC to PEP 544 Protocol
The ``NodeStore`` "abstract interface" had two abstract methods, no shared state, no ``__init__``, no helpers — by every operational measure structural rather than nominal. Zero callers in the codebase use ``isinstance(x, NodeStore)`` or ``issubclass(...)``; ``cluster.py``, ``pool.py``, and the top-level ``__init__.py`` consume it purely structurally. Convert to ``Protocol`` so third-party stores need only implement ``get_nodes`` / ``set_nodes`` without inheriting. ``@runtime_checkable`` keeps ``isinstance`` introspection available if a future caller needs it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 61a6487 commit e7c6ca1

1 file changed

Lines changed: 12 additions & 5 deletions

File tree

src/dqliteclient/node_store.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
"""Node store interfaces for cluster discovery."""
22

3-
from abc import ABC, abstractmethod
43
from collections.abc import Sequence
54
from dataclasses import dataclass
5+
from typing import Protocol, runtime_checkable
66

77
from dqlitewire import NodeRole
88

@@ -39,10 +39,18 @@ class NodeInfo:
3939
``ClusterClient.find_leader`` sorts voters first before probing."""
4040

4141

42-
class NodeStore(ABC):
43-
"""Abstract interface for storing cluster node information."""
42+
@runtime_checkable
43+
class NodeStore(Protocol):
44+
"""Structural interface for storing cluster node information.
45+
46+
PEP 544 ``Protocol`` so third-party stores need only implement
47+
``get_nodes`` / ``set_nodes`` without inheriting from this class.
48+
No callers in this codebase use ``isinstance(x, NodeStore)`` —
49+
the contract is structural — and ``MemoryNodeStore`` is the only
50+
in-tree implementation. ``@runtime_checkable`` is set so a future
51+
caller that wants ``isinstance`` introspection still gets it.
52+
"""
4453

45-
@abstractmethod
4654
async def get_nodes(self) -> Sequence[NodeInfo]:
4755
"""Return an immutable snapshot of known nodes.
4856
@@ -58,7 +66,6 @@ async def get_nodes(self) -> Sequence[NodeInfo]:
5866
"""
5967
...
6068

61-
@abstractmethod
6269
async def set_nodes(self, nodes: Sequence[NodeInfo]) -> None:
6370
"""Update list of known nodes.
6471

0 commit comments

Comments
 (0)