Skip to content

Commit 7eb35a4

Browse files
committed
add type annotations
1 parent 4e53ec6 commit 7eb35a4

File tree

9 files changed

+107
-59
lines changed

9 files changed

+107
-59
lines changed

MANIFEST.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
include README.rst LICENSE CONTRIBUTORS.rst HISTORY.rst
1+
include README.rst LICENSE CONTRIBUTORS.rst HISTORY.rst src/priority/py.typed
22

docs/source/conf.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
import sys
1616
import os
1717

18+
from typing import List, Dict
19+
1820
# If extensions (or modules to document with autodoc) are in another directory,
1921
# add these directories to sys.path here. If the directory is relative to the
2022
# documentation root, use os.path.abspath to make it absolute, like shown here.
@@ -71,7 +73,7 @@
7173

7274
# List of patterns, relative to source directory, that match files and
7375
# directories to ignore when looking for source files.
74-
exclude_patterns = []
76+
exclude_patterns = [] # type: List[str]
7577

7678
# The reST default role (used for this markup: `text`) to use for all
7779
# documents.
@@ -194,7 +196,7 @@
194196

195197
# Additional stuff for the LaTeX preamble.
196198
#'preamble': '',
197-
}
199+
} # type: Dict[str, str]
198200

199201
# Grouping the document tree into LaTeX files. List of tuples
200202
# (source start file, target name, title,

mypy.ini

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[mypy]
2+
strict=true
3+
warn_unused_configs=true
4+
show_error_codes=true
5+
6+
[mypy-test_priority]
7+
allow_untyped_defs=true
8+
check_untyped_defs=false
9+
10+
[mypy-conftest]
11+
allow_untyped_defs=true
12+
check_untyped_defs=false

setup.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env python
22
# -*- coding: utf-8 -*-
3-
from setuptools import setup, find_packages
3+
from setuptools import setup, find_packages # type: ignore[import]
44

55
setup(
66
name='priority',
@@ -30,4 +30,8 @@
3030
'Programming Language :: Python :: Implementation :: CPython',
3131
'Programming Language :: Python :: Implementation :: PyPy',
3232
],
33+
extras_require={
34+
"mypy": ["mypy>=0.812"],
35+
},
36+
install_requires=["typing >= 3.7.4.3; python_version < '3.5'"],
3337
)

src/priority/priority.py

Lines changed: 61 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import heapq
1111
import sys
1212

13+
from typing import List, Tuple, Optional
1314

1415
PY3 = 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__()

src/priority/py.typed

Whitespace-only changes.

test/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
66
Py.test fixtures for testing Priority.
77
"""
8-
import pytest
8+
import pytest # type: ignore[import]
99

1010
import priority
1111

0 commit comments

Comments
 (0)