From 55b9c72352f6c73ced7663e44b54562dff07f4df Mon Sep 17 00:00:00 2001 From: Francesc Elies Date: Mon, 27 Mar 2023 18:05:21 +0200 Subject: [PATCH 1/7] [TYP] return array dtype is always unkown but it's specified as parameter --- hypothesis-python/src/hypothesis/extra/numpy.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/hypothesis-python/src/hypothesis/extra/numpy.py b/hypothesis-python/src/hypothesis/extra/numpy.py index e2e1e095ec..9683112bfb 100644 --- a/hypothesis-python/src/hypothesis/extra/numpy.py +++ b/hypothesis-python/src/hypothesis/extra/numpy.py @@ -9,7 +9,7 @@ # obtain one at https://mozilla.org/MPL/2.0/. import math -from typing import Any, Mapping, Optional, Sequence, Tuple, Union +from typing import Any, Mapping, Optional, Sequence, Tuple, TypeVar, Union import numpy as np @@ -37,6 +37,7 @@ from hypothesis.strategies._internal.numbers import Real from hypothesis.strategies._internal.strategies import T, check_strategy from hypothesis.strategies._internal.utils import defines_strategy +from numpy.typing import DTypeLike, NDArray __all__ = [ "BroadcastableShapes", @@ -374,15 +375,18 @@ def fill_for(elements, unique, fill, name=""): return fill +D = TypeVar("D", bound=DTypeLike) + + @defines_strategy(force_reusable_values=True) def arrays( - dtype: Any, + dtype: D, shape: Union[int, st.SearchStrategy[int], Shape, st.SearchStrategy[Shape]], *, elements: Optional[Union[st.SearchStrategy, Mapping[str, Any]]] = None, fill: Optional[st.SearchStrategy[Any]] = None, unique: bool = False, -) -> st.SearchStrategy[np.ndarray]: +) -> st.SearchStrategy[NDArray[D]]: r"""Returns a strategy for generating :class:`numpy:numpy.ndarray`\ s. * ``dtype`` may be any valid input to :class:`~numpy:numpy.dtype` @@ -900,8 +904,8 @@ def integer_array_indices( shape: Shape, *, result_shape: st.SearchStrategy[Shape] = array_shapes(), - dtype: np.dtype = "int", -) -> st.SearchStrategy[Tuple[np.ndarray, ...]]: + dtype: D = np.int32, +) -> st.SearchStrategy[Tuple[NDArray[D], ...]]: """Return a search strategy for tuples of integer-arrays that, when used to index into an array of shape ``shape``, given an array whose shape was drawn from ``result_shape``. From 7eae4f27e8396141a243b8aca116cd2b13f1402e Mon Sep 17 00:00:00 2001 From: Francesc Elies Date: Tue, 28 Mar 2023 12:04:59 +0200 Subject: [PATCH 2/7] [TYP] int32 is not always the default --- hypothesis-python/src/hypothesis/extra/numpy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hypothesis-python/src/hypothesis/extra/numpy.py b/hypothesis-python/src/hypothesis/extra/numpy.py index 9683112bfb..4378008ea0 100644 --- a/hypothesis-python/src/hypothesis/extra/numpy.py +++ b/hypothesis-python/src/hypothesis/extra/numpy.py @@ -904,7 +904,7 @@ def integer_array_indices( shape: Shape, *, result_shape: st.SearchStrategy[Shape] = array_shapes(), - dtype: D = np.int32, + dtype: D = np.int_, ) -> st.SearchStrategy[Tuple[NDArray[D], ...]]: """Return a search strategy for tuples of integer-arrays that, when used to index into an array of shape ``shape``, given an array whose shape From f33ae9cd80cfcff3005b519f5f5d25ec20f8648d Mon Sep 17 00:00:00 2001 From: Francesc Elies Date: Tue, 28 Mar 2023 12:05:28 +0200 Subject: [PATCH 3/7] [TYP] strategy parameters type are related to each other --- hypothesis-python/src/hypothesis/extra/numpy.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hypothesis-python/src/hypothesis/extra/numpy.py b/hypothesis-python/src/hypothesis/extra/numpy.py index 4378008ea0..23e234d63d 100644 --- a/hypothesis-python/src/hypothesis/extra/numpy.py +++ b/hypothesis-python/src/hypothesis/extra/numpy.py @@ -383,8 +383,8 @@ def arrays( dtype: D, shape: Union[int, st.SearchStrategy[int], Shape, st.SearchStrategy[Shape]], *, - elements: Optional[Union[st.SearchStrategy, Mapping[str, Any]]] = None, - fill: Optional[st.SearchStrategy[Any]] = None, + elements: Optional[Union[st.SearchStrategy[D], Mapping[str, Any]]] = None, + fill: Optional[st.SearchStrategy[D]] = None, unique: bool = False, ) -> st.SearchStrategy[NDArray[D]]: r"""Returns a strategy for generating :class:`numpy:numpy.ndarray`\ s. From 0ba72e8174e9036f0400695dc450d0b2f1906aba Mon Sep 17 00:00:00 2001 From: Francesc Elies Date: Tue, 28 Mar 2023 12:06:03 +0200 Subject: [PATCH 4/7] authors, contribution & typo release.rst --- AUTHORS.rst | 1 + CONTRIBUTING.rst | 2 +- hypothesis-python/RELEASE.rst | 7 +++++++ 3 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 hypothesis-python/RELEASE.rst diff --git a/AUTHORS.rst b/AUTHORS.rst index ae3d941db4..5f7dac911d 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -60,6 +60,7 @@ their individual contributions. * `Felix Sheldon `_ * `Florian Bruhin `_ * `follower `_ +* `Francesc Elies `_ * `Gabe Joseph `_ * `Gary Donovan `_ * `George Macon `_ diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 959aa7feb3..5a7f461faa 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -8,7 +8,7 @@ First off: It's great that you want to contribute to Hypothesis! Thanks! Just tell me how to make a pull request --------------------------------------- -1. Make you change and ensure it has adequate tests +1. Make your change and ensure it has adequate tests 2. Create ``hypothesis-python/RELEASE.rst`` with ``RELEASE_TYPE: patch`` for small bugfixes, or ``minor`` for new features. See recent PRs for examples. 3. Add yourself to the list in ``AUTHORS.rst`` and open a PR! diff --git a/hypothesis-python/RELEASE.rst b/hypothesis-python/RELEASE.rst new file mode 100644 index 0000000000..40b5ef80d5 --- /dev/null +++ b/hypothesis-python/RELEASE.rst @@ -0,0 +1,7 @@ +RELEASE_TYPE: patch + +Numpy array strategy returned dtype is always unkown but it's actually specified +as parameter. + +This patch made that relationship between dtype parameters and returned strategy +dtype explicit. From 12b9c9ae03e6b33bca0d3705f0af6512c3ef65f7 Mon Sep 17 00:00:00 2001 From: Francesc Elies Date: Tue, 28 Mar 2023 12:08:15 +0200 Subject: [PATCH 5/7] [TYP] dtype can actually be a DTypeLike or a SearchStrategy[DTypeLike] --- hypothesis-python/src/hypothesis/extra/numpy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hypothesis-python/src/hypothesis/extra/numpy.py b/hypothesis-python/src/hypothesis/extra/numpy.py index 23e234d63d..76946b2bb1 100644 --- a/hypothesis-python/src/hypothesis/extra/numpy.py +++ b/hypothesis-python/src/hypothesis/extra/numpy.py @@ -380,7 +380,7 @@ def fill_for(elements, unique, fill, name=""): @defines_strategy(force_reusable_values=True) def arrays( - dtype: D, + dtype: Union[D, st.SearchStrategy[D]], shape: Union[int, st.SearchStrategy[int], Shape, st.SearchStrategy[Shape]], *, elements: Optional[Union[st.SearchStrategy[D], Mapping[str, Any]]] = None, From 1713b31d4331565d0d173d2c865050399d5a6039 Mon Sep 17 00:00:00 2001 From: Francesc Elies Date: Tue, 28 Mar 2023 12:13:19 +0200 Subject: [PATCH 6/7] [TYP] strategy dtypes can be different, so long as casting is lossless, thus Any --- hypothesis-python/src/hypothesis/extra/numpy.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hypothesis-python/src/hypothesis/extra/numpy.py b/hypothesis-python/src/hypothesis/extra/numpy.py index 76946b2bb1..7d3ade791b 100644 --- a/hypothesis-python/src/hypothesis/extra/numpy.py +++ b/hypothesis-python/src/hypothesis/extra/numpy.py @@ -383,8 +383,8 @@ def arrays( dtype: Union[D, st.SearchStrategy[D]], shape: Union[int, st.SearchStrategy[int], Shape, st.SearchStrategy[Shape]], *, - elements: Optional[Union[st.SearchStrategy[D], Mapping[str, Any]]] = None, - fill: Optional[st.SearchStrategy[D]] = None, + elements: Optional[Union[st.SearchStrategy[Any], Mapping[str, Any]]] = None, + fill: Optional[st.SearchStrategy[Any]] = None, unique: bool = False, ) -> st.SearchStrategy[NDArray[D]]: r"""Returns a strategy for generating :class:`numpy:numpy.ndarray`\ s. From 1c7cd4dc67fcb75c180eb7b8992929bcfc71237e Mon Sep 17 00:00:00 2001 From: Zac Hatfield-Dodds Date: Mon, 24 Apr 2023 17:18:41 -0600 Subject: [PATCH 7/7] Fix lint issues --- hypothesis-python/RELEASE.rst | 7 ++----- hypothesis-python/src/hypothesis/extra/numpy.py | 3 ++- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/hypothesis-python/RELEASE.rst b/hypothesis-python/RELEASE.rst index 40b5ef80d5..064fd87624 100644 --- a/hypothesis-python/RELEASE.rst +++ b/hypothesis-python/RELEASE.rst @@ -1,7 +1,4 @@ RELEASE_TYPE: patch -Numpy array strategy returned dtype is always unkown but it's actually specified -as parameter. - -This patch made that relationship between dtype parameters and returned strategy -dtype explicit. +This patch fixes type annotations for the :func:`~hypothesis.extra.numpy.arrays` +strategy. Thanks to Francesc Elies for :pull:`3602`. diff --git a/hypothesis-python/src/hypothesis/extra/numpy.py b/hypothesis-python/src/hypothesis/extra/numpy.py index 7d3ade791b..a8a9e40497 100644 --- a/hypothesis-python/src/hypothesis/extra/numpy.py +++ b/hypothesis-python/src/hypothesis/extra/numpy.py @@ -12,6 +12,7 @@ from typing import Any, Mapping, Optional, Sequence, Tuple, TypeVar, Union import numpy as np +from numpy.typing import DTypeLike, NDArray from hypothesis import strategies as st from hypothesis._settings import note_deprecation @@ -37,7 +38,6 @@ from hypothesis.strategies._internal.numbers import Real from hypothesis.strategies._internal.strategies import T, check_strategy from hypothesis.strategies._internal.utils import defines_strategy -from numpy.typing import DTypeLike, NDArray __all__ = [ "BroadcastableShapes", @@ -464,6 +464,7 @@ def arrays( ) # From here on, we're only dealing with values and it's relatively simple. dtype = np.dtype(dtype) + assert isinstance(dtype, np.dtype) # help mypy out a bit... if elements is None or isinstance(elements, Mapping): if dtype.kind in ("m", "M") and "[" not in dtype.str: # For datetime and timedelta dtypes, we have a tricky situation -