5151HashableT = typing .TypeVar ("HashableT" , bound = typing .Hashable )
5252
5353
54- class _Sentinel :
54+ class Sentinel :
5555 """A sentinel to denote that no value has been received yet."""
5656
57+ def __init__ (self , desc : str ) -> None :
58+ """Initialize the sentinel."""
59+ self ._desc = desc
60+
5761 def __str__ (self ) -> str :
5862 """Return a string representation of this sentinel."""
59- return "<no value received yet >"
63+ return f"<Sentinel: { self . _desc } >"
6064
6165
62- _SENTINEL = _Sentinel ()
66+ NO_KEY : typing .Final [Sentinel ] = Sentinel ("no key provided" )
67+ NO_KEY_FUNCTION : typing .Final [Sentinel ] = Sentinel ("no key function provided" )
68+ NO_VALUE_RECEIVED : typing .Final [Sentinel ] = Sentinel ("no value received yet" )
6369
6470
6571class LatestValueCache (typing .Generic [T_co , HashableT ]):
@@ -71,11 +77,11 @@ class LatestValueCache(typing.Generic[T_co, HashableT]):
7177
7278 @typing .overload
7379 def __init__ (
74- self : LatestValueCache [T_co , _Sentinel ],
80+ self : LatestValueCache [T_co , Sentinel ],
7581 receiver : Receiver [T_co ],
7682 * ,
7783 unique_id : str | None = None ,
78- key : _Sentinel = _SENTINEL ,
84+ key : Sentinel = NO_KEY_FUNCTION ,
7985 ) -> None :
8086 """Create a new cache that does not use keys.
8187
@@ -111,7 +117,7 @@ def __init__(
111117 receiver : Receiver [T_co ],
112118 * ,
113119 unique_id : str | None = None ,
114- key : typing .Callable [[T_co ], typing .Any ] | _Sentinel = _SENTINEL ,
120+ key : typing .Callable [[T_co ], typing .Any ] | Sentinel = NO_KEY_FUNCTION ,
115121 ) -> None :
116122 """Create a new cache.
117123
@@ -126,9 +132,9 @@ def __init__(
126132 received overall.
127133 """
128134 self ._receiver = receiver
129- self ._key : typing .Callable [[T_co ], HashableT ] | _Sentinel = key
135+ self ._key : typing .Callable [[T_co ], HashableT ] | Sentinel = key
130136 self ._unique_id : str = hex (id (self )) if unique_id is None else unique_id
131- self ._latest_value : T_co | _Sentinel = _SENTINEL
137+ self ._latest_value : T_co | Sentinel = NO_VALUE_RECEIVED
132138 self ._latest_value_by_key : dict [HashableT , T_co ] = {}
133139 self ._task = asyncio .create_task (
134140 self ._run (), name = f"LatestValueCache«{ self ._unique_id } »"
@@ -139,7 +145,7 @@ def unique_id(self) -> str:
139145 """The unique identifier of this instance."""
140146 return self ._unique_id
141147
142- def get (self , key : HashableT | _Sentinel = _SENTINEL ) -> T_co :
148+ def get (self , key : HashableT | Sentinel = NO_KEY ) -> T_co :
143149 """Return the latest value that has been received.
144150
145151 This raises a `ValueError` if no value has been received yet. Use `has_value` to
@@ -156,16 +162,16 @@ def get(self, key: HashableT | _Sentinel = _SENTINEL) -> T_co:
156162 Raises:
157163 ValueError: If no value has been received yet.
158164 """
159- if not isinstance (key , _Sentinel ):
165+ if not isinstance (key , Sentinel ):
160166 if key not in self ._latest_value_by_key :
161167 raise ValueError (f"No value received for key: { key !r} " )
162168 return self ._latest_value_by_key [key ]
163169
164- if isinstance (self ._latest_value , _Sentinel ):
170+ if isinstance (self ._latest_value , Sentinel ):
165171 raise ValueError ("No value has been received yet." )
166172 return self ._latest_value
167173
168- def has_value (self , key : HashableT | _Sentinel = _SENTINEL ) -> bool :
174+ def has_value (self , key : HashableT | Sentinel = NO_KEY ) -> bool :
169175 """Check whether a value has been received yet.
170176
171177 If `key` is provided, it checks whether a value has been received for that key.
@@ -176,14 +182,14 @@ def has_value(self, key: HashableT | _Sentinel = _SENTINEL) -> bool:
176182 Returns:
177183 `True` if a value has been received, `False` otherwise.
178184 """
179- if not isinstance (key , _Sentinel ):
185+ if not isinstance (key , Sentinel ):
180186 return key in self ._latest_value_by_key
181- return not isinstance (self ._latest_value , _Sentinel )
187+ return not isinstance (self ._latest_value , Sentinel )
182188
183189 async def _run (self ) -> None :
184190 async for value in self ._receiver :
185191 self ._latest_value = value
186- if not isinstance (self ._key , _Sentinel ):
192+ if not isinstance (self ._key , Sentinel ):
187193 key = self ._key (value )
188194 self ._latest_value_by_key [key ] = value
189195
0 commit comments