Files
trainlib/trainlib/domain.py

78 lines
1.9 KiB
Python

"""
Generic URI-resource mapping structure
"""
from collections.abc import Mapping, Iterator, Sequence
class Domain[U, R](Mapping[U, R]):
"""
Domain base class, generic to a URI type ``U`` and resource type ``R``.
Domains are just Mappings where the iterator behavior is specifically typed
to range over keys (URIs). Defining a specific class here gives us a base
for a nominal hierarchy, but functionally the Mapping core (sized iterables
with accessors).
"""
def __call__(self, uri: U) -> R:
"""
Get the resource for a given URI (call-based alias).
"""
return self[uri]
def __getitem__(self, uri: U) -> R:
"""
Get the resource for a given URI.
"""
raise NotImplementedError
def __iter__(self) -> Iterator[U]:
"""
Provide an iterator over domain URIs.
"""
raise NotImplementedError
def __len__(self) -> int:
"""
Measure the size the domain.
"""
raise NotImplementedError
class SequenceDomain[R](Domain[int, R]):
"""
Trivial domain implementation for wrapping sequences that can be seen as
Mappings with 0-indexed keys.
Why define this? Domains provide iterators over their *keys*, sequences
often iterate over *values*.
"""
def __init__(self, sequence: Sequence[R]) -> None:
self.sequence = sequence
def __getitem__(self, uri: int) -> R:
return self.sequence[uri]
def __iter__(self) -> Iterator[int]:
return iter(range(len(self.sequence)))
def __len__(self) -> int:
return len(self.sequence)
class TupleDomain[T](SequenceDomain[tuple[T, ...]]):
"""
Domain for homogenous tuples of the same type.
This class header exists primarily as typed alias that aligns with
TupleDataset.
"""
...