Skip to content

Commit 09308df

Browse files
committed
Improve type annotations
1 parent 2f611af commit 09308df

File tree

17 files changed

+95
-66
lines changed

17 files changed

+95
-66
lines changed

hypothesis-python/src/_hypothesis_ftz_detector.py

+18-8
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@
1818

1919
import importlib
2020
import sys
21+
from typing import TYPE_CHECKING, Callable, Optional, Set, Tuple
22+
23+
if TYPE_CHECKING:
24+
from multiprocessing import Queue
25+
from typing import TypeAlias
26+
27+
FTZCulprits: "TypeAlias" = Tuple[Optional[bool], Set[str]]
28+
2129

2230
KNOWN_EVER_CULPRITS = (
2331
# https://moyix.blogspot.com/2022/09/someones-been-messing-with-my-subnormals.html
@@ -35,32 +43,34 @@
3543
)
3644

3745

38-
def flush_to_zero():
46+
def flush_to_zero() -> bool:
3947
# If this subnormal number compares equal to zero we have a problem
4048
return 2.0**-1073 == 0
4149

4250

43-
def run_in_process(fn, *args):
51+
def run_in_process(fn: Callable[..., FTZCulprits], *args: object) -> FTZCulprits:
4452
import multiprocessing as mp
4553

4654
mp.set_start_method("spawn", force=True)
47-
q = mp.Queue()
55+
q: "Queue[FTZCulprits]" = mp.Queue()
4856
p = mp.Process(target=target, args=(q, fn, *args))
4957
p.start()
5058
retval = q.get()
5159
p.join()
5260
return retval
5361

5462

55-
def target(q, fn, *args):
63+
def target(
64+
q: "Queue[FTZCulprits]", fn: Callable[..., FTZCulprits], *args: object
65+
) -> None:
5666
q.put(fn(*args))
5767

5868

59-
def always_imported_modules():
69+
def always_imported_modules() -> FTZCulprits:
6070
return flush_to_zero(), set(sys.modules)
6171

6272

63-
def modules_imported_by(mod):
73+
def modules_imported_by(mod: str) -> FTZCulprits:
6474
"""Return the set of modules imported transitively by mod."""
6575
before = set(sys.modules)
6676
try:
@@ -77,7 +87,7 @@ def modules_imported_by(mod):
7787
CHECKED_CACHE = set()
7888

7989

80-
def identify_ftz_culprits():
90+
def identify_ftz_culprits() -> str:
8191
"""Find the modules in sys.modules which cause "mod" to be imported."""
8292
# If we've run this function before, return the same result.
8393
global KNOWN_FTZ
@@ -94,7 +104,7 @@ def identify_ftz_culprits():
94104
# that importing them in a new process sets the FTZ state. As a heuristic, we'll
95105
# start with packages known to have ever enabled FTZ, then top-level packages as
96106
# a way to eliminate large fractions of the search space relatively quickly.
97-
def key(name):
107+
def key(name: str) -> Tuple[bool, int, str]:
98108
"""Prefer known-FTZ modules, then top-level packages, then alphabetical."""
99109
return (name not in KNOWN_EVER_CULPRITS, name.count("."), name)
100110

hypothesis-python/src/hypothesis/configuration.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,22 @@
1212
import sys
1313
import warnings
1414
from pathlib import Path
15+
from typing import Union
1516

1617
import _hypothesis_globals
1718

1819
from hypothesis.errors import HypothesisSideeffectWarning
1920

2021
__hypothesis_home_directory_default = Path.cwd() / ".hypothesis"
21-
2222
__hypothesis_home_directory = None
2323

2424

25-
def set_hypothesis_home_dir(directory):
25+
def set_hypothesis_home_dir(directory: Union[str, Path, None]) -> None:
2626
global __hypothesis_home_directory
2727
__hypothesis_home_directory = None if directory is None else Path(directory)
2828

2929

30-
def storage_directory(*names, intent_to_write=True):
30+
def storage_directory(*names: str, intent_to_write: bool = True) -> Path:
3131
if intent_to_write:
3232
check_sideeffect_during_initialization(
3333
"accessing storage for {}", "/".join(names)

hypothesis-python/src/hypothesis/errors.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ class StopTest(BaseException):
214214
the Hypothesis engine, which should then continue normally.
215215
"""
216216

217-
def __init__(self, testcounter):
217+
def __init__(self, testcounter: int) -> None:
218218
super().__init__(repr(testcounter))
219219
self.testcounter = testcounter
220220

@@ -230,7 +230,7 @@ class Found(HypothesisException):
230230
class RewindRecursive(Exception):
231231
"""Signal that the type inference should be rewound due to recursive types. Internal use only."""
232232

233-
def __init__(self, target):
233+
def __init__(self, target: object) -> None:
234234
self.target = target
235235

236236

hypothesis-python/src/hypothesis/internal/cache.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ class LRUCache:
307307
# Anecdotally, OrderedDict seems quite competitive with lru_cache, but perhaps
308308
# that is localized to our access patterns.
309309

310-
def __init__(self, max_size):
310+
def __init__(self, max_size: int) -> None:
311311
assert max_size > 0
312312
self.max_size = max_size
313313
self._threadlocal = threading.local()

hypothesis-python/src/hypothesis/internal/cathetus.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from sys import float_info
1313

1414

15-
def cathetus(h, a):
15+
def cathetus(h: float, a: float) -> float:
1616
"""Given the lengths of the hypotenuse and a side of a right triangle,
1717
return the length of the other side.
1818

hypothesis-python/src/hypothesis/internal/compat.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ def int_to_byte(i: int) -> bytes:
110110
return bytes([i])
111111

112112

113-
def is_typed_named_tuple(cls):
113+
def is_typed_named_tuple(cls: type) -> bool:
114114
"""Return True if cls is probably a subtype of `typing.NamedTuple`.
115115
116116
Unfortunately types created with `class T(NamedTuple):` actually

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

+27-20
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ def label(self) -> int:
271271
return self.owner.labels[self.owner.label_indices[self.index]]
272272

273273
@property
274-
def parent(self):
274+
def parent(self) -> Optional[int]:
275275
"""The index of the example that this one is nested directly within."""
276276
if self.index == 0:
277277
return None
@@ -298,13 +298,13 @@ def ir_end(self) -> int:
298298
return self.owner.ir_ends[self.index]
299299

300300
@property
301-
def depth(self):
301+
def depth(self) -> int:
302302
"""Depth of this example in the example tree. The top-level example has a
303303
depth of 0."""
304304
return self.owner.depths[self.index]
305305

306306
@property
307-
def trivial(self):
307+
def trivial(self) -> bool:
308308
"""An example is "trivial" if it only contains forced bytes and zero bytes.
309309
All examples start out as trivial, and then get marked non-trivial when
310310
we see a byte that is neither forced nor zero."""
@@ -352,6 +352,7 @@ def __init__(self, examples: "Examples"):
352352
self.example_count = 0
353353
self.block_count = 0
354354
self.ir_node_count = 0
355+
self.result: Any = None
355356

356357
def run(self) -> Any:
357358
"""Rerun the test case with this visitor and return the
@@ -425,7 +426,7 @@ def calculated_example_property(cls: Type[ExampleProperty]) -> Any:
425426
name = cls.__name__
426427
cache_name = "__" + name
427428

428-
def lazy_calculate(self: "Examples") -> IntList:
429+
def lazy_calculate(self: "Examples") -> Any:
429430
result = getattr(self, cache_name, None)
430431
if result is None:
431432
result = cls(self).run()
@@ -465,7 +466,14 @@ def __init__(self) -> None:
465466
def freeze(self) -> None:
466467
self.__index_of_labels = None
467468

468-
def record_ir_draw(self, ir_type, value, *, kwargs, was_forced):
469+
def record_ir_draw(
470+
self,
471+
ir_type: IRTypeName,
472+
value: IRType,
473+
*,
474+
kwargs: IRKWargsType,
475+
was_forced: bool,
476+
) -> None:
469477
self.trail.append(IR_NODE_RECORD)
470478
node = IRNode(
471479
ir_type=ir_type,
@@ -517,7 +525,7 @@ def __init__(self, record: ExampleRecord, blocks: "Blocks") -> None:
517525
self.__children: "Optional[List[Sequence[int]]]" = None
518526

519527
class _starts_and_ends(ExampleProperty):
520-
def begin(self):
528+
def begin(self) -> None:
521529
self.starts = IntList.of_length(len(self.examples))
522530
self.ends = IntList.of_length(len(self.examples))
523531

@@ -543,7 +551,7 @@ def ends(self) -> IntList:
543551
return self.starts_and_ends[1]
544552

545553
class _ir_starts_and_ends(ExampleProperty):
546-
def begin(self):
554+
def begin(self) -> None:
547555
self.starts = IntList.of_length(len(self.examples))
548556
self.ends = IntList.of_length(len(self.examples))
549557

@@ -570,7 +578,7 @@ def ir_ends(self) -> IntList:
570578

571579
class _discarded(ExampleProperty):
572580
def begin(self) -> None:
573-
self.result: "Set[int]" = set() # type: ignore # IntList in parent class
581+
self.result: "Set[int]" = set()
574582

575583
def finish(self) -> FrozenSet[int]:
576584
return frozenset(self.result)
@@ -584,7 +592,7 @@ def stop_example(self, i: int, *, discarded: bool) -> None:
584592
class _trivial(ExampleProperty):
585593
def begin(self) -> None:
586594
self.nontrivial = IntList.of_length(len(self.examples))
587-
self.result: "Set[int]" = set() # type: ignore # IntList in parent class
595+
self.result: "Set[int]" = set()
588596

589597
def block(self, i: int) -> None:
590598
if not self.examples.blocks.trivial(i):
@@ -610,7 +618,7 @@ def stop_example(self, i: int, *, discarded: bool) -> None:
610618
parentage: IntList = calculated_example_property(_parentage)
611619

612620
class _depths(ExampleProperty):
613-
def begin(self):
621+
def begin(self) -> None:
614622
self.result = IntList.of_length(len(self.examples))
615623

616624
def start_example(self, i: int, label_index: int) -> None:
@@ -619,10 +627,10 @@ def start_example(self, i: int, label_index: int) -> None:
619627
depths: IntList = calculated_example_property(_depths)
620628

621629
class _ir_tree_nodes(ExampleProperty):
622-
def begin(self):
630+
def begin(self) -> None:
623631
self.result = []
624632

625-
def ir_node(self, ir_node):
633+
def ir_node(self, ir_node: "IRNode") -> None:
626634
self.result.append(ir_node)
627635

628636
ir_tree_nodes: "List[IRNode]" = calculated_example_property(_ir_tree_nodes)
@@ -788,7 +796,7 @@ def all_bounds(self) -> Iterable[Tuple[int, int]]:
788796
prev = e
789797

790798
@property
791-
def last_block_length(self):
799+
def last_block_length(self) -> int:
792800
return self.end(-1) - self.start(-1)
793801

794802
def __len__(self) -> int:
@@ -869,7 +877,7 @@ def __getitem__(self, i: int) -> Block:
869877

870878
return result
871879

872-
def __check_completion(self):
880+
def __check_completion(self) -> None:
873881
"""The list of blocks is complete if we have created every ``Block``
874882
object that we currently good and know that no more will be created.
875883
@@ -899,7 +907,7 @@ def __repr__(self) -> str:
899907
class _Overrun:
900908
status = Status.OVERRUN
901909

902-
def __repr__(self):
910+
def __repr__(self) -> str:
903911
return "Overrun"
904912

905913

@@ -1052,7 +1060,7 @@ def __eq__(self, other):
10521060
and self.was_forced == other.was_forced
10531061
)
10541062

1055-
def __hash__(self):
1063+
def __hash__(self) -> int:
10561064
return hash(
10571065
(
10581066
self.ir_type,
@@ -1062,7 +1070,7 @@ def __hash__(self):
10621070
)
10631071
)
10641072

1065-
def __repr__(self):
1073+
def __repr__(self) -> str:
10661074
# repr to avoid "BytesWarning: str() on a bytes instance" for bytes nodes
10671075
forced_marker = " [forced]" if self.was_forced else ""
10681076
return f"{self.ir_type} {self.value!r}{forced_marker} {self.kwargs!r}"
@@ -1911,8 +1919,7 @@ def _compute_draw_float_init_logic(
19111919
"writeup - and good luck!"
19121920
)
19131921

1914-
def permitted(f):
1915-
assert isinstance(f, float)
1922+
def permitted(f: float) -> bool:
19161923
if math.isnan(f):
19171924
return allow_nan
19181925
if 0 < abs(f) < smallest_nonzero_magnitude:
@@ -2080,7 +2087,7 @@ def __init__(
20802087
self._node_index = 0
20812088
self.start_example(TOP_LABEL)
20822089

2083-
def __repr__(self):
2090+
def __repr__(self) -> str:
20842091
return "ConjectureData(%s, %d bytes%s)" % (
20852092
self.status.name,
20862093
len(self.buffer),

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

+1
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ class CallStats(TypedDict):
197197
"shrink-phase": NotRequired[PhaseStatistics],
198198
"stopped-because": NotRequired[str],
199199
"targets": NotRequired[Dict[str, float]],
200+
"nodeid": NotRequired[str],
200201
},
201202
)
202203

hypothesis-python/src/hypothesis/internal/detection.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from types import MethodType
1212

1313

14-
def is_hypothesis_test(test):
14+
def is_hypothesis_test(test: object) -> bool:
1515
if isinstance(test, MethodType):
1616
return is_hypothesis_test(test.__func__)
1717
return getattr(test, "is_hypothesis_test", False)

hypothesis-python/src/hypothesis/internal/filtering.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -331,9 +331,9 @@ def get_float_predicate_bounds(predicate: Predicate) -> ConstructivePredicate:
331331
return ConstructivePredicate(kwargs, predicate)
332332

333333

334-
def max_len(size: int, element: Collection) -> bool:
334+
def max_len(size: int, element: Collection[object]) -> bool:
335335
return len(element) <= size
336336

337337

338-
def min_len(size: int, element: Collection) -> bool:
338+
def min_len(size: int, element: Collection[object]) -> bool:
339339
return size <= len(element)

hypothesis-python/src/hypothesis/internal/scrutineer.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from functools import lru_cache, reduce
1919
from os import sep
2020
from pathlib import Path
21-
from typing import TYPE_CHECKING, Dict, List, Optional, Set, Tuple
21+
from typing import TYPE_CHECKING, Dict, Iterable, List, Optional, Set, Tuple
2222

2323
from hypothesis._settings import Phase, Verbosity
2424
from hypothesis.internal.compat import PYPY
@@ -35,7 +35,7 @@
3535

3636

3737
@lru_cache(maxsize=None)
38-
def should_trace_file(fname):
38+
def should_trace_file(fname: str) -> bool:
3939
# fname.startswith("<") indicates runtime code-generation via compile,
4040
# e.g. compile("def ...", "<string>", "exec") in e.g. attrs methods.
4141
return not (is_hypothesis_file(fname) or fname.startswith("<"))
@@ -55,12 +55,12 @@ class Tracer:
5555

5656
__slots__ = ("branches", "_previous_location")
5757

58-
def __init__(self):
58+
def __init__(self) -> None:
5959
self.branches: Trace = set()
60-
self._previous_location = None
60+
self._previous_location: Optional[Location] = None
6161

6262
@staticmethod
63-
def can_trace():
63+
def can_trace() -> bool:
6464
return (
6565
(sys.version_info[:2] < (3, 12) and sys.gettrace() is None)
6666
or (
@@ -138,7 +138,7 @@ def __exit__(self, *args, **kwargs):
138138
)
139139

140140

141-
def _glob_to_re(locs):
141+
def _glob_to_re(locs: Iterable[str]) -> str:
142142
"""Translate a list of glob patterns to a combined regular expression.
143143
Only the * wildcard is supported, and patterns including special
144144
characters will only work by chance."""

0 commit comments

Comments
 (0)