Skip to content

Commit da7c8a2

Browse files
committed
type pareto.py
1 parent bd1eb7c commit da7c8a2

File tree

2 files changed

+34
-18
lines changed

2 files changed

+34
-18
lines changed

hypothesis-python/src/hypothesis/internal/conjecture/engine.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -653,7 +653,7 @@ def test_function(self, data: ConjectureData) -> None:
653653

654654
self.record_for_health_check(data)
655655

656-
def on_pareto_evict(self, data: ConjectureData) -> None:
656+
def on_pareto_evict(self, data: ConjectureResult) -> None:
657657
self.settings.database.delete(self.pareto_key, choices_to_bytes(data.choices))
658658

659659
def generate_novel_prefix(self) -> tuple[ChoiceT, ...]:

hypothesis-python/src/hypothesis/internal/conjecture/pareto.py

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,28 @@
88
# v. 2.0. If a copy of the MPL was not distributed with this file, You can
99
# obtain one at https://mozilla.org/MPL/2.0/.
1010

11+
from collections.abc import Iterator
1112
from enum import Enum
13+
from random import Random
14+
from typing import TYPE_CHECKING, Callable, Optional, Union, cast
1215

1316
from sortedcontainers import SortedList
1417

1518
from hypothesis.internal.conjecture.choice import choices_key
16-
from hypothesis.internal.conjecture.data import ConjectureData, ConjectureResult, Status
19+
from hypothesis.internal.conjecture.data import (
20+
ConjectureData,
21+
ConjectureResult,
22+
Status,
23+
_Overrun,
24+
)
1725
from hypothesis.internal.conjecture.junkdrawer import LazySequenceCopy
1826
from hypothesis.internal.conjecture.shrinker import sort_key
1927

2028
NO_SCORE = float("-inf")
2129

30+
if TYPE_CHECKING:
31+
from hypothesis.internal.conjecture.engine import ConjectureRunner
32+
2233

2334
class DominanceRelation(Enum):
2435
NO_DOMINANCE = 0
@@ -27,7 +38,7 @@ class DominanceRelation(Enum):
2738
RIGHT_DOMINATES = 3
2839

2940

30-
def dominance(left, right):
41+
def dominance(left: ConjectureResult, right: ConjectureResult) -> DominanceRelation:
3142
"""Returns the dominance relation between ``left`` and ``right``, according
3243
to the rules that one ConjectureResult dominates another if and only if it
3344
is better in every way.
@@ -125,21 +136,25 @@ class ParetoFront:
125136
see how much of a problem this is in practice before we try that.
126137
"""
127138

128-
def __init__(self, random):
139+
def __init__(self, random: Random) -> None:
129140
self.__random = random
130-
self.__eviction_listeners = []
141+
self.__eviction_listeners: list[Callable[[ConjectureResult], None]] = []
131142

132-
self.front = SortedList(key=lambda d: sort_key(d.nodes))
133-
self.__pending = None
143+
self.front: SortedList[ConjectureResult] = SortedList(
144+
key=lambda d: sort_key(d.nodes)
145+
)
146+
self.__pending: Optional[ConjectureResult] = None
134147

135-
def add(self, data):
148+
def add(self, data: Union[ConjectureData, ConjectureResult, _Overrun]) -> bool:
136149
"""Attempts to add ``data`` to the pareto front. Returns True if
137150
``data`` is now in the front, including if data is already in the
138151
collection, and False otherwise"""
139152
if data.status < Status.VALID:
140153
return False
141154

155+
assert not isinstance(data, _Overrun)
142156
data = data.as_result()
157+
data = cast(ConjectureResult, data)
143158

144159
if not self.front:
145160
self.front.add(data)
@@ -166,7 +181,7 @@ def add(self, data):
166181
# We track which values we are going to remove and remove them all
167182
# at the end so the shape of the front doesn't change while we're
168183
# using it.
169-
to_remove = []
184+
to_remove: list[ConjectureResult] = []
170185

171186
# We now iteratively sample elements from the approximate pareto
172187
# front to check whether they should be retained. When the set of
@@ -238,26 +253,26 @@ def add(self, data):
238253
finally:
239254
self.__pending = None
240255

241-
def on_evict(self, f):
256+
def on_evict(self, f: Callable[[ConjectureResult], None]) -> None:
242257
"""Register a listener function that will be called with data when it
243258
gets removed from the front because something else dominates it."""
244259
self.__eviction_listeners.append(f)
245260

246-
def __contains__(self, data):
261+
def __contains__(self, data: object) -> bool:
247262
return isinstance(data, (ConjectureData, ConjectureResult)) and (
248263
data.as_result() in self.front
249264
)
250265

251-
def __iter__(self):
266+
def __iter__(self) -> Iterator[ConjectureResult]:
252267
return iter(self.front)
253268

254-
def __getitem__(self, i):
269+
def __getitem__(self, i: int) -> ConjectureResult:
255270
return self.front[i]
256271

257-
def __len__(self):
272+
def __len__(self) -> int:
258273
return len(self.front)
259274

260-
def __remove(self, data):
275+
def __remove(self, data: ConjectureResult) -> None:
261276
try:
262277
self.front.remove(data)
263278
except ValueError:
@@ -277,11 +292,12 @@ class ParetoOptimiser:
277292
grow more powerful over time.
278293
"""
279294

280-
def __init__(self, engine):
295+
def __init__(self, engine: "ConjectureRunner") -> None:
281296
self.__engine = engine
282-
self.front = self.__engine.pareto_front
297+
assert self.__engine.pareto_front is not None
298+
self.front: ParetoFront = self.__engine.pareto_front
283299

284-
def run(self):
300+
def run(self) -> None:
285301
seen = set()
286302

287303
# We iterate backwards through the pareto front, using the shrinker to

0 commit comments

Comments
 (0)