Coverage for typed_stream/_impl/_types.py: 100%
77 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-02-12 21:24 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-02-12 21:24 +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."""
47# pylint: disable=invalid-name
48SC_IN_contra = TypeVar("SC_IN_contra", contravariant=True)
49SC_OUT_co = TypeVar("SC_OUT_co", covariant=True)
50# pylint: enable=invalid-name
53class StarCallable(Protocol[SC_IN_contra, SC_OUT_co]):
54 """A class representing a function, that takes many arguments."""
56 @abstractmethod
57 def __call__(self, *args: SC_IN_contra) -> SC_OUT_co:
58 """Handle the arguments."""
61class SupportsLessThan(Protocol):
62 """A class that supports comparison with less than."""
64 @abstractmethod
65 def __lt__(self: T, other: T) -> bool:
66 """Compare to another instance of the same type."""
69class SupportsGreaterThan(Protocol):
70 """A class that supports comparison with less than."""
72 @abstractmethod
73 def __gt__(self: T, other: T) -> bool:
74 """Compare to another instance of the same type."""
77SupportsComparison: TypeAlias = SupportsGreaterThan | SupportsLessThan
80class SupportsAdd(Protocol):
81 """A class that supports addition."""
83 @abstractmethod
84 def __add__(self: T, other: T) -> T:
85 """Add another instance of the same type to self."""
88class Closeable(abc.ABC):
89 """Class that can be closed."""
91 __slots__ = ()
93 @abc.abstractmethod
94 def close(self) -> None:
95 """Run clean-up if not run yet."""
97 def __del__(self) -> None:
98 """Run close."""
99 self.close()
101 def __enter__(self: T) -> T:
102 """Return self."""
103 return self
105 def __exit__(self, *args: object) -> None:
106 """Run close."""
107 self.close()
110class PrettyRepr(abc.ABC):
111 """ABC to inherit from to get a better repr."""
113 __slots__ = ()
115 @classmethod
116 def _module(cls) -> str:
117 return cls.__module__
119 @override
120 def __repr__(self) -> str:
121 """Return the string representation of self."""
122 args = ",".join(
123 [("..." if arg is ... else repr(arg)) for arg in self._get_args()]
124 )
125 return (
126 f"{self.__class__._module()}.{self.__class__.__qualname__}({args})"
127 )
129 @abc.abstractmethod
130 def _get_args(self) -> tuple[object, ...]: # pragma: no cover
131 """Return the args used to initializing self."""
134class ClassWithCleanUp(Closeable, PrettyRepr):
135 """A class that has a cleanup_fun and a close method."""
137 cleanup_fun: Callable[[], object | None] | None
139 __slots__ = ("cleanup_fun",)
141 def __init__(self, cleanup_fun: Callable[[], object | None]) -> None:
142 """Initialize this class."""
143 self.cleanup_fun = cleanup_fun
145 @override
146 def _get_args(self) -> tuple[object, ...]:
147 """Return the args used to initializing self."""
148 return (self.cleanup_fun,)
150 @override
151 def close(self) -> None:
152 """Run clean-up if not run yet."""
153 if self.cleanup_fun:
154 self.cleanup_fun()
155 self.cleanup_fun = None
158class IteratorProxy(Iterator[V], Generic[V, T], PrettyRepr, abc.ABC):
159 """Proxy an iterator."""
161 _iterator: Iterator[T]
162 __slots__ = ("_iterator",)
164 def __init__(self, iterable: Iterable[T]) -> None:
165 """Init self."""
166 self._iterator = iter(iterable)
168 @override
169 def __iter__(self) -> Self:
170 """Return self."""
171 return self
173 @override
174 @abc.abstractmethod
175 def __next__(self) -> V:
176 """Return the next element."""
178 @override
179 def _get_args(self) -> tuple[object, ...]:
180 """Return the args used to initializing self."""
181 return (self._iterator,)