11# This contains the main Connection class. Everything in h11 revolves around
22# this.
3+ from enum import auto , Enum
34from typing import Any , Callable , cast , Dict , List , Optional , Tuple , Type , Union
45
56from ._events import (
2223 DONE ,
2324 ERROR ,
2425 MIGHT_SWITCH_PROTOCOL ,
26+ Role ,
2527 SEND_BODY ,
2628 SERVER ,
29+ State ,
2730 SWITCHED_PROTOCOL ,
31+ SwitchState ,
32+ SwitchType ,
2833)
29- from ._util import ( # Import the internal things we need
30- LocalProtocolError ,
31- RemoteProtocolError ,
32- Sentinel ,
33- )
34+ from ._util import LocalProtocolError # Import the internal things we need
35+ from ._util import RemoteProtocolError
3436from ._writers import WRITERS , WritersType
3537
3638# Everything in __all__ gets re-exported as part of the h11 public API.
3739__all__ = ["Connection" , "NEED_DATA" , "PAUSED" ]
3840
3941
40- class NEED_DATA (Sentinel , metaclass = Sentinel ):
41- pass
42+ class PseudoEvent (Enum ):
43+ NEED_DATA = auto ()
44+ PAUSED = auto ()
4245
4346
44- class PAUSED ( Sentinel , metaclass = Sentinel ):
45- pass
47+ NEED_DATA = PseudoEvent . NEED_DATA
48+ PAUSED = PseudoEvent . PAUSED
4649
4750
4851# If we ever have this much buffered without it making a complete parseable
@@ -154,15 +157,15 @@ class Connection:
154157
155158 def __init__ (
156159 self ,
157- our_role : Type [ Sentinel ] ,
160+ our_role : Role ,
158161 max_incomplete_event_size : int = DEFAULT_MAX_INCOMPLETE_EVENT_SIZE ,
159162 ) -> None :
160163 self ._max_incomplete_event_size = max_incomplete_event_size
161164 # State and role tracking
162165 if our_role not in (CLIENT , SERVER ):
163166 raise ValueError ("expected CLIENT or SERVER, not {!r}" .format (our_role ))
164167 self .our_role = our_role
165- self .their_role : Type [ Sentinel ]
168+ self .their_role : Role
166169 if our_role is CLIENT :
167170 self .their_role = SERVER
168171 else :
@@ -192,7 +195,7 @@ def __init__(
192195 self .client_is_waiting_for_100_continue = False
193196
194197 @property
195- def states (self ) -> Dict [Type [ Sentinel ], Type [ Sentinel ]]:
198+ def states (self ) -> Dict [Role , Union [ State , SwitchState ]]:
196199 """A dictionary like::
197200
198201 {CLIENT: <client state>, SERVER: <server state>}
@@ -203,14 +206,14 @@ def states(self) -> Dict[Type[Sentinel], Type[Sentinel]]:
203206 return dict (self ._cstate .states )
204207
205208 @property
206- def our_state (self ) -> Type [ Sentinel ]:
209+ def our_state (self ) -> Union [ State , SwitchState ]:
207210 """The current state of whichever role we are playing. See
208211 :ref:`state-machine` for details.
209212 """
210213 return self ._cstate .states [self .our_role ]
211214
212215 @property
213- def their_state (self ) -> Type [ Sentinel ]:
216+ def their_state (self ) -> Union [ State , SwitchState ]:
214217 """The current state of whichever role we are NOT playing. See
215218 :ref:`state-machine` for details.
216219 """
@@ -240,12 +243,12 @@ def start_next_cycle(self) -> None:
240243 assert not self .client_is_waiting_for_100_continue
241244 self ._respond_to_state_changes (old_states )
242245
243- def _process_error (self , role : Type [ Sentinel ] ) -> None :
246+ def _process_error (self , role : Role ) -> None :
244247 old_states = dict (self ._cstate .states )
245248 self ._cstate .process_error (role )
246249 self ._respond_to_state_changes (old_states )
247250
248- def _server_switch_event (self , event : Event ) -> Optional [Type [ Sentinel ] ]:
251+ def _server_switch_event (self , event : Event ) -> Optional [SwitchType ]:
249252 if type (event ) is InformationalResponse and event .status_code == 101 :
250253 return _SWITCH_UPGRADE
251254 if type (event ) is Response :
@@ -257,7 +260,7 @@ def _server_switch_event(self, event: Event) -> Optional[Type[Sentinel]]:
257260 return None
258261
259262 # All events go through here
260- def _process_event (self , role : Type [ Sentinel ] , event : Event ) -> None :
263+ def _process_event (self , role : Role , event : Event ) -> None :
261264 # First, pass the event through the state machine to make sure it
262265 # succeeds.
263266 old_states = dict (self ._cstate .states )
@@ -307,7 +310,7 @@ def _process_event(self, role: Type[Sentinel], event: Event) -> None:
307310
308311 def _get_io_object (
309312 self ,
310- role : Type [ Sentinel ] ,
313+ role : Role ,
311314 event : Optional [Event ],
312315 io_dict : Union [ReadersType , WritersType ],
313316 ) -> Optional [Callable [..., Any ]]:
@@ -323,13 +326,13 @@ def _get_io_object(
323326 else :
324327 # General case: the io_dict just has the appropriate reader/writer
325328 # for this state
326- return io_dict .get ((role , state )) # type: ignore[return-value]
329+ return io_dict .get ((role , state )) # type: ignore[arg-type, return-value]
327330
328331 # This must be called after any action that might have caused
329332 # self._cstate.states to change.
330333 def _respond_to_state_changes (
331334 self ,
332- old_states : Dict [Type [ Sentinel ], Type [ Sentinel ]],
335+ old_states : Dict [Role , Union [ State , SwitchState ]],
333336 event : Optional [Event ] = None ,
334337 ) -> None :
335338 # Update reader/writer
@@ -423,7 +426,7 @@ def _extract_next_receive_event(
423426 event = NEED_DATA
424427 return event # type: ignore[no-any-return]
425428
426- def next_event (self ) -> Union [Event , Type [ NEED_DATA ], Type [ PAUSED ] ]:
429+ def next_event (self ) -> Union [Event , PseudoEvent ]:
427430 """Parse the next event out of our receive buffer, update our internal
428431 state, and return it.
429432
0 commit comments