1010import heapq
1111import sys
1212
13+ from typing import List , Tuple , Optional
1314
1415PY3 = sys .version_info [0 ] == 3
1516
@@ -84,22 +85,22 @@ class Stream(object):
8485 :param stream_id: The stream ID for the new stream.
8586 :param weight: (optional) The stream weight. Defaults to 16.
8687 """
87- def __init__ (self , stream_id , weight = 16 ):
88+ def __init__ (self , stream_id , weight = 16 ): # type: (int, int) -> None
8889 self .stream_id = stream_id
8990 self .weight = weight
90- self .children = []
91- self .parent = None
92- self .child_queue = []
91+ self .children = [] # type: List[Stream]
92+ self .parent = None # type: Optional[Stream]
93+ self .child_queue = [] # type: List[Tuple[int, Stream]]
9394 self .active = True
9495 self .last_weight = 0
9596 self ._deficit = 0
9697
9798 @property
98- def weight (self ):
99+ def weight (self ): # type: () -> int
99100 return self ._weight
100101
101102 @weight .setter
102- def weight (self , value ):
103+ def weight (self , value ): # type: (int) -> None
103104 # RFC 7540 § 5.3.2: "All dependent streams are allocated an integer
104105 # weight between 1 and 256 (inclusive)."
105106 if not isinstance (value , int ):
@@ -109,7 +110,7 @@ def weight(self, value):
109110 "Stream weight must be between 1 and 256 (inclusive)" )
110111 self ._weight = value
111112
112- def add_child (self , child ):
113+ def add_child (self , child ): # type: (Stream) -> None
113114 """
114115 Add a stream that depends on this one.
115116
@@ -119,7 +120,7 @@ def add_child(self, child):
119120 self .children .append (child )
120121 heapq .heappush (self .child_queue , (self .last_weight , child ))
121122
122- def add_child_exclusive (self , child ):
123+ def add_child_exclusive (self , child ): # type: (Stream) -> None
123124 """
124125 Add a stream that exclusively depends on this one.
125126
@@ -134,7 +135,12 @@ def add_child_exclusive(self, child):
134135 for old_child in old_children :
135136 child .add_child (old_child )
136137
137- def remove_child (self , child , strip_children = True ):
138+ def remove_child (
139+ self ,
140+ child , # type: Stream
141+ strip_children = True , # type: bool
142+ ):
143+ # type: (...) -> None
138144 """
139145 Removes a child stream from this stream. This is a potentially somewhat
140146 expensive operation.
@@ -150,7 +156,7 @@ def remove_child(self, child, strip_children=True):
150156 # it in the old one
151157 self .children .remove (child )
152158
153- new_queue = []
159+ new_queue = [] # type: List[Tuple[int, Stream]]
154160
155161 while self .child_queue :
156162 level , stream = heapq .heappop (self .child_queue )
@@ -165,7 +171,7 @@ def remove_child(self, child, strip_children=True):
165171 for new_child in child .children :
166172 self .add_child (new_child )
167173
168- def schedule (self ):
174+ def schedule (self ): # type: () -> int
169175 """
170176 Returns the stream ID of the next child to schedule. Potentially
171177 recurses down the tree of priorities.
@@ -205,45 +211,45 @@ def schedule(self):
205211 return next_stream
206212
207213 # Custom repr
208- def __repr__ (self ):
214+ def __repr__ (self ): # type: () -> str
209215 return "Stream<id=%d, weight=%d>" % (self .stream_id , self .weight )
210216
211217 # Custom comparison
212- def __eq__ (self , other ):
218+ def __eq__ (self , other ): # type: (object) -> bool
213219 if not isinstance (other , Stream ): # pragma: no cover
214220 return False
215221
216222 return self .stream_id == other .stream_id
217223
218- def __ne__ (self , other ):
224+ def __ne__ (self , other ): # type: (object) -> bool
219225 return not self .__eq__ (other )
220226
221- def __lt__ (self , other ):
227+ def __lt__ (self , other ): # type: (Stream) -> bool
222228 if not isinstance (other , Stream ): # pragma: no cover
223229 return NotImplemented
224230
225231 return self .stream_id < other .stream_id
226232
227- def __le__ (self , other ):
233+ def __le__ (self , other ): # type: (Stream) -> bool
228234 if not isinstance (other , Stream ): # pragma: no cover
229235 return NotImplemented
230236
231237 return self .stream_id <= other .stream_id
232238
233- def __gt__ (self , other ):
239+ def __gt__ (self , other ): # type: (Stream) -> bool
234240 if not isinstance (other , Stream ): # pragma: no cover
235241 return NotImplemented
236242
237243 return self .stream_id > other .stream_id
238244
239- def __ge__ (self , other ):
245+ def __ge__ (self , other ): # type: (Stream) -> bool
240246 if not isinstance (other , Stream ): # pragma: no cover
241247 return NotImplemented
242248
243249 return self .stream_id >= other .stream_id
244250
245251
246- def _stream_cycle (new_parent , current ):
252+ def _stream_cycle (new_parent , current ): # type: (Stream, Stream) -> bool
247253 """
248254 Reports whether the new parent depends on the current stream.
249255 """
@@ -253,7 +259,7 @@ def _stream_cycle(new_parent, current):
253259 # get more than 100 streams deep. This should catch accidental
254260 # tree loops. This is the definition of defensive programming.
255261 for _ in range (100 ):
256- parent = parent .parent
262+ parent = parent .parent # type: ignore[assignment]
257263 if parent .stream_id == current .stream_id :
258264 return True
259265 elif parent .stream_id == 0 :
@@ -289,7 +295,7 @@ class PriorityTree(object):
289295 default.
290296 :type maximum_streams: ``int``
291297 """
292- def __init__ (self , maximum_streams = 1000 ):
298+ def __init__ (self , maximum_streams = 1000 ): # type: (int) -> None
293299 # This flat array keeps hold of all the streams that are logically
294300 # dependent on stream 0.
295301 self ._root_stream = Stream (stream_id = 0 , weight = 1 )
@@ -302,7 +308,7 @@ def __init__(self, maximum_streams=1000):
302308 raise ValueError ("maximum_streams must be a positive integer." )
303309 self ._maximum_streams = maximum_streams
304310
305- def _get_or_insert_parent (self , parent_stream_id ):
311+ def _get_or_insert_parent (self , parent_stream_id ): # type: (int) -> Stream
306312 """
307313 When inserting or reprioritizing a stream it is possible to make it
308314 dependent on a stream that is no longer in the tree. In this situation,
@@ -316,18 +322,26 @@ def _get_or_insert_parent(self, parent_stream_id):
316322 self .block (parent_stream_id )
317323 return self ._streams [parent_stream_id ]
318324
319- def _exclusive_insert (self , parent_stream , inserted_stream ):
325+ def _exclusive_insert (
326+ self ,
327+ parent_stream , # type: Stream
328+ inserted_stream , # type: Stream
329+ ):
330+ # type: (...) -> None
320331 """
321332 Insert ``inserted_stream`` beneath ``parent_stream``, obeying the
322333 semantics of exclusive insertion.
323334 """
324335 parent_stream .add_child_exclusive (inserted_stream )
325336
326- def insert_stream (self ,
327- stream_id ,
328- depends_on = None ,
329- weight = 16 ,
330- exclusive = False ):
337+ def insert_stream (
338+ self ,
339+ stream_id , # type: int
340+ depends_on = None , # type: Optional[int]
341+ weight = 16 , # type: int
342+ exclusive = False , # type: bool
343+ ):
344+ # type: (...) -> None
331345 """
332346 Insert a stream into the tree.
333347
@@ -368,11 +382,14 @@ def insert_stream(self,
368382 parent .add_child (stream )
369383 self ._streams [stream_id ] = stream
370384
371- def reprioritize (self ,
372- stream_id ,
373- depends_on = None ,
374- weight = 16 ,
375- exclusive = False ):
385+ def reprioritize (
386+ self ,
387+ stream_id , # type: int
388+ depends_on = None , # type: Optional[int]
389+ weight = 16 , # type: int
390+ exclusive = False , # type: bool
391+ ):
392+ # type: (...) -> None
376393 """
377394 Update the priority status of a stream already in the tree.
378395
@@ -415,10 +432,10 @@ def reprioritize(self,
415432 # its parent, and make it a child of our current parent, and then
416433 # continue.
417434 if cycle :
418- new_parent .parent .remove_child (new_parent )
419- current_stream .parent .add_child (new_parent )
435+ new_parent .parent .remove_child (new_parent ) # type: ignore[union-attr]
436+ current_stream .parent .add_child (new_parent ) # type: ignore[union-attr]
420437
421- current_stream .parent .remove_child (
438+ current_stream .parent .remove_child ( # type: ignore[union-attr]
422439 current_stream , strip_children = False
423440 )
424441
@@ -427,7 +444,7 @@ def reprioritize(self,
427444 else :
428445 new_parent .add_child (current_stream )
429446
430- def remove_stream (self , stream_id ):
447+ def remove_stream (self , stream_id ): # type: (int) -> None
431448 """
432449 Removes a stream from the priority tree.
433450
@@ -442,9 +459,10 @@ def remove_stream(self, stream_id):
442459 raise MissingStreamError ("Stream %d not in tree" % stream_id )
443460
444461 parent = child .parent
445- parent .remove_child (child )
462+ parent .remove_child (child ) # type: ignore[union-attr]
463+
446464
447- def block (self , stream_id ):
465+ def block (self , stream_id ): # type: (int) -> None
448466 """
449467 Marks a given stream as blocked, with no data to send.
450468
@@ -458,7 +476,7 @@ def block(self, stream_id):
458476 except KeyError :
459477 raise MissingStreamError ("Stream %d not in tree" % stream_id )
460478
461- def unblock (self , stream_id ):
479+ def unblock (self , stream_id ): # type: (int) -> None
462480 """
463481 Marks a given stream as unblocked, with more data to send.
464482
@@ -473,14 +491,14 @@ def unblock(self, stream_id):
473491 raise MissingStreamError ("Stream %d not in tree" % stream_id )
474492
475493 # The iterator protocol
476- def __iter__ (self ): # pragma: no cover
494+ def __iter__ (self ): # type: () -> PriorityTree # pragma: no cover
477495 return self
478496
479- def __next__ (self ): # pragma: no cover
497+ def __next__ (self ): # type: () -> int # pragma: no cover
480498 try :
481499 return self ._root_stream .schedule ()
482500 except IndexError :
483501 raise DeadlockError ("No unblocked streams to schedule." )
484502
485- def next (self ): # pragma: no cover
503+ def next (self ): # type: () -> int # pragma: no cover
486504 return self .__next__ ()
0 commit comments