From db985ae09186b6e4f04b8a336755e8fcca1ea372 Mon Sep 17 00:00:00 2001 From: Matthew Date: Fri, 5 Nov 2021 12:10:11 +0000 Subject: [PATCH 1/7] Update stubs data-apis/array-api@f4c8c7f884647174e8ba19e2249914e9f894207a --- array_api_tests/function_stubs/__init__.py | 8 +- .../function_stubs/array_object.py | 158 +----------------- .../function_stubs/set_functions.py | 5 +- 3 files changed, 6 insertions(+), 165 deletions(-) diff --git a/array_api_tests/function_stubs/__init__.py b/array_api_tests/function_stubs/__init__.py index 0b560378..c6beb686 100644 --- a/array_api_tests/function_stubs/__init__.py +++ b/array_api_tests/function_stubs/__init__.py @@ -9,9 +9,9 @@ __all__ = [] -from .array_object import __abs__, __add__, __and__, __array_namespace__, __bool__, __dlpack__, __dlpack_device__, __eq__, __float__, __floordiv__, __ge__, __getitem__, __gt__, __index__, __int__, __invert__, __le__, __lshift__, __lt__, __matmul__, __mod__, __mul__, __ne__, __neg__, __or__, __pos__, __pow__, __rshift__, __setitem__, __sub__, __truediv__, __xor__, to_device, __iadd__, __radd__, __iand__, __rand__, __ifloordiv__, __rfloordiv__, __ilshift__, __rlshift__, __imatmul__, __rmatmul__, __imod__, __rmod__, __imul__, __rmul__, __ior__, __ror__, __ipow__, __rpow__, __irshift__, __rrshift__, __isub__, __rsub__, __itruediv__, __rtruediv__, __ixor__, __rxor__, dtype, device, mT, ndim, shape, size, T +from .array_object import __abs__, __add__, __and__, __array_namespace__, __bool__, __dlpack__, __dlpack_device__, __eq__, __float__, __floordiv__, __ge__, __getitem__, __gt__, __index__, __int__, __invert__, __le__, __lshift__, __lt__, __matmul__, __mod__, __mul__, __ne__, __neg__, __or__, __pos__, __pow__, __rshift__, __setitem__, __sub__, __truediv__, __xor__, to_device, dtype, device, mT, ndim, shape, size, T -__all__ += ['__abs__', '__add__', '__and__', '__array_namespace__', '__bool__', '__dlpack__', '__dlpack_device__', '__eq__', '__float__', '__floordiv__', '__ge__', '__getitem__', '__gt__', '__index__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__matmul__', '__mod__', '__mul__', '__ne__', '__neg__', '__or__', '__pos__', '__pow__', '__rshift__', '__setitem__', '__sub__', '__truediv__', '__xor__', 'to_device', '__iadd__', '__radd__', '__iand__', '__rand__', '__ifloordiv__', '__rfloordiv__', '__ilshift__', '__rlshift__', '__imatmul__', '__rmatmul__', '__imod__', '__rmod__', '__imul__', '__rmul__', '__ior__', '__ror__', '__ipow__', '__rpow__', '__irshift__', '__rrshift__', '__isub__', '__rsub__', '__itruediv__', '__rtruediv__', '__ixor__', '__rxor__', 'dtype', 'device', 'mT', 'ndim', 'shape', 'size', 'T'] +__all__ += ['__abs__', '__add__', '__and__', '__array_namespace__', '__bool__', '__dlpack__', '__dlpack_device__', '__eq__', '__float__', '__floordiv__', '__ge__', '__getitem__', '__gt__', '__index__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__matmul__', '__mod__', '__mul__', '__ne__', '__neg__', '__or__', '__pos__', '__pow__', '__rshift__', '__setitem__', '__sub__', '__truediv__', '__xor__', 'to_device', 'dtype', 'device', 'mT', 'ndim', 'shape', 'size', 'T'] from .constants import e, inf, nan, pi @@ -41,9 +41,9 @@ __all__ += ['argmax', 'argmin', 'nonzero', 'where'] -from .set_functions import unique_all, unique_counts, unique_inverse, unique_values +from .set_functions import unique_all, unique_inverse, unique_values -__all__ += ['unique_all', 'unique_counts', 'unique_inverse', 'unique_values'] +__all__ += ['unique_all', 'unique_inverse', 'unique_values'] from .sorting_functions import argsort, sort diff --git a/array_api_tests/function_stubs/array_object.py b/array_api_tests/function_stubs/array_object.py index ec4c33fd..7793d259 100644 --- a/array_api_tests/function_stubs/array_object.py +++ b/array_api_tests/function_stubs/array_object.py @@ -211,162 +211,6 @@ def to_device(self: array, device: device, /, *, stream: Optional[Union[int, Any """ pass -def __iadd__(self: array, other: Union[int, float, array], /) -> array: - """ - Note: __iadd__ is a method of the array object. - """ - pass - -def __radd__(self: array, other: Union[int, float, array], /) -> array: - """ - Note: __radd__ is a method of the array object. - """ - pass - -def __iand__(self: array, other: Union[int, bool, array], /) -> array: - """ - Note: __iand__ is a method of the array object. - """ - pass - -def __rand__(self: array, other: Union[int, bool, array], /) -> array: - """ - Note: __rand__ is a method of the array object. - """ - pass - -def __ifloordiv__(self: array, other: Union[int, float, array], /) -> array: - """ - Note: __ifloordiv__ is a method of the array object. - """ - pass - -def __rfloordiv__(self: array, other: Union[int, float, array], /) -> array: - """ - Note: __rfloordiv__ is a method of the array object. - """ - pass - -def __ilshift__(self: array, other: Union[int, array], /) -> array: - """ - Note: __ilshift__ is a method of the array object. - """ - pass - -def __rlshift__(self: array, other: Union[int, array], /) -> array: - """ - Note: __rlshift__ is a method of the array object. - """ - pass - -def __imatmul__(self: array, other: array, /) -> array: - """ - Note: __imatmul__ is a method of the array object. - """ - pass - -def __rmatmul__(self: array, other: array, /) -> array: - """ - Note: __rmatmul__ is a method of the array object. - """ - pass - -def __imod__(self: array, other: Union[int, float, array], /) -> array: - """ - Note: __imod__ is a method of the array object. - """ - pass - -def __rmod__(self: array, other: Union[int, float, array], /) -> array: - """ - Note: __rmod__ is a method of the array object. - """ - pass - -def __imul__(self: array, other: Union[int, float, array], /) -> array: - """ - Note: __imul__ is a method of the array object. - """ - pass - -def __rmul__(self: array, other: Union[int, float, array], /) -> array: - """ - Note: __rmul__ is a method of the array object. - """ - pass - -def __ior__(self: array, other: Union[int, bool, array], /) -> array: - """ - Note: __ior__ is a method of the array object. - """ - pass - -def __ror__(self: array, other: Union[int, bool, array], /) -> array: - """ - Note: __ror__ is a method of the array object. - """ - pass - -def __ipow__(self: array, other: Union[int, float, array], /) -> array: - """ - Note: __ipow__ is a method of the array object. - """ - pass - -def __rpow__(self: array, other: Union[int, float, array], /) -> array: - """ - Note: __rpow__ is a method of the array object. - """ - pass - -def __irshift__(self: array, other: Union[int, array], /) -> array: - """ - Note: __irshift__ is a method of the array object. - """ - pass - -def __rrshift__(self: array, other: Union[int, array], /) -> array: - """ - Note: __rrshift__ is a method of the array object. - """ - pass - -def __isub__(self: array, other: Union[int, float, array], /) -> array: - """ - Note: __isub__ is a method of the array object. - """ - pass - -def __rsub__(self: array, other: Union[int, float, array], /) -> array: - """ - Note: __rsub__ is a method of the array object. - """ - pass - -def __itruediv__(self: array, other: Union[int, float, array], /) -> array: - """ - Note: __itruediv__ is a method of the array object. - """ - pass - -def __rtruediv__(self: array, other: Union[int, float, array], /) -> array: - """ - Note: __rtruediv__ is a method of the array object. - """ - pass - -def __ixor__(self: array, other: Union[int, bool, array], /) -> array: - """ - Note: __ixor__ is a method of the array object. - """ - pass - -def __rxor__(self: array, other: Union[int, bool, array], /) -> array: - """ - Note: __rxor__ is a method of the array object. - """ - pass - # Note: dtype is an attribute of the array object. dtype: dtype = None @@ -388,4 +232,4 @@ def __rxor__(self: array, other: Union[int, bool, array], /) -> array: # Note: T is an attribute of the array object. T: array = None -__all__ = ['__abs__', '__add__', '__and__', '__array_namespace__', '__bool__', '__dlpack__', '__dlpack_device__', '__eq__', '__float__', '__floordiv__', '__ge__', '__getitem__', '__gt__', '__index__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__matmul__', '__mod__', '__mul__', '__ne__', '__neg__', '__or__', '__pos__', '__pow__', '__rshift__', '__setitem__', '__sub__', '__truediv__', '__xor__', 'to_device', '__iadd__', '__radd__', '__iand__', '__rand__', '__ifloordiv__', '__rfloordiv__', '__ilshift__', '__rlshift__', '__imatmul__', '__rmatmul__', '__imod__', '__rmod__', '__imul__', '__rmul__', '__ior__', '__ror__', '__ipow__', '__rpow__', '__irshift__', '__rrshift__', '__isub__', '__rsub__', '__itruediv__', '__rtruediv__', '__ixor__', '__rxor__', 'dtype', 'device', 'mT', 'ndim', 'shape', 'size', 'T'] +__all__ = ['__abs__', '__add__', '__and__', '__array_namespace__', '__bool__', '__dlpack__', '__dlpack_device__', '__eq__', '__float__', '__floordiv__', '__ge__', '__getitem__', '__gt__', '__index__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__matmul__', '__mod__', '__mul__', '__ne__', '__neg__', '__or__', '__pos__', '__pow__', '__rshift__', '__setitem__', '__sub__', '__truediv__', '__xor__', 'to_device', 'dtype', 'device', 'mT', 'ndim', 'shape', 'size', 'T'] diff --git a/array_api_tests/function_stubs/set_functions.py b/array_api_tests/function_stubs/set_functions.py index efc1ff52..abecc517 100644 --- a/array_api_tests/function_stubs/set_functions.py +++ b/array_api_tests/function_stubs/set_functions.py @@ -15,13 +15,10 @@ def unique_all(x: array, /) -> Tuple[array, array, array, array]: pass -def unique_counts(x: array, /) -> Tuple[array, array]: - pass - def unique_inverse(x: array, /) -> Tuple[array, array]: pass def unique_values(x: array, /) -> array: pass -__all__ = ['unique_all', 'unique_counts', 'unique_inverse', 'unique_values'] +__all__ = ['unique_all', 'unique_inverse', 'unique_values'] From cb9e802fdb2e83b5fe6d93562b7d79650ccc8230 Mon Sep 17 00:00:00 2001 From: Matthew Date: Fri, 5 Nov 2021 17:35:48 +0000 Subject: [PATCH 2/7] Rudimentary generation of op special case tests --- array_api_tests/special_cases/test___abs__.py | 52 ++ array_api_tests/special_cases/test___add__.py | 225 +++++++ array_api_tests/special_cases/test___mul__.py | 123 ++++ array_api_tests/special_cases/test___pow__.py | 326 ++++++++++ .../special_cases/test___truediv__.py | 292 +++++++++ generate_stubs.py | 555 +++++++++++++----- 6 files changed, 1412 insertions(+), 161 deletions(-) create mode 100644 array_api_tests/special_cases/test___abs__.py create mode 100644 array_api_tests/special_cases/test___add__.py create mode 100644 array_api_tests/special_cases/test___mul__.py create mode 100644 array_api_tests/special_cases/test___pow__.py create mode 100644 array_api_tests/special_cases/test___truediv__.py diff --git a/array_api_tests/special_cases/test___abs__.py b/array_api_tests/special_cases/test___abs__.py new file mode 100644 index 00000000..868440f8 --- /dev/null +++ b/array_api_tests/special_cases/test___abs__.py @@ -0,0 +1,52 @@ +""" +Special cases tests for x.__abs__. + +These tests are generated from the special cases listed in the spec. + +NOTE: This file is generated automatically by the generate_stubs.py script. Do +not modify it directly. +""" + +from ..array_helpers import NaN, assert_exactly_equal, exactly_equal, infinity, zero +from ..hypothesis_helpers import numeric_arrays + +from hypothesis import given + + +@given(numeric_arrays) +def test___abs___special_cases_one_arg_equal_1(arg1): + """ + Special case test for `__abs__(self, /)`: + + - If `x_i` is `NaN`, the result is `NaN`. + + """ + res = (arg1).__abs__() + mask = exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)) + assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays) +def test___abs___special_cases_one_arg_equal_2(arg1): + """ + Special case test for `__abs__(self, /)`: + + - If `x_i` is `-0`, the result is `+0`. + + """ + res = (arg1).__abs__() + mask = exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)) + assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays) +def test___abs___special_cases_one_arg_equal_3(arg1): + """ + Special case test for `__abs__(self, /)`: + + - If `x_i` is `-infinity`, the result is `+infinity`. + + """ + res = (arg1).__abs__() + mask = exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)) + assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test___add__.py b/array_api_tests/special_cases/test___add__.py new file mode 100644 index 00000000..ae1f6b8b --- /dev/null +++ b/array_api_tests/special_cases/test___add__.py @@ -0,0 +1,225 @@ +""" +Special cases tests for x.__add__. + +These tests are generated from the special cases listed in the spec. + +NOTE: This file is generated automatically by the generate_stubs.py script. Do +not modify it directly. +""" + +from ..array_helpers import (NaN, assert_exactly_equal, exactly_equal, infinity, isfinite, + logical_and, logical_or, non_zero, zero) +from ..hypothesis_helpers import numeric_arrays + +from hypothesis import given + + +@given(numeric_arrays, numeric_arrays) +def test___add___special_cases_two_args_either(arg1, arg2): + """ + Special case test for `__add__(self, other, /)`: + + - If either `x1_i` or `x2_i` is `NaN`, the result is `NaN`. + + """ + res = arg1.__add__(arg2) + mask = logical_or(exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)), exactly_equal(arg2, NaN(arg1.shape, arg1.dtype))) + assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___add___special_cases_two_args_equal__equal_1(arg1, arg2): + """ + Special case test for `__add__(self, other, /)`: + + - If `x1_i` is `+infinity` and `x2_i` is `-infinity`, the result is `NaN`. + + """ + res = arg1.__add__(arg2) + mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___add___special_cases_two_args_equal__equal_2(arg1, arg2): + """ + Special case test for `__add__(self, other, /)`: + + - If `x1_i` is `-infinity` and `x2_i` is `+infinity`, the result is `NaN`. + + """ + res = arg1.__add__(arg2) + mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___add___special_cases_two_args_equal__equal_3(arg1, arg2): + """ + Special case test for `__add__(self, other, /)`: + + - If `x1_i` is `+infinity` and `x2_i` is `+infinity`, the result is `+infinity`. + + """ + res = arg1.__add__(arg2) + mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___add___special_cases_two_args_equal__equal_4(arg1, arg2): + """ + Special case test for `__add__(self, other, /)`: + + - If `x1_i` is `-infinity` and `x2_i` is `-infinity`, the result is `-infinity`. + + """ + res = arg1.__add__(arg2) + mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___add___special_cases_two_args_equal__equal_5(arg1, arg2): + """ + Special case test for `__add__(self, other, /)`: + + - If `x1_i` is `+infinity` and `x2_i` is a finite number, the result is `+infinity`. + + """ + res = arg1.__add__(arg2) + mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), isfinite(arg2)) + assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___add___special_cases_two_args_equal__equal_6(arg1, arg2): + """ + Special case test for `__add__(self, other, /)`: + + - If `x1_i` is `-infinity` and `x2_i` is a finite number, the result is `-infinity`. + + """ + res = arg1.__add__(arg2) + mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), isfinite(arg2)) + assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___add___special_cases_two_args_equal__equal_7(arg1, arg2): + """ + Special case test for `__add__(self, other, /)`: + + - If `x1_i` is a finite number and `x2_i` is `+infinity`, the result is `+infinity`. + + """ + res = arg1.__add__(arg2) + mask = logical_and(isfinite(arg1), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___add___special_cases_two_args_equal__equal_8(arg1, arg2): + """ + Special case test for `__add__(self, other, /)`: + + - If `x1_i` is a finite number and `x2_i` is `-infinity`, the result is `-infinity`. + + """ + res = arg1.__add__(arg2) + mask = logical_and(isfinite(arg1), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___add___special_cases_two_args_equal__equal_9(arg1, arg2): + """ + Special case test for `__add__(self, other, /)`: + + - If `x1_i` is `-0` and `x2_i` is `-0`, the result is `-0`. + + """ + res = arg1.__add__(arg2) + mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___add___special_cases_two_args_equal__equal_10(arg1, arg2): + """ + Special case test for `__add__(self, other, /)`: + + - If `x1_i` is `-0` and `x2_i` is `+0`, the result is `+0`. + + """ + res = arg1.__add__(arg2) + mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___add___special_cases_two_args_equal__equal_11(arg1, arg2): + """ + Special case test for `__add__(self, other, /)`: + + - If `x1_i` is `+0` and `x2_i` is `-0`, the result is `+0`. + + """ + res = arg1.__add__(arg2) + mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___add___special_cases_two_args_equal__equal_12(arg1, arg2): + """ + Special case test for `__add__(self, other, /)`: + + - If `x1_i` is `+0` and `x2_i` is `+0`, the result is `+0`. + + """ + res = arg1.__add__(arg2) + mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___add___special_cases_two_args_equal__equal_13(arg1, arg2): + """ + Special case test for `__add__(self, other, /)`: + + - If `x1_i` is a nonzero finite number and `x2_i` is `-x1_i`, the result is `+0`. + + """ + res = arg1.__add__(arg2) + mask = logical_and(logical_and(isfinite(arg1), non_zero(arg1)), exactly_equal(arg2, -arg1)) + assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___add___special_cases_two_args_either__equal(arg1, arg2): + """ + Special case test for `__add__(self, other, /)`: + + - If `x1_i` is either `+0` or `-0` and `x2_i` is a nonzero finite number, the result is `x2_i`. + + """ + res = arg1.__add__(arg2) + mask = logical_and(logical_or(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg1, -zero(arg1.shape, arg1.dtype))), logical_and(isfinite(arg2), non_zero(arg2))) + assert_exactly_equal(res[mask], (arg2)[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___add___special_cases_two_args_equal__either(arg1, arg2): + """ + Special case test for `__add__(self, other, /)`: + + - If `x1_i` is a nonzero finite number and `x2_i` is either `+0` or `-0`, the result is `x1_i`. + + """ + res = arg1.__add__(arg2) + mask = logical_and(logical_and(isfinite(arg1), non_zero(arg1)), logical_or(exactly_equal(arg2, zero(arg2.shape, arg2.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype)))) + assert_exactly_equal(res[mask], (arg1)[mask]) + +# TODO: Implement REMAINING test for: +# - In the remaining cases, when neither `infinity`, `+0`, `-0`, nor a `NaN` is involved, and the operands have the same mathematical sign or have different magnitudes, the sum must be computed and rounded to the nearest representable value according to IEEE 754-2019 and a supported round mode. If the magnitude is too large to represent, the operation overflows and the result is an `infinity` of appropriate mathematical sign. diff --git a/array_api_tests/special_cases/test___mul__.py b/array_api_tests/special_cases/test___mul__.py new file mode 100644 index 00000000..694d93f1 --- /dev/null +++ b/array_api_tests/special_cases/test___mul__.py @@ -0,0 +1,123 @@ +""" +Special cases tests for x.__mul__. + +These tests are generated from the special cases listed in the spec. + +NOTE: This file is generated automatically by the generate_stubs.py script. Do +not modify it directly. +""" + +from ..array_helpers import (NaN, assert_exactly_equal, assert_isinf, + assert_negative_mathematical_sign, assert_positive_mathematical_sign, + exactly_equal, infinity, isfinite, logical_and, logical_not, + logical_or, non_zero, same_sign, zero) +from ..hypothesis_helpers import numeric_arrays + +from hypothesis import given + + +@given(numeric_arrays, numeric_arrays) +def test___mul___special_cases_two_args_either(arg1, arg2): + """ + Special case test for `__mul__(self, other, /)`: + + - If either `x1_i` or `x2_i` is `NaN`, the result is `NaN`. + + """ + res = arg1.__mul__(arg2) + mask = logical_or(exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)), exactly_equal(arg2, NaN(arg1.shape, arg1.dtype))) + assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___mul___special_cases_two_args_either__either_1(arg1, arg2): + """ + Special case test for `__mul__(self, other, /)`: + + - If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is either `+0` or `-0`, the result is `NaN`. + + """ + res = arg1.__mul__(arg2) + mask = logical_and(logical_or(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype))), logical_or(exactly_equal(arg2, zero(arg2.shape, arg2.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype)))) + assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___mul___special_cases_two_args_either__either_2(arg1, arg2): + """ + Special case test for `__mul__(self, other, /)`: + + - If `x1_i` is either `+0` or `-0` and `x2_i` is either `+infinity` or `-infinity`, the result is `NaN`. + + """ + res = arg1.__mul__(arg2) + mask = logical_and(logical_or(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg1, -zero(arg1.shape, arg1.dtype))), logical_or(exactly_equal(arg2, infinity(arg2.shape, arg2.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype)))) + assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___mul___special_cases_two_args_either__either_3(arg1, arg2): + """ + Special case test for `__mul__(self, other, /)`: + + - If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is either `+infinity` or `-infinity`, the result is a signed infinity with the mathematical sign determined by the rule already stated above. + + """ + res = arg1.__mul__(arg2) + mask = logical_and(logical_or(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype))), logical_or(exactly_equal(arg2, infinity(arg2.shape, arg2.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype)))) + assert_isinf(res[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___mul___special_cases_two_args_same_sign_except(arg1, arg2): + """ + Special case test for `__mul__(self, other, /)`: + + - If `x1_i` and `x2_i` have the same mathematical sign, the result has a positive mathematical sign, unless the result is `NaN`. If the result is `NaN`, the "sign" of `NaN` is implementation-defined. + + """ + res = arg1.__mul__(arg2) + mask = logical_and(same_sign(arg1, arg2), logical_not(exactly_equal(res, NaN(res.shape, res.dtype)))) + assert_positive_mathematical_sign(res[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___mul___special_cases_two_args_different_signs_except(arg1, arg2): + """ + Special case test for `__mul__(self, other, /)`: + + - If `x1_i` and `x2_i` have different mathematical signs, the result has a negative mathematical sign, unless the result is `NaN`. If the result is `NaN`, the "sign" of `NaN` is implementation-defined. + + """ + res = arg1.__mul__(arg2) + mask = logical_and(logical_not(same_sign(arg1, arg2)), logical_not(exactly_equal(res, NaN(res.shape, res.dtype)))) + assert_negative_mathematical_sign(res[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___mul___special_cases_two_args_either__equal(arg1, arg2): + """ + Special case test for `__mul__(self, other, /)`: + + - If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is a nonzero finite number, the result is a signed infinity with the mathematical sign determined by the rule already stated above. + + """ + res = arg1.__mul__(arg2) + mask = logical_and(logical_or(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype))), logical_and(isfinite(arg2), non_zero(arg2))) + assert_isinf(res[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___mul___special_cases_two_args_equal__either(arg1, arg2): + """ + Special case test for `__mul__(self, other, /)`: + + - If `x1_i` is a nonzero finite number and `x2_i` is either `+infinity` or `-infinity`, the result is a signed infinity with the mathematical sign determined by the rule already stated above. + + """ + res = arg1.__mul__(arg2) + mask = logical_and(logical_and(isfinite(arg1), non_zero(arg1)), logical_or(exactly_equal(arg2, infinity(arg2.shape, arg2.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype)))) + assert_isinf(res[mask]) + +# TODO: Implement REMAINING test for: +# - In the remaining cases, where neither `infinity` nor `NaN` is involved, the product must be computed and rounded to the nearest representable value according to IEEE 754-2019 and a supported rounding mode. If the magnitude is too large to represent, the result is an `infinity` of appropriate mathematical sign. If the magnitude is too small to represent, the result is a zero of appropriate mathematical sign. diff --git a/array_api_tests/special_cases/test___pow__.py b/array_api_tests/special_cases/test___pow__.py new file mode 100644 index 00000000..3a6a5a8d --- /dev/null +++ b/array_api_tests/special_cases/test___pow__.py @@ -0,0 +1,326 @@ +""" +Special cases tests for x.__pow__. + +These tests are generated from the special cases listed in the spec. + +NOTE: This file is generated automatically by the generate_stubs.py script. Do +not modify it directly. +""" + +from ..array_helpers import (NaN, assert_exactly_equal, exactly_equal, greater, infinity, isfinite, + isintegral, isodd, less, logical_and, logical_not, notequal, one, zero) +from ..hypothesis_helpers import numeric_arrays + +from hypothesis import given + + +@given(numeric_arrays, numeric_arrays) +def test___pow___special_cases_two_args_notequal__equal(arg1, arg2): + """ + Special case test for `__pow__(self, other, /)`: + + - If `x1_i` is not equal to `1` and `x2_i` is `NaN`, the result is `NaN`. + + """ + res = arg1.__pow__(arg2) + mask = logical_and(logical_not(exactly_equal(arg1, one(arg1.shape, arg1.dtype))), exactly_equal(arg2, NaN(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___pow___special_cases_two_args_even_if_1(arg1, arg2): + """ + Special case test for `__pow__(self, other, /)`: + + - If `x2_i` is `+0`, the result is `1`, even if `x1_i` is `NaN`. + + """ + res = arg1.__pow__(arg2) + mask = exactly_equal(arg2, zero(arg2.shape, arg2.dtype)) + assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___pow___special_cases_two_args_even_if_2(arg1, arg2): + """ + Special case test for `__pow__(self, other, /)`: + + - If `x2_i` is `-0`, the result is `1`, even if `x1_i` is `NaN`. + + """ + res = arg1.__pow__(arg2) + mask = exactly_equal(arg2, -zero(arg2.shape, arg2.dtype)) + assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___pow___special_cases_two_args_equal__notequal_1(arg1, arg2): + """ + Special case test for `__pow__(self, other, /)`: + + - If `x1_i` is `NaN` and `x2_i` is not equal to `0`, the result is `NaN`. + + """ + res = arg1.__pow__(arg2) + mask = logical_and(exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)), notequal(arg2, zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___pow___special_cases_two_args_equal__notequal_2(arg1, arg2): + """ + Special case test for `__pow__(self, other, /)`: + + - If `x1_i` is `1` and `x2_i` is not `NaN`, the result is `1`. + + """ + res = arg1.__pow__(arg2) + mask = logical_and(exactly_equal(arg1, one(arg1.shape, arg1.dtype)), logical_not(exactly_equal(arg2, NaN(arg2.shape, arg2.dtype)))) + assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___pow___special_cases_two_args_absgreater__equal_1(arg1, arg2): + """ + Special case test for `__pow__(self, other, /)`: + + - If `abs(x1_i)` is greater than `1` and `x2_i` is `+infinity`, the result is `+infinity`. + + """ + res = arg1.__pow__(arg2) + mask = logical_and(greater(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___pow___special_cases_two_args_absgreater__equal_2(arg1, arg2): + """ + Special case test for `__pow__(self, other, /)`: + + - If `abs(x1_i)` is greater than `1` and `x2_i` is `-infinity`, the result is `+0`. + + """ + res = arg1.__pow__(arg2) + mask = logical_and(greater(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___pow___special_cases_two_args_absequal__equal_1(arg1, arg2): + """ + Special case test for `__pow__(self, other, /)`: + + - If `abs(x1_i)` is `1` and `x2_i` is `+infinity`, the result is `1`. + + """ + res = arg1.__pow__(arg2) + mask = logical_and(exactly_equal(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___pow___special_cases_two_args_absequal__equal_2(arg1, arg2): + """ + Special case test for `__pow__(self, other, /)`: + + - If `abs(x1_i)` is `1` and `x2_i` is `-infinity`, the result is `1`. + + """ + res = arg1.__pow__(arg2) + mask = logical_and(exactly_equal(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___pow___special_cases_two_args_absless__equal_1(arg1, arg2): + """ + Special case test for `__pow__(self, other, /)`: + + - If `abs(x1_i)` is less than `1` and `x2_i` is `+infinity`, the result is `+0`. + + """ + res = arg1.__pow__(arg2) + mask = logical_and(less(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___pow___special_cases_two_args_absless__equal_2(arg1, arg2): + """ + Special case test for `__pow__(self, other, /)`: + + - If `abs(x1_i)` is less than `1` and `x2_i` is `-infinity`, the result is `+infinity`. + + """ + res = arg1.__pow__(arg2) + mask = logical_and(less(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___pow___special_cases_two_args_equal__greater_1(arg1, arg2): + """ + Special case test for `__pow__(self, other, /)`: + + - If `x1_i` is `+infinity` and `x2_i` is greater than `0`, the result is `+infinity`. + + """ + res = arg1.__pow__(arg2) + mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), greater(arg2, zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___pow___special_cases_two_args_equal__greater_2(arg1, arg2): + """ + Special case test for `__pow__(self, other, /)`: + + - If `x1_i` is `-infinity` and `x2_i` is greater than `0`, the result is `-infinity`. + + """ + res = arg1.__pow__(arg2) + mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), greater(arg2, zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___pow___special_cases_two_args_equal__greater_3(arg1, arg2): + """ + Special case test for `__pow__(self, other, /)`: + + - If `x1_i` is `+0` and `x2_i` is greater than `0`, the result is `+0`. + + """ + res = arg1.__pow__(arg2) + mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), greater(arg2, zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___pow___special_cases_two_args_equal__less_1(arg1, arg2): + """ + Special case test for `__pow__(self, other, /)`: + + - If `x1_i` is `+infinity` and `x2_i` is less than `0`, the result is `+0`. + + """ + res = arg1.__pow__(arg2) + mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), less(arg2, zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___pow___special_cases_two_args_equal__less_2(arg1, arg2): + """ + Special case test for `__pow__(self, other, /)`: + + - If `x1_i` is `+0` and `x2_i` is less than `0`, the result is `+infinity`. + + """ + res = arg1.__pow__(arg2) + mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), less(arg2, zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___pow___special_cases_two_args_equal__greater_notequal_1(arg1, arg2): + """ + Special case test for `__pow__(self, other, /)`: + + - If `x1_i` is `-infinity`, `x2_i` is greater than `0`, and `x2_i` is not an odd integer value, the result is `+infinity`. + + """ + res = arg1.__pow__(arg2) + mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(greater(arg2, zero(arg2.shape, arg2.dtype)), logical_not(isodd(arg2)))) + assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___pow___special_cases_two_args_equal__greater_notequal_2(arg1, arg2): + """ + Special case test for `__pow__(self, other, /)`: + + - If `x1_i` is `-0`, `x2_i` is greater than `0`, and `x2_i` is not an odd integer value, the result is `+0`. + + """ + res = arg1.__pow__(arg2) + mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), logical_and(greater(arg2, zero(arg2.shape, arg2.dtype)), logical_not(isodd(arg2)))) + assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___pow___special_cases_two_args_equal__less_equal_1(arg1, arg2): + """ + Special case test for `__pow__(self, other, /)`: + + - If `x1_i` is `-infinity`, `x2_i` is less than `0`, and `x2_i` is an odd integer value, the result is `-0`. + + """ + res = arg1.__pow__(arg2) + mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(less(arg2, zero(arg2.shape, arg2.dtype)), isodd(arg2))) + assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___pow___special_cases_two_args_equal__less_equal_2(arg1, arg2): + """ + Special case test for `__pow__(self, other, /)`: + + - If `x1_i` is `-0`, `x2_i` is less than `0`, and `x2_i` is an odd integer value, the result is `-infinity`. + + """ + res = arg1.__pow__(arg2) + mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), logical_and(less(arg2, zero(arg2.shape, arg2.dtype)), isodd(arg2))) + assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___pow___special_cases_two_args_equal__less_notequal_1(arg1, arg2): + """ + Special case test for `__pow__(self, other, /)`: + + - If `x1_i` is `-infinity`, `x2_i` is less than `0`, and `x2_i` is not an odd integer value, the result is `+0`. + + """ + res = arg1.__pow__(arg2) + mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(less(arg2, zero(arg2.shape, arg2.dtype)), logical_not(isodd(arg2)))) + assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___pow___special_cases_two_args_equal__less_notequal_2(arg1, arg2): + """ + Special case test for `__pow__(self, other, /)`: + + - If `x1_i` is `-0`, `x2_i` is less than `0`, and `x2_i` is not an odd integer value, the result is `+infinity`. + + """ + res = arg1.__pow__(arg2) + mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), logical_and(less(arg2, zero(arg2.shape, arg2.dtype)), logical_not(isodd(arg2)))) + assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___pow___special_cases_two_args_equal__greater_equal(arg1, arg2): + """ + Special case test for `__pow__(self, other, /)`: + + - If `x1_i` is `-0`, `x2_i` is greater than `0`, and `x2_i` is an odd integer value, the result is `-0`. + + """ + res = arg1.__pow__(arg2) + mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), logical_and(greater(arg2, zero(arg2.shape, arg2.dtype)), isodd(arg2))) + assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___pow___special_cases_two_args_less_equal__equal_notequal(arg1, arg2): + """ + Special case test for `__pow__(self, other, /)`: + + - If `x1_i` is less than `0`, `x1_i` is a finite number, `x2_i` is a finite number, and `x2_i` is not an integer value, the result is `NaN`. + + """ + res = arg1.__pow__(arg2) + mask = logical_and(logical_and(less(arg1, zero(arg1.shape, arg1.dtype)), isfinite(arg1)), logical_and(isfinite(arg2), logical_not(isintegral(arg2)))) + assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test___truediv__.py b/array_api_tests/special_cases/test___truediv__.py new file mode 100644 index 00000000..12866a28 --- /dev/null +++ b/array_api_tests/special_cases/test___truediv__.py @@ -0,0 +1,292 @@ +""" +Special cases tests for x.__truediv__. + +These tests are generated from the special cases listed in the spec. + +NOTE: This file is generated automatically by the generate_stubs.py script. Do +not modify it directly. +""" + +from ..array_helpers import (NaN, assert_exactly_equal, assert_negative_mathematical_sign, + assert_positive_mathematical_sign, exactly_equal, greater, infinity, + isfinite, isnegative, ispositive, less, logical_and, logical_not, + logical_or, non_zero, same_sign, zero) +from ..hypothesis_helpers import numeric_arrays + +from hypothesis import given + + +@given(numeric_arrays, numeric_arrays) +def test___truediv___special_cases_two_args_either(arg1, arg2): + """ + Special case test for `__truediv__(self, other, /)`: + + - If either `x1_i` or `x2_i` is `NaN`, the result is `NaN`. + + """ + res = arg1.__truediv__(arg2) + mask = logical_or(exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)), exactly_equal(arg2, NaN(arg1.shape, arg1.dtype))) + assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___truediv___special_cases_two_args_either__either_1(arg1, arg2): + """ + Special case test for `__truediv__(self, other, /)`: + + - If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is either `+infinity` or `-infinity`, the result is `NaN`. + + """ + res = arg1.__truediv__(arg2) + mask = logical_and(logical_or(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype))), logical_or(exactly_equal(arg2, infinity(arg2.shape, arg2.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype)))) + assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___truediv___special_cases_two_args_either__either_2(arg1, arg2): + """ + Special case test for `__truediv__(self, other, /)`: + + - If `x1_i` is either `+0` or `-0` and `x2_i` is either `+0` or `-0`, the result is `NaN`. + + """ + res = arg1.__truediv__(arg2) + mask = logical_and(logical_or(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg1, -zero(arg1.shape, arg1.dtype))), logical_or(exactly_equal(arg2, zero(arg2.shape, arg2.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype)))) + assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___truediv___special_cases_two_args_equal__greater_1(arg1, arg2): + """ + Special case test for `__truediv__(self, other, /)`: + + - If `x1_i` is `+0` and `x2_i` is greater than `0`, the result is `+0`. + + """ + res = arg1.__truediv__(arg2) + mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), greater(arg2, zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___truediv___special_cases_two_args_equal__greater_2(arg1, arg2): + """ + Special case test for `__truediv__(self, other, /)`: + + - If `x1_i` is `-0` and `x2_i` is greater than `0`, the result is `-0`. + + """ + res = arg1.__truediv__(arg2) + mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), greater(arg2, zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___truediv___special_cases_two_args_equal__less_1(arg1, arg2): + """ + Special case test for `__truediv__(self, other, /)`: + + - If `x1_i` is `+0` and `x2_i` is less than `0`, the result is `-0`. + + """ + res = arg1.__truediv__(arg2) + mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), less(arg2, zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___truediv___special_cases_two_args_equal__less_2(arg1, arg2): + """ + Special case test for `__truediv__(self, other, /)`: + + - If `x1_i` is `-0` and `x2_i` is less than `0`, the result is `+0`. + + """ + res = arg1.__truediv__(arg2) + mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), less(arg2, zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___truediv___special_cases_two_args_greater__equal_1(arg1, arg2): + """ + Special case test for `__truediv__(self, other, /)`: + + - If `x1_i` is greater than `0` and `x2_i` is `+0`, the result is `+infinity`. + + """ + res = arg1.__truediv__(arg2) + mask = logical_and(greater(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___truediv___special_cases_two_args_greater__equal_2(arg1, arg2): + """ + Special case test for `__truediv__(self, other, /)`: + + - If `x1_i` is greater than `0` and `x2_i` is `-0`, the result is `-infinity`. + + """ + res = arg1.__truediv__(arg2) + mask = logical_and(greater(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___truediv___special_cases_two_args_less__equal_1(arg1, arg2): + """ + Special case test for `__truediv__(self, other, /)`: + + - If `x1_i` is less than `0` and `x2_i` is `+0`, the result is `-infinity`. + + """ + res = arg1.__truediv__(arg2) + mask = logical_and(less(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___truediv___special_cases_two_args_less__equal_2(arg1, arg2): + """ + Special case test for `__truediv__(self, other, /)`: + + - If `x1_i` is less than `0` and `x2_i` is `-0`, the result is `+infinity`. + + """ + res = arg1.__truediv__(arg2) + mask = logical_and(less(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___truediv___special_cases_two_args_equal__equal_1(arg1, arg2): + """ + Special case test for `__truediv__(self, other, /)`: + + - If `x1_i` is `+infinity` and `x2_i` is a positive (i.e., greater than `0`) finite number, the result is `+infinity`. + + """ + res = arg1.__truediv__(arg2) + mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), logical_and(isfinite(arg2), ispositive(arg2))) + assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___truediv___special_cases_two_args_equal__equal_2(arg1, arg2): + """ + Special case test for `__truediv__(self, other, /)`: + + - If `x1_i` is `+infinity` and `x2_i` is a negative (i.e., less than `0`) finite number, the result is `-infinity`. + + """ + res = arg1.__truediv__(arg2) + mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), logical_and(isfinite(arg2), isnegative(arg2))) + assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___truediv___special_cases_two_args_equal__equal_3(arg1, arg2): + """ + Special case test for `__truediv__(self, other, /)`: + + - If `x1_i` is `-infinity` and `x2_i` is a positive (i.e., greater than `0`) finite number, the result is `-infinity`. + + """ + res = arg1.__truediv__(arg2) + mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(isfinite(arg2), ispositive(arg2))) + assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___truediv___special_cases_two_args_equal__equal_4(arg1, arg2): + """ + Special case test for `__truediv__(self, other, /)`: + + - If `x1_i` is `-infinity` and `x2_i` is a negative (i.e., less than `0`) finite number, the result is `+infinity`. + + """ + res = arg1.__truediv__(arg2) + mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(isfinite(arg2), isnegative(arg2))) + assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___truediv___special_cases_two_args_equal__equal_5(arg1, arg2): + """ + Special case test for `__truediv__(self, other, /)`: + + - If `x1_i` is a positive (i.e., greater than `0`) finite number and `x2_i` is `+infinity`, the result is `+0`. + + """ + res = arg1.__truediv__(arg2) + mask = logical_and(logical_and(isfinite(arg1), ispositive(arg1)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___truediv___special_cases_two_args_equal__equal_6(arg1, arg2): + """ + Special case test for `__truediv__(self, other, /)`: + + - If `x1_i` is a positive (i.e., greater than `0`) finite number and `x2_i` is `-infinity`, the result is `-0`. + + """ + res = arg1.__truediv__(arg2) + mask = logical_and(logical_and(isfinite(arg1), ispositive(arg1)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___truediv___special_cases_two_args_equal__equal_7(arg1, arg2): + """ + Special case test for `__truediv__(self, other, /)`: + + - If `x1_i` is a negative (i.e., less than `0`) finite number and `x2_i` is `+infinity`, the result is `-0`. + + """ + res = arg1.__truediv__(arg2) + mask = logical_and(logical_and(isfinite(arg1), isnegative(arg1)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___truediv___special_cases_two_args_equal__equal_8(arg1, arg2): + """ + Special case test for `__truediv__(self, other, /)`: + + - If `x1_i` is a negative (i.e., less than `0`) finite number and `x2_i` is `-infinity`, the result is `+0`. + + """ + res = arg1.__truediv__(arg2) + mask = logical_and(logical_and(isfinite(arg1), isnegative(arg1)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___truediv___special_cases_two_args_same_sign_both(arg1, arg2): + """ + Special case test for `__truediv__(self, other, /)`: + + - If `x1_i` and `x2_i` have the same mathematical sign and are both nonzero finite numbers, the result has a positive mathematical sign. + + """ + res = arg1.__truediv__(arg2) + mask = logical_and(same_sign(arg1, arg2), logical_and(logical_and(isfinite(arg1), non_zero(arg1)), logical_and(isfinite(arg2), non_zero(arg2)))) + assert_positive_mathematical_sign(res[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___truediv___special_cases_two_args_different_signs_both(arg1, arg2): + """ + Special case test for `__truediv__(self, other, /)`: + + - If `x1_i` and `x2_i` have different mathematical signs and are both nonzero finite numbers, the result has a negative mathematical sign. + + """ + res = arg1.__truediv__(arg2) + mask = logical_and(logical_not(same_sign(arg1, arg2)), logical_and(logical_and(isfinite(arg1), non_zero(arg1)), logical_and(isfinite(arg2), non_zero(arg2)))) + assert_negative_mathematical_sign(res[mask]) + +# TODO: Implement REMAINING test for: +# - In the remaining cases, where neither `-infinity`, `+0`, `-0`, nor `NaN` is involved, the quotient must be computed and rounded to the nearest representable value according to IEEE 754-2019 and a supported rounding mode. If the magnitude is too larger to represent, the operation overflows and the result is an `infinity` of appropriate mathematical sign. If the magnitude is too small to represent, the operation underflows and the result is a zero of appropriate mathematical sign. diff --git a/generate_stubs.py b/generate_stubs.py index 6aa0fba4..68c84022 100755 --- a/generate_stubs.py +++ b/generate_stubs.py @@ -15,11 +15,13 @@ import ast import itertools from collections import defaultdict +from typing import DefaultDict, Dict, List import regex from removestar.removestar import fix_code FUNCTION_HEADER_RE = regex.compile(r'\(function-(.*?)\)') +METHOD_HEADER_RE = regex.compile(r'\(method-(.*?)\)') HEADER_RE = regex.compile(r'\((?:function-linalg|function|method|constant|attribute)-(.*?)\)') FUNCTION_RE = regex.compile(r'\(function-.*\)=\n#+ ?(.*\(.*\))') METHOD_RE = regex.compile(r'\(method-.*\)=\n#+ ?(.*\(.*\))') @@ -82,6 +84,24 @@ ''' +OP_SPECIAL_CASES_HEADER = '''\ +""" +Special cases tests for x.{func}. + +These tests are generated from the special cases listed in the spec. + +NOTE: This file is generated automatically by the generate_stubs.py script. Do +not modify it directly. +""" + +from ..array_helpers import * +from ..hypothesis_helpers import numeric_arrays + +from hypothesis import given + +''' + + TYPES_HEADER = '''\ """ This file defines the types for type annotations. @@ -128,9 +148,8 @@ class iinfo_object: def main(): parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument('array_api_repo', help="Path to clone of the array-api repository") - parser.add_argument('--no-write', help="""Print what it would do but don't - write any files""", action='store_false', dest='write') - parser.add_argument('-v', '--verbose', help="""Print verbose output to the terminal""", action='store_true') + parser.add_argument('--no-write', help="Print what it would do but don't write any files", action='store_false', dest='write') + parser.add_argument('-v', '--verbose', help="Print verbose output to the terminal", action='store_true') args = parser.parse_args() types_path = os.path.join('array_api_tests', 'function_stubs', '_types.py') @@ -249,7 +268,7 @@ def {annotated_sig}:{doc} if args.write: with open(py_path, 'w') as f: f.write(code) - if filename == 'elementwise_functions.md': + if filename == 'elementwise_functions.md' and False: special_cases = parse_special_cases(text, verbose=args.verbose) for func in special_cases: py_path = os.path.join('array_api_tests', 'special_cases', f'test_{func}.py') @@ -276,6 +295,33 @@ def {annotated_sig}:{doc} if args.write: with open(py_path, 'w') as f: f.write(code) + elif filename == 'array_object.md': + special_cases = parse_special_cases(text, verbose=args.verbose) + for func in special_cases: + py_path = os.path.join('array_api_tests', 'special_cases', f'test_{func}.py') + tests = [] + for typ in special_cases[func]: + multiple = len(special_cases[func][typ]) > 1 + for i, m in enumerate(special_cases[func][typ], 1): + test_name_extra = typ.lower() + if multiple: + test_name_extra += f"_{i}" + try: + test = generate_special_case_test(func, typ, m, + test_name_extra, sigs) + if test is None: + raise NotImplementedError("Special case test not implemented") + tests.append(test) + except: + print(f"Error with {func}() {typ}: {m.group(0)}:\n", file=sys.stderr) + raise + if tests: + code = OP_SPECIAL_CASES_HEADER.format(func=func) + '\n'.join(tests) + # quiet=False will make it print a warning if a name is not found (indicating an error) + code = fix_code(code, file=py_path, verbose=False, quiet=False) + if args.write: + with open(py_path, 'w') as f: + f.write(code) init_path = os.path.join('array_api_tests', 'function_stubs', '__init__.py') if args.write: @@ -482,183 +528,369 @@ def test_{func}_special_cases_{test_name_extra}(arg1, arg2): {assertion} """ +OP_ONE_ARG_TEMPLATE = """ +{decorator} +def test_{func}_special_cases_{test_name_extra}(arg1): + {doc} + res = (arg1).{func}() + mask = {mask} + {assertion} +""" + +OP_TWO_ARGS_TEMPLATE = """ +{decorator} +def test_{func}_special_cases_{test_name_extra}(arg1, arg2): + {doc} + res = arg1.{func}(arg2) + mask = {mask} + {assertion} +""" + + REMAINING_TEMPLATE = """# TODO: Implement REMAINING test for: # {text} """ def generate_special_case_test(func, typ, m, test_name_extra, sigs): - + is_op = func.startswith("__") doc = f'''""" Special case test for `{sigs[func]}`: {m.group(0)} """''' - if typ.startswith("ONE_ARG"): - decorator = "@given(numeric_arrays)" - if typ == "ONE_ARG_EQUAL": - value1, result = m.groups() - value1 = parse_value(value1, 'arg1') - mask = get_mask("exactly_equal", "arg1", value1) - elif typ == "ONE_ARG_GREATER": - value1, result = m.groups() - value1 = parse_value(value1, 'arg1') - mask = get_mask("greater", "arg1", value1) - elif typ == "ONE_ARG_LESS": - value1, result = m.groups() - value1 = parse_value(value1, 'arg1') - mask = get_mask("less", "arg1", value1) - elif typ == "ONE_ARG_EITHER": - value1, value2, result = m.groups() - value1 = parse_value(value1, 'arg1') - value2 = parse_value(value2, 'arg1') - mask1 = get_mask("exactly_equal", "arg1", value1) - mask2 = get_mask("exactly_equal", "arg1", value2) - mask = f"logical_or({mask1}, {mask2})" - elif typ == "ONE_ARG_ALREADY_INTEGER_VALUED": - result, = m.groups() - mask = parse_value("integer", "arg1") - elif typ == "ONE_ARG_TWO_INTEGERS_EQUALLY_CLOSE": - result, = m.groups() - mask = "logical_and(not_equal(floor(arg1), ceil(arg1)), equal(subtract(arg1, floor(arg1)), subtract(ceil(arg1), arg1)))" - else: - raise ValueError(f"Unrecognized special value type {typ}") - assertion = get_assert("exactly_equal", result) - return ONE_ARG_TEMPLATE.format( - decorator=decorator, - func=func, - test_name_extra=test_name_extra, - doc=doc, - mask=mask, - assertion=assertion, - ) - - elif typ.startswith("TWO_ARGS"): - decorator = "@given(numeric_arrays, numeric_arrays)" - if typ in [ - "TWO_ARGS_EQUAL__EQUAL", - "TWO_ARGS_GREATER__EQUAL", - "TWO_ARGS_LESS__EQUAL", - "TWO_ARGS_EQUAL__GREATER", - "TWO_ARGS_EQUAL__LESS", - "TWO_ARGS_EQUAL__NOTEQUAL", - "TWO_ARGS_NOTEQUAL__EQUAL", - "TWO_ARGS_ABSEQUAL__EQUAL", - "TWO_ARGS_ABSGREATER__EQUAL", - "TWO_ARGS_ABSLESS__EQUAL", - "TWO_ARGS_GREATER_EQUAL__EQUAL", - "TWO_ARGS_LESS_EQUAL__EQUAL", - "TWO_ARGS_EQUAL__LESS_EQUAL", - "TWO_ARGS_EQUAL__LESS_NOTEQUAL", - "TWO_ARGS_EQUAL__GREATER_EQUAL", - "TWO_ARGS_EQUAL__GREATER_NOTEQUAL", - "TWO_ARGS_LESS_EQUAL__EQUAL_NOTEQUAL", - "TWO_ARGS_EITHER__EQUAL", - "TWO_ARGS_EQUAL__EITHER", - "TWO_ARGS_EITHER__EITHER", - ]: - arg1typs, arg2typs = [i.split('_') for i in typ[len("TWO_ARGS_"):].split("__")] - if arg1typs == ["EITHER"]: - arg1typs = ["EITHER_EQUAL", "EITHER_EQUAL"] - if arg2typs == ["EITHER"]: - arg2typs = ["EITHER_EQUAL", "EITHER_EQUAL"] - *values, result = m.groups() - if len(values) != len(arg1typs) + len(arg2typs): - raise RuntimeError(f"Unexpected number of parsed values for {typ}: len({values}) != len({arg1typs}) + len({arg2typs})") - arg1values, arg2values = values[:len(arg1typs)], values[len(arg1typs):] - arg1values = [parse_value(value, 'arg1') for value in arg1values] - arg2values = [parse_value(value, 'arg2') for value in arg2values] - - tomask = lambda t: t.lower().replace("either_equal", "equal").replace("equal", "exactly_equal") - value1masks = [get_mask(tomask(t), 'arg1', v) for t, v in - zip(arg1typs, arg1values)] - value2masks = [get_mask(tomask(t), 'arg2', v) for t, v in - zip(arg2typs, arg2values)] - if len(value1masks) > 1: - if arg1typs[0] == "EITHER_EQUAL": - mask1 = f"logical_or({value1masks[0]}, {value1masks[1]})" - else: - mask1 = f"logical_and({value1masks[0]}, {value1masks[1]})" + if is_op: + if typ.startswith("ONE_ARG"): + decorator = "@given(numeric_arrays)" + if typ == "ONE_ARG_EQUAL": + value1, result = m.groups() + value1 = parse_value(value1, 'arg1') + mask = get_mask("exactly_equal", "arg1", value1) + elif typ == "ONE_ARG_GREATER": + value1, result = m.groups() + value1 = parse_value(value1, 'arg1') + mask = get_mask("greater", "arg1", value1) + elif typ == "ONE_ARG_LESS": + value1, result = m.groups() + value1 = parse_value(value1, 'arg1') + mask = get_mask("less", "arg1", value1) + elif typ == "ONE_ARG_EITHER": + value1, value2, result = m.groups() + value1 = parse_value(value1, 'arg1') + value2 = parse_value(value2, 'arg1') + mask1 = get_mask("exactly_equal", "arg1", value1) + mask2 = get_mask("exactly_equal", "arg1", value2) + mask = f"logical_or({mask1}, {mask2})" + elif typ == "ONE_ARG_ALREADY_INTEGER_VALUED": + result, = m.groups() + mask = parse_value("integer", "arg1") + elif typ == "ONE_ARG_TWO_INTEGERS_EQUALLY_CLOSE": + result, = m.groups() + mask = "logical_and(not_equal(floor(arg1), ceil(arg1)), equal(subtract(arg1, floor(arg1)), subtract(ceil(arg1), arg1)))" else: - mask1 = value1masks[0] - if len(value2masks) > 1: - if arg2typs[0] == "EITHER_EQUAL": - mask2 = f"logical_or({value2masks[0]}, {value2masks[1]})" + raise ValueError(f"Unrecognized special value type {typ}") + assertion = get_assert("exactly_equal", result) + return OP_ONE_ARG_TEMPLATE.format( + decorator=decorator, + func=func, + test_name_extra=test_name_extra, + doc=doc, + mask=mask, + assertion=assertion, + ) + + elif typ.startswith("TWO_ARGS"): + decorator = "@given(numeric_arrays, numeric_arrays)" + if typ in [ + "TWO_ARGS_EQUAL__EQUAL", + "TWO_ARGS_GREATER__EQUAL", + "TWO_ARGS_LESS__EQUAL", + "TWO_ARGS_EQUAL__GREATER", + "TWO_ARGS_EQUAL__LESS", + "TWO_ARGS_EQUAL__NOTEQUAL", + "TWO_ARGS_NOTEQUAL__EQUAL", + "TWO_ARGS_ABSEQUAL__EQUAL", + "TWO_ARGS_ABSGREATER__EQUAL", + "TWO_ARGS_ABSLESS__EQUAL", + "TWO_ARGS_GREATER_EQUAL__EQUAL", + "TWO_ARGS_LESS_EQUAL__EQUAL", + "TWO_ARGS_EQUAL__LESS_EQUAL", + "TWO_ARGS_EQUAL__LESS_NOTEQUAL", + "TWO_ARGS_EQUAL__GREATER_EQUAL", + "TWO_ARGS_EQUAL__GREATER_NOTEQUAL", + "TWO_ARGS_LESS_EQUAL__EQUAL_NOTEQUAL", + "TWO_ARGS_EITHER__EQUAL", + "TWO_ARGS_EQUAL__EITHER", + "TWO_ARGS_EITHER__EITHER", + ]: + arg1typs, arg2typs = [i.split('_') for i in typ[len("TWO_ARGS_"):].split("__")] + if arg1typs == ["EITHER"]: + arg1typs = ["EITHER_EQUAL", "EITHER_EQUAL"] + if arg2typs == ["EITHER"]: + arg2typs = ["EITHER_EQUAL", "EITHER_EQUAL"] + *values, result = m.groups() + if len(values) != len(arg1typs) + len(arg2typs): + raise RuntimeError(f"Unexpected number of parsed values for {typ}: len({values}) != len({arg1typs}) + len({arg2typs})") + arg1values, arg2values = values[:len(arg1typs)], values[len(arg1typs):] + arg1values = [parse_value(value, 'arg1') for value in arg1values] + arg2values = [parse_value(value, 'arg2') for value in arg2values] + + tomask = lambda t: t.lower().replace("either_equal", "equal").replace("equal", "exactly_equal") + value1masks = [get_mask(tomask(t), 'arg1', v) for t, v in + zip(arg1typs, arg1values)] + value2masks = [get_mask(tomask(t), 'arg2', v) for t, v in + zip(arg2typs, arg2values)] + if len(value1masks) > 1: + if arg1typs[0] == "EITHER_EQUAL": + mask1 = f"logical_or({value1masks[0]}, {value1masks[1]})" + else: + mask1 = f"logical_and({value1masks[0]}, {value1masks[1]})" else: - mask2 = f"logical_and({value2masks[0]}, {value2masks[1]})" + mask1 = value1masks[0] + if len(value2masks) > 1: + if arg2typs[0] == "EITHER_EQUAL": + mask2 = f"logical_or({value2masks[0]}, {value2masks[1]})" + else: + mask2 = f"logical_and({value2masks[0]}, {value2masks[1]})" + else: + mask2 = value2masks[0] + + mask = f"logical_and({mask1}, {mask2})" + assertion = get_assert("exactly_equal", result) + + elif typ == "TWO_ARGS_EITHER": + value, result = m.groups() + value = parse_value(value, "arg1") + mask1 = get_mask("exactly_equal", "arg1", value) + mask2 = get_mask("exactly_equal", "arg2", value) + mask = f"logical_or({mask1}, {mask2})" + assertion = get_assert("exactly_equal", result) + elif typ == "TWO_ARGS_SAME_SIGN": + result, = m.groups() + mask = "same_sign(arg1, arg2)" + assertion = get_assert("exactly_equal", result) + elif typ == "TWO_ARGS_SAME_SIGN_EXCEPT": + result, value, value1, value2 = m.groups() + assert value == value1 == value2 + value = parse_value(value, "res") + mask = f"logical_and(same_sign(arg1, arg2), logical_not(exactly_equal(res, {value})))" + assertion = get_assert("exactly_equal", result) + elif typ == "TWO_ARGS_SAME_SIGN_BOTH": + value, result = m.groups() + mask1 = get_mask("exactly_equal", "arg1", value) + mask2 = get_mask("exactly_equal", "arg2", value) + mask = f"logical_and(same_sign(arg1, arg2), logical_and({mask1}, {mask2}))" + assertion = get_assert("exactly_equal", result) + elif typ == "TWO_ARGS_DIFFERENT_SIGNS": + result, = m.groups() + mask = "logical_not(same_sign(arg1, arg2))" + assertion = get_assert("exactly_equal", result) + elif typ == "TWO_ARGS_DIFFERENT_SIGNS_EXCEPT": + result, value, value1, value2 = m.groups() + assert value == value1 == value2 + value = parse_value(value, "res") + mask = f"logical_and(logical_not(same_sign(arg1, arg2)), logical_not(exactly_equal(res, {value})))" + assertion = get_assert("exactly_equal", result) + elif typ == "TWO_ARGS_DIFFERENT_SIGNS_BOTH": + value, result = m.groups() + mask1 = get_mask("exactly_equal", "arg1", value) + mask2 = get_mask("exactly_equal", "arg2", value) + mask = f"logical_and(logical_not(same_sign(arg1, arg2)), logical_and({mask1}, {mask2}))" + assertion = get_assert("exactly_equal", result) + elif typ == "TWO_ARGS_EVEN_IF": + value1, result, value2 = m.groups() + value1 = parse_value(value1, "arg2") + mask = get_mask("exactly_equal", "arg2", value1) + assertion = get_assert("exactly_equal", result) else: - mask2 = value2masks[0] - - mask = f"logical_and({mask1}, {mask2})" - assertion = get_assert("exactly_equal", result) + raise ValueError(f"Unrecognized special value type {typ}") + return OP_TWO_ARGS_TEMPLATE.format( + decorator=decorator, + func=func, + test_name_extra=test_name_extra, + doc=doc, + mask=mask, + assertion=assertion, + ) + + + elif typ == "REMAINING": + return REMAINING_TEMPLATE.format(text=m.group(0)) + else: + raise RuntimeError(f"Unexpected type {typ}") - elif typ == "TWO_ARGS_EITHER": - value, result = m.groups() - value = parse_value(value, "arg1") - mask1 = get_mask("exactly_equal", "arg1", value) - mask2 = get_mask("exactly_equal", "arg2", value) - mask = f"logical_or({mask1}, {mask2})" - assertion = get_assert("exactly_equal", result) - elif typ == "TWO_ARGS_SAME_SIGN": - result, = m.groups() - mask = "same_sign(arg1, arg2)" - assertion = get_assert("exactly_equal", result) - elif typ == "TWO_ARGS_SAME_SIGN_EXCEPT": - result, value, value1, value2 = m.groups() - assert value == value1 == value2 - value = parse_value(value, "res") - mask = f"logical_and(same_sign(arg1, arg2), logical_not(exactly_equal(res, {value})))" - assertion = get_assert("exactly_equal", result) - elif typ == "TWO_ARGS_SAME_SIGN_BOTH": - value, result = m.groups() - mask1 = get_mask("exactly_equal", "arg1", value) - mask2 = get_mask("exactly_equal", "arg2", value) - mask = f"logical_and(same_sign(arg1, arg2), logical_and({mask1}, {mask2}))" - assertion = get_assert("exactly_equal", result) - elif typ == "TWO_ARGS_DIFFERENT_SIGNS": - result, = m.groups() - mask = "logical_not(same_sign(arg1, arg2))" - assertion = get_assert("exactly_equal", result) - elif typ == "TWO_ARGS_DIFFERENT_SIGNS_EXCEPT": - result, value, value1, value2 = m.groups() - assert value == value1 == value2 - value = parse_value(value, "res") - mask = f"logical_and(logical_not(same_sign(arg1, arg2)), logical_not(exactly_equal(res, {value})))" - assertion = get_assert("exactly_equal", result) - elif typ == "TWO_ARGS_DIFFERENT_SIGNS_BOTH": - value, result = m.groups() - mask1 = get_mask("exactly_equal", "arg1", value) - mask2 = get_mask("exactly_equal", "arg2", value) - mask = f"logical_and(logical_not(same_sign(arg1, arg2)), logical_and({mask1}, {mask2}))" - assertion = get_assert("exactly_equal", result) - elif typ == "TWO_ARGS_EVEN_IF": - value1, result, value2 = m.groups() - value1 = parse_value(value1, "arg2") - mask = get_mask("exactly_equal", "arg2", value1) + else: + if typ.startswith("ONE_ARG"): + decorator = "@given(numeric_arrays)" + if typ == "ONE_ARG_EQUAL": + value1, result = m.groups() + value1 = parse_value(value1, 'arg1') + mask = get_mask("exactly_equal", "arg1", value1) + elif typ == "ONE_ARG_GREATER": + value1, result = m.groups() + value1 = parse_value(value1, 'arg1') + mask = get_mask("greater", "arg1", value1) + elif typ == "ONE_ARG_LESS": + value1, result = m.groups() + value1 = parse_value(value1, 'arg1') + mask = get_mask("less", "arg1", value1) + elif typ == "ONE_ARG_EITHER": + value1, value2, result = m.groups() + value1 = parse_value(value1, 'arg1') + value2 = parse_value(value2, 'arg1') + mask1 = get_mask("exactly_equal", "arg1", value1) + mask2 = get_mask("exactly_equal", "arg1", value2) + mask = f"logical_or({mask1}, {mask2})" + elif typ == "ONE_ARG_ALREADY_INTEGER_VALUED": + result, = m.groups() + mask = parse_value("integer", "arg1") + elif typ == "ONE_ARG_TWO_INTEGERS_EQUALLY_CLOSE": + result, = m.groups() + mask = "logical_and(not_equal(floor(arg1), ceil(arg1)), equal(subtract(arg1, floor(arg1)), subtract(ceil(arg1), arg1)))" + else: + raise ValueError(f"Unrecognized special value type {typ}") assertion = get_assert("exactly_equal", result) + return ONE_ARG_TEMPLATE.format( + decorator=decorator, + func=func, + test_name_extra=test_name_extra, + doc=doc, + mask=mask, + assertion=assertion, + ) + + elif typ.startswith("TWO_ARGS"): + decorator = "@given(numeric_arrays, numeric_arrays)" + if typ in [ + "TWO_ARGS_EQUAL__EQUAL", + "TWO_ARGS_GREATER__EQUAL", + "TWO_ARGS_LESS__EQUAL", + "TWO_ARGS_EQUAL__GREATER", + "TWO_ARGS_EQUAL__LESS", + "TWO_ARGS_EQUAL__NOTEQUAL", + "TWO_ARGS_NOTEQUAL__EQUAL", + "TWO_ARGS_ABSEQUAL__EQUAL", + "TWO_ARGS_ABSGREATER__EQUAL", + "TWO_ARGS_ABSLESS__EQUAL", + "TWO_ARGS_GREATER_EQUAL__EQUAL", + "TWO_ARGS_LESS_EQUAL__EQUAL", + "TWO_ARGS_EQUAL__LESS_EQUAL", + "TWO_ARGS_EQUAL__LESS_NOTEQUAL", + "TWO_ARGS_EQUAL__GREATER_EQUAL", + "TWO_ARGS_EQUAL__GREATER_NOTEQUAL", + "TWO_ARGS_LESS_EQUAL__EQUAL_NOTEQUAL", + "TWO_ARGS_EITHER__EQUAL", + "TWO_ARGS_EQUAL__EITHER", + "TWO_ARGS_EITHER__EITHER", + ]: + arg1typs, arg2typs = [i.split('_') for i in typ[len("TWO_ARGS_"):].split("__")] + if arg1typs == ["EITHER"]: + arg1typs = ["EITHER_EQUAL", "EITHER_EQUAL"] + if arg2typs == ["EITHER"]: + arg2typs = ["EITHER_EQUAL", "EITHER_EQUAL"] + *values, result = m.groups() + if len(values) != len(arg1typs) + len(arg2typs): + raise RuntimeError(f"Unexpected number of parsed values for {typ}: len({values}) != len({arg1typs}) + len({arg2typs})") + arg1values, arg2values = values[:len(arg1typs)], values[len(arg1typs):] + arg1values = [parse_value(value, 'arg1') for value in arg1values] + arg2values = [parse_value(value, 'arg2') for value in arg2values] + + tomask = lambda t: t.lower().replace("either_equal", "equal").replace("equal", "exactly_equal") + value1masks = [get_mask(tomask(t), 'arg1', v) for t, v in + zip(arg1typs, arg1values)] + value2masks = [get_mask(tomask(t), 'arg2', v) for t, v in + zip(arg2typs, arg2values)] + if len(value1masks) > 1: + if arg1typs[0] == "EITHER_EQUAL": + mask1 = f"logical_or({value1masks[0]}, {value1masks[1]})" + else: + mask1 = f"logical_and({value1masks[0]}, {value1masks[1]})" + else: + mask1 = value1masks[0] + if len(value2masks) > 1: + if arg2typs[0] == "EITHER_EQUAL": + mask2 = f"logical_or({value2masks[0]}, {value2masks[1]})" + else: + mask2 = f"logical_and({value2masks[0]}, {value2masks[1]})" + else: + mask2 = value2masks[0] + + mask = f"logical_and({mask1}, {mask2})" + assertion = get_assert("exactly_equal", result) + + elif typ == "TWO_ARGS_EITHER": + value, result = m.groups() + value = parse_value(value, "arg1") + mask1 = get_mask("exactly_equal", "arg1", value) + mask2 = get_mask("exactly_equal", "arg2", value) + mask = f"logical_or({mask1}, {mask2})" + assertion = get_assert("exactly_equal", result) + elif typ == "TWO_ARGS_SAME_SIGN": + result, = m.groups() + mask = "same_sign(arg1, arg2)" + assertion = get_assert("exactly_equal", result) + elif typ == "TWO_ARGS_SAME_SIGN_EXCEPT": + result, value, value1, value2 = m.groups() + assert value == value1 == value2 + value = parse_value(value, "res") + mask = f"logical_and(same_sign(arg1, arg2), logical_not(exactly_equal(res, {value})))" + assertion = get_assert("exactly_equal", result) + elif typ == "TWO_ARGS_SAME_SIGN_BOTH": + value, result = m.groups() + mask1 = get_mask("exactly_equal", "arg1", value) + mask2 = get_mask("exactly_equal", "arg2", value) + mask = f"logical_and(same_sign(arg1, arg2), logical_and({mask1}, {mask2}))" + assertion = get_assert("exactly_equal", result) + elif typ == "TWO_ARGS_DIFFERENT_SIGNS": + result, = m.groups() + mask = "logical_not(same_sign(arg1, arg2))" + assertion = get_assert("exactly_equal", result) + elif typ == "TWO_ARGS_DIFFERENT_SIGNS_EXCEPT": + result, value, value1, value2 = m.groups() + assert value == value1 == value2 + value = parse_value(value, "res") + mask = f"logical_and(logical_not(same_sign(arg1, arg2)), logical_not(exactly_equal(res, {value})))" + assertion = get_assert("exactly_equal", result) + elif typ == "TWO_ARGS_DIFFERENT_SIGNS_BOTH": + value, result = m.groups() + mask1 = get_mask("exactly_equal", "arg1", value) + mask2 = get_mask("exactly_equal", "arg2", value) + mask = f"logical_and(logical_not(same_sign(arg1, arg2)), logical_and({mask1}, {mask2}))" + assertion = get_assert("exactly_equal", result) + elif typ == "TWO_ARGS_EVEN_IF": + value1, result, value2 = m.groups() + value1 = parse_value(value1, "arg2") + mask = get_mask("exactly_equal", "arg2", value1) + assertion = get_assert("exactly_equal", result) + else: + raise ValueError(f"Unrecognized special value type {typ}") + return TWO_ARGS_TEMPLATE.format( + decorator=decorator, + func=func, + test_name_extra=test_name_extra, + doc=doc, + mask=mask, + assertion=assertion, + ) + + elif typ == "REMAINING": + return REMAINING_TEMPLATE.format(text=m.group(0)) else: - raise ValueError(f"Unrecognized special value type {typ}") - return TWO_ARGS_TEMPLATE.format( - decorator=decorator, - func=func, - test_name_extra=test_name_extra, - doc=doc, - mask=mask, - assertion=assertion, - ) - - elif typ == "REMAINING": - return REMAINING_TEMPLATE.format(text=m.group(0)) - else: - raise RuntimeError(f"Unexpected type {typ}") + raise RuntimeError(f"Unexpected type {typ}") -def parse_special_cases(spec_text, verbose=False): +def parse_special_cases(spec_text, verbose=False) -> Dict[str, DefaultDict[str, List[regex.Match]]]: special_cases = {} in_block = False + name = None for line in spec_text.splitlines(): - m = FUNCTION_HEADER_RE.match(line) - if m: - name = m.group(1) + func_m = FUNCTION_HEADER_RE.match(line) + method_m = METHOD_HEADER_RE.match(line) + if func_m: + name = func_m.group(1) + special_cases[name] = defaultdict(list) + continue + elif method_m: + name = method_m.group(1) special_cases[name] = defaultdict(list) continue if line == '#### Special Cases': @@ -668,7 +900,8 @@ def parse_special_cases(spec_text, verbose=False): in_block = False continue if in_block: - if '- ' not in line: + # assert name is not None, f"in block but name is None, at {i=} {line=}" + if '- ' not in line or name is None: continue for typ, reg in SPECIAL_CASE_REGEXS.items(): m = reg.match(line) From 1b177dfefac03807b1e06903451f7db62398c7cb Mon Sep 17 00:00:00 2001 From: Matthew Date: Mon, 8 Nov 2021 11:17:49 +0000 Subject: [PATCH 3/7] Rudimentary in-place op special case tests --- array_api_tests/function_stubs/__init__.py | 8 +- .../function_stubs/array_object.py | 158 +++++++- .../function_stubs/set_functions.py | 5 +- array_api_tests/special_cases/test___abs__.py | 2 +- array_api_tests/special_cases/test___add__.py | 2 +- .../special_cases/test___iadd__.py | 244 ++++++++++++ .../special_cases/test___imul__.py | 134 +++++++ .../special_cases/test___ipow__.py | 353 ++++++++++++++++++ .../special_cases/test___itruediv__.py | 316 ++++++++++++++++ array_api_tests/special_cases/test___mul__.py | 2 +- array_api_tests/special_cases/test___pow__.py | 54 +-- .../special_cases/test___truediv__.py | 2 +- generate_stubs.py | 178 +++++++-- 13 files changed, 1395 insertions(+), 63 deletions(-) create mode 100644 array_api_tests/special_cases/test___iadd__.py create mode 100644 array_api_tests/special_cases/test___imul__.py create mode 100644 array_api_tests/special_cases/test___ipow__.py create mode 100644 array_api_tests/special_cases/test___itruediv__.py diff --git a/array_api_tests/function_stubs/__init__.py b/array_api_tests/function_stubs/__init__.py index c6beb686..0b560378 100644 --- a/array_api_tests/function_stubs/__init__.py +++ b/array_api_tests/function_stubs/__init__.py @@ -9,9 +9,9 @@ __all__ = [] -from .array_object import __abs__, __add__, __and__, __array_namespace__, __bool__, __dlpack__, __dlpack_device__, __eq__, __float__, __floordiv__, __ge__, __getitem__, __gt__, __index__, __int__, __invert__, __le__, __lshift__, __lt__, __matmul__, __mod__, __mul__, __ne__, __neg__, __or__, __pos__, __pow__, __rshift__, __setitem__, __sub__, __truediv__, __xor__, to_device, dtype, device, mT, ndim, shape, size, T +from .array_object import __abs__, __add__, __and__, __array_namespace__, __bool__, __dlpack__, __dlpack_device__, __eq__, __float__, __floordiv__, __ge__, __getitem__, __gt__, __index__, __int__, __invert__, __le__, __lshift__, __lt__, __matmul__, __mod__, __mul__, __ne__, __neg__, __or__, __pos__, __pow__, __rshift__, __setitem__, __sub__, __truediv__, __xor__, to_device, __iadd__, __radd__, __iand__, __rand__, __ifloordiv__, __rfloordiv__, __ilshift__, __rlshift__, __imatmul__, __rmatmul__, __imod__, __rmod__, __imul__, __rmul__, __ior__, __ror__, __ipow__, __rpow__, __irshift__, __rrshift__, __isub__, __rsub__, __itruediv__, __rtruediv__, __ixor__, __rxor__, dtype, device, mT, ndim, shape, size, T -__all__ += ['__abs__', '__add__', '__and__', '__array_namespace__', '__bool__', '__dlpack__', '__dlpack_device__', '__eq__', '__float__', '__floordiv__', '__ge__', '__getitem__', '__gt__', '__index__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__matmul__', '__mod__', '__mul__', '__ne__', '__neg__', '__or__', '__pos__', '__pow__', '__rshift__', '__setitem__', '__sub__', '__truediv__', '__xor__', 'to_device', 'dtype', 'device', 'mT', 'ndim', 'shape', 'size', 'T'] +__all__ += ['__abs__', '__add__', '__and__', '__array_namespace__', '__bool__', '__dlpack__', '__dlpack_device__', '__eq__', '__float__', '__floordiv__', '__ge__', '__getitem__', '__gt__', '__index__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__matmul__', '__mod__', '__mul__', '__ne__', '__neg__', '__or__', '__pos__', '__pow__', '__rshift__', '__setitem__', '__sub__', '__truediv__', '__xor__', 'to_device', '__iadd__', '__radd__', '__iand__', '__rand__', '__ifloordiv__', '__rfloordiv__', '__ilshift__', '__rlshift__', '__imatmul__', '__rmatmul__', '__imod__', '__rmod__', '__imul__', '__rmul__', '__ior__', '__ror__', '__ipow__', '__rpow__', '__irshift__', '__rrshift__', '__isub__', '__rsub__', '__itruediv__', '__rtruediv__', '__ixor__', '__rxor__', 'dtype', 'device', 'mT', 'ndim', 'shape', 'size', 'T'] from .constants import e, inf, nan, pi @@ -41,9 +41,9 @@ __all__ += ['argmax', 'argmin', 'nonzero', 'where'] -from .set_functions import unique_all, unique_inverse, unique_values +from .set_functions import unique_all, unique_counts, unique_inverse, unique_values -__all__ += ['unique_all', 'unique_inverse', 'unique_values'] +__all__ += ['unique_all', 'unique_counts', 'unique_inverse', 'unique_values'] from .sorting_functions import argsort, sort diff --git a/array_api_tests/function_stubs/array_object.py b/array_api_tests/function_stubs/array_object.py index 7793d259..ec4c33fd 100644 --- a/array_api_tests/function_stubs/array_object.py +++ b/array_api_tests/function_stubs/array_object.py @@ -211,6 +211,162 @@ def to_device(self: array, device: device, /, *, stream: Optional[Union[int, Any """ pass +def __iadd__(self: array, other: Union[int, float, array], /) -> array: + """ + Note: __iadd__ is a method of the array object. + """ + pass + +def __radd__(self: array, other: Union[int, float, array], /) -> array: + """ + Note: __radd__ is a method of the array object. + """ + pass + +def __iand__(self: array, other: Union[int, bool, array], /) -> array: + """ + Note: __iand__ is a method of the array object. + """ + pass + +def __rand__(self: array, other: Union[int, bool, array], /) -> array: + """ + Note: __rand__ is a method of the array object. + """ + pass + +def __ifloordiv__(self: array, other: Union[int, float, array], /) -> array: + """ + Note: __ifloordiv__ is a method of the array object. + """ + pass + +def __rfloordiv__(self: array, other: Union[int, float, array], /) -> array: + """ + Note: __rfloordiv__ is a method of the array object. + """ + pass + +def __ilshift__(self: array, other: Union[int, array], /) -> array: + """ + Note: __ilshift__ is a method of the array object. + """ + pass + +def __rlshift__(self: array, other: Union[int, array], /) -> array: + """ + Note: __rlshift__ is a method of the array object. + """ + pass + +def __imatmul__(self: array, other: array, /) -> array: + """ + Note: __imatmul__ is a method of the array object. + """ + pass + +def __rmatmul__(self: array, other: array, /) -> array: + """ + Note: __rmatmul__ is a method of the array object. + """ + pass + +def __imod__(self: array, other: Union[int, float, array], /) -> array: + """ + Note: __imod__ is a method of the array object. + """ + pass + +def __rmod__(self: array, other: Union[int, float, array], /) -> array: + """ + Note: __rmod__ is a method of the array object. + """ + pass + +def __imul__(self: array, other: Union[int, float, array], /) -> array: + """ + Note: __imul__ is a method of the array object. + """ + pass + +def __rmul__(self: array, other: Union[int, float, array], /) -> array: + """ + Note: __rmul__ is a method of the array object. + """ + pass + +def __ior__(self: array, other: Union[int, bool, array], /) -> array: + """ + Note: __ior__ is a method of the array object. + """ + pass + +def __ror__(self: array, other: Union[int, bool, array], /) -> array: + """ + Note: __ror__ is a method of the array object. + """ + pass + +def __ipow__(self: array, other: Union[int, float, array], /) -> array: + """ + Note: __ipow__ is a method of the array object. + """ + pass + +def __rpow__(self: array, other: Union[int, float, array], /) -> array: + """ + Note: __rpow__ is a method of the array object. + """ + pass + +def __irshift__(self: array, other: Union[int, array], /) -> array: + """ + Note: __irshift__ is a method of the array object. + """ + pass + +def __rrshift__(self: array, other: Union[int, array], /) -> array: + """ + Note: __rrshift__ is a method of the array object. + """ + pass + +def __isub__(self: array, other: Union[int, float, array], /) -> array: + """ + Note: __isub__ is a method of the array object. + """ + pass + +def __rsub__(self: array, other: Union[int, float, array], /) -> array: + """ + Note: __rsub__ is a method of the array object. + """ + pass + +def __itruediv__(self: array, other: Union[int, float, array], /) -> array: + """ + Note: __itruediv__ is a method of the array object. + """ + pass + +def __rtruediv__(self: array, other: Union[int, float, array], /) -> array: + """ + Note: __rtruediv__ is a method of the array object. + """ + pass + +def __ixor__(self: array, other: Union[int, bool, array], /) -> array: + """ + Note: __ixor__ is a method of the array object. + """ + pass + +def __rxor__(self: array, other: Union[int, bool, array], /) -> array: + """ + Note: __rxor__ is a method of the array object. + """ + pass + # Note: dtype is an attribute of the array object. dtype: dtype = None @@ -232,4 +388,4 @@ def to_device(self: array, device: device, /, *, stream: Optional[Union[int, Any # Note: T is an attribute of the array object. T: array = None -__all__ = ['__abs__', '__add__', '__and__', '__array_namespace__', '__bool__', '__dlpack__', '__dlpack_device__', '__eq__', '__float__', '__floordiv__', '__ge__', '__getitem__', '__gt__', '__index__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__matmul__', '__mod__', '__mul__', '__ne__', '__neg__', '__or__', '__pos__', '__pow__', '__rshift__', '__setitem__', '__sub__', '__truediv__', '__xor__', 'to_device', 'dtype', 'device', 'mT', 'ndim', 'shape', 'size', 'T'] +__all__ = ['__abs__', '__add__', '__and__', '__array_namespace__', '__bool__', '__dlpack__', '__dlpack_device__', '__eq__', '__float__', '__floordiv__', '__ge__', '__getitem__', '__gt__', '__index__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__matmul__', '__mod__', '__mul__', '__ne__', '__neg__', '__or__', '__pos__', '__pow__', '__rshift__', '__setitem__', '__sub__', '__truediv__', '__xor__', 'to_device', '__iadd__', '__radd__', '__iand__', '__rand__', '__ifloordiv__', '__rfloordiv__', '__ilshift__', '__rlshift__', '__imatmul__', '__rmatmul__', '__imod__', '__rmod__', '__imul__', '__rmul__', '__ior__', '__ror__', '__ipow__', '__rpow__', '__irshift__', '__rrshift__', '__isub__', '__rsub__', '__itruediv__', '__rtruediv__', '__ixor__', '__rxor__', 'dtype', 'device', 'mT', 'ndim', 'shape', 'size', 'T'] diff --git a/array_api_tests/function_stubs/set_functions.py b/array_api_tests/function_stubs/set_functions.py index abecc517..efc1ff52 100644 --- a/array_api_tests/function_stubs/set_functions.py +++ b/array_api_tests/function_stubs/set_functions.py @@ -15,10 +15,13 @@ def unique_all(x: array, /) -> Tuple[array, array, array, array]: pass +def unique_counts(x: array, /) -> Tuple[array, array]: + pass + def unique_inverse(x: array, /) -> Tuple[array, array]: pass def unique_values(x: array, /) -> array: pass -__all__ = ['unique_all', 'unique_inverse', 'unique_values'] +__all__ = ['unique_all', 'unique_counts', 'unique_inverse', 'unique_values'] diff --git a/array_api_tests/special_cases/test___abs__.py b/array_api_tests/special_cases/test___abs__.py index 868440f8..ea0a22d9 100644 --- a/array_api_tests/special_cases/test___abs__.py +++ b/array_api_tests/special_cases/test___abs__.py @@ -1,5 +1,5 @@ """ -Special cases tests for x.__abs__. +Special cases tests for __abs__. These tests are generated from the special cases listed in the spec. diff --git a/array_api_tests/special_cases/test___add__.py b/array_api_tests/special_cases/test___add__.py index ae1f6b8b..78d1eab0 100644 --- a/array_api_tests/special_cases/test___add__.py +++ b/array_api_tests/special_cases/test___add__.py @@ -1,5 +1,5 @@ """ -Special cases tests for x.__add__. +Special cases tests for __add__. These tests are generated from the special cases listed in the spec. diff --git a/array_api_tests/special_cases/test___iadd__.py b/array_api_tests/special_cases/test___iadd__.py new file mode 100644 index 00000000..6be0fd59 --- /dev/null +++ b/array_api_tests/special_cases/test___iadd__.py @@ -0,0 +1,244 @@ +""" +Special cases tests for __iadd__. + +These tests are generated from the special cases listed in the spec. + +NOTE: This file is generated automatically by the generate_stubs.py script. Do +not modify it directly. +""" + +from operator import iadd + +from ..array_helpers import (NaN, assert_exactly_equal, exactly_equal, infinity, isfinite, + logical_and, logical_or, non_zero, zero) +from ..hypothesis_helpers import numeric_arrays +from .. import _array_module as xp + +from hypothesis import given + + +@given(numeric_arrays, numeric_arrays) +def test___iadd___special_cases_two_args_either(arg1, arg2): + """ + Special case test for `__iadd__(self, other, /)`: + + - If either `x1_i` or `x2_i` is `NaN`, the result is `NaN`. + + """ + res = xp.asarray(arg1, copy=True) + iadd(res, arg2) + mask = logical_or(exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)), exactly_equal(arg2, NaN(arg1.shape, arg1.dtype))) + assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___iadd___special_cases_two_args_equal__equal_1(arg1, arg2): + """ + Special case test for `__iadd__(self, other, /)`: + + - If `x1_i` is `+infinity` and `x2_i` is `-infinity`, the result is `NaN`. + + """ + res = xp.asarray(arg1, copy=True) + iadd(res, arg2) + mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___iadd___special_cases_two_args_equal__equal_2(arg1, arg2): + """ + Special case test for `__iadd__(self, other, /)`: + + - If `x1_i` is `-infinity` and `x2_i` is `+infinity`, the result is `NaN`. + + """ + res = xp.asarray(arg1, copy=True) + iadd(res, arg2) + mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___iadd___special_cases_two_args_equal__equal_3(arg1, arg2): + """ + Special case test for `__iadd__(self, other, /)`: + + - If `x1_i` is `+infinity` and `x2_i` is `+infinity`, the result is `+infinity`. + + """ + res = xp.asarray(arg1, copy=True) + iadd(res, arg2) + mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___iadd___special_cases_two_args_equal__equal_4(arg1, arg2): + """ + Special case test for `__iadd__(self, other, /)`: + + - If `x1_i` is `-infinity` and `x2_i` is `-infinity`, the result is `-infinity`. + + """ + res = xp.asarray(arg1, copy=True) + iadd(res, arg2) + mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___iadd___special_cases_two_args_equal__equal_5(arg1, arg2): + """ + Special case test for `__iadd__(self, other, /)`: + + - If `x1_i` is `+infinity` and `x2_i` is a finite number, the result is `+infinity`. + + """ + res = xp.asarray(arg1, copy=True) + iadd(res, arg2) + mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), isfinite(arg2)) + assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___iadd___special_cases_two_args_equal__equal_6(arg1, arg2): + """ + Special case test for `__iadd__(self, other, /)`: + + - If `x1_i` is `-infinity` and `x2_i` is a finite number, the result is `-infinity`. + + """ + res = xp.asarray(arg1, copy=True) + iadd(res, arg2) + mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), isfinite(arg2)) + assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___iadd___special_cases_two_args_equal__equal_7(arg1, arg2): + """ + Special case test for `__iadd__(self, other, /)`: + + - If `x1_i` is a finite number and `x2_i` is `+infinity`, the result is `+infinity`. + + """ + res = xp.asarray(arg1, copy=True) + iadd(res, arg2) + mask = logical_and(isfinite(arg1), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___iadd___special_cases_two_args_equal__equal_8(arg1, arg2): + """ + Special case test for `__iadd__(self, other, /)`: + + - If `x1_i` is a finite number and `x2_i` is `-infinity`, the result is `-infinity`. + + """ + res = xp.asarray(arg1, copy=True) + iadd(res, arg2) + mask = logical_and(isfinite(arg1), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___iadd___special_cases_two_args_equal__equal_9(arg1, arg2): + """ + Special case test for `__iadd__(self, other, /)`: + + - If `x1_i` is `-0` and `x2_i` is `-0`, the result is `-0`. + + """ + res = xp.asarray(arg1, copy=True) + iadd(res, arg2) + mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___iadd___special_cases_two_args_equal__equal_10(arg1, arg2): + """ + Special case test for `__iadd__(self, other, /)`: + + - If `x1_i` is `-0` and `x2_i` is `+0`, the result is `+0`. + + """ + res = xp.asarray(arg1, copy=True) + iadd(res, arg2) + mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___iadd___special_cases_two_args_equal__equal_11(arg1, arg2): + """ + Special case test for `__iadd__(self, other, /)`: + + - If `x1_i` is `+0` and `x2_i` is `-0`, the result is `+0`. + + """ + res = xp.asarray(arg1, copy=True) + iadd(res, arg2) + mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___iadd___special_cases_two_args_equal__equal_12(arg1, arg2): + """ + Special case test for `__iadd__(self, other, /)`: + + - If `x1_i` is `+0` and `x2_i` is `+0`, the result is `+0`. + + """ + res = xp.asarray(arg1, copy=True) + iadd(res, arg2) + mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___iadd___special_cases_two_args_equal__equal_13(arg1, arg2): + """ + Special case test for `__iadd__(self, other, /)`: + + - If `x1_i` is a nonzero finite number and `x2_i` is `-x1_i`, the result is `+0`. + + """ + res = xp.asarray(arg1, copy=True) + iadd(res, arg2) + mask = logical_and(logical_and(isfinite(arg1), non_zero(arg1)), exactly_equal(arg2, -arg1)) + assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___iadd___special_cases_two_args_either__equal(arg1, arg2): + """ + Special case test for `__iadd__(self, other, /)`: + + - If `x1_i` is either `+0` or `-0` and `x2_i` is a nonzero finite number, the result is `x2_i`. + + """ + res = xp.asarray(arg1, copy=True) + iadd(res, arg2) + mask = logical_and(logical_or(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg1, -zero(arg1.shape, arg1.dtype))), logical_and(isfinite(arg2), non_zero(arg2))) + assert_exactly_equal(res[mask], (arg2)[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___iadd___special_cases_two_args_equal__either(arg1, arg2): + """ + Special case test for `__iadd__(self, other, /)`: + + - If `x1_i` is a nonzero finite number and `x2_i` is either `+0` or `-0`, the result is `x1_i`. + + """ + res = xp.asarray(arg1, copy=True) + iadd(res, arg2) + mask = logical_and(logical_and(isfinite(arg1), non_zero(arg1)), logical_or(exactly_equal(arg2, zero(arg2.shape, arg2.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype)))) + assert_exactly_equal(res[mask], (arg1)[mask]) + +# TODO: Implement REMAINING test for: +# - In the remaining cases, when neither `infinity`, `+0`, `-0`, nor a `NaN` is involved, and the operands have the same mathematical sign or have different magnitudes, the sum must be computed and rounded to the nearest representable value according to IEEE 754-2019 and a supported round mode. If the magnitude is too large to represent, the operation overflows and the result is an `infinity` of appropriate mathematical sign. diff --git a/array_api_tests/special_cases/test___imul__.py b/array_api_tests/special_cases/test___imul__.py new file mode 100644 index 00000000..9bfa9940 --- /dev/null +++ b/array_api_tests/special_cases/test___imul__.py @@ -0,0 +1,134 @@ +""" +Special cases tests for __imul__. + +These tests are generated from the special cases listed in the spec. + +NOTE: This file is generated automatically by the generate_stubs.py script. Do +not modify it directly. +""" + +from operator import imul + +from ..array_helpers import (NaN, assert_exactly_equal, assert_isinf, + assert_negative_mathematical_sign, assert_positive_mathematical_sign, + exactly_equal, infinity, isfinite, logical_and, logical_not, + logical_or, non_zero, same_sign, zero) +from ..hypothesis_helpers import numeric_arrays +from .. import _array_module as xp + +from hypothesis import given + + +@given(numeric_arrays, numeric_arrays) +def test___imul___special_cases_two_args_either(arg1, arg2): + """ + Special case test for `__imul__(self, other, /)`: + + - If either `x1_i` or `x2_i` is `NaN`, the result is `NaN`. + + """ + res = xp.asarray(arg1, copy=True) + imul(res, arg2) + mask = logical_or(exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)), exactly_equal(arg2, NaN(arg1.shape, arg1.dtype))) + assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___imul___special_cases_two_args_either__either_1(arg1, arg2): + """ + Special case test for `__imul__(self, other, /)`: + + - If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is either `+0` or `-0`, the result is `NaN`. + + """ + res = xp.asarray(arg1, copy=True) + imul(res, arg2) + mask = logical_and(logical_or(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype))), logical_or(exactly_equal(arg2, zero(arg2.shape, arg2.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype)))) + assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___imul___special_cases_two_args_either__either_2(arg1, arg2): + """ + Special case test for `__imul__(self, other, /)`: + + - If `x1_i` is either `+0` or `-0` and `x2_i` is either `+infinity` or `-infinity`, the result is `NaN`. + + """ + res = xp.asarray(arg1, copy=True) + imul(res, arg2) + mask = logical_and(logical_or(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg1, -zero(arg1.shape, arg1.dtype))), logical_or(exactly_equal(arg2, infinity(arg2.shape, arg2.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype)))) + assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___imul___special_cases_two_args_either__either_3(arg1, arg2): + """ + Special case test for `__imul__(self, other, /)`: + + - If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is either `+infinity` or `-infinity`, the result is a signed infinity with the mathematical sign determined by the rule already stated above. + + """ + res = xp.asarray(arg1, copy=True) + imul(res, arg2) + mask = logical_and(logical_or(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype))), logical_or(exactly_equal(arg2, infinity(arg2.shape, arg2.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype)))) + assert_isinf(res[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___imul___special_cases_two_args_same_sign_except(arg1, arg2): + """ + Special case test for `__imul__(self, other, /)`: + + - If `x1_i` and `x2_i` have the same mathematical sign, the result has a positive mathematical sign, unless the result is `NaN`. If the result is `NaN`, the "sign" of `NaN` is implementation-defined. + + """ + res = xp.asarray(arg1, copy=True) + imul(res, arg2) + mask = logical_and(same_sign(arg1, arg2), logical_not(exactly_equal(res, NaN(res.shape, res.dtype)))) + assert_positive_mathematical_sign(res[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___imul___special_cases_two_args_different_signs_except(arg1, arg2): + """ + Special case test for `__imul__(self, other, /)`: + + - If `x1_i` and `x2_i` have different mathematical signs, the result has a negative mathematical sign, unless the result is `NaN`. If the result is `NaN`, the "sign" of `NaN` is implementation-defined. + + """ + res = xp.asarray(arg1, copy=True) + imul(res, arg2) + mask = logical_and(logical_not(same_sign(arg1, arg2)), logical_not(exactly_equal(res, NaN(res.shape, res.dtype)))) + assert_negative_mathematical_sign(res[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___imul___special_cases_two_args_either__equal(arg1, arg2): + """ + Special case test for `__imul__(self, other, /)`: + + - If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is a nonzero finite number, the result is a signed infinity with the mathematical sign determined by the rule already stated above. + + """ + res = xp.asarray(arg1, copy=True) + imul(res, arg2) + mask = logical_and(logical_or(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype))), logical_and(isfinite(arg2), non_zero(arg2))) + assert_isinf(res[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___imul___special_cases_two_args_equal__either(arg1, arg2): + """ + Special case test for `__imul__(self, other, /)`: + + - If `x1_i` is a nonzero finite number and `x2_i` is either `+infinity` or `-infinity`, the result is a signed infinity with the mathematical sign determined by the rule already stated above. + + """ + res = xp.asarray(arg1, copy=True) + imul(res, arg2) + mask = logical_and(logical_and(isfinite(arg1), non_zero(arg1)), logical_or(exactly_equal(arg2, infinity(arg2.shape, arg2.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype)))) + assert_isinf(res[mask]) + +# TODO: Implement REMAINING test for: +# - In the remaining cases, where neither `infinity` nor `NaN` is involved, the product must be computed and rounded to the nearest representable value according to IEEE 754-2019 and a supported rounding mode. If the magnitude is too large to represent, the result is an `infinity` of appropriate mathematical sign. If the magnitude is too small to represent, the result is a zero of appropriate mathematical sign. diff --git a/array_api_tests/special_cases/test___ipow__.py b/array_api_tests/special_cases/test___ipow__.py new file mode 100644 index 00000000..83cb2f27 --- /dev/null +++ b/array_api_tests/special_cases/test___ipow__.py @@ -0,0 +1,353 @@ +""" +Special cases tests for __ipow__. + +These tests are generated from the special cases listed in the spec. + +NOTE: This file is generated automatically by the generate_stubs.py script. Do +not modify it directly. +""" + +from operator import ipow + +from ..array_helpers import (NaN, assert_exactly_equal, exactly_equal, greater, infinity, isfinite, + isintegral, isodd, less, logical_and, logical_not, notequal, one, zero) +from ..hypothesis_helpers import numeric_arrays +from .. import _array_module as xp + +from hypothesis import given + + +@given(numeric_arrays, numeric_arrays) +def test___ipow___special_cases_two_args_notequal__equal(arg1, arg2): + """ + Special case test for `__ipow__(self, other, /)`: + + - If `x1_i` is not equal to `1` and `x2_i` is `NaN`, the result is `NaN`. + + """ + res = xp.asarray(arg1, copy=True) + ipow(res, arg2) + mask = logical_and(logical_not(exactly_equal(arg1, one(arg1.shape, arg1.dtype))), exactly_equal(arg2, NaN(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___ipow___special_cases_two_args_even_if_1(arg1, arg2): + """ + Special case test for `__ipow__(self, other, /)`: + + - If `x2_i` is `+0`, the result is `1`, even if `x1_i` is `NaN`. + + """ + res = xp.asarray(arg1, copy=True) + ipow(res, arg2) + mask = exactly_equal(arg2, zero(arg2.shape, arg2.dtype)) + assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___ipow___special_cases_two_args_even_if_2(arg1, arg2): + """ + Special case test for `__ipow__(self, other, /)`: + + - If `x2_i` is `-0`, the result is `1`, even if `x1_i` is `NaN`. + + """ + res = xp.asarray(arg1, copy=True) + ipow(res, arg2) + mask = exactly_equal(arg2, -zero(arg2.shape, arg2.dtype)) + assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___ipow___special_cases_two_args_equal__notequal_1(arg1, arg2): + """ + Special case test for `__ipow__(self, other, /)`: + + - If `x1_i` is `NaN` and `x2_i` is not equal to `0`, the result is `NaN`. + + """ + res = xp.asarray(arg1, copy=True) + ipow(res, arg2) + mask = logical_and(exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)), notequal(arg2, zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___ipow___special_cases_two_args_equal__notequal_2(arg1, arg2): + """ + Special case test for `__ipow__(self, other, /)`: + + - If `x1_i` is `1` and `x2_i` is not `NaN`, the result is `1`. + + """ + res = xp.asarray(arg1, copy=True) + ipow(res, arg2) + mask = logical_and(exactly_equal(arg1, one(arg1.shape, arg1.dtype)), logical_not(exactly_equal(arg2, NaN(arg2.shape, arg2.dtype)))) + assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___ipow___special_cases_two_args_absgreater__equal_1(arg1, arg2): + """ + Special case test for `__ipow__(self, other, /)`: + + - If `abs(x1_i)` is greater than `1` and `x2_i` is `+infinity`, the result is `+infinity`. + + """ + res = xp.asarray(arg1, copy=True) + ipow(res, arg2) + mask = logical_and(greater(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___ipow___special_cases_two_args_absgreater__equal_2(arg1, arg2): + """ + Special case test for `__ipow__(self, other, /)`: + + - If `abs(x1_i)` is greater than `1` and `x2_i` is `-infinity`, the result is `+0`. + + """ + res = xp.asarray(arg1, copy=True) + ipow(res, arg2) + mask = logical_and(greater(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___ipow___special_cases_two_args_absequal__equal_1(arg1, arg2): + """ + Special case test for `__ipow__(self, other, /)`: + + - If `abs(x1_i)` is `1` and `x2_i` is `+infinity`, the result is `1`. + + """ + res = xp.asarray(arg1, copy=True) + ipow(res, arg2) + mask = logical_and(exactly_equal(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___ipow___special_cases_two_args_absequal__equal_2(arg1, arg2): + """ + Special case test for `__ipow__(self, other, /)`: + + - If `abs(x1_i)` is `1` and `x2_i` is `-infinity`, the result is `1`. + + """ + res = xp.asarray(arg1, copy=True) + ipow(res, arg2) + mask = logical_and(exactly_equal(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___ipow___special_cases_two_args_absless__equal_1(arg1, arg2): + """ + Special case test for `__ipow__(self, other, /)`: + + - If `abs(x1_i)` is less than `1` and `x2_i` is `+infinity`, the result is `+0`. + + """ + res = xp.asarray(arg1, copy=True) + ipow(res, arg2) + mask = logical_and(less(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___ipow___special_cases_two_args_absless__equal_2(arg1, arg2): + """ + Special case test for `__ipow__(self, other, /)`: + + - If `abs(x1_i)` is less than `1` and `x2_i` is `-infinity`, the result is `+infinity`. + + """ + res = xp.asarray(arg1, copy=True) + ipow(res, arg2) + mask = logical_and(less(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___ipow___special_cases_two_args_equal__greater_1(arg1, arg2): + """ + Special case test for `__ipow__(self, other, /)`: + + - If `x1_i` is `+infinity` and `x2_i` is greater than `0`, the result is `+infinity`. + + """ + res = xp.asarray(arg1, copy=True) + ipow(res, arg2) + mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), greater(arg2, zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___ipow___special_cases_two_args_equal__greater_2(arg1, arg2): + """ + Special case test for `__ipow__(self, other, /)`: + + - If `x1_i` is `+0` and `x2_i` is greater than `0`, the result is `+0`. + + """ + res = xp.asarray(arg1, copy=True) + ipow(res, arg2) + mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), greater(arg2, zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___ipow___special_cases_two_args_equal__less_1(arg1, arg2): + """ + Special case test for `__ipow__(self, other, /)`: + + - If `x1_i` is `+infinity` and `x2_i` is less than `0`, the result is `+0`. + + """ + res = xp.asarray(arg1, copy=True) + ipow(res, arg2) + mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), less(arg2, zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___ipow___special_cases_two_args_equal__less_2(arg1, arg2): + """ + Special case test for `__ipow__(self, other, /)`: + + - If `x1_i` is `+0` and `x2_i` is less than `0`, the result is `+infinity`. + + """ + res = xp.asarray(arg1, copy=True) + ipow(res, arg2) + mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), less(arg2, zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___ipow___special_cases_two_args_equal__greater_equal_1(arg1, arg2): + """ + Special case test for `__ipow__(self, other, /)`: + + - If `x1_i` is `-infinity`, `x2_i` is greater than `0`, and `x2_i` is an odd integer value, the result is `-infinity`. + + """ + res = xp.asarray(arg1, copy=True) + ipow(res, arg2) + mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(greater(arg2, zero(arg2.shape, arg2.dtype)), isodd(arg2))) + assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___ipow___special_cases_two_args_equal__greater_equal_2(arg1, arg2): + """ + Special case test for `__ipow__(self, other, /)`: + + - If `x1_i` is `-0`, `x2_i` is greater than `0`, and `x2_i` is an odd integer value, the result is `-0`. + + """ + res = xp.asarray(arg1, copy=True) + ipow(res, arg2) + mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), logical_and(greater(arg2, zero(arg2.shape, arg2.dtype)), isodd(arg2))) + assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___ipow___special_cases_two_args_equal__greater_notequal_1(arg1, arg2): + """ + Special case test for `__ipow__(self, other, /)`: + + - If `x1_i` is `-infinity`, `x2_i` is greater than `0`, and `x2_i` is not an odd integer value, the result is `+infinity`. + + """ + res = xp.asarray(arg1, copy=True) + ipow(res, arg2) + mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(greater(arg2, zero(arg2.shape, arg2.dtype)), logical_not(isodd(arg2)))) + assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___ipow___special_cases_two_args_equal__greater_notequal_2(arg1, arg2): + """ + Special case test for `__ipow__(self, other, /)`: + + - If `x1_i` is `-0`, `x2_i` is greater than `0`, and `x2_i` is not an odd integer value, the result is `+0`. + + """ + res = xp.asarray(arg1, copy=True) + ipow(res, arg2) + mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), logical_and(greater(arg2, zero(arg2.shape, arg2.dtype)), logical_not(isodd(arg2)))) + assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___ipow___special_cases_two_args_equal__less_equal_1(arg1, arg2): + """ + Special case test for `__ipow__(self, other, /)`: + + - If `x1_i` is `-infinity`, `x2_i` is less than `0`, and `x2_i` is an odd integer value, the result is `-0`. + + """ + res = xp.asarray(arg1, copy=True) + ipow(res, arg2) + mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(less(arg2, zero(arg2.shape, arg2.dtype)), isodd(arg2))) + assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___ipow___special_cases_two_args_equal__less_equal_2(arg1, arg2): + """ + Special case test for `__ipow__(self, other, /)`: + + - If `x1_i` is `-0`, `x2_i` is less than `0`, and `x2_i` is an odd integer value, the result is `-infinity`. + + """ + res = xp.asarray(arg1, copy=True) + ipow(res, arg2) + mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), logical_and(less(arg2, zero(arg2.shape, arg2.dtype)), isodd(arg2))) + assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___ipow___special_cases_two_args_equal__less_notequal_1(arg1, arg2): + """ + Special case test for `__ipow__(self, other, /)`: + + - If `x1_i` is `-infinity`, `x2_i` is less than `0`, and `x2_i` is not an odd integer value, the result is `+0`. + + """ + res = xp.asarray(arg1, copy=True) + ipow(res, arg2) + mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(less(arg2, zero(arg2.shape, arg2.dtype)), logical_not(isodd(arg2)))) + assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___ipow___special_cases_two_args_equal__less_notequal_2(arg1, arg2): + """ + Special case test for `__ipow__(self, other, /)`: + + - If `x1_i` is `-0`, `x2_i` is less than `0`, and `x2_i` is not an odd integer value, the result is `+infinity`. + + """ + res = xp.asarray(arg1, copy=True) + ipow(res, arg2) + mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), logical_and(less(arg2, zero(arg2.shape, arg2.dtype)), logical_not(isodd(arg2)))) + assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___ipow___special_cases_two_args_less_equal__equal_notequal(arg1, arg2): + """ + Special case test for `__ipow__(self, other, /)`: + + - If `x1_i` is less than `0`, `x1_i` is a finite number, `x2_i` is a finite number, and `x2_i` is not an integer value, the result is `NaN`. + + """ + res = xp.asarray(arg1, copy=True) + ipow(res, arg2) + mask = logical_and(logical_and(less(arg1, zero(arg1.shape, arg1.dtype)), isfinite(arg1)), logical_and(isfinite(arg2), logical_not(isintegral(arg2)))) + assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test___itruediv__.py b/array_api_tests/special_cases/test___itruediv__.py new file mode 100644 index 00000000..cef5fa4e --- /dev/null +++ b/array_api_tests/special_cases/test___itruediv__.py @@ -0,0 +1,316 @@ +""" +Special cases tests for __itruediv__. + +These tests are generated from the special cases listed in the spec. + +NOTE: This file is generated automatically by the generate_stubs.py script. Do +not modify it directly. +""" + +from operator import itruediv + +from ..array_helpers import (NaN, assert_exactly_equal, assert_negative_mathematical_sign, + assert_positive_mathematical_sign, exactly_equal, greater, infinity, + isfinite, isnegative, ispositive, less, logical_and, logical_not, + logical_or, non_zero, same_sign, zero) +from ..hypothesis_helpers import numeric_arrays +from .. import _array_module as xp + +from hypothesis import given + + +@given(numeric_arrays, numeric_arrays) +def test___itruediv___special_cases_two_args_either(arg1, arg2): + """ + Special case test for `__itruediv__(self, other, /)`: + + - If either `x1_i` or `x2_i` is `NaN`, the result is `NaN`. + + """ + res = xp.asarray(arg1, copy=True) + itruediv(res, arg2) + mask = logical_or(exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)), exactly_equal(arg2, NaN(arg1.shape, arg1.dtype))) + assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___itruediv___special_cases_two_args_either__either_1(arg1, arg2): + """ + Special case test for `__itruediv__(self, other, /)`: + + - If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is either `+infinity` or `-infinity`, the result is `NaN`. + + """ + res = xp.asarray(arg1, copy=True) + itruediv(res, arg2) + mask = logical_and(logical_or(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype))), logical_or(exactly_equal(arg2, infinity(arg2.shape, arg2.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype)))) + assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___itruediv___special_cases_two_args_either__either_2(arg1, arg2): + """ + Special case test for `__itruediv__(self, other, /)`: + + - If `x1_i` is either `+0` or `-0` and `x2_i` is either `+0` or `-0`, the result is `NaN`. + + """ + res = xp.asarray(arg1, copy=True) + itruediv(res, arg2) + mask = logical_and(logical_or(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg1, -zero(arg1.shape, arg1.dtype))), logical_or(exactly_equal(arg2, zero(arg2.shape, arg2.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype)))) + assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___itruediv___special_cases_two_args_equal__greater_1(arg1, arg2): + """ + Special case test for `__itruediv__(self, other, /)`: + + - If `x1_i` is `+0` and `x2_i` is greater than `0`, the result is `+0`. + + """ + res = xp.asarray(arg1, copy=True) + itruediv(res, arg2) + mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), greater(arg2, zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___itruediv___special_cases_two_args_equal__greater_2(arg1, arg2): + """ + Special case test for `__itruediv__(self, other, /)`: + + - If `x1_i` is `-0` and `x2_i` is greater than `0`, the result is `-0`. + + """ + res = xp.asarray(arg1, copy=True) + itruediv(res, arg2) + mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), greater(arg2, zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___itruediv___special_cases_two_args_equal__less_1(arg1, arg2): + """ + Special case test for `__itruediv__(self, other, /)`: + + - If `x1_i` is `+0` and `x2_i` is less than `0`, the result is `-0`. + + """ + res = xp.asarray(arg1, copy=True) + itruediv(res, arg2) + mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), less(arg2, zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___itruediv___special_cases_two_args_equal__less_2(arg1, arg2): + """ + Special case test for `__itruediv__(self, other, /)`: + + - If `x1_i` is `-0` and `x2_i` is less than `0`, the result is `+0`. + + """ + res = xp.asarray(arg1, copy=True) + itruediv(res, arg2) + mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), less(arg2, zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___itruediv___special_cases_two_args_greater__equal_1(arg1, arg2): + """ + Special case test for `__itruediv__(self, other, /)`: + + - If `x1_i` is greater than `0` and `x2_i` is `+0`, the result is `+infinity`. + + """ + res = xp.asarray(arg1, copy=True) + itruediv(res, arg2) + mask = logical_and(greater(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___itruediv___special_cases_two_args_greater__equal_2(arg1, arg2): + """ + Special case test for `__itruediv__(self, other, /)`: + + - If `x1_i` is greater than `0` and `x2_i` is `-0`, the result is `-infinity`. + + """ + res = xp.asarray(arg1, copy=True) + itruediv(res, arg2) + mask = logical_and(greater(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___itruediv___special_cases_two_args_less__equal_1(arg1, arg2): + """ + Special case test for `__itruediv__(self, other, /)`: + + - If `x1_i` is less than `0` and `x2_i` is `+0`, the result is `-infinity`. + + """ + res = xp.asarray(arg1, copy=True) + itruediv(res, arg2) + mask = logical_and(less(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___itruediv___special_cases_two_args_less__equal_2(arg1, arg2): + """ + Special case test for `__itruediv__(self, other, /)`: + + - If `x1_i` is less than `0` and `x2_i` is `-0`, the result is `+infinity`. + + """ + res = xp.asarray(arg1, copy=True) + itruediv(res, arg2) + mask = logical_and(less(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___itruediv___special_cases_two_args_equal__equal_1(arg1, arg2): + """ + Special case test for `__itruediv__(self, other, /)`: + + - If `x1_i` is `+infinity` and `x2_i` is a positive (i.e., greater than `0`) finite number, the result is `+infinity`. + + """ + res = xp.asarray(arg1, copy=True) + itruediv(res, arg2) + mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), logical_and(isfinite(arg2), ispositive(arg2))) + assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___itruediv___special_cases_two_args_equal__equal_2(arg1, arg2): + """ + Special case test for `__itruediv__(self, other, /)`: + + - If `x1_i` is `+infinity` and `x2_i` is a negative (i.e., less than `0`) finite number, the result is `-infinity`. + + """ + res = xp.asarray(arg1, copy=True) + itruediv(res, arg2) + mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), logical_and(isfinite(arg2), isnegative(arg2))) + assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___itruediv___special_cases_two_args_equal__equal_3(arg1, arg2): + """ + Special case test for `__itruediv__(self, other, /)`: + + - If `x1_i` is `-infinity` and `x2_i` is a positive (i.e., greater than `0`) finite number, the result is `-infinity`. + + """ + res = xp.asarray(arg1, copy=True) + itruediv(res, arg2) + mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(isfinite(arg2), ispositive(arg2))) + assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___itruediv___special_cases_two_args_equal__equal_4(arg1, arg2): + """ + Special case test for `__itruediv__(self, other, /)`: + + - If `x1_i` is `-infinity` and `x2_i` is a negative (i.e., less than `0`) finite number, the result is `+infinity`. + + """ + res = xp.asarray(arg1, copy=True) + itruediv(res, arg2) + mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(isfinite(arg2), isnegative(arg2))) + assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___itruediv___special_cases_two_args_equal__equal_5(arg1, arg2): + """ + Special case test for `__itruediv__(self, other, /)`: + + - If `x1_i` is a positive (i.e., greater than `0`) finite number and `x2_i` is `+infinity`, the result is `+0`. + + """ + res = xp.asarray(arg1, copy=True) + itruediv(res, arg2) + mask = logical_and(logical_and(isfinite(arg1), ispositive(arg1)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___itruediv___special_cases_two_args_equal__equal_6(arg1, arg2): + """ + Special case test for `__itruediv__(self, other, /)`: + + - If `x1_i` is a positive (i.e., greater than `0`) finite number and `x2_i` is `-infinity`, the result is `-0`. + + """ + res = xp.asarray(arg1, copy=True) + itruediv(res, arg2) + mask = logical_and(logical_and(isfinite(arg1), ispositive(arg1)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___itruediv___special_cases_two_args_equal__equal_7(arg1, arg2): + """ + Special case test for `__itruediv__(self, other, /)`: + + - If `x1_i` is a negative (i.e., less than `0`) finite number and `x2_i` is `+infinity`, the result is `-0`. + + """ + res = xp.asarray(arg1, copy=True) + itruediv(res, arg2) + mask = logical_and(logical_and(isfinite(arg1), isnegative(arg1)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___itruediv___special_cases_two_args_equal__equal_8(arg1, arg2): + """ + Special case test for `__itruediv__(self, other, /)`: + + - If `x1_i` is a negative (i.e., less than `0`) finite number and `x2_i` is `-infinity`, the result is `+0`. + + """ + res = xp.asarray(arg1, copy=True) + itruediv(res, arg2) + mask = logical_and(logical_and(isfinite(arg1), isnegative(arg1)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) + assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___itruediv___special_cases_two_args_same_sign_both(arg1, arg2): + """ + Special case test for `__itruediv__(self, other, /)`: + + - If `x1_i` and `x2_i` have the same mathematical sign and are both nonzero finite numbers, the result has a positive mathematical sign. + + """ + res = xp.asarray(arg1, copy=True) + itruediv(res, arg2) + mask = logical_and(same_sign(arg1, arg2), logical_and(logical_and(isfinite(arg1), non_zero(arg1)), logical_and(isfinite(arg2), non_zero(arg2)))) + assert_positive_mathematical_sign(res[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___itruediv___special_cases_two_args_different_signs_both(arg1, arg2): + """ + Special case test for `__itruediv__(self, other, /)`: + + - If `x1_i` and `x2_i` have different mathematical signs and are both nonzero finite numbers, the result has a negative mathematical sign. + + """ + res = xp.asarray(arg1, copy=True) + itruediv(res, arg2) + mask = logical_and(logical_not(same_sign(arg1, arg2)), logical_and(logical_and(isfinite(arg1), non_zero(arg1)), logical_and(isfinite(arg2), non_zero(arg2)))) + assert_negative_mathematical_sign(res[mask]) + +# TODO: Implement REMAINING test for: +# - In the remaining cases, where neither `-infinity`, `+0`, `-0`, nor `NaN` is involved, the quotient must be computed and rounded to the nearest representable value according to IEEE 754-2019 and a supported rounding mode. If the magnitude is too larger to represent, the operation overflows and the result is an `infinity` of appropriate mathematical sign. If the magnitude is too small to represent, the operation underflows and the result is a zero of appropriate mathematical sign. diff --git a/array_api_tests/special_cases/test___mul__.py b/array_api_tests/special_cases/test___mul__.py index 694d93f1..110bf9a4 100644 --- a/array_api_tests/special_cases/test___mul__.py +++ b/array_api_tests/special_cases/test___mul__.py @@ -1,5 +1,5 @@ """ -Special cases tests for x.__mul__. +Special cases tests for __mul__. These tests are generated from the special cases listed in the spec. diff --git a/array_api_tests/special_cases/test___pow__.py b/array_api_tests/special_cases/test___pow__.py index 3a6a5a8d..428137bc 100644 --- a/array_api_tests/special_cases/test___pow__.py +++ b/array_api_tests/special_cases/test___pow__.py @@ -1,5 +1,5 @@ """ -Special cases tests for x.__pow__. +Special cases tests for __pow__. These tests are generated from the special cases listed in the spec. @@ -172,19 +172,6 @@ def test___pow___special_cases_two_args_equal__greater_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) def test___pow___special_cases_two_args_equal__greater_2(arg1, arg2): - """ - Special case test for `__pow__(self, other, /)`: - - - If `x1_i` is `-infinity` and `x2_i` is greater than `0`, the result is `-infinity`. - - """ - res = arg1.__pow__(arg2) - mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), greater(arg2, zero(arg2.shape, arg2.dtype))) - assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) - - -@given(numeric_arrays, numeric_arrays) -def test___pow___special_cases_two_args_equal__greater_3(arg1, arg2): """ Special case test for `__pow__(self, other, /)`: @@ -222,6 +209,32 @@ def test___pow___special_cases_two_args_equal__less_2(arg1, arg2): assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) +@given(numeric_arrays, numeric_arrays) +def test___pow___special_cases_two_args_equal__greater_equal_1(arg1, arg2): + """ + Special case test for `__pow__(self, other, /)`: + + - If `x1_i` is `-infinity`, `x2_i` is greater than `0`, and `x2_i` is an odd integer value, the result is `-infinity`. + + """ + res = arg1.__pow__(arg2) + mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(greater(arg2, zero(arg2.shape, arg2.dtype)), isodd(arg2))) + assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) + + +@given(numeric_arrays, numeric_arrays) +def test___pow___special_cases_two_args_equal__greater_equal_2(arg1, arg2): + """ + Special case test for `__pow__(self, other, /)`: + + - If `x1_i` is `-0`, `x2_i` is greater than `0`, and `x2_i` is an odd integer value, the result is `-0`. + + """ + res = arg1.__pow__(arg2) + mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), logical_and(greater(arg2, zero(arg2.shape, arg2.dtype)), isodd(arg2))) + assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) + + @given(numeric_arrays, numeric_arrays) def test___pow___special_cases_two_args_equal__greater_notequal_1(arg1, arg2): """ @@ -300,19 +313,6 @@ def test___pow___special_cases_two_args_equal__less_notequal_2(arg1, arg2): assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) -@given(numeric_arrays, numeric_arrays) -def test___pow___special_cases_two_args_equal__greater_equal(arg1, arg2): - """ - Special case test for `__pow__(self, other, /)`: - - - If `x1_i` is `-0`, `x2_i` is greater than `0`, and `x2_i` is an odd integer value, the result is `-0`. - - """ - res = arg1.__pow__(arg2) - mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), logical_and(greater(arg2, zero(arg2.shape, arg2.dtype)), isodd(arg2))) - assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) - - @given(numeric_arrays, numeric_arrays) def test___pow___special_cases_two_args_less_equal__equal_notequal(arg1, arg2): """ diff --git a/array_api_tests/special_cases/test___truediv__.py b/array_api_tests/special_cases/test___truediv__.py index 12866a28..a32de039 100644 --- a/array_api_tests/special_cases/test___truediv__.py +++ b/array_api_tests/special_cases/test___truediv__.py @@ -1,5 +1,5 @@ """ -Special cases tests for x.__truediv__. +Special cases tests for __truediv__. These tests are generated from the special cases listed in the spec. diff --git a/generate_stubs.py b/generate_stubs.py index 68c84022..7180d3a9 100755 --- a/generate_stubs.py +++ b/generate_stubs.py @@ -31,6 +31,50 @@ REFLECTED_OPERATOR_RE = regex.compile(r'- +`__r(.*)__`') ALIAS_RE = regex.compile(r'Alias for {ref}`function-(.*)`.') +OPS = [ + '__abs__', + '__add__', + '__and__', + '__bool__', + '__eq__', + '__float__', + '__floordiv__', + '__ge__', + '__getitem__', + '__gt__', + '__invert__', + '__le__', + '__lshift__', + '__lt__', + '__matmul__', + '__mod__', + '__mul__', + '__ne__', + '__neg__', + '__or__', + '__pos__', + '__pow__', + '__rshift__', + '__sub__', + '__truediv__', + '__xor__' +] +IOPS = [ + '__iadd__', + '__isub__', + '__imul__', + '__itruediv__', + '__ifloordiv__', + '__ipow__', + '__imod__', + '__imatmul__', + '__iand__', + '__ior__', + '__ixor__', + '__ilshift__', + '__irshift__' +] + NAME_RE = regex.compile(r'(.*?)\(.*\)') STUB_FILE_HEADER = '''\ @@ -86,7 +130,25 @@ OP_SPECIAL_CASES_HEADER = '''\ """ -Special cases tests for x.{func}. +Special cases tests for {func}. + +These tests are generated from the special cases listed in the spec. + +NOTE: This file is generated automatically by the generate_stubs.py script. Do +not modify it directly. +""" + +from ..array_helpers import * +from ..hypothesis_helpers import numeric_arrays + +from hypothesis import given + +''' + + +IOP_SPECIAL_CASES_HEADER = '''\ +""" +Special cases tests for {func}. These tests are generated from the special cases listed in the spec. @@ -94,8 +156,11 @@ not modify it directly. """ +from operator import {operator} + from ..array_helpers import * from ..hypothesis_helpers import numeric_arrays +from .. import _array_module as xp from hypothesis import given @@ -268,7 +333,7 @@ def {annotated_sig}:{doc} if args.write: with open(py_path, 'w') as f: f.write(code) - if filename == 'elementwise_functions.md' and False: + if filename == 'elementwise_functions.md': special_cases = parse_special_cases(text, verbose=args.verbose) for func in special_cases: py_path = os.path.join('array_api_tests', 'special_cases', f'test_{func}.py') @@ -296,7 +361,7 @@ def {annotated_sig}:{doc} with open(py_path, 'w') as f: f.write(code) elif filename == 'array_object.md': - special_cases = parse_special_cases(text, verbose=args.verbose) + special_cases = parse_op_special_cases(text, verbose=args.verbose) for func in special_cases: py_path = os.path.join('array_api_tests', 'special_cases', f'test_{func}.py') tests = [] @@ -316,12 +381,20 @@ def {annotated_sig}:{doc} print(f"Error with {func}() {typ}: {m.group(0)}:\n", file=sys.stderr) raise if tests: - code = OP_SPECIAL_CASES_HEADER.format(func=func) + '\n'.join(tests) - # quiet=False will make it print a warning if a name is not found (indicating an error) - code = fix_code(code, file=py_path, verbose=False, quiet=False) - if args.write: - with open(py_path, 'w') as f: - f.write(code) + if func in IOPS: + code = IOP_SPECIAL_CASES_HEADER.format(func=func, operator=func[2:-2]) + '\n'.join(tests) + # quiet=False will make it print a warning if a name is not found (indicating an error) + code = fix_code(code, file=py_path, verbose=False, quiet=False) + if args.write: + with open(py_path, 'w') as f: + f.write(code) + else: + code = OP_SPECIAL_CASES_HEADER.format(func=func) + '\n'.join(tests) + # quiet=False will make it print a warning if a name is not found (indicating an error) + code = fix_code(code, file=py_path, verbose=False, quiet=False) + if args.write: + with open(py_path, 'w') as f: + f.write(code) init_path = os.path.join('array_api_tests', 'function_stubs', '__init__.py') if args.write: @@ -546,6 +619,15 @@ def test_{func}_special_cases_{test_name_extra}(arg1, arg2): {assertion} """ +IOP_TWO_ARGS_TEMPLATE = """ +{decorator} +def test_{func}_special_cases_{test_name_extra}(arg1, arg2): + {doc} + res = xp.asarray(arg1, copy=True) + {operator}(res, arg2) + mask = {mask} + {assertion} +""" REMAINING_TEMPLATE = """# TODO: Implement REMAINING test for: # {text} @@ -704,15 +786,26 @@ def generate_special_case_test(func, typ, m, test_name_extra, sigs): assertion = get_assert("exactly_equal", result) else: raise ValueError(f"Unrecognized special value type {typ}") - return OP_TWO_ARGS_TEMPLATE.format( - decorator=decorator, - func=func, - test_name_extra=test_name_extra, - doc=doc, - mask=mask, - assertion=assertion, - ) + if func in OPS: + return OP_TWO_ARGS_TEMPLATE.format( + decorator=decorator, + func=func, + test_name_extra=test_name_extra, + doc=doc, + mask=mask, + assertion=assertion, + ) + else: + return IOP_TWO_ARGS_TEMPLATE.format( + decorator=decorator, + func=func, + test_name_extra=test_name_extra, + doc=doc, + operator=func[2:-2], + mask=mask, + assertion=assertion, + ) elif typ == "REMAINING": return REMAINING_TEMPLATE.format(text=m.group(0)) @@ -881,17 +974,45 @@ def generate_special_case_test(func, typ, m, test_name_extra, sigs): def parse_special_cases(spec_text, verbose=False) -> Dict[str, DefaultDict[str, List[regex.Match]]]: special_cases = {} in_block = False - name = None for line in spec_text.splitlines(): - func_m = FUNCTION_HEADER_RE.match(line) - method_m = METHOD_HEADER_RE.match(line) - if func_m: - name = func_m.group(1) + m = FUNCTION_HEADER_RE.match(line) + if m: + name = m.group(1) special_cases[name] = defaultdict(list) continue - elif method_m: - name = method_m.group(1) - special_cases[name] = defaultdict(list) + if line == '#### Special Cases': + in_block = True + continue + elif line.startswith('#'): + in_block = False + continue + if in_block: + if '- ' not in line: + continue + for typ, reg in SPECIAL_CASE_REGEXS.items(): + m = reg.match(line) + if m: + if verbose: + print(f"Matched {typ} for {name}: {m.groups()}") + special_cases[name][typ].append(m) + break + else: + raise ValueError(f"Unrecognized special case string for '{name}':\n{line}") + + return special_cases + +def parse_op_special_cases(spec_text, verbose=False) -> Dict[str, DefaultDict[str, List[regex.Match]]]: + special_cases = {} + in_block = False + name = None + for line in spec_text.splitlines(): + m = METHOD_HEADER_RE.match(line) + if m: + name = m.group(1) + if name in OPS: + special_cases[name] = defaultdict(list) + else: + name = None continue if line == '#### Special Cases': in_block = True @@ -900,7 +1021,6 @@ def parse_special_cases(spec_text, verbose=False) -> Dict[str, DefaultDict[str, in_block = False continue if in_block: - # assert name is not None, f"in block but name is None, at {i=} {line=}" if '- ' not in line or name is None: continue for typ, reg in SPECIAL_CASE_REGEXS.items(): @@ -912,6 +1032,12 @@ def parse_special_cases(spec_text, verbose=False) -> Dict[str, DefaultDict[str, break else: raise ValueError(f"Unrecognized special case string for '{name}':\n{line}") + for line in spec_text.splitlines(): + for name in IN_PLACE_OPERATOR_RE.findall(spec_text): + op = f"__{name}__" + iop = f"__i{name}__" + special_cases[iop] = special_cases[op] + continue return special_cases From dc1ce166a503077604ecdcaa2c5b221ab42c4a81 Mon Sep 17 00:00:00 2001 From: Matthew Date: Mon, 8 Nov 2021 12:31:25 +0000 Subject: [PATCH 4/7] Move `parse_op_special_cases` functionality to `parse_special_cases` --- generate_stubs.py | 54 +++++++++-------------------------------------- 1 file changed, 10 insertions(+), 44 deletions(-) diff --git a/generate_stubs.py b/generate_stubs.py index 7180d3a9..81ce73f8 100755 --- a/generate_stubs.py +++ b/generate_stubs.py @@ -361,7 +361,11 @@ def {annotated_sig}:{doc} with open(py_path, 'w') as f: f.write(code) elif filename == 'array_object.md': - special_cases = parse_op_special_cases(text, verbose=args.verbose) + special_cases = parse_special_cases(text, verbose=args.verbose) + for name in IN_PLACE_OPERATOR_RE.findall(text): + op = f"__{name}__" + iop = f"__i{name}__" + special_cases[iop] = special_cases[op] for func in special_cases: py_path = os.path.join('array_api_tests', 'special_cases', f'test_{func}.py') tests = [] @@ -972,47 +976,15 @@ def generate_special_case_test(func, typ, m, test_name_extra, sigs): raise RuntimeError(f"Unexpected type {typ}") def parse_special_cases(spec_text, verbose=False) -> Dict[str, DefaultDict[str, List[regex.Match]]]: - special_cases = {} - in_block = False - for line in spec_text.splitlines(): - m = FUNCTION_HEADER_RE.match(line) - if m: - name = m.group(1) - special_cases[name] = defaultdict(list) - continue - if line == '#### Special Cases': - in_block = True - continue - elif line.startswith('#'): - in_block = False - continue - if in_block: - if '- ' not in line: - continue - for typ, reg in SPECIAL_CASE_REGEXS.items(): - m = reg.match(line) - if m: - if verbose: - print(f"Matched {typ} for {name}: {m.groups()}") - special_cases[name][typ].append(m) - break - else: - raise ValueError(f"Unrecognized special case string for '{name}':\n{line}") - - return special_cases - -def parse_op_special_cases(spec_text, verbose=False) -> Dict[str, DefaultDict[str, List[regex.Match]]]: special_cases = {} in_block = False name = None for line in spec_text.splitlines(): - m = METHOD_HEADER_RE.match(line) - if m: - name = m.group(1) - if name in OPS: - special_cases[name] = defaultdict(list) - else: - name = None + func_m = FUNCTION_HEADER_RE.match(line) + meth_m = METHOD_HEADER_RE.match(line) + if func_m or meth_m: + name = func_m.group(1) if func_m else meth_m.group(1) + special_cases[name] = defaultdict(list) continue if line == '#### Special Cases': in_block = True @@ -1032,12 +1004,6 @@ def parse_op_special_cases(spec_text, verbose=False) -> Dict[str, DefaultDict[st break else: raise ValueError(f"Unrecognized special case string for '{name}':\n{line}") - for line in spec_text.splitlines(): - for name in IN_PLACE_OPERATOR_RE.findall(spec_text): - op = f"__{name}__" - iop = f"__i{name}__" - special_cases[iop] = special_cases[op] - continue return special_cases From cf94b3a00cee95b53d0cd0d4af0b4b5d78c83ffb Mon Sep 17 00:00:00 2001 From: Matthew Date: Mon, 8 Nov 2021 12:40:40 +0000 Subject: [PATCH 5/7] Refactor `generate_special_case_test` --- generate_stubs.py | 459 ++++++++++++++++------------------------------ 1 file changed, 159 insertions(+), 300 deletions(-) diff --git a/generate_stubs.py b/generate_stubs.py index 81ce73f8..f750d9eb 100755 --- a/generate_stubs.py +++ b/generate_stubs.py @@ -638,44 +638,43 @@ def test_{func}_special_cases_{test_name_extra}(arg1, arg2): """ def generate_special_case_test(func, typ, m, test_name_extra, sigs): - is_op = func.startswith("__") doc = f'''""" Special case test for `{sigs[func]}`: {m.group(0)} """''' - if is_op: - if typ.startswith("ONE_ARG"): - decorator = "@given(numeric_arrays)" - if typ == "ONE_ARG_EQUAL": - value1, result = m.groups() - value1 = parse_value(value1, 'arg1') - mask = get_mask("exactly_equal", "arg1", value1) - elif typ == "ONE_ARG_GREATER": - value1, result = m.groups() - value1 = parse_value(value1, 'arg1') - mask = get_mask("greater", "arg1", value1) - elif typ == "ONE_ARG_LESS": - value1, result = m.groups() - value1 = parse_value(value1, 'arg1') - mask = get_mask("less", "arg1", value1) - elif typ == "ONE_ARG_EITHER": - value1, value2, result = m.groups() - value1 = parse_value(value1, 'arg1') - value2 = parse_value(value2, 'arg1') - mask1 = get_mask("exactly_equal", "arg1", value1) - mask2 = get_mask("exactly_equal", "arg1", value2) - mask = f"logical_or({mask1}, {mask2})" - elif typ == "ONE_ARG_ALREADY_INTEGER_VALUED": - result, = m.groups() - mask = parse_value("integer", "arg1") - elif typ == "ONE_ARG_TWO_INTEGERS_EQUALLY_CLOSE": - result, = m.groups() - mask = "logical_and(not_equal(floor(arg1), ceil(arg1)), equal(subtract(arg1, floor(arg1)), subtract(ceil(arg1), arg1)))" - else: - raise ValueError(f"Unrecognized special value type {typ}") - assertion = get_assert("exactly_equal", result) + if typ.startswith("ONE_ARG"): + decorator = "@given(numeric_arrays)" + if typ == "ONE_ARG_EQUAL": + value1, result = m.groups() + value1 = parse_value(value1, 'arg1') + mask = get_mask("exactly_equal", "arg1", value1) + elif typ == "ONE_ARG_GREATER": + value1, result = m.groups() + value1 = parse_value(value1, 'arg1') + mask = get_mask("greater", "arg1", value1) + elif typ == "ONE_ARG_LESS": + value1, result = m.groups() + value1 = parse_value(value1, 'arg1') + mask = get_mask("less", "arg1", value1) + elif typ == "ONE_ARG_EITHER": + value1, value2, result = m.groups() + value1 = parse_value(value1, 'arg1') + value2 = parse_value(value2, 'arg1') + mask1 = get_mask("exactly_equal", "arg1", value1) + mask2 = get_mask("exactly_equal", "arg1", value2) + mask = f"logical_or({mask1}, {mask2})" + elif typ == "ONE_ARG_ALREADY_INTEGER_VALUED": + result, = m.groups() + mask = parse_value("integer", "arg1") + elif typ == "ONE_ARG_TWO_INTEGERS_EQUALLY_CLOSE": + result, = m.groups() + mask = "logical_and(not_equal(floor(arg1), ceil(arg1)), equal(subtract(arg1, floor(arg1)), subtract(ceil(arg1), arg1)))" + else: + raise ValueError(f"Unrecognized special value type {typ}") + assertion = get_assert("exactly_equal", result) + if func in OPS: return OP_ONE_ARG_TEMPLATE.format( decorator=decorator, func=func, @@ -684,169 +683,7 @@ def generate_special_case_test(func, typ, m, test_name_extra, sigs): mask=mask, assertion=assertion, ) - - elif typ.startswith("TWO_ARGS"): - decorator = "@given(numeric_arrays, numeric_arrays)" - if typ in [ - "TWO_ARGS_EQUAL__EQUAL", - "TWO_ARGS_GREATER__EQUAL", - "TWO_ARGS_LESS__EQUAL", - "TWO_ARGS_EQUAL__GREATER", - "TWO_ARGS_EQUAL__LESS", - "TWO_ARGS_EQUAL__NOTEQUAL", - "TWO_ARGS_NOTEQUAL__EQUAL", - "TWO_ARGS_ABSEQUAL__EQUAL", - "TWO_ARGS_ABSGREATER__EQUAL", - "TWO_ARGS_ABSLESS__EQUAL", - "TWO_ARGS_GREATER_EQUAL__EQUAL", - "TWO_ARGS_LESS_EQUAL__EQUAL", - "TWO_ARGS_EQUAL__LESS_EQUAL", - "TWO_ARGS_EQUAL__LESS_NOTEQUAL", - "TWO_ARGS_EQUAL__GREATER_EQUAL", - "TWO_ARGS_EQUAL__GREATER_NOTEQUAL", - "TWO_ARGS_LESS_EQUAL__EQUAL_NOTEQUAL", - "TWO_ARGS_EITHER__EQUAL", - "TWO_ARGS_EQUAL__EITHER", - "TWO_ARGS_EITHER__EITHER", - ]: - arg1typs, arg2typs = [i.split('_') for i in typ[len("TWO_ARGS_"):].split("__")] - if arg1typs == ["EITHER"]: - arg1typs = ["EITHER_EQUAL", "EITHER_EQUAL"] - if arg2typs == ["EITHER"]: - arg2typs = ["EITHER_EQUAL", "EITHER_EQUAL"] - *values, result = m.groups() - if len(values) != len(arg1typs) + len(arg2typs): - raise RuntimeError(f"Unexpected number of parsed values for {typ}: len({values}) != len({arg1typs}) + len({arg2typs})") - arg1values, arg2values = values[:len(arg1typs)], values[len(arg1typs):] - arg1values = [parse_value(value, 'arg1') for value in arg1values] - arg2values = [parse_value(value, 'arg2') for value in arg2values] - - tomask = lambda t: t.lower().replace("either_equal", "equal").replace("equal", "exactly_equal") - value1masks = [get_mask(tomask(t), 'arg1', v) for t, v in - zip(arg1typs, arg1values)] - value2masks = [get_mask(tomask(t), 'arg2', v) for t, v in - zip(arg2typs, arg2values)] - if len(value1masks) > 1: - if arg1typs[0] == "EITHER_EQUAL": - mask1 = f"logical_or({value1masks[0]}, {value1masks[1]})" - else: - mask1 = f"logical_and({value1masks[0]}, {value1masks[1]})" - else: - mask1 = value1masks[0] - if len(value2masks) > 1: - if arg2typs[0] == "EITHER_EQUAL": - mask2 = f"logical_or({value2masks[0]}, {value2masks[1]})" - else: - mask2 = f"logical_and({value2masks[0]}, {value2masks[1]})" - else: - mask2 = value2masks[0] - - mask = f"logical_and({mask1}, {mask2})" - assertion = get_assert("exactly_equal", result) - - elif typ == "TWO_ARGS_EITHER": - value, result = m.groups() - value = parse_value(value, "arg1") - mask1 = get_mask("exactly_equal", "arg1", value) - mask2 = get_mask("exactly_equal", "arg2", value) - mask = f"logical_or({mask1}, {mask2})" - assertion = get_assert("exactly_equal", result) - elif typ == "TWO_ARGS_SAME_SIGN": - result, = m.groups() - mask = "same_sign(arg1, arg2)" - assertion = get_assert("exactly_equal", result) - elif typ == "TWO_ARGS_SAME_SIGN_EXCEPT": - result, value, value1, value2 = m.groups() - assert value == value1 == value2 - value = parse_value(value, "res") - mask = f"logical_and(same_sign(arg1, arg2), logical_not(exactly_equal(res, {value})))" - assertion = get_assert("exactly_equal", result) - elif typ == "TWO_ARGS_SAME_SIGN_BOTH": - value, result = m.groups() - mask1 = get_mask("exactly_equal", "arg1", value) - mask2 = get_mask("exactly_equal", "arg2", value) - mask = f"logical_and(same_sign(arg1, arg2), logical_and({mask1}, {mask2}))" - assertion = get_assert("exactly_equal", result) - elif typ == "TWO_ARGS_DIFFERENT_SIGNS": - result, = m.groups() - mask = "logical_not(same_sign(arg1, arg2))" - assertion = get_assert("exactly_equal", result) - elif typ == "TWO_ARGS_DIFFERENT_SIGNS_EXCEPT": - result, value, value1, value2 = m.groups() - assert value == value1 == value2 - value = parse_value(value, "res") - mask = f"logical_and(logical_not(same_sign(arg1, arg2)), logical_not(exactly_equal(res, {value})))" - assertion = get_assert("exactly_equal", result) - elif typ == "TWO_ARGS_DIFFERENT_SIGNS_BOTH": - value, result = m.groups() - mask1 = get_mask("exactly_equal", "arg1", value) - mask2 = get_mask("exactly_equal", "arg2", value) - mask = f"logical_and(logical_not(same_sign(arg1, arg2)), logical_and({mask1}, {mask2}))" - assertion = get_assert("exactly_equal", result) - elif typ == "TWO_ARGS_EVEN_IF": - value1, result, value2 = m.groups() - value1 = parse_value(value1, "arg2") - mask = get_mask("exactly_equal", "arg2", value1) - assertion = get_assert("exactly_equal", result) - else: - raise ValueError(f"Unrecognized special value type {typ}") - - if func in OPS: - return OP_TWO_ARGS_TEMPLATE.format( - decorator=decorator, - func=func, - test_name_extra=test_name_extra, - doc=doc, - mask=mask, - assertion=assertion, - ) - else: - return IOP_TWO_ARGS_TEMPLATE.format( - decorator=decorator, - func=func, - test_name_extra=test_name_extra, - doc=doc, - operator=func[2:-2], - mask=mask, - assertion=assertion, - ) - - elif typ == "REMAINING": - return REMAINING_TEMPLATE.format(text=m.group(0)) else: - raise RuntimeError(f"Unexpected type {typ}") - - else: - if typ.startswith("ONE_ARG"): - decorator = "@given(numeric_arrays)" - if typ == "ONE_ARG_EQUAL": - value1, result = m.groups() - value1 = parse_value(value1, 'arg1') - mask = get_mask("exactly_equal", "arg1", value1) - elif typ == "ONE_ARG_GREATER": - value1, result = m.groups() - value1 = parse_value(value1, 'arg1') - mask = get_mask("greater", "arg1", value1) - elif typ == "ONE_ARG_LESS": - value1, result = m.groups() - value1 = parse_value(value1, 'arg1') - mask = get_mask("less", "arg1", value1) - elif typ == "ONE_ARG_EITHER": - value1, value2, result = m.groups() - value1 = parse_value(value1, 'arg1') - value2 = parse_value(value2, 'arg1') - mask1 = get_mask("exactly_equal", "arg1", value1) - mask2 = get_mask("exactly_equal", "arg1", value2) - mask = f"logical_or({mask1}, {mask2})" - elif typ == "ONE_ARG_ALREADY_INTEGER_VALUED": - result, = m.groups() - mask = parse_value("integer", "arg1") - elif typ == "ONE_ARG_TWO_INTEGERS_EQUALLY_CLOSE": - result, = m.groups() - mask = "logical_and(not_equal(floor(arg1), ceil(arg1)), equal(subtract(arg1, floor(arg1)), subtract(ceil(arg1), arg1)))" - else: - raise ValueError(f"Unrecognized special value type {typ}") - assertion = get_assert("exactly_equal", result) return ONE_ARG_TEMPLATE.format( decorator=decorator, func=func, @@ -856,111 +693,132 @@ def generate_special_case_test(func, typ, m, test_name_extra, sigs): assertion=assertion, ) - elif typ.startswith("TWO_ARGS"): - decorator = "@given(numeric_arrays, numeric_arrays)" - if typ in [ - "TWO_ARGS_EQUAL__EQUAL", - "TWO_ARGS_GREATER__EQUAL", - "TWO_ARGS_LESS__EQUAL", - "TWO_ARGS_EQUAL__GREATER", - "TWO_ARGS_EQUAL__LESS", - "TWO_ARGS_EQUAL__NOTEQUAL", - "TWO_ARGS_NOTEQUAL__EQUAL", - "TWO_ARGS_ABSEQUAL__EQUAL", - "TWO_ARGS_ABSGREATER__EQUAL", - "TWO_ARGS_ABSLESS__EQUAL", - "TWO_ARGS_GREATER_EQUAL__EQUAL", - "TWO_ARGS_LESS_EQUAL__EQUAL", - "TWO_ARGS_EQUAL__LESS_EQUAL", - "TWO_ARGS_EQUAL__LESS_NOTEQUAL", - "TWO_ARGS_EQUAL__GREATER_EQUAL", - "TWO_ARGS_EQUAL__GREATER_NOTEQUAL", - "TWO_ARGS_LESS_EQUAL__EQUAL_NOTEQUAL", - "TWO_ARGS_EITHER__EQUAL", - "TWO_ARGS_EQUAL__EITHER", - "TWO_ARGS_EITHER__EITHER", - ]: - arg1typs, arg2typs = [i.split('_') for i in typ[len("TWO_ARGS_"):].split("__")] - if arg1typs == ["EITHER"]: - arg1typs = ["EITHER_EQUAL", "EITHER_EQUAL"] - if arg2typs == ["EITHER"]: - arg2typs = ["EITHER_EQUAL", "EITHER_EQUAL"] - *values, result = m.groups() - if len(values) != len(arg1typs) + len(arg2typs): - raise RuntimeError(f"Unexpected number of parsed values for {typ}: len({values}) != len({arg1typs}) + len({arg2typs})") - arg1values, arg2values = values[:len(arg1typs)], values[len(arg1typs):] - arg1values = [parse_value(value, 'arg1') for value in arg1values] - arg2values = [parse_value(value, 'arg2') for value in arg2values] - - tomask = lambda t: t.lower().replace("either_equal", "equal").replace("equal", "exactly_equal") - value1masks = [get_mask(tomask(t), 'arg1', v) for t, v in - zip(arg1typs, arg1values)] - value2masks = [get_mask(tomask(t), 'arg2', v) for t, v in - zip(arg2typs, arg2values)] - if len(value1masks) > 1: - if arg1typs[0] == "EITHER_EQUAL": - mask1 = f"logical_or({value1masks[0]}, {value1masks[1]})" - else: - mask1 = f"logical_and({value1masks[0]}, {value1masks[1]})" + elif typ.startswith("TWO_ARGS"): + decorator = "@given(numeric_arrays, numeric_arrays)" + if typ in [ + "TWO_ARGS_EQUAL__EQUAL", + "TWO_ARGS_GREATER__EQUAL", + "TWO_ARGS_LESS__EQUAL", + "TWO_ARGS_EQUAL__GREATER", + "TWO_ARGS_EQUAL__LESS", + "TWO_ARGS_EQUAL__NOTEQUAL", + "TWO_ARGS_NOTEQUAL__EQUAL", + "TWO_ARGS_ABSEQUAL__EQUAL", + "TWO_ARGS_ABSGREATER__EQUAL", + "TWO_ARGS_ABSLESS__EQUAL", + "TWO_ARGS_GREATER_EQUAL__EQUAL", + "TWO_ARGS_LESS_EQUAL__EQUAL", + "TWO_ARGS_EQUAL__LESS_EQUAL", + "TWO_ARGS_EQUAL__LESS_NOTEQUAL", + "TWO_ARGS_EQUAL__GREATER_EQUAL", + "TWO_ARGS_EQUAL__GREATER_NOTEQUAL", + "TWO_ARGS_LESS_EQUAL__EQUAL_NOTEQUAL", + "TWO_ARGS_EITHER__EQUAL", + "TWO_ARGS_EQUAL__EITHER", + "TWO_ARGS_EITHER__EITHER", + ]: + arg1typs, arg2typs = [i.split('_') for i in typ[len("TWO_ARGS_"):].split("__")] + if arg1typs == ["EITHER"]: + arg1typs = ["EITHER_EQUAL", "EITHER_EQUAL"] + if arg2typs == ["EITHER"]: + arg2typs = ["EITHER_EQUAL", "EITHER_EQUAL"] + *values, result = m.groups() + if len(values) != len(arg1typs) + len(arg2typs): + raise RuntimeError(f"Unexpected number of parsed values for {typ}: len({values}) != len({arg1typs}) + len({arg2typs})") + arg1values, arg2values = values[:len(arg1typs)], values[len(arg1typs):] + arg1values = [parse_value(value, 'arg1') for value in arg1values] + arg2values = [parse_value(value, 'arg2') for value in arg2values] + + tomask = lambda t: t.lower().replace("either_equal", "equal").replace("equal", "exactly_equal") + value1masks = [get_mask(tomask(t), 'arg1', v) for t, v in + zip(arg1typs, arg1values)] + value2masks = [get_mask(tomask(t), 'arg2', v) for t, v in + zip(arg2typs, arg2values)] + if len(value1masks) > 1: + if arg1typs[0] == "EITHER_EQUAL": + mask1 = f"logical_or({value1masks[0]}, {value1masks[1]})" else: - mask1 = value1masks[0] - if len(value2masks) > 1: - if arg2typs[0] == "EITHER_EQUAL": - mask2 = f"logical_or({value2masks[0]}, {value2masks[1]})" - else: - mask2 = f"logical_and({value2masks[0]}, {value2masks[1]})" + mask1 = f"logical_and({value1masks[0]}, {value1masks[1]})" + else: + mask1 = value1masks[0] + if len(value2masks) > 1: + if arg2typs[0] == "EITHER_EQUAL": + mask2 = f"logical_or({value2masks[0]}, {value2masks[1]})" else: - mask2 = value2masks[0] - - mask = f"logical_and({mask1}, {mask2})" - assertion = get_assert("exactly_equal", result) - - elif typ == "TWO_ARGS_EITHER": - value, result = m.groups() - value = parse_value(value, "arg1") - mask1 = get_mask("exactly_equal", "arg1", value) - mask2 = get_mask("exactly_equal", "arg2", value) - mask = f"logical_or({mask1}, {mask2})" - assertion = get_assert("exactly_equal", result) - elif typ == "TWO_ARGS_SAME_SIGN": - result, = m.groups() - mask = "same_sign(arg1, arg2)" - assertion = get_assert("exactly_equal", result) - elif typ == "TWO_ARGS_SAME_SIGN_EXCEPT": - result, value, value1, value2 = m.groups() - assert value == value1 == value2 - value = parse_value(value, "res") - mask = f"logical_and(same_sign(arg1, arg2), logical_not(exactly_equal(res, {value})))" - assertion = get_assert("exactly_equal", result) - elif typ == "TWO_ARGS_SAME_SIGN_BOTH": - value, result = m.groups() - mask1 = get_mask("exactly_equal", "arg1", value) - mask2 = get_mask("exactly_equal", "arg2", value) - mask = f"logical_and(same_sign(arg1, arg2), logical_and({mask1}, {mask2}))" - assertion = get_assert("exactly_equal", result) - elif typ == "TWO_ARGS_DIFFERENT_SIGNS": - result, = m.groups() - mask = "logical_not(same_sign(arg1, arg2))" - assertion = get_assert("exactly_equal", result) - elif typ == "TWO_ARGS_DIFFERENT_SIGNS_EXCEPT": - result, value, value1, value2 = m.groups() - assert value == value1 == value2 - value = parse_value(value, "res") - mask = f"logical_and(logical_not(same_sign(arg1, arg2)), logical_not(exactly_equal(res, {value})))" - assertion = get_assert("exactly_equal", result) - elif typ == "TWO_ARGS_DIFFERENT_SIGNS_BOTH": - value, result = m.groups() - mask1 = get_mask("exactly_equal", "arg1", value) - mask2 = get_mask("exactly_equal", "arg2", value) - mask = f"logical_and(logical_not(same_sign(arg1, arg2)), logical_and({mask1}, {mask2}))" - assertion = get_assert("exactly_equal", result) - elif typ == "TWO_ARGS_EVEN_IF": - value1, result, value2 = m.groups() - value1 = parse_value(value1, "arg2") - mask = get_mask("exactly_equal", "arg2", value1) - assertion = get_assert("exactly_equal", result) + mask2 = f"logical_and({value2masks[0]}, {value2masks[1]})" else: - raise ValueError(f"Unrecognized special value type {typ}") + mask2 = value2masks[0] + + mask = f"logical_and({mask1}, {mask2})" + assertion = get_assert("exactly_equal", result) + + elif typ == "TWO_ARGS_EITHER": + value, result = m.groups() + value = parse_value(value, "arg1") + mask1 = get_mask("exactly_equal", "arg1", value) + mask2 = get_mask("exactly_equal", "arg2", value) + mask = f"logical_or({mask1}, {mask2})" + assertion = get_assert("exactly_equal", result) + elif typ == "TWO_ARGS_SAME_SIGN": + result, = m.groups() + mask = "same_sign(arg1, arg2)" + assertion = get_assert("exactly_equal", result) + elif typ == "TWO_ARGS_SAME_SIGN_EXCEPT": + result, value, value1, value2 = m.groups() + assert value == value1 == value2 + value = parse_value(value, "res") + mask = f"logical_and(same_sign(arg1, arg2), logical_not(exactly_equal(res, {value})))" + assertion = get_assert("exactly_equal", result) + elif typ == "TWO_ARGS_SAME_SIGN_BOTH": + value, result = m.groups() + mask1 = get_mask("exactly_equal", "arg1", value) + mask2 = get_mask("exactly_equal", "arg2", value) + mask = f"logical_and(same_sign(arg1, arg2), logical_and({mask1}, {mask2}))" + assertion = get_assert("exactly_equal", result) + elif typ == "TWO_ARGS_DIFFERENT_SIGNS": + result, = m.groups() + mask = "logical_not(same_sign(arg1, arg2))" + assertion = get_assert("exactly_equal", result) + elif typ == "TWO_ARGS_DIFFERENT_SIGNS_EXCEPT": + result, value, value1, value2 = m.groups() + assert value == value1 == value2 + value = parse_value(value, "res") + mask = f"logical_and(logical_not(same_sign(arg1, arg2)), logical_not(exactly_equal(res, {value})))" + assertion = get_assert("exactly_equal", result) + elif typ == "TWO_ARGS_DIFFERENT_SIGNS_BOTH": + value, result = m.groups() + mask1 = get_mask("exactly_equal", "arg1", value) + mask2 = get_mask("exactly_equal", "arg2", value) + mask = f"logical_and(logical_not(same_sign(arg1, arg2)), logical_and({mask1}, {mask2}))" + assertion = get_assert("exactly_equal", result) + elif typ == "TWO_ARGS_EVEN_IF": + value1, result, value2 = m.groups() + value1 = parse_value(value1, "arg2") + mask = get_mask("exactly_equal", "arg2", value1) + assertion = get_assert("exactly_equal", result) + else: + raise ValueError(f"Unrecognized special value type {typ}") + + if func in OPS: + return OP_TWO_ARGS_TEMPLATE.format( + decorator=decorator, + func=func, + test_name_extra=test_name_extra, + doc=doc, + mask=mask, + assertion=assertion, + ) + elif func in IOPS: + return IOP_TWO_ARGS_TEMPLATE.format( + decorator=decorator, + func=func, + test_name_extra=test_name_extra, + doc=doc, + operator=func[2:-2], + mask=mask, + assertion=assertion, + ) + else: return TWO_ARGS_TEMPLATE.format( decorator=decorator, func=func, @@ -970,10 +828,11 @@ def generate_special_case_test(func, typ, m, test_name_extra, sigs): assertion=assertion, ) - elif typ == "REMAINING": - return REMAINING_TEMPLATE.format(text=m.group(0)) - else: - raise RuntimeError(f"Unexpected type {typ}") + elif typ == "REMAINING": + return REMAINING_TEMPLATE.format(text=m.group(0)) + + else: + raise RuntimeError(f"Unexpected type {typ}") def parse_special_cases(spec_text, verbose=False) -> Dict[str, DefaultDict[str, List[regex.Match]]]: special_cases = {} From 26cd1afcb6fcea1d3e65303c551401b6f7167c45 Mon Sep 17 00:00:00 2001 From: Matthew Date: Mon, 8 Nov 2021 14:04:23 +0000 Subject: [PATCH 6/7] Refactor test making --- .../{test___abs__.py => test_dunder_abs.py} | 6 +- .../{test___add__.py => test_dunder_add.py} | 32 +++--- .../{test___iadd__.py => test_dunder_iadd.py} | 32 +++--- .../{test___imul__.py => test_dunder_imul.py} | 16 +-- .../{test___ipow__.py => test_dunder_ipow.py} | 48 ++++---- ..._itruediv__.py => test_dunder_itruediv.py} | 42 +++---- .../{test___mul__.py => test_dunder_mul.py} | 16 +-- .../{test___pow__.py => test_dunder_pow.py} | 48 ++++---- ...___truediv__.py => test_dunder_truediv.py} | 42 +++---- generate_stubs.py | 104 ++++++++---------- 10 files changed, 189 insertions(+), 197 deletions(-) rename array_api_tests/special_cases/{test___abs__.py => test_dunder_abs.py} (88%) rename array_api_tests/special_cases/{test___add__.py => test_dunder_add.py} (87%) rename array_api_tests/special_cases/{test___iadd__.py => test_dunder_iadd.py} (88%) rename array_api_tests/special_cases/{test___imul__.py => test_dunder_imul.py} (91%) rename array_api_tests/special_cases/{test___ipow__.py => test_dunder_ipow.py} (87%) rename array_api_tests/special_cases/{test___itruediv__.py => test_dunder_itruediv.py} (88%) rename array_api_tests/special_cases/{test___mul__.py => test_dunder_mul.py} (90%) rename array_api_tests/special_cases/{test___pow__.py => test_dunder_pow.py} (86%) rename array_api_tests/special_cases/{test___truediv__.py => test_dunder_truediv.py} (87%) diff --git a/array_api_tests/special_cases/test___abs__.py b/array_api_tests/special_cases/test_dunder_abs.py similarity index 88% rename from array_api_tests/special_cases/test___abs__.py rename to array_api_tests/special_cases/test_dunder_abs.py index ea0a22d9..5028f1b7 100644 --- a/array_api_tests/special_cases/test___abs__.py +++ b/array_api_tests/special_cases/test_dunder_abs.py @@ -14,7 +14,7 @@ @given(numeric_arrays) -def test___abs___special_cases_one_arg_equal_1(arg1): +def test_abs_special_cases_one_arg_equal_1(arg1): """ Special case test for `__abs__(self, /)`: @@ -27,7 +27,7 @@ def test___abs___special_cases_one_arg_equal_1(arg1): @given(numeric_arrays) -def test___abs___special_cases_one_arg_equal_2(arg1): +def test_abs_special_cases_one_arg_equal_2(arg1): """ Special case test for `__abs__(self, /)`: @@ -40,7 +40,7 @@ def test___abs___special_cases_one_arg_equal_2(arg1): @given(numeric_arrays) -def test___abs___special_cases_one_arg_equal_3(arg1): +def test_abs_special_cases_one_arg_equal_3(arg1): """ Special case test for `__abs__(self, /)`: diff --git a/array_api_tests/special_cases/test___add__.py b/array_api_tests/special_cases/test_dunder_add.py similarity index 87% rename from array_api_tests/special_cases/test___add__.py rename to array_api_tests/special_cases/test_dunder_add.py index 78d1eab0..d3b5e169 100644 --- a/array_api_tests/special_cases/test___add__.py +++ b/array_api_tests/special_cases/test_dunder_add.py @@ -15,7 +15,7 @@ @given(numeric_arrays, numeric_arrays) -def test___add___special_cases_two_args_either(arg1, arg2): +def test_add_special_cases_two_args_either(arg1, arg2): """ Special case test for `__add__(self, other, /)`: @@ -28,7 +28,7 @@ def test___add___special_cases_two_args_either(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___add___special_cases_two_args_equal__equal_1(arg1, arg2): +def test_add_special_cases_two_args_equal__equal_1(arg1, arg2): """ Special case test for `__add__(self, other, /)`: @@ -41,7 +41,7 @@ def test___add___special_cases_two_args_equal__equal_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___add___special_cases_two_args_equal__equal_2(arg1, arg2): +def test_add_special_cases_two_args_equal__equal_2(arg1, arg2): """ Special case test for `__add__(self, other, /)`: @@ -54,7 +54,7 @@ def test___add___special_cases_two_args_equal__equal_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___add___special_cases_two_args_equal__equal_3(arg1, arg2): +def test_add_special_cases_two_args_equal__equal_3(arg1, arg2): """ Special case test for `__add__(self, other, /)`: @@ -67,7 +67,7 @@ def test___add___special_cases_two_args_equal__equal_3(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___add___special_cases_two_args_equal__equal_4(arg1, arg2): +def test_add_special_cases_two_args_equal__equal_4(arg1, arg2): """ Special case test for `__add__(self, other, /)`: @@ -80,7 +80,7 @@ def test___add___special_cases_two_args_equal__equal_4(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___add___special_cases_two_args_equal__equal_5(arg1, arg2): +def test_add_special_cases_two_args_equal__equal_5(arg1, arg2): """ Special case test for `__add__(self, other, /)`: @@ -93,7 +93,7 @@ def test___add___special_cases_two_args_equal__equal_5(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___add___special_cases_two_args_equal__equal_6(arg1, arg2): +def test_add_special_cases_two_args_equal__equal_6(arg1, arg2): """ Special case test for `__add__(self, other, /)`: @@ -106,7 +106,7 @@ def test___add___special_cases_two_args_equal__equal_6(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___add___special_cases_two_args_equal__equal_7(arg1, arg2): +def test_add_special_cases_two_args_equal__equal_7(arg1, arg2): """ Special case test for `__add__(self, other, /)`: @@ -119,7 +119,7 @@ def test___add___special_cases_two_args_equal__equal_7(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___add___special_cases_two_args_equal__equal_8(arg1, arg2): +def test_add_special_cases_two_args_equal__equal_8(arg1, arg2): """ Special case test for `__add__(self, other, /)`: @@ -132,7 +132,7 @@ def test___add___special_cases_two_args_equal__equal_8(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___add___special_cases_two_args_equal__equal_9(arg1, arg2): +def test_add_special_cases_two_args_equal__equal_9(arg1, arg2): """ Special case test for `__add__(self, other, /)`: @@ -145,7 +145,7 @@ def test___add___special_cases_two_args_equal__equal_9(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___add___special_cases_two_args_equal__equal_10(arg1, arg2): +def test_add_special_cases_two_args_equal__equal_10(arg1, arg2): """ Special case test for `__add__(self, other, /)`: @@ -158,7 +158,7 @@ def test___add___special_cases_two_args_equal__equal_10(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___add___special_cases_two_args_equal__equal_11(arg1, arg2): +def test_add_special_cases_two_args_equal__equal_11(arg1, arg2): """ Special case test for `__add__(self, other, /)`: @@ -171,7 +171,7 @@ def test___add___special_cases_two_args_equal__equal_11(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___add___special_cases_two_args_equal__equal_12(arg1, arg2): +def test_add_special_cases_two_args_equal__equal_12(arg1, arg2): """ Special case test for `__add__(self, other, /)`: @@ -184,7 +184,7 @@ def test___add___special_cases_two_args_equal__equal_12(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___add___special_cases_two_args_equal__equal_13(arg1, arg2): +def test_add_special_cases_two_args_equal__equal_13(arg1, arg2): """ Special case test for `__add__(self, other, /)`: @@ -197,7 +197,7 @@ def test___add___special_cases_two_args_equal__equal_13(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___add___special_cases_two_args_either__equal(arg1, arg2): +def test_add_special_cases_two_args_either__equal(arg1, arg2): """ Special case test for `__add__(self, other, /)`: @@ -210,7 +210,7 @@ def test___add___special_cases_two_args_either__equal(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___add___special_cases_two_args_equal__either(arg1, arg2): +def test_add_special_cases_two_args_equal__either(arg1, arg2): """ Special case test for `__add__(self, other, /)`: diff --git a/array_api_tests/special_cases/test___iadd__.py b/array_api_tests/special_cases/test_dunder_iadd.py similarity index 88% rename from array_api_tests/special_cases/test___iadd__.py rename to array_api_tests/special_cases/test_dunder_iadd.py index 6be0fd59..42d80f5f 100644 --- a/array_api_tests/special_cases/test___iadd__.py +++ b/array_api_tests/special_cases/test_dunder_iadd.py @@ -18,7 +18,7 @@ @given(numeric_arrays, numeric_arrays) -def test___iadd___special_cases_two_args_either(arg1, arg2): +def test_iadd_special_cases_two_args_either(arg1, arg2): """ Special case test for `__iadd__(self, other, /)`: @@ -32,7 +32,7 @@ def test___iadd___special_cases_two_args_either(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___iadd___special_cases_two_args_equal__equal_1(arg1, arg2): +def test_iadd_special_cases_two_args_equal__equal_1(arg1, arg2): """ Special case test for `__iadd__(self, other, /)`: @@ -46,7 +46,7 @@ def test___iadd___special_cases_two_args_equal__equal_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___iadd___special_cases_two_args_equal__equal_2(arg1, arg2): +def test_iadd_special_cases_two_args_equal__equal_2(arg1, arg2): """ Special case test for `__iadd__(self, other, /)`: @@ -60,7 +60,7 @@ def test___iadd___special_cases_two_args_equal__equal_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___iadd___special_cases_two_args_equal__equal_3(arg1, arg2): +def test_iadd_special_cases_two_args_equal__equal_3(arg1, arg2): """ Special case test for `__iadd__(self, other, /)`: @@ -74,7 +74,7 @@ def test___iadd___special_cases_two_args_equal__equal_3(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___iadd___special_cases_two_args_equal__equal_4(arg1, arg2): +def test_iadd_special_cases_two_args_equal__equal_4(arg1, arg2): """ Special case test for `__iadd__(self, other, /)`: @@ -88,7 +88,7 @@ def test___iadd___special_cases_two_args_equal__equal_4(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___iadd___special_cases_two_args_equal__equal_5(arg1, arg2): +def test_iadd_special_cases_two_args_equal__equal_5(arg1, arg2): """ Special case test for `__iadd__(self, other, /)`: @@ -102,7 +102,7 @@ def test___iadd___special_cases_two_args_equal__equal_5(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___iadd___special_cases_two_args_equal__equal_6(arg1, arg2): +def test_iadd_special_cases_two_args_equal__equal_6(arg1, arg2): """ Special case test for `__iadd__(self, other, /)`: @@ -116,7 +116,7 @@ def test___iadd___special_cases_two_args_equal__equal_6(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___iadd___special_cases_two_args_equal__equal_7(arg1, arg2): +def test_iadd_special_cases_two_args_equal__equal_7(arg1, arg2): """ Special case test for `__iadd__(self, other, /)`: @@ -130,7 +130,7 @@ def test___iadd___special_cases_two_args_equal__equal_7(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___iadd___special_cases_two_args_equal__equal_8(arg1, arg2): +def test_iadd_special_cases_two_args_equal__equal_8(arg1, arg2): """ Special case test for `__iadd__(self, other, /)`: @@ -144,7 +144,7 @@ def test___iadd___special_cases_two_args_equal__equal_8(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___iadd___special_cases_two_args_equal__equal_9(arg1, arg2): +def test_iadd_special_cases_two_args_equal__equal_9(arg1, arg2): """ Special case test for `__iadd__(self, other, /)`: @@ -158,7 +158,7 @@ def test___iadd___special_cases_two_args_equal__equal_9(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___iadd___special_cases_two_args_equal__equal_10(arg1, arg2): +def test_iadd_special_cases_two_args_equal__equal_10(arg1, arg2): """ Special case test for `__iadd__(self, other, /)`: @@ -172,7 +172,7 @@ def test___iadd___special_cases_two_args_equal__equal_10(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___iadd___special_cases_two_args_equal__equal_11(arg1, arg2): +def test_iadd_special_cases_two_args_equal__equal_11(arg1, arg2): """ Special case test for `__iadd__(self, other, /)`: @@ -186,7 +186,7 @@ def test___iadd___special_cases_two_args_equal__equal_11(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___iadd___special_cases_two_args_equal__equal_12(arg1, arg2): +def test_iadd_special_cases_two_args_equal__equal_12(arg1, arg2): """ Special case test for `__iadd__(self, other, /)`: @@ -200,7 +200,7 @@ def test___iadd___special_cases_two_args_equal__equal_12(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___iadd___special_cases_two_args_equal__equal_13(arg1, arg2): +def test_iadd_special_cases_two_args_equal__equal_13(arg1, arg2): """ Special case test for `__iadd__(self, other, /)`: @@ -214,7 +214,7 @@ def test___iadd___special_cases_two_args_equal__equal_13(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___iadd___special_cases_two_args_either__equal(arg1, arg2): +def test_iadd_special_cases_two_args_either__equal(arg1, arg2): """ Special case test for `__iadd__(self, other, /)`: @@ -228,7 +228,7 @@ def test___iadd___special_cases_two_args_either__equal(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___iadd___special_cases_two_args_equal__either(arg1, arg2): +def test_iadd_special_cases_two_args_equal__either(arg1, arg2): """ Special case test for `__iadd__(self, other, /)`: diff --git a/array_api_tests/special_cases/test___imul__.py b/array_api_tests/special_cases/test_dunder_imul.py similarity index 91% rename from array_api_tests/special_cases/test___imul__.py rename to array_api_tests/special_cases/test_dunder_imul.py index 9bfa9940..f781c27c 100644 --- a/array_api_tests/special_cases/test___imul__.py +++ b/array_api_tests/special_cases/test_dunder_imul.py @@ -20,7 +20,7 @@ @given(numeric_arrays, numeric_arrays) -def test___imul___special_cases_two_args_either(arg1, arg2): +def test_imul_special_cases_two_args_either(arg1, arg2): """ Special case test for `__imul__(self, other, /)`: @@ -34,7 +34,7 @@ def test___imul___special_cases_two_args_either(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___imul___special_cases_two_args_either__either_1(arg1, arg2): +def test_imul_special_cases_two_args_either__either_1(arg1, arg2): """ Special case test for `__imul__(self, other, /)`: @@ -48,7 +48,7 @@ def test___imul___special_cases_two_args_either__either_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___imul___special_cases_two_args_either__either_2(arg1, arg2): +def test_imul_special_cases_two_args_either__either_2(arg1, arg2): """ Special case test for `__imul__(self, other, /)`: @@ -62,7 +62,7 @@ def test___imul___special_cases_two_args_either__either_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___imul___special_cases_two_args_either__either_3(arg1, arg2): +def test_imul_special_cases_two_args_either__either_3(arg1, arg2): """ Special case test for `__imul__(self, other, /)`: @@ -76,7 +76,7 @@ def test___imul___special_cases_two_args_either__either_3(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___imul___special_cases_two_args_same_sign_except(arg1, arg2): +def test_imul_special_cases_two_args_same_sign_except(arg1, arg2): """ Special case test for `__imul__(self, other, /)`: @@ -90,7 +90,7 @@ def test___imul___special_cases_two_args_same_sign_except(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___imul___special_cases_two_args_different_signs_except(arg1, arg2): +def test_imul_special_cases_two_args_different_signs_except(arg1, arg2): """ Special case test for `__imul__(self, other, /)`: @@ -104,7 +104,7 @@ def test___imul___special_cases_two_args_different_signs_except(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___imul___special_cases_two_args_either__equal(arg1, arg2): +def test_imul_special_cases_two_args_either__equal(arg1, arg2): """ Special case test for `__imul__(self, other, /)`: @@ -118,7 +118,7 @@ def test___imul___special_cases_two_args_either__equal(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___imul___special_cases_two_args_equal__either(arg1, arg2): +def test_imul_special_cases_two_args_equal__either(arg1, arg2): """ Special case test for `__imul__(self, other, /)`: diff --git a/array_api_tests/special_cases/test___ipow__.py b/array_api_tests/special_cases/test_dunder_ipow.py similarity index 87% rename from array_api_tests/special_cases/test___ipow__.py rename to array_api_tests/special_cases/test_dunder_ipow.py index 83cb2f27..535adfc0 100644 --- a/array_api_tests/special_cases/test___ipow__.py +++ b/array_api_tests/special_cases/test_dunder_ipow.py @@ -18,7 +18,7 @@ @given(numeric_arrays, numeric_arrays) -def test___ipow___special_cases_two_args_notequal__equal(arg1, arg2): +def test_ipow_special_cases_two_args_notequal__equal(arg1, arg2): """ Special case test for `__ipow__(self, other, /)`: @@ -32,7 +32,7 @@ def test___ipow___special_cases_two_args_notequal__equal(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___ipow___special_cases_two_args_even_if_1(arg1, arg2): +def test_ipow_special_cases_two_args_even_if_1(arg1, arg2): """ Special case test for `__ipow__(self, other, /)`: @@ -46,7 +46,7 @@ def test___ipow___special_cases_two_args_even_if_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___ipow___special_cases_two_args_even_if_2(arg1, arg2): +def test_ipow_special_cases_two_args_even_if_2(arg1, arg2): """ Special case test for `__ipow__(self, other, /)`: @@ -60,7 +60,7 @@ def test___ipow___special_cases_two_args_even_if_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___ipow___special_cases_two_args_equal__notequal_1(arg1, arg2): +def test_ipow_special_cases_two_args_equal__notequal_1(arg1, arg2): """ Special case test for `__ipow__(self, other, /)`: @@ -74,7 +74,7 @@ def test___ipow___special_cases_two_args_equal__notequal_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___ipow___special_cases_two_args_equal__notequal_2(arg1, arg2): +def test_ipow_special_cases_two_args_equal__notequal_2(arg1, arg2): """ Special case test for `__ipow__(self, other, /)`: @@ -88,7 +88,7 @@ def test___ipow___special_cases_two_args_equal__notequal_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___ipow___special_cases_two_args_absgreater__equal_1(arg1, arg2): +def test_ipow_special_cases_two_args_absgreater__equal_1(arg1, arg2): """ Special case test for `__ipow__(self, other, /)`: @@ -102,7 +102,7 @@ def test___ipow___special_cases_two_args_absgreater__equal_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___ipow___special_cases_two_args_absgreater__equal_2(arg1, arg2): +def test_ipow_special_cases_two_args_absgreater__equal_2(arg1, arg2): """ Special case test for `__ipow__(self, other, /)`: @@ -116,7 +116,7 @@ def test___ipow___special_cases_two_args_absgreater__equal_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___ipow___special_cases_two_args_absequal__equal_1(arg1, arg2): +def test_ipow_special_cases_two_args_absequal__equal_1(arg1, arg2): """ Special case test for `__ipow__(self, other, /)`: @@ -130,7 +130,7 @@ def test___ipow___special_cases_two_args_absequal__equal_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___ipow___special_cases_two_args_absequal__equal_2(arg1, arg2): +def test_ipow_special_cases_two_args_absequal__equal_2(arg1, arg2): """ Special case test for `__ipow__(self, other, /)`: @@ -144,7 +144,7 @@ def test___ipow___special_cases_two_args_absequal__equal_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___ipow___special_cases_two_args_absless__equal_1(arg1, arg2): +def test_ipow_special_cases_two_args_absless__equal_1(arg1, arg2): """ Special case test for `__ipow__(self, other, /)`: @@ -158,7 +158,7 @@ def test___ipow___special_cases_two_args_absless__equal_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___ipow___special_cases_two_args_absless__equal_2(arg1, arg2): +def test_ipow_special_cases_two_args_absless__equal_2(arg1, arg2): """ Special case test for `__ipow__(self, other, /)`: @@ -172,7 +172,7 @@ def test___ipow___special_cases_two_args_absless__equal_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___ipow___special_cases_two_args_equal__greater_1(arg1, arg2): +def test_ipow_special_cases_two_args_equal__greater_1(arg1, arg2): """ Special case test for `__ipow__(self, other, /)`: @@ -186,7 +186,7 @@ def test___ipow___special_cases_two_args_equal__greater_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___ipow___special_cases_two_args_equal__greater_2(arg1, arg2): +def test_ipow_special_cases_two_args_equal__greater_2(arg1, arg2): """ Special case test for `__ipow__(self, other, /)`: @@ -200,7 +200,7 @@ def test___ipow___special_cases_two_args_equal__greater_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___ipow___special_cases_two_args_equal__less_1(arg1, arg2): +def test_ipow_special_cases_two_args_equal__less_1(arg1, arg2): """ Special case test for `__ipow__(self, other, /)`: @@ -214,7 +214,7 @@ def test___ipow___special_cases_two_args_equal__less_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___ipow___special_cases_two_args_equal__less_2(arg1, arg2): +def test_ipow_special_cases_two_args_equal__less_2(arg1, arg2): """ Special case test for `__ipow__(self, other, /)`: @@ -228,7 +228,7 @@ def test___ipow___special_cases_two_args_equal__less_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___ipow___special_cases_two_args_equal__greater_equal_1(arg1, arg2): +def test_ipow_special_cases_two_args_equal__greater_equal_1(arg1, arg2): """ Special case test for `__ipow__(self, other, /)`: @@ -242,7 +242,7 @@ def test___ipow___special_cases_two_args_equal__greater_equal_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___ipow___special_cases_two_args_equal__greater_equal_2(arg1, arg2): +def test_ipow_special_cases_two_args_equal__greater_equal_2(arg1, arg2): """ Special case test for `__ipow__(self, other, /)`: @@ -256,7 +256,7 @@ def test___ipow___special_cases_two_args_equal__greater_equal_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___ipow___special_cases_two_args_equal__greater_notequal_1(arg1, arg2): +def test_ipow_special_cases_two_args_equal__greater_notequal_1(arg1, arg2): """ Special case test for `__ipow__(self, other, /)`: @@ -270,7 +270,7 @@ def test___ipow___special_cases_two_args_equal__greater_notequal_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___ipow___special_cases_two_args_equal__greater_notequal_2(arg1, arg2): +def test_ipow_special_cases_two_args_equal__greater_notequal_2(arg1, arg2): """ Special case test for `__ipow__(self, other, /)`: @@ -284,7 +284,7 @@ def test___ipow___special_cases_two_args_equal__greater_notequal_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___ipow___special_cases_two_args_equal__less_equal_1(arg1, arg2): +def test_ipow_special_cases_two_args_equal__less_equal_1(arg1, arg2): """ Special case test for `__ipow__(self, other, /)`: @@ -298,7 +298,7 @@ def test___ipow___special_cases_two_args_equal__less_equal_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___ipow___special_cases_two_args_equal__less_equal_2(arg1, arg2): +def test_ipow_special_cases_two_args_equal__less_equal_2(arg1, arg2): """ Special case test for `__ipow__(self, other, /)`: @@ -312,7 +312,7 @@ def test___ipow___special_cases_two_args_equal__less_equal_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___ipow___special_cases_two_args_equal__less_notequal_1(arg1, arg2): +def test_ipow_special_cases_two_args_equal__less_notequal_1(arg1, arg2): """ Special case test for `__ipow__(self, other, /)`: @@ -326,7 +326,7 @@ def test___ipow___special_cases_two_args_equal__less_notequal_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___ipow___special_cases_two_args_equal__less_notequal_2(arg1, arg2): +def test_ipow_special_cases_two_args_equal__less_notequal_2(arg1, arg2): """ Special case test for `__ipow__(self, other, /)`: @@ -340,7 +340,7 @@ def test___ipow___special_cases_two_args_equal__less_notequal_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___ipow___special_cases_two_args_less_equal__equal_notequal(arg1, arg2): +def test_ipow_special_cases_two_args_less_equal__equal_notequal(arg1, arg2): """ Special case test for `__ipow__(self, other, /)`: diff --git a/array_api_tests/special_cases/test___itruediv__.py b/array_api_tests/special_cases/test_dunder_itruediv.py similarity index 88% rename from array_api_tests/special_cases/test___itruediv__.py rename to array_api_tests/special_cases/test_dunder_itruediv.py index cef5fa4e..44d41795 100644 --- a/array_api_tests/special_cases/test___itruediv__.py +++ b/array_api_tests/special_cases/test_dunder_itruediv.py @@ -20,7 +20,7 @@ @given(numeric_arrays, numeric_arrays) -def test___itruediv___special_cases_two_args_either(arg1, arg2): +def test_itruediv_special_cases_two_args_either(arg1, arg2): """ Special case test for `__itruediv__(self, other, /)`: @@ -34,7 +34,7 @@ def test___itruediv___special_cases_two_args_either(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___itruediv___special_cases_two_args_either__either_1(arg1, arg2): +def test_itruediv_special_cases_two_args_either__either_1(arg1, arg2): """ Special case test for `__itruediv__(self, other, /)`: @@ -48,7 +48,7 @@ def test___itruediv___special_cases_two_args_either__either_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___itruediv___special_cases_two_args_either__either_2(arg1, arg2): +def test_itruediv_special_cases_two_args_either__either_2(arg1, arg2): """ Special case test for `__itruediv__(self, other, /)`: @@ -62,7 +62,7 @@ def test___itruediv___special_cases_two_args_either__either_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___itruediv___special_cases_two_args_equal__greater_1(arg1, arg2): +def test_itruediv_special_cases_two_args_equal__greater_1(arg1, arg2): """ Special case test for `__itruediv__(self, other, /)`: @@ -76,7 +76,7 @@ def test___itruediv___special_cases_two_args_equal__greater_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___itruediv___special_cases_two_args_equal__greater_2(arg1, arg2): +def test_itruediv_special_cases_two_args_equal__greater_2(arg1, arg2): """ Special case test for `__itruediv__(self, other, /)`: @@ -90,7 +90,7 @@ def test___itruediv___special_cases_two_args_equal__greater_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___itruediv___special_cases_two_args_equal__less_1(arg1, arg2): +def test_itruediv_special_cases_two_args_equal__less_1(arg1, arg2): """ Special case test for `__itruediv__(self, other, /)`: @@ -104,7 +104,7 @@ def test___itruediv___special_cases_two_args_equal__less_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___itruediv___special_cases_two_args_equal__less_2(arg1, arg2): +def test_itruediv_special_cases_two_args_equal__less_2(arg1, arg2): """ Special case test for `__itruediv__(self, other, /)`: @@ -118,7 +118,7 @@ def test___itruediv___special_cases_two_args_equal__less_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___itruediv___special_cases_two_args_greater__equal_1(arg1, arg2): +def test_itruediv_special_cases_two_args_greater__equal_1(arg1, arg2): """ Special case test for `__itruediv__(self, other, /)`: @@ -132,7 +132,7 @@ def test___itruediv___special_cases_two_args_greater__equal_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___itruediv___special_cases_two_args_greater__equal_2(arg1, arg2): +def test_itruediv_special_cases_two_args_greater__equal_2(arg1, arg2): """ Special case test for `__itruediv__(self, other, /)`: @@ -146,7 +146,7 @@ def test___itruediv___special_cases_two_args_greater__equal_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___itruediv___special_cases_two_args_less__equal_1(arg1, arg2): +def test_itruediv_special_cases_two_args_less__equal_1(arg1, arg2): """ Special case test for `__itruediv__(self, other, /)`: @@ -160,7 +160,7 @@ def test___itruediv___special_cases_two_args_less__equal_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___itruediv___special_cases_two_args_less__equal_2(arg1, arg2): +def test_itruediv_special_cases_two_args_less__equal_2(arg1, arg2): """ Special case test for `__itruediv__(self, other, /)`: @@ -174,7 +174,7 @@ def test___itruediv___special_cases_two_args_less__equal_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___itruediv___special_cases_two_args_equal__equal_1(arg1, arg2): +def test_itruediv_special_cases_two_args_equal__equal_1(arg1, arg2): """ Special case test for `__itruediv__(self, other, /)`: @@ -188,7 +188,7 @@ def test___itruediv___special_cases_two_args_equal__equal_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___itruediv___special_cases_two_args_equal__equal_2(arg1, arg2): +def test_itruediv_special_cases_two_args_equal__equal_2(arg1, arg2): """ Special case test for `__itruediv__(self, other, /)`: @@ -202,7 +202,7 @@ def test___itruediv___special_cases_two_args_equal__equal_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___itruediv___special_cases_two_args_equal__equal_3(arg1, arg2): +def test_itruediv_special_cases_two_args_equal__equal_3(arg1, arg2): """ Special case test for `__itruediv__(self, other, /)`: @@ -216,7 +216,7 @@ def test___itruediv___special_cases_two_args_equal__equal_3(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___itruediv___special_cases_two_args_equal__equal_4(arg1, arg2): +def test_itruediv_special_cases_two_args_equal__equal_4(arg1, arg2): """ Special case test for `__itruediv__(self, other, /)`: @@ -230,7 +230,7 @@ def test___itruediv___special_cases_two_args_equal__equal_4(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___itruediv___special_cases_two_args_equal__equal_5(arg1, arg2): +def test_itruediv_special_cases_two_args_equal__equal_5(arg1, arg2): """ Special case test for `__itruediv__(self, other, /)`: @@ -244,7 +244,7 @@ def test___itruediv___special_cases_two_args_equal__equal_5(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___itruediv___special_cases_two_args_equal__equal_6(arg1, arg2): +def test_itruediv_special_cases_two_args_equal__equal_6(arg1, arg2): """ Special case test for `__itruediv__(self, other, /)`: @@ -258,7 +258,7 @@ def test___itruediv___special_cases_two_args_equal__equal_6(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___itruediv___special_cases_two_args_equal__equal_7(arg1, arg2): +def test_itruediv_special_cases_two_args_equal__equal_7(arg1, arg2): """ Special case test for `__itruediv__(self, other, /)`: @@ -272,7 +272,7 @@ def test___itruediv___special_cases_two_args_equal__equal_7(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___itruediv___special_cases_two_args_equal__equal_8(arg1, arg2): +def test_itruediv_special_cases_two_args_equal__equal_8(arg1, arg2): """ Special case test for `__itruediv__(self, other, /)`: @@ -286,7 +286,7 @@ def test___itruediv___special_cases_two_args_equal__equal_8(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___itruediv___special_cases_two_args_same_sign_both(arg1, arg2): +def test_itruediv_special_cases_two_args_same_sign_both(arg1, arg2): """ Special case test for `__itruediv__(self, other, /)`: @@ -300,7 +300,7 @@ def test___itruediv___special_cases_two_args_same_sign_both(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___itruediv___special_cases_two_args_different_signs_both(arg1, arg2): +def test_itruediv_special_cases_two_args_different_signs_both(arg1, arg2): """ Special case test for `__itruediv__(self, other, /)`: diff --git a/array_api_tests/special_cases/test___mul__.py b/array_api_tests/special_cases/test_dunder_mul.py similarity index 90% rename from array_api_tests/special_cases/test___mul__.py rename to array_api_tests/special_cases/test_dunder_mul.py index 110bf9a4..983f3654 100644 --- a/array_api_tests/special_cases/test___mul__.py +++ b/array_api_tests/special_cases/test_dunder_mul.py @@ -17,7 +17,7 @@ @given(numeric_arrays, numeric_arrays) -def test___mul___special_cases_two_args_either(arg1, arg2): +def test_mul_special_cases_two_args_either(arg1, arg2): """ Special case test for `__mul__(self, other, /)`: @@ -30,7 +30,7 @@ def test___mul___special_cases_two_args_either(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___mul___special_cases_two_args_either__either_1(arg1, arg2): +def test_mul_special_cases_two_args_either__either_1(arg1, arg2): """ Special case test for `__mul__(self, other, /)`: @@ -43,7 +43,7 @@ def test___mul___special_cases_two_args_either__either_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___mul___special_cases_two_args_either__either_2(arg1, arg2): +def test_mul_special_cases_two_args_either__either_2(arg1, arg2): """ Special case test for `__mul__(self, other, /)`: @@ -56,7 +56,7 @@ def test___mul___special_cases_two_args_either__either_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___mul___special_cases_two_args_either__either_3(arg1, arg2): +def test_mul_special_cases_two_args_either__either_3(arg1, arg2): """ Special case test for `__mul__(self, other, /)`: @@ -69,7 +69,7 @@ def test___mul___special_cases_two_args_either__either_3(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___mul___special_cases_two_args_same_sign_except(arg1, arg2): +def test_mul_special_cases_two_args_same_sign_except(arg1, arg2): """ Special case test for `__mul__(self, other, /)`: @@ -82,7 +82,7 @@ def test___mul___special_cases_two_args_same_sign_except(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___mul___special_cases_two_args_different_signs_except(arg1, arg2): +def test_mul_special_cases_two_args_different_signs_except(arg1, arg2): """ Special case test for `__mul__(self, other, /)`: @@ -95,7 +95,7 @@ def test___mul___special_cases_two_args_different_signs_except(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___mul___special_cases_two_args_either__equal(arg1, arg2): +def test_mul_special_cases_two_args_either__equal(arg1, arg2): """ Special case test for `__mul__(self, other, /)`: @@ -108,7 +108,7 @@ def test___mul___special_cases_two_args_either__equal(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___mul___special_cases_two_args_equal__either(arg1, arg2): +def test_mul_special_cases_two_args_equal__either(arg1, arg2): """ Special case test for `__mul__(self, other, /)`: diff --git a/array_api_tests/special_cases/test___pow__.py b/array_api_tests/special_cases/test_dunder_pow.py similarity index 86% rename from array_api_tests/special_cases/test___pow__.py rename to array_api_tests/special_cases/test_dunder_pow.py index 428137bc..b90abd4c 100644 --- a/array_api_tests/special_cases/test___pow__.py +++ b/array_api_tests/special_cases/test_dunder_pow.py @@ -15,7 +15,7 @@ @given(numeric_arrays, numeric_arrays) -def test___pow___special_cases_two_args_notequal__equal(arg1, arg2): +def test_pow_special_cases_two_args_notequal__equal(arg1, arg2): """ Special case test for `__pow__(self, other, /)`: @@ -28,7 +28,7 @@ def test___pow___special_cases_two_args_notequal__equal(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___pow___special_cases_two_args_even_if_1(arg1, arg2): +def test_pow_special_cases_two_args_even_if_1(arg1, arg2): """ Special case test for `__pow__(self, other, /)`: @@ -41,7 +41,7 @@ def test___pow___special_cases_two_args_even_if_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___pow___special_cases_two_args_even_if_2(arg1, arg2): +def test_pow_special_cases_two_args_even_if_2(arg1, arg2): """ Special case test for `__pow__(self, other, /)`: @@ -54,7 +54,7 @@ def test___pow___special_cases_two_args_even_if_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___pow___special_cases_two_args_equal__notequal_1(arg1, arg2): +def test_pow_special_cases_two_args_equal__notequal_1(arg1, arg2): """ Special case test for `__pow__(self, other, /)`: @@ -67,7 +67,7 @@ def test___pow___special_cases_two_args_equal__notequal_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___pow___special_cases_two_args_equal__notequal_2(arg1, arg2): +def test_pow_special_cases_two_args_equal__notequal_2(arg1, arg2): """ Special case test for `__pow__(self, other, /)`: @@ -80,7 +80,7 @@ def test___pow___special_cases_two_args_equal__notequal_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___pow___special_cases_two_args_absgreater__equal_1(arg1, arg2): +def test_pow_special_cases_two_args_absgreater__equal_1(arg1, arg2): """ Special case test for `__pow__(self, other, /)`: @@ -93,7 +93,7 @@ def test___pow___special_cases_two_args_absgreater__equal_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___pow___special_cases_two_args_absgreater__equal_2(arg1, arg2): +def test_pow_special_cases_two_args_absgreater__equal_2(arg1, arg2): """ Special case test for `__pow__(self, other, /)`: @@ -106,7 +106,7 @@ def test___pow___special_cases_two_args_absgreater__equal_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___pow___special_cases_two_args_absequal__equal_1(arg1, arg2): +def test_pow_special_cases_two_args_absequal__equal_1(arg1, arg2): """ Special case test for `__pow__(self, other, /)`: @@ -119,7 +119,7 @@ def test___pow___special_cases_two_args_absequal__equal_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___pow___special_cases_two_args_absequal__equal_2(arg1, arg2): +def test_pow_special_cases_two_args_absequal__equal_2(arg1, arg2): """ Special case test for `__pow__(self, other, /)`: @@ -132,7 +132,7 @@ def test___pow___special_cases_two_args_absequal__equal_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___pow___special_cases_two_args_absless__equal_1(arg1, arg2): +def test_pow_special_cases_two_args_absless__equal_1(arg1, arg2): """ Special case test for `__pow__(self, other, /)`: @@ -145,7 +145,7 @@ def test___pow___special_cases_two_args_absless__equal_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___pow___special_cases_two_args_absless__equal_2(arg1, arg2): +def test_pow_special_cases_two_args_absless__equal_2(arg1, arg2): """ Special case test for `__pow__(self, other, /)`: @@ -158,7 +158,7 @@ def test___pow___special_cases_two_args_absless__equal_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___pow___special_cases_two_args_equal__greater_1(arg1, arg2): +def test_pow_special_cases_two_args_equal__greater_1(arg1, arg2): """ Special case test for `__pow__(self, other, /)`: @@ -171,7 +171,7 @@ def test___pow___special_cases_two_args_equal__greater_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___pow___special_cases_two_args_equal__greater_2(arg1, arg2): +def test_pow_special_cases_two_args_equal__greater_2(arg1, arg2): """ Special case test for `__pow__(self, other, /)`: @@ -184,7 +184,7 @@ def test___pow___special_cases_two_args_equal__greater_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___pow___special_cases_two_args_equal__less_1(arg1, arg2): +def test_pow_special_cases_two_args_equal__less_1(arg1, arg2): """ Special case test for `__pow__(self, other, /)`: @@ -197,7 +197,7 @@ def test___pow___special_cases_two_args_equal__less_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___pow___special_cases_two_args_equal__less_2(arg1, arg2): +def test_pow_special_cases_two_args_equal__less_2(arg1, arg2): """ Special case test for `__pow__(self, other, /)`: @@ -210,7 +210,7 @@ def test___pow___special_cases_two_args_equal__less_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___pow___special_cases_two_args_equal__greater_equal_1(arg1, arg2): +def test_pow_special_cases_two_args_equal__greater_equal_1(arg1, arg2): """ Special case test for `__pow__(self, other, /)`: @@ -223,7 +223,7 @@ def test___pow___special_cases_two_args_equal__greater_equal_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___pow___special_cases_two_args_equal__greater_equal_2(arg1, arg2): +def test_pow_special_cases_two_args_equal__greater_equal_2(arg1, arg2): """ Special case test for `__pow__(self, other, /)`: @@ -236,7 +236,7 @@ def test___pow___special_cases_two_args_equal__greater_equal_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___pow___special_cases_two_args_equal__greater_notequal_1(arg1, arg2): +def test_pow_special_cases_two_args_equal__greater_notequal_1(arg1, arg2): """ Special case test for `__pow__(self, other, /)`: @@ -249,7 +249,7 @@ def test___pow___special_cases_two_args_equal__greater_notequal_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___pow___special_cases_two_args_equal__greater_notequal_2(arg1, arg2): +def test_pow_special_cases_two_args_equal__greater_notequal_2(arg1, arg2): """ Special case test for `__pow__(self, other, /)`: @@ -262,7 +262,7 @@ def test___pow___special_cases_two_args_equal__greater_notequal_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___pow___special_cases_two_args_equal__less_equal_1(arg1, arg2): +def test_pow_special_cases_two_args_equal__less_equal_1(arg1, arg2): """ Special case test for `__pow__(self, other, /)`: @@ -275,7 +275,7 @@ def test___pow___special_cases_two_args_equal__less_equal_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___pow___special_cases_two_args_equal__less_equal_2(arg1, arg2): +def test_pow_special_cases_two_args_equal__less_equal_2(arg1, arg2): """ Special case test for `__pow__(self, other, /)`: @@ -288,7 +288,7 @@ def test___pow___special_cases_two_args_equal__less_equal_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___pow___special_cases_two_args_equal__less_notequal_1(arg1, arg2): +def test_pow_special_cases_two_args_equal__less_notequal_1(arg1, arg2): """ Special case test for `__pow__(self, other, /)`: @@ -301,7 +301,7 @@ def test___pow___special_cases_two_args_equal__less_notequal_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___pow___special_cases_two_args_equal__less_notequal_2(arg1, arg2): +def test_pow_special_cases_two_args_equal__less_notequal_2(arg1, arg2): """ Special case test for `__pow__(self, other, /)`: @@ -314,7 +314,7 @@ def test___pow___special_cases_two_args_equal__less_notequal_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___pow___special_cases_two_args_less_equal__equal_notequal(arg1, arg2): +def test_pow_special_cases_two_args_less_equal__equal_notequal(arg1, arg2): """ Special case test for `__pow__(self, other, /)`: diff --git a/array_api_tests/special_cases/test___truediv__.py b/array_api_tests/special_cases/test_dunder_truediv.py similarity index 87% rename from array_api_tests/special_cases/test___truediv__.py rename to array_api_tests/special_cases/test_dunder_truediv.py index a32de039..d08302f2 100644 --- a/array_api_tests/special_cases/test___truediv__.py +++ b/array_api_tests/special_cases/test_dunder_truediv.py @@ -17,7 +17,7 @@ @given(numeric_arrays, numeric_arrays) -def test___truediv___special_cases_two_args_either(arg1, arg2): +def test_truediv_special_cases_two_args_either(arg1, arg2): """ Special case test for `__truediv__(self, other, /)`: @@ -30,7 +30,7 @@ def test___truediv___special_cases_two_args_either(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___truediv___special_cases_two_args_either__either_1(arg1, arg2): +def test_truediv_special_cases_two_args_either__either_1(arg1, arg2): """ Special case test for `__truediv__(self, other, /)`: @@ -43,7 +43,7 @@ def test___truediv___special_cases_two_args_either__either_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___truediv___special_cases_two_args_either__either_2(arg1, arg2): +def test_truediv_special_cases_two_args_either__either_2(arg1, arg2): """ Special case test for `__truediv__(self, other, /)`: @@ -56,7 +56,7 @@ def test___truediv___special_cases_two_args_either__either_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___truediv___special_cases_two_args_equal__greater_1(arg1, arg2): +def test_truediv_special_cases_two_args_equal__greater_1(arg1, arg2): """ Special case test for `__truediv__(self, other, /)`: @@ -69,7 +69,7 @@ def test___truediv___special_cases_two_args_equal__greater_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___truediv___special_cases_two_args_equal__greater_2(arg1, arg2): +def test_truediv_special_cases_two_args_equal__greater_2(arg1, arg2): """ Special case test for `__truediv__(self, other, /)`: @@ -82,7 +82,7 @@ def test___truediv___special_cases_two_args_equal__greater_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___truediv___special_cases_two_args_equal__less_1(arg1, arg2): +def test_truediv_special_cases_two_args_equal__less_1(arg1, arg2): """ Special case test for `__truediv__(self, other, /)`: @@ -95,7 +95,7 @@ def test___truediv___special_cases_two_args_equal__less_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___truediv___special_cases_two_args_equal__less_2(arg1, arg2): +def test_truediv_special_cases_two_args_equal__less_2(arg1, arg2): """ Special case test for `__truediv__(self, other, /)`: @@ -108,7 +108,7 @@ def test___truediv___special_cases_two_args_equal__less_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___truediv___special_cases_two_args_greater__equal_1(arg1, arg2): +def test_truediv_special_cases_two_args_greater__equal_1(arg1, arg2): """ Special case test for `__truediv__(self, other, /)`: @@ -121,7 +121,7 @@ def test___truediv___special_cases_two_args_greater__equal_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___truediv___special_cases_two_args_greater__equal_2(arg1, arg2): +def test_truediv_special_cases_two_args_greater__equal_2(arg1, arg2): """ Special case test for `__truediv__(self, other, /)`: @@ -134,7 +134,7 @@ def test___truediv___special_cases_two_args_greater__equal_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___truediv___special_cases_two_args_less__equal_1(arg1, arg2): +def test_truediv_special_cases_two_args_less__equal_1(arg1, arg2): """ Special case test for `__truediv__(self, other, /)`: @@ -147,7 +147,7 @@ def test___truediv___special_cases_two_args_less__equal_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___truediv___special_cases_two_args_less__equal_2(arg1, arg2): +def test_truediv_special_cases_two_args_less__equal_2(arg1, arg2): """ Special case test for `__truediv__(self, other, /)`: @@ -160,7 +160,7 @@ def test___truediv___special_cases_two_args_less__equal_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___truediv___special_cases_two_args_equal__equal_1(arg1, arg2): +def test_truediv_special_cases_two_args_equal__equal_1(arg1, arg2): """ Special case test for `__truediv__(self, other, /)`: @@ -173,7 +173,7 @@ def test___truediv___special_cases_two_args_equal__equal_1(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___truediv___special_cases_two_args_equal__equal_2(arg1, arg2): +def test_truediv_special_cases_two_args_equal__equal_2(arg1, arg2): """ Special case test for `__truediv__(self, other, /)`: @@ -186,7 +186,7 @@ def test___truediv___special_cases_two_args_equal__equal_2(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___truediv___special_cases_two_args_equal__equal_3(arg1, arg2): +def test_truediv_special_cases_two_args_equal__equal_3(arg1, arg2): """ Special case test for `__truediv__(self, other, /)`: @@ -199,7 +199,7 @@ def test___truediv___special_cases_two_args_equal__equal_3(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___truediv___special_cases_two_args_equal__equal_4(arg1, arg2): +def test_truediv_special_cases_two_args_equal__equal_4(arg1, arg2): """ Special case test for `__truediv__(self, other, /)`: @@ -212,7 +212,7 @@ def test___truediv___special_cases_two_args_equal__equal_4(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___truediv___special_cases_two_args_equal__equal_5(arg1, arg2): +def test_truediv_special_cases_two_args_equal__equal_5(arg1, arg2): """ Special case test for `__truediv__(self, other, /)`: @@ -225,7 +225,7 @@ def test___truediv___special_cases_two_args_equal__equal_5(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___truediv___special_cases_two_args_equal__equal_6(arg1, arg2): +def test_truediv_special_cases_two_args_equal__equal_6(arg1, arg2): """ Special case test for `__truediv__(self, other, /)`: @@ -238,7 +238,7 @@ def test___truediv___special_cases_two_args_equal__equal_6(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___truediv___special_cases_two_args_equal__equal_7(arg1, arg2): +def test_truediv_special_cases_two_args_equal__equal_7(arg1, arg2): """ Special case test for `__truediv__(self, other, /)`: @@ -251,7 +251,7 @@ def test___truediv___special_cases_two_args_equal__equal_7(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___truediv___special_cases_two_args_equal__equal_8(arg1, arg2): +def test_truediv_special_cases_two_args_equal__equal_8(arg1, arg2): """ Special case test for `__truediv__(self, other, /)`: @@ -264,7 +264,7 @@ def test___truediv___special_cases_two_args_equal__equal_8(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___truediv___special_cases_two_args_same_sign_both(arg1, arg2): +def test_truediv_special_cases_two_args_same_sign_both(arg1, arg2): """ Special case test for `__truediv__(self, other, /)`: @@ -277,7 +277,7 @@ def test___truediv___special_cases_two_args_same_sign_both(arg1, arg2): @given(numeric_arrays, numeric_arrays) -def test___truediv___special_cases_two_args_different_signs_both(arg1, arg2): +def test_truediv_special_cases_two_args_different_signs_both(arg1, arg2): """ Special case test for `__truediv__(self, other, /)`: diff --git a/generate_stubs.py b/generate_stubs.py index f750d9eb..e529f5ec 100755 --- a/generate_stubs.py +++ b/generate_stubs.py @@ -11,11 +11,11 @@ """ import argparse import os -import sys import ast import itertools from collections import defaultdict from typing import DefaultDict, Dict, List +from pathlib import Path import regex from removestar.removestar import fix_code @@ -222,6 +222,10 @@ def main(): with open(types_path, 'w') as f: f.write(TYPES_HEADER) + special_cases_dir = Path('array_api_tests/special_cases') + special_cases_dir.mkdir(exist_ok=True) + (special_cases_dir / '__init__.py').touch() + spec_dir = os.path.join(args.array_api_repo, 'spec', 'API_specification') extensions_dir = os.path.join(args.array_api_repo, 'spec', 'extensions') files = sorted([os.path.join(spec_dir, f) for f in os.listdir(spec_dir)] @@ -333,26 +337,12 @@ def {annotated_sig}:{doc} if args.write: with open(py_path, 'w') as f: f.write(code) + if filename == 'elementwise_functions.md': special_cases = parse_special_cases(text, verbose=args.verbose) for func in special_cases: py_path = os.path.join('array_api_tests', 'special_cases', f'test_{func}.py') - tests = [] - for typ in special_cases[func]: - multiple = len(special_cases[func][typ]) > 1 - for i, m in enumerate(special_cases[func][typ], 1): - test_name_extra = typ.lower() - if multiple: - test_name_extra += f"_{i}" - try: - test = generate_special_case_test(func, typ, m, - test_name_extra, sigs) - if test is None: - raise NotImplementedError("Special case test not implemented") - tests.append(test) - except: - print(f"Error with {func}() {typ}: {m.group(0)}:\n", file=sys.stderr) - raise + tests = make_special_case_tests(func, special_cases, sigs) if tests: code = SPECIAL_CASES_HEADER.format(func=func) + '\n'.join(tests) # quiet=False will make it print a warning if a name is not found (indicating an error) @@ -361,44 +351,30 @@ def {annotated_sig}:{doc} with open(py_path, 'w') as f: f.write(code) elif filename == 'array_object.md': - special_cases = parse_special_cases(text, verbose=args.verbose) + op_special_cases = parse_special_cases(text, verbose=args.verbose) + for func in op_special_cases: + py_path = os.path.join('array_api_tests', 'special_cases', f'test_dunder_{func[2:-2]}.py') + tests = make_special_case_tests(func, op_special_cases, sigs) + if tests: + code = OP_SPECIAL_CASES_HEADER.format(func=func) + '\n'.join(tests) + code = fix_code(code, file=py_path, verbose=False, quiet=False) + if args.write: + with open(py_path, 'w') as f: + f.write(code) + iop_special_cases = {} for name in IN_PLACE_OPERATOR_RE.findall(text): op = f"__{name}__" iop = f"__i{name}__" - special_cases[iop] = special_cases[op] - for func in special_cases: - py_path = os.path.join('array_api_tests', 'special_cases', f'test_{func}.py') - tests = [] - for typ in special_cases[func]: - multiple = len(special_cases[func][typ]) > 1 - for i, m in enumerate(special_cases[func][typ], 1): - test_name_extra = typ.lower() - if multiple: - test_name_extra += f"_{i}" - try: - test = generate_special_case_test(func, typ, m, - test_name_extra, sigs) - if test is None: - raise NotImplementedError("Special case test not implemented") - tests.append(test) - except: - print(f"Error with {func}() {typ}: {m.group(0)}:\n", file=sys.stderr) - raise + iop_special_cases[iop] = op_special_cases[op] + for func in iop_special_cases: + py_path = os.path.join('array_api_tests', 'special_cases', f'test_dunder_{func[2:-2]}.py') + tests = make_special_case_tests(func, iop_special_cases, sigs) if tests: - if func in IOPS: - code = IOP_SPECIAL_CASES_HEADER.format(func=func, operator=func[2:-2]) + '\n'.join(tests) - # quiet=False will make it print a warning if a name is not found (indicating an error) - code = fix_code(code, file=py_path, verbose=False, quiet=False) - if args.write: - with open(py_path, 'w') as f: - f.write(code) - else: - code = OP_SPECIAL_CASES_HEADER.format(func=func) + '\n'.join(tests) - # quiet=False will make it print a warning if a name is not found (indicating an error) - code = fix_code(code, file=py_path, verbose=False, quiet=False) - if args.write: - with open(py_path, 'w') as f: - f.write(code) + code = IOP_SPECIAL_CASES_HEADER.format(func=func, operator=func[2:-2]) + '\n'.join(tests) + code = fix_code(code, file=py_path, verbose=False, quiet=False) + if args.write: + with open(py_path, 'w') as f: + f.write(code) init_path = os.path.join('array_api_tests', 'function_stubs', '__init__.py') if args.write: @@ -607,7 +583,7 @@ def test_{func}_special_cases_{test_name_extra}(arg1, arg2): OP_ONE_ARG_TEMPLATE = """ {decorator} -def test_{func}_special_cases_{test_name_extra}(arg1): +def test_{op}_special_cases_{test_name_extra}(arg1): {doc} res = (arg1).{func}() mask = {mask} @@ -616,7 +592,7 @@ def test_{func}_special_cases_{test_name_extra}(arg1): OP_TWO_ARGS_TEMPLATE = """ {decorator} -def test_{func}_special_cases_{test_name_extra}(arg1, arg2): +def test_{op}_special_cases_{test_name_extra}(arg1, arg2): {doc} res = arg1.{func}(arg2) mask = {mask} @@ -625,10 +601,10 @@ def test_{func}_special_cases_{test_name_extra}(arg1, arg2): IOP_TWO_ARGS_TEMPLATE = """ {decorator} -def test_{func}_special_cases_{test_name_extra}(arg1, arg2): +def test_{op}_special_cases_{test_name_extra}(arg1, arg2): {doc} res = xp.asarray(arg1, copy=True) - {operator}(res, arg2) + {op}(res, arg2) mask = {mask} {assertion} """ @@ -678,6 +654,7 @@ def generate_special_case_test(func, typ, m, test_name_extra, sigs): return OP_ONE_ARG_TEMPLATE.format( decorator=decorator, func=func, + op=func[2:-2], test_name_extra=test_name_extra, doc=doc, mask=mask, @@ -803,6 +780,7 @@ def generate_special_case_test(func, typ, m, test_name_extra, sigs): return OP_TWO_ARGS_TEMPLATE.format( decorator=decorator, func=func, + op=func[2:-2], test_name_extra=test_name_extra, doc=doc, mask=mask, @@ -812,9 +790,9 @@ def generate_special_case_test(func, typ, m, test_name_extra, sigs): return IOP_TWO_ARGS_TEMPLATE.format( decorator=decorator, func=func, + op=func[2:-2], test_name_extra=test_name_extra, doc=doc, - operator=func[2:-2], mask=mask, assertion=assertion, ) @@ -866,6 +844,20 @@ def parse_special_cases(spec_text, verbose=False) -> Dict[str, DefaultDict[str, return special_cases +def make_special_case_tests(func, special_cases: Dict[str, DefaultDict[str, List[regex.Match]]], sigs) -> List[str]: + tests = [] + for typ in special_cases[func]: + multiple = len(special_cases[func][typ]) > 1 + for i, m in enumerate(special_cases[func][typ], 1): + test_name_extra = typ.lower() + if multiple: + test_name_extra += f"_{i}" + test = generate_special_case_test(func, typ, m, test_name_extra, sigs) + assert test is not None # sanity check + tests.append(test) + return tests + + PARAMETER_RE = regex.compile(r"- +\*\*(.*)\*\*: _(.*)_") def parse_annotations(spec_text, all_annotations, verbose=False): annotations = defaultdict(dict) From 3e3b166e8abe95a706931558a890a12c98a81288 Mon Sep 17 00:00:00 2001 From: Matthew Date: Mon, 8 Nov 2021 15:34:05 +0000 Subject: [PATCH 7/7] Use `asarray()` from `array_helpers.py` --- .../special_cases/test_dunder_iadd.py | 35 ++++++------ .../special_cases/test_dunder_imul.py | 19 ++++--- .../special_cases/test_dunder_ipow.py | 54 +++++++++---------- .../special_cases/test_dunder_itruediv.py | 45 ++++++++-------- generate_stubs.py | 3 +- 5 files changed, 76 insertions(+), 80 deletions(-) diff --git a/array_api_tests/special_cases/test_dunder_iadd.py b/array_api_tests/special_cases/test_dunder_iadd.py index 42d80f5f..692877bf 100644 --- a/array_api_tests/special_cases/test_dunder_iadd.py +++ b/array_api_tests/special_cases/test_dunder_iadd.py @@ -9,10 +9,9 @@ from operator import iadd -from ..array_helpers import (NaN, assert_exactly_equal, exactly_equal, infinity, isfinite, +from ..array_helpers import (NaN, asarray, assert_exactly_equal, exactly_equal, infinity, isfinite, logical_and, logical_or, non_zero, zero) from ..hypothesis_helpers import numeric_arrays -from .. import _array_module as xp from hypothesis import given @@ -25,7 +24,7 @@ def test_iadd_special_cases_two_args_either(arg1, arg2): - If either `x1_i` or `x2_i` is `NaN`, the result is `NaN`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) iadd(res, arg2) mask = logical_or(exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)), exactly_equal(arg2, NaN(arg1.shape, arg1.dtype))) assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) @@ -39,7 +38,7 @@ def test_iadd_special_cases_two_args_equal__equal_1(arg1, arg2): - If `x1_i` is `+infinity` and `x2_i` is `-infinity`, the result is `NaN`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) iadd(res, arg2) mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) @@ -53,7 +52,7 @@ def test_iadd_special_cases_two_args_equal__equal_2(arg1, arg2): - If `x1_i` is `-infinity` and `x2_i` is `+infinity`, the result is `NaN`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) iadd(res, arg2) mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) @@ -67,7 +66,7 @@ def test_iadd_special_cases_two_args_equal__equal_3(arg1, arg2): - If `x1_i` is `+infinity` and `x2_i` is `+infinity`, the result is `+infinity`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) iadd(res, arg2) mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) @@ -81,7 +80,7 @@ def test_iadd_special_cases_two_args_equal__equal_4(arg1, arg2): - If `x1_i` is `-infinity` and `x2_i` is `-infinity`, the result is `-infinity`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) iadd(res, arg2) mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) @@ -95,7 +94,7 @@ def test_iadd_special_cases_two_args_equal__equal_5(arg1, arg2): - If `x1_i` is `+infinity` and `x2_i` is a finite number, the result is `+infinity`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) iadd(res, arg2) mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), isfinite(arg2)) assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) @@ -109,7 +108,7 @@ def test_iadd_special_cases_two_args_equal__equal_6(arg1, arg2): - If `x1_i` is `-infinity` and `x2_i` is a finite number, the result is `-infinity`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) iadd(res, arg2) mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), isfinite(arg2)) assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) @@ -123,7 +122,7 @@ def test_iadd_special_cases_two_args_equal__equal_7(arg1, arg2): - If `x1_i` is a finite number and `x2_i` is `+infinity`, the result is `+infinity`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) iadd(res, arg2) mask = logical_and(isfinite(arg1), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) @@ -137,7 +136,7 @@ def test_iadd_special_cases_two_args_equal__equal_8(arg1, arg2): - If `x1_i` is a finite number and `x2_i` is `-infinity`, the result is `-infinity`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) iadd(res, arg2) mask = logical_and(isfinite(arg1), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) @@ -151,7 +150,7 @@ def test_iadd_special_cases_two_args_equal__equal_9(arg1, arg2): - If `x1_i` is `-0` and `x2_i` is `-0`, the result is `-0`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) iadd(res, arg2) mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) @@ -165,7 +164,7 @@ def test_iadd_special_cases_two_args_equal__equal_10(arg1, arg2): - If `x1_i` is `-0` and `x2_i` is `+0`, the result is `+0`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) iadd(res, arg2) mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, zero(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) @@ -179,7 +178,7 @@ def test_iadd_special_cases_two_args_equal__equal_11(arg1, arg2): - If `x1_i` is `+0` and `x2_i` is `-0`, the result is `+0`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) iadd(res, arg2) mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) @@ -193,7 +192,7 @@ def test_iadd_special_cases_two_args_equal__equal_12(arg1, arg2): - If `x1_i` is `+0` and `x2_i` is `+0`, the result is `+0`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) iadd(res, arg2) mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, zero(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) @@ -207,7 +206,7 @@ def test_iadd_special_cases_two_args_equal__equal_13(arg1, arg2): - If `x1_i` is a nonzero finite number and `x2_i` is `-x1_i`, the result is `+0`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) iadd(res, arg2) mask = logical_and(logical_and(isfinite(arg1), non_zero(arg1)), exactly_equal(arg2, -arg1)) assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) @@ -221,7 +220,7 @@ def test_iadd_special_cases_two_args_either__equal(arg1, arg2): - If `x1_i` is either `+0` or `-0` and `x2_i` is a nonzero finite number, the result is `x2_i`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) iadd(res, arg2) mask = logical_and(logical_or(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg1, -zero(arg1.shape, arg1.dtype))), logical_and(isfinite(arg2), non_zero(arg2))) assert_exactly_equal(res[mask], (arg2)[mask]) @@ -235,7 +234,7 @@ def test_iadd_special_cases_two_args_equal__either(arg1, arg2): - If `x1_i` is a nonzero finite number and `x2_i` is either `+0` or `-0`, the result is `x1_i`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) iadd(res, arg2) mask = logical_and(logical_and(isfinite(arg1), non_zero(arg1)), logical_or(exactly_equal(arg2, zero(arg2.shape, arg2.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype)))) assert_exactly_equal(res[mask], (arg1)[mask]) diff --git a/array_api_tests/special_cases/test_dunder_imul.py b/array_api_tests/special_cases/test_dunder_imul.py index f781c27c..a077fb9a 100644 --- a/array_api_tests/special_cases/test_dunder_imul.py +++ b/array_api_tests/special_cases/test_dunder_imul.py @@ -9,12 +9,11 @@ from operator import imul -from ..array_helpers import (NaN, assert_exactly_equal, assert_isinf, +from ..array_helpers import (NaN, asarray, assert_exactly_equal, assert_isinf, assert_negative_mathematical_sign, assert_positive_mathematical_sign, exactly_equal, infinity, isfinite, logical_and, logical_not, logical_or, non_zero, same_sign, zero) from ..hypothesis_helpers import numeric_arrays -from .. import _array_module as xp from hypothesis import given @@ -27,7 +26,7 @@ def test_imul_special_cases_two_args_either(arg1, arg2): - If either `x1_i` or `x2_i` is `NaN`, the result is `NaN`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) imul(res, arg2) mask = logical_or(exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)), exactly_equal(arg2, NaN(arg1.shape, arg1.dtype))) assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) @@ -41,7 +40,7 @@ def test_imul_special_cases_two_args_either__either_1(arg1, arg2): - If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is either `+0` or `-0`, the result is `NaN`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) imul(res, arg2) mask = logical_and(logical_or(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype))), logical_or(exactly_equal(arg2, zero(arg2.shape, arg2.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype)))) assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) @@ -55,7 +54,7 @@ def test_imul_special_cases_two_args_either__either_2(arg1, arg2): - If `x1_i` is either `+0` or `-0` and `x2_i` is either `+infinity` or `-infinity`, the result is `NaN`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) imul(res, arg2) mask = logical_and(logical_or(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg1, -zero(arg1.shape, arg1.dtype))), logical_or(exactly_equal(arg2, infinity(arg2.shape, arg2.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype)))) assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) @@ -69,7 +68,7 @@ def test_imul_special_cases_two_args_either__either_3(arg1, arg2): - If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is either `+infinity` or `-infinity`, the result is a signed infinity with the mathematical sign determined by the rule already stated above. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) imul(res, arg2) mask = logical_and(logical_or(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype))), logical_or(exactly_equal(arg2, infinity(arg2.shape, arg2.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype)))) assert_isinf(res[mask]) @@ -83,7 +82,7 @@ def test_imul_special_cases_two_args_same_sign_except(arg1, arg2): - If `x1_i` and `x2_i` have the same mathematical sign, the result has a positive mathematical sign, unless the result is `NaN`. If the result is `NaN`, the "sign" of `NaN` is implementation-defined. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) imul(res, arg2) mask = logical_and(same_sign(arg1, arg2), logical_not(exactly_equal(res, NaN(res.shape, res.dtype)))) assert_positive_mathematical_sign(res[mask]) @@ -97,7 +96,7 @@ def test_imul_special_cases_two_args_different_signs_except(arg1, arg2): - If `x1_i` and `x2_i` have different mathematical signs, the result has a negative mathematical sign, unless the result is `NaN`. If the result is `NaN`, the "sign" of `NaN` is implementation-defined. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) imul(res, arg2) mask = logical_and(logical_not(same_sign(arg1, arg2)), logical_not(exactly_equal(res, NaN(res.shape, res.dtype)))) assert_negative_mathematical_sign(res[mask]) @@ -111,7 +110,7 @@ def test_imul_special_cases_two_args_either__equal(arg1, arg2): - If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is a nonzero finite number, the result is a signed infinity with the mathematical sign determined by the rule already stated above. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) imul(res, arg2) mask = logical_and(logical_or(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype))), logical_and(isfinite(arg2), non_zero(arg2))) assert_isinf(res[mask]) @@ -125,7 +124,7 @@ def test_imul_special_cases_two_args_equal__either(arg1, arg2): - If `x1_i` is a nonzero finite number and `x2_i` is either `+infinity` or `-infinity`, the result is a signed infinity with the mathematical sign determined by the rule already stated above. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) imul(res, arg2) mask = logical_and(logical_and(isfinite(arg1), non_zero(arg1)), logical_or(exactly_equal(arg2, infinity(arg2.shape, arg2.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype)))) assert_isinf(res[mask]) diff --git a/array_api_tests/special_cases/test_dunder_ipow.py b/array_api_tests/special_cases/test_dunder_ipow.py index 535adfc0..0ca5e705 100644 --- a/array_api_tests/special_cases/test_dunder_ipow.py +++ b/array_api_tests/special_cases/test_dunder_ipow.py @@ -9,10 +9,10 @@ from operator import ipow -from ..array_helpers import (NaN, assert_exactly_equal, exactly_equal, greater, infinity, isfinite, - isintegral, isodd, less, logical_and, logical_not, notequal, one, zero) +from ..array_helpers import (NaN, asarray, assert_exactly_equal, exactly_equal, greater, infinity, + isfinite, isintegral, isodd, less, logical_and, logical_not, notequal, + one, zero) from ..hypothesis_helpers import numeric_arrays -from .. import _array_module as xp from hypothesis import given @@ -25,7 +25,7 @@ def test_ipow_special_cases_two_args_notequal__equal(arg1, arg2): - If `x1_i` is not equal to `1` and `x2_i` is `NaN`, the result is `NaN`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) ipow(res, arg2) mask = logical_and(logical_not(exactly_equal(arg1, one(arg1.shape, arg1.dtype))), exactly_equal(arg2, NaN(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) @@ -39,7 +39,7 @@ def test_ipow_special_cases_two_args_even_if_1(arg1, arg2): - If `x2_i` is `+0`, the result is `1`, even if `x1_i` is `NaN`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) ipow(res, arg2) mask = exactly_equal(arg2, zero(arg2.shape, arg2.dtype)) assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) @@ -53,7 +53,7 @@ def test_ipow_special_cases_two_args_even_if_2(arg1, arg2): - If `x2_i` is `-0`, the result is `1`, even if `x1_i` is `NaN`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) ipow(res, arg2) mask = exactly_equal(arg2, -zero(arg2.shape, arg2.dtype)) assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) @@ -67,7 +67,7 @@ def test_ipow_special_cases_two_args_equal__notequal_1(arg1, arg2): - If `x1_i` is `NaN` and `x2_i` is not equal to `0`, the result is `NaN`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) ipow(res, arg2) mask = logical_and(exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)), notequal(arg2, zero(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) @@ -81,7 +81,7 @@ def test_ipow_special_cases_two_args_equal__notequal_2(arg1, arg2): - If `x1_i` is `1` and `x2_i` is not `NaN`, the result is `1`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) ipow(res, arg2) mask = logical_and(exactly_equal(arg1, one(arg1.shape, arg1.dtype)), logical_not(exactly_equal(arg2, NaN(arg2.shape, arg2.dtype)))) assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) @@ -95,7 +95,7 @@ def test_ipow_special_cases_two_args_absgreater__equal_1(arg1, arg2): - If `abs(x1_i)` is greater than `1` and `x2_i` is `+infinity`, the result is `+infinity`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) ipow(res, arg2) mask = logical_and(greater(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) @@ -109,7 +109,7 @@ def test_ipow_special_cases_two_args_absgreater__equal_2(arg1, arg2): - If `abs(x1_i)` is greater than `1` and `x2_i` is `-infinity`, the result is `+0`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) ipow(res, arg2) mask = logical_and(greater(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) @@ -123,7 +123,7 @@ def test_ipow_special_cases_two_args_absequal__equal_1(arg1, arg2): - If `abs(x1_i)` is `1` and `x2_i` is `+infinity`, the result is `1`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) ipow(res, arg2) mask = logical_and(exactly_equal(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) @@ -137,7 +137,7 @@ def test_ipow_special_cases_two_args_absequal__equal_2(arg1, arg2): - If `abs(x1_i)` is `1` and `x2_i` is `-infinity`, the result is `1`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) ipow(res, arg2) mask = logical_and(exactly_equal(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (one(arg1.shape, arg1.dtype))[mask]) @@ -151,7 +151,7 @@ def test_ipow_special_cases_two_args_absless__equal_1(arg1, arg2): - If `abs(x1_i)` is less than `1` and `x2_i` is `+infinity`, the result is `+0`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) ipow(res, arg2) mask = logical_and(less(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) @@ -165,7 +165,7 @@ def test_ipow_special_cases_two_args_absless__equal_2(arg1, arg2): - If `abs(x1_i)` is less than `1` and `x2_i` is `-infinity`, the result is `+infinity`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) ipow(res, arg2) mask = logical_and(less(abs(arg1), one(arg1.shape, arg1.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) @@ -179,7 +179,7 @@ def test_ipow_special_cases_two_args_equal__greater_1(arg1, arg2): - If `x1_i` is `+infinity` and `x2_i` is greater than `0`, the result is `+infinity`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) ipow(res, arg2) mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), greater(arg2, zero(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) @@ -193,7 +193,7 @@ def test_ipow_special_cases_two_args_equal__greater_2(arg1, arg2): - If `x1_i` is `+0` and `x2_i` is greater than `0`, the result is `+0`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) ipow(res, arg2) mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), greater(arg2, zero(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) @@ -207,7 +207,7 @@ def test_ipow_special_cases_two_args_equal__less_1(arg1, arg2): - If `x1_i` is `+infinity` and `x2_i` is less than `0`, the result is `+0`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) ipow(res, arg2) mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), less(arg2, zero(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) @@ -221,7 +221,7 @@ def test_ipow_special_cases_two_args_equal__less_2(arg1, arg2): - If `x1_i` is `+0` and `x2_i` is less than `0`, the result is `+infinity`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) ipow(res, arg2) mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), less(arg2, zero(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) @@ -235,7 +235,7 @@ def test_ipow_special_cases_two_args_equal__greater_equal_1(arg1, arg2): - If `x1_i` is `-infinity`, `x2_i` is greater than `0`, and `x2_i` is an odd integer value, the result is `-infinity`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) ipow(res, arg2) mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(greater(arg2, zero(arg2.shape, arg2.dtype)), isodd(arg2))) assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) @@ -249,7 +249,7 @@ def test_ipow_special_cases_two_args_equal__greater_equal_2(arg1, arg2): - If `x1_i` is `-0`, `x2_i` is greater than `0`, and `x2_i` is an odd integer value, the result is `-0`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) ipow(res, arg2) mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), logical_and(greater(arg2, zero(arg2.shape, arg2.dtype)), isodd(arg2))) assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) @@ -263,7 +263,7 @@ def test_ipow_special_cases_two_args_equal__greater_notequal_1(arg1, arg2): - If `x1_i` is `-infinity`, `x2_i` is greater than `0`, and `x2_i` is not an odd integer value, the result is `+infinity`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) ipow(res, arg2) mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(greater(arg2, zero(arg2.shape, arg2.dtype)), logical_not(isodd(arg2)))) assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) @@ -277,7 +277,7 @@ def test_ipow_special_cases_two_args_equal__greater_notequal_2(arg1, arg2): - If `x1_i` is `-0`, `x2_i` is greater than `0`, and `x2_i` is not an odd integer value, the result is `+0`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) ipow(res, arg2) mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), logical_and(greater(arg2, zero(arg2.shape, arg2.dtype)), logical_not(isodd(arg2)))) assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) @@ -291,7 +291,7 @@ def test_ipow_special_cases_two_args_equal__less_equal_1(arg1, arg2): - If `x1_i` is `-infinity`, `x2_i` is less than `0`, and `x2_i` is an odd integer value, the result is `-0`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) ipow(res, arg2) mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(less(arg2, zero(arg2.shape, arg2.dtype)), isodd(arg2))) assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) @@ -305,7 +305,7 @@ def test_ipow_special_cases_two_args_equal__less_equal_2(arg1, arg2): - If `x1_i` is `-0`, `x2_i` is less than `0`, and `x2_i` is an odd integer value, the result is `-infinity`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) ipow(res, arg2) mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), logical_and(less(arg2, zero(arg2.shape, arg2.dtype)), isodd(arg2))) assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) @@ -319,7 +319,7 @@ def test_ipow_special_cases_two_args_equal__less_notequal_1(arg1, arg2): - If `x1_i` is `-infinity`, `x2_i` is less than `0`, and `x2_i` is not an odd integer value, the result is `+0`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) ipow(res, arg2) mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(less(arg2, zero(arg2.shape, arg2.dtype)), logical_not(isodd(arg2)))) assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) @@ -333,7 +333,7 @@ def test_ipow_special_cases_two_args_equal__less_notequal_2(arg1, arg2): - If `x1_i` is `-0`, `x2_i` is less than `0`, and `x2_i` is not an odd integer value, the result is `+infinity`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) ipow(res, arg2) mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), logical_and(less(arg2, zero(arg2.shape, arg2.dtype)), logical_not(isodd(arg2)))) assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) @@ -347,7 +347,7 @@ def test_ipow_special_cases_two_args_less_equal__equal_notequal(arg1, arg2): - If `x1_i` is less than `0`, `x1_i` is a finite number, `x2_i` is a finite number, and `x2_i` is not an integer value, the result is `NaN`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) ipow(res, arg2) mask = logical_and(logical_and(less(arg1, zero(arg1.shape, arg1.dtype)), isfinite(arg1)), logical_and(isfinite(arg2), logical_not(isintegral(arg2)))) assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) diff --git a/array_api_tests/special_cases/test_dunder_itruediv.py b/array_api_tests/special_cases/test_dunder_itruediv.py index 44d41795..e6747d40 100644 --- a/array_api_tests/special_cases/test_dunder_itruediv.py +++ b/array_api_tests/special_cases/test_dunder_itruediv.py @@ -9,12 +9,11 @@ from operator import itruediv -from ..array_helpers import (NaN, assert_exactly_equal, assert_negative_mathematical_sign, +from ..array_helpers import (NaN, asarray, assert_exactly_equal, assert_negative_mathematical_sign, assert_positive_mathematical_sign, exactly_equal, greater, infinity, isfinite, isnegative, ispositive, less, logical_and, logical_not, logical_or, non_zero, same_sign, zero) from ..hypothesis_helpers import numeric_arrays -from .. import _array_module as xp from hypothesis import given @@ -27,7 +26,7 @@ def test_itruediv_special_cases_two_args_either(arg1, arg2): - If either `x1_i` or `x2_i` is `NaN`, the result is `NaN`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) itruediv(res, arg2) mask = logical_or(exactly_equal(arg1, NaN(arg1.shape, arg1.dtype)), exactly_equal(arg2, NaN(arg1.shape, arg1.dtype))) assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) @@ -41,7 +40,7 @@ def test_itruediv_special_cases_two_args_either__either_1(arg1, arg2): - If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is either `+infinity` or `-infinity`, the result is `NaN`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) itruediv(res, arg2) mask = logical_and(logical_or(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype))), logical_or(exactly_equal(arg2, infinity(arg2.shape, arg2.dtype)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype)))) assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) @@ -55,7 +54,7 @@ def test_itruediv_special_cases_two_args_either__either_2(arg1, arg2): - If `x1_i` is either `+0` or `-0` and `x2_i` is either `+0` or `-0`, the result is `NaN`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) itruediv(res, arg2) mask = logical_and(logical_or(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg1, -zero(arg1.shape, arg1.dtype))), logical_or(exactly_equal(arg2, zero(arg2.shape, arg2.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype)))) assert_exactly_equal(res[mask], (NaN(arg1.shape, arg1.dtype))[mask]) @@ -69,7 +68,7 @@ def test_itruediv_special_cases_two_args_equal__greater_1(arg1, arg2): - If `x1_i` is `+0` and `x2_i` is greater than `0`, the result is `+0`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) itruediv(res, arg2) mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), greater(arg2, zero(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) @@ -83,7 +82,7 @@ def test_itruediv_special_cases_two_args_equal__greater_2(arg1, arg2): - If `x1_i` is `-0` and `x2_i` is greater than `0`, the result is `-0`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) itruediv(res, arg2) mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), greater(arg2, zero(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) @@ -97,7 +96,7 @@ def test_itruediv_special_cases_two_args_equal__less_1(arg1, arg2): - If `x1_i` is `+0` and `x2_i` is less than `0`, the result is `-0`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) itruediv(res, arg2) mask = logical_and(exactly_equal(arg1, zero(arg1.shape, arg1.dtype)), less(arg2, zero(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) @@ -111,7 +110,7 @@ def test_itruediv_special_cases_two_args_equal__less_2(arg1, arg2): - If `x1_i` is `-0` and `x2_i` is less than `0`, the result is `+0`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) itruediv(res, arg2) mask = logical_and(exactly_equal(arg1, -zero(arg1.shape, arg1.dtype)), less(arg2, zero(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) @@ -125,7 +124,7 @@ def test_itruediv_special_cases_two_args_greater__equal_1(arg1, arg2): - If `x1_i` is greater than `0` and `x2_i` is `+0`, the result is `+infinity`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) itruediv(res, arg2) mask = logical_and(greater(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, zero(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) @@ -139,7 +138,7 @@ def test_itruediv_special_cases_two_args_greater__equal_2(arg1, arg2): - If `x1_i` is greater than `0` and `x2_i` is `-0`, the result is `-infinity`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) itruediv(res, arg2) mask = logical_and(greater(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) @@ -153,7 +152,7 @@ def test_itruediv_special_cases_two_args_less__equal_1(arg1, arg2): - If `x1_i` is less than `0` and `x2_i` is `+0`, the result is `-infinity`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) itruediv(res, arg2) mask = logical_and(less(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, zero(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) @@ -167,7 +166,7 @@ def test_itruediv_special_cases_two_args_less__equal_2(arg1, arg2): - If `x1_i` is less than `0` and `x2_i` is `-0`, the result is `+infinity`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) itruediv(res, arg2) mask = logical_and(less(arg1, zero(arg1.shape, arg1.dtype)), exactly_equal(arg2, -zero(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) @@ -181,7 +180,7 @@ def test_itruediv_special_cases_two_args_equal__equal_1(arg1, arg2): - If `x1_i` is `+infinity` and `x2_i` is a positive (i.e., greater than `0`) finite number, the result is `+infinity`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) itruediv(res, arg2) mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), logical_and(isfinite(arg2), ispositive(arg2))) assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) @@ -195,7 +194,7 @@ def test_itruediv_special_cases_two_args_equal__equal_2(arg1, arg2): - If `x1_i` is `+infinity` and `x2_i` is a negative (i.e., less than `0`) finite number, the result is `-infinity`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) itruediv(res, arg2) mask = logical_and(exactly_equal(arg1, infinity(arg1.shape, arg1.dtype)), logical_and(isfinite(arg2), isnegative(arg2))) assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) @@ -209,7 +208,7 @@ def test_itruediv_special_cases_two_args_equal__equal_3(arg1, arg2): - If `x1_i` is `-infinity` and `x2_i` is a positive (i.e., greater than `0`) finite number, the result is `-infinity`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) itruediv(res, arg2) mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(isfinite(arg2), ispositive(arg2))) assert_exactly_equal(res[mask], (-infinity(arg1.shape, arg1.dtype))[mask]) @@ -223,7 +222,7 @@ def test_itruediv_special_cases_two_args_equal__equal_4(arg1, arg2): - If `x1_i` is `-infinity` and `x2_i` is a negative (i.e., less than `0`) finite number, the result is `+infinity`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) itruediv(res, arg2) mask = logical_and(exactly_equal(arg1, -infinity(arg1.shape, arg1.dtype)), logical_and(isfinite(arg2), isnegative(arg2))) assert_exactly_equal(res[mask], (infinity(arg1.shape, arg1.dtype))[mask]) @@ -237,7 +236,7 @@ def test_itruediv_special_cases_two_args_equal__equal_5(arg1, arg2): - If `x1_i` is a positive (i.e., greater than `0`) finite number and `x2_i` is `+infinity`, the result is `+0`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) itruediv(res, arg2) mask = logical_and(logical_and(isfinite(arg1), ispositive(arg1)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) @@ -251,7 +250,7 @@ def test_itruediv_special_cases_two_args_equal__equal_6(arg1, arg2): - If `x1_i` is a positive (i.e., greater than `0`) finite number and `x2_i` is `-infinity`, the result is `-0`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) itruediv(res, arg2) mask = logical_and(logical_and(isfinite(arg1), ispositive(arg1)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) @@ -265,7 +264,7 @@ def test_itruediv_special_cases_two_args_equal__equal_7(arg1, arg2): - If `x1_i` is a negative (i.e., less than `0`) finite number and `x2_i` is `+infinity`, the result is `-0`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) itruediv(res, arg2) mask = logical_and(logical_and(isfinite(arg1), isnegative(arg1)), exactly_equal(arg2, infinity(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (-zero(arg1.shape, arg1.dtype))[mask]) @@ -279,7 +278,7 @@ def test_itruediv_special_cases_two_args_equal__equal_8(arg1, arg2): - If `x1_i` is a negative (i.e., less than `0`) finite number and `x2_i` is `-infinity`, the result is `+0`. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) itruediv(res, arg2) mask = logical_and(logical_and(isfinite(arg1), isnegative(arg1)), exactly_equal(arg2, -infinity(arg2.shape, arg2.dtype))) assert_exactly_equal(res[mask], (zero(arg1.shape, arg1.dtype))[mask]) @@ -293,7 +292,7 @@ def test_itruediv_special_cases_two_args_same_sign_both(arg1, arg2): - If `x1_i` and `x2_i` have the same mathematical sign and are both nonzero finite numbers, the result has a positive mathematical sign. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) itruediv(res, arg2) mask = logical_and(same_sign(arg1, arg2), logical_and(logical_and(isfinite(arg1), non_zero(arg1)), logical_and(isfinite(arg2), non_zero(arg2)))) assert_positive_mathematical_sign(res[mask]) @@ -307,7 +306,7 @@ def test_itruediv_special_cases_two_args_different_signs_both(arg1, arg2): - If `x1_i` and `x2_i` have different mathematical signs and are both nonzero finite numbers, the result has a negative mathematical sign. """ - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) itruediv(res, arg2) mask = logical_and(logical_not(same_sign(arg1, arg2)), logical_and(logical_and(isfinite(arg1), non_zero(arg1)), logical_and(isfinite(arg2), non_zero(arg2)))) assert_negative_mathematical_sign(res[mask]) diff --git a/generate_stubs.py b/generate_stubs.py index e529f5ec..857f6d1c 100755 --- a/generate_stubs.py +++ b/generate_stubs.py @@ -160,7 +160,6 @@ from ..array_helpers import * from ..hypothesis_helpers import numeric_arrays -from .. import _array_module as xp from hypothesis import given @@ -603,7 +602,7 @@ def test_{op}_special_cases_{test_name_extra}(arg1, arg2): {decorator} def test_{op}_special_cases_{test_name_extra}(arg1, arg2): {doc} - res = xp.asarray(arg1, copy=True) + res = asarray(arg1, copy=True) {op}(res, arg2) mask = {mask} {assertion}