From 2211bc9c20e69552c936c41d177a849b7b205338 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Fri, 23 Aug 2024 23:04:23 +0200 Subject: [PATCH 1/5] BUG: Fix array_equal for numeric and non-numeric scalar types --- numpy/_core/numeric.py | 16 ++++++++-------- numpy/_core/tests/test_numeric.py | 7 +++++++ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/numpy/_core/numeric.py b/numpy/_core/numeric.py index 39b3de44fabe..9b0939e9d54b 100644 --- a/numpy/_core/numeric.py +++ b/numpy/_core/numeric.py @@ -2554,24 +2554,24 @@ def array_equal(a1, a2, equal_nan=False): if a1.shape != a2.shape: return False if not equal_nan: - return builtins.bool((a1 == a2).all()) - cannot_have_nan = (_dtype_cannot_hold_nan(a1.dtype) - and _dtype_cannot_hold_nan(a2.dtype)) - if cannot_have_nan: - if a1 is a2: - return True - return builtins.bool((a1 == a2).all()) + return builtins.bool((asarray(a1 == a2)).all()) if a1 is a2: # nan will compare equal so an array will compare equal to itself. return True + + cannot_have_nan = (_dtype_cannot_hold_nan(a1.dtype) + and _dtype_cannot_hold_nan(a2.dtype)) + if cannot_have_nan: + return builtins.bool(asarray(a1 == a2).all()) + # Handling NaN values if equal_nan is True a1nan, a2nan = isnan(a1), isnan(a2) # NaN's occur at different locations if not (a1nan == a2nan).all(): return False # Shapes of a1, a2 and masks are guaranteed to be consistent by this point - return builtins.bool((a1[~a1nan] == a2[~a1nan]).all()) + return builtins.bool(asarray(a1[~a1nan] == a2[~a1nan]).all()) def _array_equiv_dispatcher(a1, a2): diff --git a/numpy/_core/tests/test_numeric.py b/numpy/_core/tests/test_numeric.py index 7714fab752f7..402116c43d08 100644 --- a/numpy/_core/tests/test_numeric.py +++ b/numpy/_core/tests/test_numeric.py @@ -2192,6 +2192,13 @@ def test_array_equal_equal_nan(self, bx, by, equal_nan, expected): assert_(res is expected) assert_(type(res) is bool) + def test_array_equal_different_scalar_types(self): + # https://github.com/numpy/numpy/issues/27271 + a = np.array("foo") + b = np.array(1) + assert not np.array_equal(a, b) + assert not np.array_equiv(a, b) + def test_none_compares_elementwise(self): a = np.array([None, 1, None], dtype=object) assert_equal(a == None, [True, False, True]) From 95355b71f85cdfed128d3b0cf6f549e2b34a909f Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Fri, 23 Aug 2024 23:14:19 +0200 Subject: [PATCH 2/5] add asarray for array_equiv --- numpy/_core/numeric.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/numpy/_core/numeric.py b/numpy/_core/numeric.py index 9b0939e9d54b..413b032eb243 100644 --- a/numpy/_core/numeric.py +++ b/numpy/_core/numeric.py @@ -2624,7 +2624,7 @@ def array_equiv(a1, a2): except Exception: return False - return builtins.bool((a1 == a2).all()) + return builtins.bool(asarray(a1 == a2).all()) def _astype_dispatcher(x, dtype, /, *, copy=None, device=None): From b15960f6bd2797a147f22f4bf0d9c9ec5e879265 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Sat, 24 Aug 2024 22:15:00 +0200 Subject: [PATCH 3/5] remove final asarray call --- numpy/_core/numeric.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/numpy/_core/numeric.py b/numpy/_core/numeric.py index 413b032eb243..16dc2ff2339a 100644 --- a/numpy/_core/numeric.py +++ b/numpy/_core/numeric.py @@ -2571,7 +2571,7 @@ def array_equal(a1, a2, equal_nan=False): if not (a1nan == a2nan).all(): return False # Shapes of a1, a2 and masks are guaranteed to be consistent by this point - return builtins.bool(asarray(a1[~a1nan] == a2[~a1nan]).all()) + return builtins.bool((a1[~a1nan] == a2[~a1nan]).all()) def _array_equiv_dispatcher(a1, a2): From 4ba6b85d3058759b0f64eb455a4c90627e12c107 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Sun, 25 Aug 2024 22:43:18 +0200 Subject: [PATCH 4/5] use asanyarray --- numpy/_core/numeric.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/numpy/_core/numeric.py b/numpy/_core/numeric.py index 16dc2ff2339a..d6f9219b2021 100644 --- a/numpy/_core/numeric.py +++ b/numpy/_core/numeric.py @@ -2554,7 +2554,7 @@ def array_equal(a1, a2, equal_nan=False): if a1.shape != a2.shape: return False if not equal_nan: - return builtins.bool((asarray(a1 == a2)).all()) + return builtins.bool((asanyarray(a1 == a2)).all()) if a1 is a2: # nan will compare equal so an array will compare equal to itself. From 8ede522b2a95528f7f0b98ce142a80d0c74ee9a9 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Sun, 25 Aug 2024 22:44:08 +0200 Subject: [PATCH 5/5] use asanyarray --- numpy/_core/numeric.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/numpy/_core/numeric.py b/numpy/_core/numeric.py index d6f9219b2021..1f3f1c20dbd1 100644 --- a/numpy/_core/numeric.py +++ b/numpy/_core/numeric.py @@ -2624,7 +2624,7 @@ def array_equiv(a1, a2): except Exception: return False - return builtins.bool(asarray(a1 == a2).all()) + return builtins.bool(asanyarray(a1 == a2).all()) def _astype_dispatcher(x, dtype, /, *, copy=None, device=None):