Skip to content

Commit

Permalink
Use py39 type annotations
Browse files Browse the repository at this point in the history
  • Loading branch information
Zac-HD committed Oct 9, 2024
1 parent 60b1316 commit fb91f66
Show file tree
Hide file tree
Showing 12 changed files with 91 additions and 109 deletions.
12 changes: 4 additions & 8 deletions hypothesis-python/src/hypothesis/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,15 @@
import warnings
import zlib
from collections import defaultdict
from collections.abc import Coroutine, Hashable
from functools import partial
from random import Random
from typing import (
TYPE_CHECKING,
Any,
BinaryIO,
Callable,
Coroutine,
Hashable,
List,
Optional,
Tuple,
Type,
TypeVar,
Union,
overload,
Expand Down Expand Up @@ -179,7 +175,7 @@ def __init__(self, *args: Any, **kwargs: Any) -> None:
if not (args or kwargs):
raise InvalidArgument("An example must provide at least one argument")

self.hypothesis_explicit_examples: List[Example] = []
self.hypothesis_explicit_examples: list[Example] = []
self._this_example = Example(tuple(args), kwargs)

def __call__(self, test: TestFunc) -> TestFunc:
Expand All @@ -194,7 +190,7 @@ def xfail(
*,
reason: str = "",
raises: Union[
Type[BaseException], Tuple[Type[BaseException], ...]
type[BaseException], tuple[type[BaseException], ...]
] = BaseException,
) -> "example":
"""Mark this example as an expected failure, similarly to
Expand Down Expand Up @@ -1825,7 +1821,7 @@ def find(
)
specifier.validate()

last: List[Ex] = []
last: list[Ex] = []

@settings
@given(specifier)
Expand Down
60 changes: 27 additions & 33 deletions hypothesis-python/src/hypothesis/extra/ghostwriter.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
import types
import warnings
from collections import OrderedDict, defaultdict
from collections.abc import Iterable, Mapping
from itertools import permutations, zip_longest
from keyword import iskeyword as _iskeyword
from string import ascii_lowercase
Expand All @@ -91,16 +92,9 @@
Any,
Callable,
DefaultDict,
Dict,
ForwardRef,
Iterable,
List,
Mapping,
NamedTuple,
Optional,
Set,
Tuple,
Type,
TypeVar,
Union,
get_args,
Expand Down Expand Up @@ -156,8 +150,8 @@ def test_{test_kind}_{func_name}({arg_names}){return_annotation}:
reject()
""".strip()

Except = Union[Type[Exception], Tuple[Type[Exception], ...]]
ImportSet = Set[Union[str, Tuple[str, str]]]
Except = Union[type[Exception], tuple[type[Exception], ...]]
ImportSet = set[Union[str, tuple[str, str]]]
_quietly_settings = settings(
database=None,
deadline=None,
Expand All @@ -166,7 +160,7 @@ def test_{test_kind}_{func_name}({arg_names}){return_annotation}:
)


def _dedupe_exceptions(exc: Tuple[Type[Exception], ...]) -> Tuple[Type[Exception], ...]:
def _dedupe_exceptions(exc: tuple[type[Exception], ...]) -> tuple[type[Exception], ...]:
# This is reminiscent of de-duplication logic I wrote for flake8-bugbear,
# but with access to the actual objects we can just check for subclasses.
# This lets us print e.g. `Exception` instead of `(Exception, OSError)`.
Expand All @@ -177,7 +171,7 @@ def _dedupe_exceptions(exc: Tuple[Type[Exception], ...]) -> Tuple[Type[Exception
return tuple(sorted(uniques, key=lambda e: e.__name__))


def _check_except(except_: Except) -> Tuple[Type[Exception], ...]:
def _check_except(except_: Except) -> tuple[type[Exception], ...]:
if isinstance(except_, tuple):
for i, e in enumerate(except_):
if not isinstance(e, type) or not issubclass(e, Exception):
Expand All @@ -194,7 +188,7 @@ def _check_except(except_: Except) -> Tuple[Type[Exception], ...]:
return (except_,)


def _exception_string(except_: Tuple[Type[Exception], ...]) -> Tuple[ImportSet, str]:
def _exception_string(except_: tuple[type[Exception], ...]) -> tuple[ImportSet, str]:
if not except_:
return set(), ""
exceptions = []
Expand All @@ -215,7 +209,7 @@ def _check_style(style: str) -> None:
raise InvalidArgument(f"Valid styles are 'pytest' or 'unittest', got {style!r}")


def _exceptions_from_docstring(doc: str) -> Tuple[Type[Exception], ...]:
def _exceptions_from_docstring(doc: str) -> tuple[type[Exception], ...]:
"""Return a tuple of exceptions that the docstring says may be raised.
Note that we ignore non-builtin exception types for simplicity, as this is
Expand Down Expand Up @@ -250,7 +244,7 @@ def _type_from_doc_fragment(token: str) -> Optional[type]:
if elems is None and elem_token.endswith("s"):
elems = _type_from_doc_fragment(elem_token[:-1])
if elems is not None and coll_token in ("list", "sequence", "collection"):
return List[elems] # type: ignore
return list[elems] # type: ignore
# This might be e.g. "array-like of float"; arrays is better than nothing
# even if we can't conveniently pass a generic type around.
return _type_from_doc_fragment(coll_token)
Expand Down Expand Up @@ -451,7 +445,7 @@ def _guess_strategy_by_argname(name: str) -> st.SearchStrategy:
return st.nothing()


def _get_params_builtin_fn(func: Callable) -> List[inspect.Parameter]:
def _get_params_builtin_fn(func: Callable) -> list[inspect.Parameter]:
if (
isinstance(func, (types.BuiltinFunctionType, types.BuiltinMethodType))
and hasattr(func, "__doc__")
Expand Down Expand Up @@ -483,7 +477,7 @@ def _get_params_builtin_fn(func: Callable) -> List[inspect.Parameter]:
return []


def _get_params_ufunc(func: Callable) -> List[inspect.Parameter]:
def _get_params_ufunc(func: Callable) -> list[inspect.Parameter]:
if _is_probably_ufunc(func):
# `inspect.signature` results vary for ufunc objects, but we can work out
# what the required parameters would look like if it was reliable.
Expand All @@ -498,7 +492,7 @@ def _get_params_ufunc(func: Callable) -> List[inspect.Parameter]:
return []


def _get_params(func: Callable) -> Dict[str, inspect.Parameter]:
def _get_params(func: Callable) -> dict[str, inspect.Parameter]:
"""Get non-vararg parameters of `func` as an ordered dict."""
try:
params = list(get_signature(func).parameters.values())
Expand All @@ -522,7 +516,7 @@ def _get_params(func: Callable) -> Dict[str, inspect.Parameter]:

def _params_to_dict(
params: Iterable[inspect.Parameter],
) -> Dict[str, inspect.Parameter]:
) -> dict[str, inspect.Parameter]:
var_param_kinds = (inspect.Parameter.VAR_POSITIONAL, inspect.Parameter.VAR_KEYWORD)
return OrderedDict((p.name, p) for p in params if p.kind not in var_param_kinds)

Expand All @@ -548,7 +542,7 @@ def _with_any_registered():

def _get_strategies(
*funcs: Callable, pass_result_to_next_func: bool = False
) -> Dict[str, st.SearchStrategy]:
) -> dict[str, st.SearchStrategy]:
"""Return a dict of strategies for the union of arguments to `funcs`.
If `pass_result_to_next_func` is True, assume that the result of each function
Expand All @@ -558,7 +552,7 @@ def _get_strategies(
This dict is used to construct our call to the `@given(...)` decorator.
"""
assert funcs, "Must pass at least one function"
given_strategies: Dict[str, st.SearchStrategy] = {}
given_strategies: dict[str, st.SearchStrategy] = {}
for i, f in enumerate(funcs):
params = _get_params(f)
if pass_result_to_next_func and i >= 1:
Expand Down Expand Up @@ -735,7 +729,7 @@ def _valid_syntax_repr(strategy):

# When we ghostwrite for a module, we want to treat that as the __module__ for
# each function, rather than whichever internal file it was actually defined in.
KNOWN_FUNCTION_LOCATIONS: Dict[object, str] = {}
KNOWN_FUNCTION_LOCATIONS: dict[object, str] = {}


def _get_module_helper(obj):
Expand Down Expand Up @@ -832,13 +826,13 @@ def _make_test_body(
*funcs: Callable,
ghost: str,
test_body: str,
except_: Tuple[Type[Exception], ...],
except_: tuple[type[Exception], ...],
assertions: str = "",
style: str,
given_strategies: Optional[Mapping[str, Union[str, st.SearchStrategy]]] = None,
imports: Optional[ImportSet] = None,
annotate: bool,
) -> Tuple[ImportSet, str]:
) -> tuple[ImportSet, str]:
# A set of modules to import - we might add to this later. The import code
# is written later, so we can have one import section for multiple magic()
# test functions.
Expand Down Expand Up @@ -899,7 +893,7 @@ def _make_test_body(
def _annotate_args(
argnames: Iterable[str], funcs: Iterable[Callable], imports: ImportSet
) -> Iterable[str]:
arg_parameters: DefaultDict[str, Set[Any]] = defaultdict(set)
arg_parameters: DefaultDict[str, set[Any]] = defaultdict(set)
for func in funcs:
try:
params = tuple(get_signature(func, eval_str=True).parameters.values())
Expand All @@ -922,7 +916,7 @@ def _annotate_args(

class _AnnotationData(NamedTuple):
type_name: str
imports: Set[str]
imports: set[str]


def _parameters_to_annotation_name(
Expand All @@ -949,7 +943,7 @@ def _parameters_to_annotation_name(


def _join_generics(
origin_type_data: Optional[Tuple[str, Set[str]]],
origin_type_data: Optional[tuple[str, set[str]]],
annotations: Iterable[Optional[_AnnotationData]],
) -> Optional[_AnnotationData]:
if origin_type_data is None:
Expand All @@ -976,9 +970,9 @@ def _join_generics(

def _join_argument_annotations(
annotations: Iterable[Optional[_AnnotationData]],
) -> Optional[Tuple[List[str], Set[str]]]:
imports: Set[str] = set()
arg_types: List[str] = []
) -> Optional[tuple[list[str], set[str]]]:
imports: set[str] = set()
arg_types: list[str] = []

for annotation in annotations:
if annotation is None:
Expand Down Expand Up @@ -1134,10 +1128,10 @@ def _is_probably_ufunc(obj):
)


def _get_testable_functions(thing: object) -> Dict[str, Callable]:
def _get_testable_functions(thing: object) -> dict[str, Callable]:
by_name = {}
if callable(thing):
funcs: List[Optional[Any]] = [thing]
funcs: list[Optional[Any]] = [thing]
elif isinstance(thing, types.ModuleType):
if hasattr(thing, "__all__"):
funcs = [getattr(thing, name, None) for name in thing.__all__]
Expand Down Expand Up @@ -1732,10 +1726,10 @@ def _make_binop_body(
commutative: bool = True,
identity: Union[X, EllipsisType, None] = ...,
distributes_over: Optional[Callable[[X, X], X]] = None,
except_: Tuple[Type[Exception], ...],
except_: tuple[type[Exception], ...],
style: str,
annotate: bool,
) -> Tuple[ImportSet, str]:
) -> tuple[ImportSet, str]:
strategies = _get_strategies(func)
operands, b = (strategies.pop(p) for p in list(_get_params(func))[:2])
if repr(operands) != repr(b):
Expand Down
4 changes: 2 additions & 2 deletions hypothesis-python/src/hypothesis/internal/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import sysconfig
import typing
from functools import partial
from typing import Any, ForwardRef, List, Optional, TypedDict as TypedDict, get_args
from typing import Any, ForwardRef, Optional, TypedDict as TypedDict, get_args

try:
BaseExceptionGroup = BaseExceptionGroup
Expand Down Expand Up @@ -218,7 +218,7 @@ def ceil(x):
return y


def extract_bits(x: int, /, width: Optional[int] = None) -> List[int]:
def extract_bits(x: int, /, width: Optional[int] = None) -> list[int]:
assert x >= 0
result = []
while x:
Expand Down
Loading

0 comments on commit fb91f66

Please sign in to comment.