Coverage for typed_stream/_impl/_types.py: 100%
77 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-23 18:47 +0000
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-23 18:47 +0000
1# Licensed under the EUPL-1.2 or later.
2# You may obtain a copy of the licence in all the official languages of the
3# European Union at https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
5"""Helpful types."""
7from __future__ import annotations
9import abc
10from abc import abstractmethod
11from collections.abc import Callable, Iterable, Iterator
12from os import PathLike
13from typing import Generic, Protocol, TypeAlias, TypeGuard, TypeVar
15from ._typing import Self, override
17__all__ = (
18 "ClassWithCleanUp",
19 "Closeable",
20 "IteratorProxy",
21 "PathLikeType",
22 "PrettyRepr",
23 "StarCallable",
24 "SupportsAdd",
25 "SupportsComparison",
26 "SupportsGreaterThan",
27 "SupportsLessThan",
28 "TypeGuardingCallable",
29)
31PathLikeType = bytes | PathLike[bytes] | PathLike[str] | str
33T = TypeVar("T")
34V = TypeVar("V")
35T_co = TypeVar("T_co", covariant=True)
36V_contra = TypeVar("V_contra", contravariant=True)
39class TypeGuardingCallable(Protocol[T_co, V_contra]):
40 """A class representing a function that type guards."""
42 @abstractmethod
43 def __call__(self, value: V_contra) -> TypeGuard[T_co]:
44 """Return True if value isinstance of T_co."""
47ScIn_contra = TypeVar("ScIn_contra", contravariant=True)
48ScOut_co = TypeVar("ScOut_co", covariant=True)
51class StarCallable(Protocol[ScIn_contra, ScOut_co]):
52 """A class representing a function, that takes many arguments."""
54 @abstractmethod
55 def __call__(self, *args: ScIn_contra) -> ScOut_co:
56 """Handle the arguments."""
59class SupportsLessThan(Protocol):
60 """A class that supports comparison with less than."""
62 @abstractmethod
63 def __lt__(self: T, other: T) -> bool:
64 """Compare to another instance of the same type."""
67class SupportsGreaterThan(Protocol):
68 """A class that supports comparison with less than."""
70 @abstractmethod
71 def __gt__(self: T, other: T) -> bool:
72 """Compare to another instance of the same type."""
75SupportsComparison: TypeAlias = SupportsGreaterThan | SupportsLessThan
78class SupportsAdd(Protocol):
79 """A class that supports addition."""
81 @abstractmethod
82 def __add__(self: T, other: T) -> T:
83 """Add another instance of the same type to self."""
86class Closeable(abc.ABC):
87 """Class that can be closed."""
89 __slots__ = ()
91 @abc.abstractmethod
92 def close(self) -> None:
93 """Run clean-up if not run yet."""
95 def __del__(self) -> None:
96 """Run close."""
97 self.close()
99 def __enter__(self: T) -> T:
100 """Return self."""
101 return self
103 def __exit__(self, *args: object) -> None:
104 """Run close."""
105 self.close()
108class PrettyRepr(abc.ABC):
109 """ABC to inherit from to get a better repr."""
111 __slots__ = ()
113 @classmethod
114 def _module(cls) -> str:
115 return cls.__module__
117 @override
118 def __repr__(self) -> str:
119 """Return the string representation of self."""
120 args = ",".join(
121 [("..." if arg is ... else repr(arg)) for arg in self._get_args()]
122 )
123 return (
124 f"{self.__class__._module()}.{self.__class__.__qualname__}({args})"
125 )
127 @abc.abstractmethod
128 def _get_args(self) -> tuple[object, ...]: # pragma: no cover
129 """Return the args used to initializing self."""
132class ClassWithCleanUp(Closeable, PrettyRepr):
133 """A class that has a cleanup_fun and a close method."""
135 cleanup_fun: Callable[[], object | None] | None
137 __slots__ = ("cleanup_fun",)
139 def __init__(self, cleanup_fun: Callable[[], object | None]) -> None:
140 """Initialize this class."""
141 self.cleanup_fun = cleanup_fun
143 @override
144 def _get_args(self) -> tuple[object, ...]:
145 """Return the args used to initializing self."""
146 return (self.cleanup_fun,)
148 @override
149 def close(self) -> None:
150 """Run clean-up if not run yet."""
151 if self.cleanup_fun:
152 self.cleanup_fun()
153 self.cleanup_fun = None
156class IteratorProxy(Iterator[V], Generic[V, T], PrettyRepr, abc.ABC):
157 """Proxy an iterator."""
159 _iterator: Iterator[T]
160 __slots__ = ("_iterator",)
162 def __init__(self, iterable: Iterable[T]) -> None:
163 """Init self."""
164 self._iterator = iter(iterable)
166 @override
167 def __iter__(self) -> Self:
168 """Return self."""
169 return self
171 @override
172 @abc.abstractmethod
173 def __next__(self) -> V:
174 """Return the next element."""
176 @override
177 def _get_args(self) -> tuple[object, ...]:
178 """Return the args used to initializing self."""
179 return (self._iterator,)