66import dataclasses
77import enum
88import functools
9- import typing
109from collections .abc import Callable , Iterator
1110from dataclasses import dataclass
1211from datetime import datetime , timezone
13- from typing import Generic , Protocol , Self , SupportsFloat , overload
12+ from typing import Generic , Self , SupportsFloat , TypeVar , overload
1413
1514from ._quantities import Power
1615
17- UNIX_EPOCH = datetime .fromtimestamp (0.0 , tz = timezone .utc )
18- """The UNIX epoch (in UTC)."""
19-
20-
21- class Comparable (Protocol ):
22- def __lt__ (self , other : Self ) -> bool :
23- ...
24-
25- def __gt__ (self , other : Self ) -> bool :
26- ...
27-
28- def __le__ (self , other : Self ) -> bool :
29- ...
30-
31- def __ge__ (self , other : Self ) -> bool :
32- ...
33-
34-
35- _T = typing .TypeVar ("_T" )
36- SupportsFloatT = typing .TypeVar ("SupportsFloatT" , bound = SupportsFloat )
16+ SupportsFloatT = TypeVar ("SupportsFloatT" , bound = SupportsFloat )
3717"""Type variable for types that support conversion to float."""
3818
39- ComparableT = typing .TypeVar ("ComparableT" , bound = Comparable )
19+ UNIX_EPOCH = datetime .fromtimestamp (0.0 , tz = timezone .utc )
20+ """The UNIX epoch (in UTC)."""
4021
4122
4223@dataclass (frozen = True , order = True )
43- class Sample (Generic [_T ]):
24+ class Sample (Generic [SupportsFloatT ]):
4425 """A measurement taken at a particular point in time.
4526
4627 The `value` could be `None` if a component is malfunctioning or data is
@@ -51,12 +32,12 @@ class Sample(Generic[_T]):
5132 timestamp : datetime
5233 """The time when this sample was generated."""
5334
54- value : _T | None = None
35+ value : SupportsFloatT | None = None
5536 """The value of this sample."""
5637
5738
5839@dataclass (frozen = True )
59- class Sample3Phase (Generic [ComparableT ]):
40+ class Sample3Phase (Generic [SupportsFloatT ]):
6041 """A 3-phase measurement made at a particular point in time.
6142
6243 Each of the `value` fields could be `None` if a component is malfunctioning
@@ -67,16 +48,16 @@ class Sample3Phase(Generic[ComparableT]):
6748
6849 timestamp : datetime
6950 """The time when this sample was generated."""
70- value_p1 : ComparableT | None
51+ value_p1 : SupportsFloatT | None
7152 """The value of the 1st phase in this sample."""
7253
73- value_p2 : ComparableT | None
54+ value_p2 : SupportsFloatT | None
7455 """The value of the 2nd phase in this sample."""
7556
76- value_p3 : ComparableT | None
57+ value_p3 : SupportsFloatT | None
7758 """The value of the 3rd phase in this sample."""
7859
79- def __iter__ (self ) -> Iterator [ComparableT | None ]:
60+ def __iter__ (self ) -> Iterator [SupportsFloatT | None ]:
8061 """Return an iterator that yields values from each of the phases.
8162
8263 Yields:
@@ -87,14 +68,14 @@ def __iter__(self) -> Iterator[ComparableT | None]:
8768 yield self .value_p3
8869
8970 @overload
90- def max (self , default : ComparableT ) -> ComparableT :
71+ def max (self , default : SupportsFloatT ) -> SupportsFloatT :
9172 ...
9273
9374 @overload
94- def max (self , default : None = None ) -> ComparableT | None :
75+ def max (self , default : None = None ) -> SupportsFloatT | None :
9576 ...
9677
97- def max (self , default : ComparableT | None = None ) -> ComparableT | None :
78+ def max (self , default : SupportsFloatT | None = None ) -> SupportsFloatT | None :
9879 """Return the max value among all phases, or default if they are all `None`.
9980
10081 Args:
@@ -105,21 +86,21 @@ def max(self, default: ComparableT | None = None) -> ComparableT | None:
10586 """
10687 if not any (self ):
10788 return default
108- value : ComparableT = functools .reduce (
109- lambda x , y : x if x > y else y ,
89+ value : SupportsFloatT = functools .reduce (
90+ lambda x , y : x if float ( x ) > float ( y ) else y ,
11091 filter (None , self ),
11192 )
11293 return value
11394
11495 @overload
115- def min (self , default : ComparableT ) -> ComparableT :
96+ def min (self , default : SupportsFloatT ) -> SupportsFloatT :
11697 ...
11798
11899 @overload
119- def min (self , default : None = None ) -> ComparableT | None :
100+ def min (self , default : None = None ) -> SupportsFloatT | None :
120101 ...
121102
122- def min (self , default : ComparableT | None = None ) -> ComparableT | None :
103+ def min (self , default : SupportsFloatT | None = None ) -> SupportsFloatT | None :
123104 """Return the min value among all phases, or default if they are all `None`.
124105
125106 Args:
@@ -130,16 +111,16 @@ def min(self, default: ComparableT | None = None) -> ComparableT | None:
130111 """
131112 if not any (self ):
132113 return default
133- value : ComparableT = functools .reduce (
134- lambda x , y : x if x < y else y ,
114+ value : SupportsFloatT = functools .reduce (
115+ lambda x , y : x if float ( x ) < float ( y ) else y ,
135116 filter (None , self ),
136117 )
137118 return value
138119
139120 def map (
140121 self ,
141- function : Callable [[ComparableT ], ComparableT ],
142- default : ComparableT | None = None ,
122+ function : Callable [[SupportsFloatT ], SupportsFloatT ],
123+ default : SupportsFloatT | None = None ,
143124 ) -> Self :
144125 """Apply the given function on each of the phase values and return the result.
145126
@@ -161,6 +142,9 @@ def map(
161142 )
162143
163144
145+ _T = TypeVar ("_T" )
146+
147+
164148@dataclass (frozen = True )
165149class Bounds (Generic [_T ]):
166150 """Lower and upper bound values."""
0 commit comments