6
6
import dataclasses
7
7
import enum
8
8
import functools
9
- import typing
10
9
from collections .abc import Callable , Iterator
11
10
from dataclasses import dataclass
12
11
from datetime import datetime , timezone
13
- from typing import Generic , Protocol , Self , SupportsFloat , overload
12
+ from typing import Generic , Self , SupportsFloat , TypeVar , overload
14
13
15
14
from ._quantities import Power
16
15
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 )
37
17
"""Type variable for types that support conversion to float."""
38
18
39
- ComparableT = typing .TypeVar ("ComparableT" , bound = Comparable )
19
+ UNIX_EPOCH = datetime .fromtimestamp (0.0 , tz = timezone .utc )
20
+ """The UNIX epoch (in UTC)."""
40
21
41
22
42
23
@dataclass (frozen = True , order = True )
43
- class Sample (Generic [_T ]):
24
+ class Sample (Generic [SupportsFloatT ]):
44
25
"""A measurement taken at a particular point in time.
45
26
46
27
The `value` could be `None` if a component is malfunctioning or data is
@@ -51,12 +32,12 @@ class Sample(Generic[_T]):
51
32
timestamp : datetime
52
33
"""The time when this sample was generated."""
53
34
54
- value : _T | None = None
35
+ value : SupportsFloatT | None = None
55
36
"""The value of this sample."""
56
37
57
38
58
39
@dataclass (frozen = True )
59
- class Sample3Phase (Generic [ComparableT ]):
40
+ class Sample3Phase (Generic [SupportsFloatT ]):
60
41
"""A 3-phase measurement made at a particular point in time.
61
42
62
43
Each of the `value` fields could be `None` if a component is malfunctioning
@@ -67,16 +48,16 @@ class Sample3Phase(Generic[ComparableT]):
67
48
68
49
timestamp : datetime
69
50
"""The time when this sample was generated."""
70
- value_p1 : ComparableT | None
51
+ value_p1 : SupportsFloatT | None
71
52
"""The value of the 1st phase in this sample."""
72
53
73
- value_p2 : ComparableT | None
54
+ value_p2 : SupportsFloatT | None
74
55
"""The value of the 2nd phase in this sample."""
75
56
76
- value_p3 : ComparableT | None
57
+ value_p3 : SupportsFloatT | None
77
58
"""The value of the 3rd phase in this sample."""
78
59
79
- def __iter__ (self ) -> Iterator [ComparableT | None ]:
60
+ def __iter__ (self ) -> Iterator [SupportsFloatT | None ]:
80
61
"""Return an iterator that yields values from each of the phases.
81
62
82
63
Yields:
@@ -87,14 +68,14 @@ def __iter__(self) -> Iterator[ComparableT | None]:
87
68
yield self .value_p3
88
69
89
70
@overload
90
- def max (self , default : ComparableT ) -> ComparableT :
71
+ def max (self , default : SupportsFloatT ) -> SupportsFloatT :
91
72
...
92
73
93
74
@overload
94
- def max (self , default : None = None ) -> ComparableT | None :
75
+ def max (self , default : None = None ) -> SupportsFloatT | None :
95
76
...
96
77
97
- def max (self , default : ComparableT | None = None ) -> ComparableT | None :
78
+ def max (self , default : SupportsFloatT | None = None ) -> SupportsFloatT | None :
98
79
"""Return the max value among all phases, or default if they are all `None`.
99
80
100
81
Args:
@@ -105,21 +86,21 @@ def max(self, default: ComparableT | None = None) -> ComparableT | None:
105
86
"""
106
87
if not any (self ):
107
88
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 ,
110
91
filter (None , self ),
111
92
)
112
93
return value
113
94
114
95
@overload
115
- def min (self , default : ComparableT ) -> ComparableT :
96
+ def min (self , default : SupportsFloatT ) -> SupportsFloatT :
116
97
...
117
98
118
99
@overload
119
- def min (self , default : None = None ) -> ComparableT | None :
100
+ def min (self , default : None = None ) -> SupportsFloatT | None :
120
101
...
121
102
122
- def min (self , default : ComparableT | None = None ) -> ComparableT | None :
103
+ def min (self , default : SupportsFloatT | None = None ) -> SupportsFloatT | None :
123
104
"""Return the min value among all phases, or default if they are all `None`.
124
105
125
106
Args:
@@ -130,16 +111,16 @@ def min(self, default: ComparableT | None = None) -> ComparableT | None:
130
111
"""
131
112
if not any (self ):
132
113
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 ,
135
116
filter (None , self ),
136
117
)
137
118
return value
138
119
139
120
def map (
140
121
self ,
141
- function : Callable [[ComparableT ], ComparableT ],
142
- default : ComparableT | None = None ,
122
+ function : Callable [[SupportsFloatT ], SupportsFloatT ],
123
+ default : SupportsFloatT | None = None ,
143
124
) -> Self :
144
125
"""Apply the given function on each of the phase values and return the result.
145
126
@@ -161,6 +142,9 @@ def map(
161
142
)
162
143
163
144
145
+ _T = TypeVar ("_T" )
146
+
147
+
164
148
@dataclass (frozen = True )
165
149
class Bounds (Generic [_T ]):
166
150
"""Lower and upper bound values."""
0 commit comments