From 113221ea8ea51bc4e6d30ffa37de9def31e801c5 Mon Sep 17 00:00:00 2001 From: Paresh Joshi Date: Fri, 5 Dec 2025 15:29:54 +0000 Subject: [PATCH 01/10] TST: fix regression in longdouble alias check on Windows --- .../@test/runtime/test_ctype_assumptions.py | 51 ++++++++++--------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py b/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py index 63d425c3..ee3bbe8f 100644 --- a/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py +++ b/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py @@ -23,36 +23,39 @@ def test_longlong_64(char: str) -> None: assert np.dtype(char).alignment == 8 -@pytest.mark.parametrize( - ("name_c", "name_expect"), - [ - ("byte", "int8"), - ("short", "int16"), - ("intc", "int32"), - ("long", "int32" if WIN32 else f"int{SIZE_P}"), - ("intp", f"int{SIZE_P}"), - ], -) +# --- Integer Aliases --- +_int_aliases = [ + ("byte", "int8"), + ("short", "int16"), + ("intc", "int32"), + ("intp", f"int{SIZE_P}"), + # On Windows long is int32 (LLP64), on Linux it matches pointer size (LP64). + ("long", "int32" if WIN32 else f"int{SIZE_P}"), +] + + +@pytest.mark.parametrize(("name_c", "name_expect"), _int_aliases) def test_alias_integer(name_c: str, name_expect: str) -> None: signed_c: type[np.signedinteger] = getattr(np, name_c) signed_expect: type[np.signedinteger] = getattr(np, name_expect) - assert signed_c is signed_expect + assert np.dtype(signed_c) == np.dtype(signed_expect) unsigned_c: type[np.unsignedinteger] = getattr(np, f"u{name_c}") unsigned_expect: type[np.unsignedinteger] = getattr(np, f"u{name_expect}") - assert unsigned_c is unsigned_expect - - -@pytest.mark.parametrize( - ("name_c", "name_expect"), - [ - ("half", "float16"), - ("single", "float32"), - ("double", "float64"), - ("longdouble", "float96" if WIN32 else f"float{SIZE_P + 64}"), - ], -) + assert np.dtype(unsigned_c) == np.dtype(unsigned_expect) + + +# --- Floating Point Aliases --- +_float_aliases = [ + ("half", "float16"), + ("single", "float32"), + ("double", "float64"), + ("longdouble", np.dtype(np.longdouble).name), +] + + +@pytest.mark.parametrize(("name_c", "name_expect"), _float_aliases) def test_alias_floating(name_c: str, name_expect: str) -> None: floating_c: type[np.floating] = getattr(np, name_c) floating_expect: type[np.floating] = getattr(np, name_expect) - assert floating_c is floating_expect + assert np.dtype(floating_c) == np.dtype(floating_expect) \ No newline at end of file From a514216d1c952bc3dd8f3563cab3ca5f97d7e2fa Mon Sep 17 00:00:00 2001 From: Paresh Joshi Date: Fri, 5 Dec 2025 21:09:47 +0530 Subject: [PATCH 02/10] Update test_ctype_assumptions.py --- src/numpy-stubs/@test/runtime/test_ctype_assumptions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py b/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py index ee3bbe8f..fcd1f157 100644 --- a/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py +++ b/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py @@ -58,4 +58,4 @@ def test_alias_integer(name_c: str, name_expect: str) -> None: def test_alias_floating(name_c: str, name_expect: str) -> None: floating_c: type[np.floating] = getattr(np, name_c) floating_expect: type[np.floating] = getattr(np, name_expect) - assert np.dtype(floating_c) == np.dtype(floating_expect) \ No newline at end of file + assert np.dtype(floating_c) == np.dtype(floating_expect) From 85071da6be243ed1271880e5dc61c6a0c96a7e1b Mon Sep 17 00:00:00 2001 From: Paresh Joshi Date: Fri, 5 Dec 2025 21:39:52 +0530 Subject: [PATCH 03/10] Enhance floating point alias tests with longdouble check --- src/numpy-stubs/@test/runtime/test_ctype_assumptions.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py b/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py index fcd1f157..0397739b 100644 --- a/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py +++ b/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py @@ -46,6 +46,10 @@ def test_alias_integer(name_c: str, name_expect: str) -> None: # --- Floating Point Aliases --- +_longdouble_name = np.dtype(np.longdouble).name +assert _longdouble_name in {"float64", "float96", "float128"}, \ + f"Unrecognized longdouble type: {_longdouble_name}" + _float_aliases = [ ("half", "float16"), ("single", "float32"), From 8d6c16b1a99dec52163853ecd1022c40dec3f7ae Mon Sep 17 00:00:00 2001 From: Paresh Joshi Date: Fri, 5 Dec 2025 21:47:00 +0530 Subject: [PATCH 04/10] Fix formatting in test_ctype_assumptions.py --- src/numpy-stubs/@test/runtime/test_ctype_assumptions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py b/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py index 0397739b..fbda421c 100644 --- a/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py +++ b/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py @@ -49,7 +49,7 @@ def test_alias_integer(name_c: str, name_expect: str) -> None: _longdouble_name = np.dtype(np.longdouble).name assert _longdouble_name in {"float64", "float96", "float128"}, \ f"Unrecognized longdouble type: {_longdouble_name}" - + _float_aliases = [ ("half", "float16"), ("single", "float32"), From 5a7971dfcf1d0d2ca8e57d6d1426545aaf3d7d3b Mon Sep 17 00:00:00 2001 From: Paresh Joshi Date: Tue, 9 Dec 2025 10:08:25 +0530 Subject: [PATCH 05/10] Refactor integer and floating point alias tests --- .../@test/runtime/test_ctype_assumptions.py | 63 ++++++++++--------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py b/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py index fbda421c..c434812b 100644 --- a/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py +++ b/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py @@ -23,43 +23,46 @@ def test_longlong_64(char: str) -> None: assert np.dtype(char).alignment == 8 -# --- Integer Aliases --- -_int_aliases = [ - ("byte", "int8"), - ("short", "int16"), - ("intc", "int32"), - ("intp", f"int{SIZE_P}"), - # On Windows long is int32 (LLP64), on Linux it matches pointer size (LP64). - ("long", "int32" if WIN32 else f"int{SIZE_P}"), -] - - -@pytest.mark.parametrize(("name_c", "name_expect"), _int_aliases) +@pytest.mark.parametrize( + ("name_c", "name_expect"), + [ + ("byte", "int8"), + ("short", "int16"), + ("intc", "int32"), + ("intp", f"int{SIZE_P}"), + ("long", "int32" if WIN32 else f"int{SIZE_P}"), + ], +) def test_alias_integer(name_c: str, name_expect: str) -> None: signed_c: type[np.signedinteger] = getattr(np, name_c) signed_expect: type[np.signedinteger] = getattr(np, name_expect) - assert np.dtype(signed_c) == np.dtype(signed_expect) + assert signed_c is signed_expect unsigned_c: type[np.unsignedinteger] = getattr(np, f"u{name_c}") unsigned_expect: type[np.unsignedinteger] = getattr(np, f"u{name_expect}") - assert np.dtype(unsigned_c) == np.dtype(unsigned_expect) - + assert unsigned_c is unsigned_expect + + +@pytest.mark.parametrize( + ("name_c", "name_expect"), + [ + ("half", "float16"), + ("single", "float32"), + ("double", "float64"), + ], +) +def test_alias_floating_standard(name_c: str, name_expect: str) -> None: + floating_c: type[np.floating] = getattr(np, name_c) + floating_expect: type[np.floating] = getattr(np, name_expect) + assert floating_c is floating_expect -# --- Floating Point Aliases --- -_longdouble_name = np.dtype(np.longdouble).name -assert _longdouble_name in {"float64", "float96", "float128"}, \ - f"Unrecognized longdouble type: {_longdouble_name}" -_float_aliases = [ - ("half", "float16"), - ("single", "float32"), - ("double", "float64"), - ("longdouble", np.dtype(np.longdouble).name), -] +def test_alias_longdouble() -> None: + ld_name = np.dtype(np.longdouble).name + if WIN32: + assert ld_name in {"float64", "float96"} + else: + assert ld_name == "float128" -@pytest.mark.parametrize(("name_c", "name_expect"), _float_aliases) -def test_alias_floating(name_c: str, name_expect: str) -> None: - floating_c: type[np.floating] = getattr(np, name_c) - floating_expect: type[np.floating] = getattr(np, name_expect) - assert np.dtype(floating_c) == np.dtype(floating_expect) + assert np.longdouble is getattr(np, ld_name) From bf0e7906cb07331dae87bc49ec23a6a79c503158 Mon Sep 17 00:00:00 2001 From: jetsetbrand Date: Tue, 9 Dec 2025 10:29:35 +0530 Subject: [PATCH 06/10] fix: resolve platform specific ctypes assumptions and format --- src/numpy-stubs/@test/runtime/test_ctype_assumptions.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py b/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py index c434812b..14920421 100644 --- a/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py +++ b/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py @@ -45,11 +45,7 @@ def test_alias_integer(name_c: str, name_expect: str) -> None: @pytest.mark.parametrize( ("name_c", "name_expect"), - [ - ("half", "float16"), - ("single", "float32"), - ("double", "float64"), - ], + [("half", "float16"), ("single", "float32"), ("double", "float64")], ) def test_alias_floating_standard(name_c: str, name_expect: str) -> None: floating_c: type[np.floating] = getattr(np, name_c) From 8333bf1e60c4c941bea9eb2c4ce95ca1ebd3edf8 Mon Sep 17 00:00:00 2001 From: jetsetbrand Date: Tue, 9 Dec 2025 10:47:54 +0530 Subject: [PATCH 07/10] fix: relax strict type identity checks and improve platform detection --- .../@test/runtime/test_ctype_assumptions.py | 47 +++++++++++-------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py b/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py index 14920421..e0bd467b 100644 --- a/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py +++ b/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py @@ -1,26 +1,27 @@ # ruff: noqa: S101, PLR2004 import ctypes as ct +import platform import sys import pytest - import numpy as np -WIN32 = sys.platform == "win32" +IS_WIN = sys.platform == "win32" +IS_X86 = platform.machine().lower() in ("x86_64", "amd64", "i386", "i686") SIZE_P = ct.sizeof(ct.c_ssize_t) * 8 -def test_maxsize_32_or_64() -> None: - # assume we're either on a 32 or a 64 bit system +def test_maxsize_width() -> None: assert SIZE_P in {32, 64} assert sys.maxsize == (1 << (SIZE_P - 1)) - 1 @pytest.mark.parametrize("char", ["q", "Q"]) def test_longlong_64(char: str) -> None: - assert np.dtype(char).itemsize == 8 - assert np.dtype(char).alignment == 8 + dt = np.dtype(char) + assert dt.itemsize == 8 + assert dt.alignment == 8 @pytest.mark.parametrize( @@ -30,17 +31,17 @@ def test_longlong_64(char: str) -> None: ("short", "int16"), ("intc", "int32"), ("intp", f"int{SIZE_P}"), - ("long", "int32" if WIN32 else f"int{SIZE_P}"), + ("long", "int32" if IS_WIN else f"int{SIZE_P}"), ], ) def test_alias_integer(name_c: str, name_expect: str) -> None: - signed_c: type[np.signedinteger] = getattr(np, name_c) - signed_expect: type[np.signedinteger] = getattr(np, name_expect) - assert signed_c is signed_expect + signed_c = np.dtype(getattr(np, name_c)) + signed_expect = np.dtype(getattr(np, name_expect)) + assert signed_c == signed_expect - unsigned_c: type[np.unsignedinteger] = getattr(np, f"u{name_c}") - unsigned_expect: type[np.unsignedinteger] = getattr(np, f"u{name_expect}") - assert unsigned_c is unsigned_expect + unsigned_c = np.dtype(getattr(np, f"u{name_c}")) + unsigned_expect = np.dtype(getattr(np, f"u{name_expect}")) + assert unsigned_c == unsigned_expect @pytest.mark.parametrize( @@ -48,17 +49,25 @@ def test_alias_integer(name_c: str, name_expect: str) -> None: [("half", "float16"), ("single", "float32"), ("double", "float64")], ) def test_alias_floating_standard(name_c: str, name_expect: str) -> None: - floating_c: type[np.floating] = getattr(np, name_c) - floating_expect: type[np.floating] = getattr(np, name_expect) - assert floating_c is floating_expect + floating_c = np.dtype(getattr(np, name_c)) + floating_expect = np.dtype(getattr(np, name_expect)) + assert floating_c == floating_expect def test_alias_longdouble() -> None: + """ + Verify longdouble alias. + - Windows: float64 (MSVC) or float96 (MinGW). + - x86 Linux/Mac: float128 . + - ARM64 Linux/Mac: float64 . + """ ld_name = np.dtype(np.longdouble).name - if WIN32: + if IS_WIN: assert ld_name in {"float64", "float96"} + elif IS_X86: + assert ld_name == f"float{SIZE_P + 64}" else: - assert ld_name == "float128" + assert ld_name in {"float64", "float128"} - assert np.longdouble is getattr(np, ld_name) + assert np.dtype(np.longdouble) == np.dtype(getattr(np, ld_name)) From ac6adab0418729c0e8e9046c79dec7becc207a88 Mon Sep 17 00:00:00 2001 From: jetsetbrand Date: Tue, 9 Dec 2025 11:04:30 +0530 Subject: [PATCH 08/10] style: apply automatic ruff import formatting --- src/numpy-stubs/@test/runtime/test_ctype_assumptions.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py b/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py index e0bd467b..5c79dc1d 100644 --- a/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py +++ b/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py @@ -5,10 +5,11 @@ import sys import pytest + import numpy as np IS_WIN = sys.platform == "win32" -IS_X86 = platform.machine().lower() in ("x86_64", "amd64", "i386", "i686") +IS_X86 = platform.machine().lower() in {"x86_64", "amd64", "i386", "i686"} SIZE_P = ct.sizeof(ct.c_ssize_t) * 8 From 209b42eff374e261d8beeb78e32888b69a1d411a Mon Sep 17 00:00:00 2001 From: jetsetbrand Date: Tue, 9 Dec 2025 11:22:28 +0530 Subject: [PATCH 09/10] fix: restore strict type hints and fix windows compatibility --- .../@test/runtime/test_ctype_assumptions.py | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py b/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py index 5c79dc1d..acaae19d 100644 --- a/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py +++ b/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py @@ -4,16 +4,16 @@ import platform import sys -import pytest - import numpy as np +import pytest IS_WIN = sys.platform == "win32" IS_X86 = platform.machine().lower() in {"x86_64", "amd64", "i386", "i686"} SIZE_P = ct.sizeof(ct.c_ssize_t) * 8 -def test_maxsize_width() -> None: +def test_maxsize_32_or_64() -> None: + # assume we're either on a 32 or a 64 bit system assert SIZE_P in {32, 64} assert sys.maxsize == (1 << (SIZE_P - 1)) - 1 @@ -36,13 +36,13 @@ def test_longlong_64(char: str) -> None: ], ) def test_alias_integer(name_c: str, name_expect: str) -> None: - signed_c = np.dtype(getattr(np, name_c)) - signed_expect = np.dtype(getattr(np, name_expect)) - assert signed_c == signed_expect + signed_c: type[np.signedinteger] = getattr(np, name_c) + signed_expect: type[np.signedinteger] = getattr(np, name_expect) + assert np.dtype(signed_c) == np.dtype(signed_expect) - unsigned_c = np.dtype(getattr(np, f"u{name_c}")) - unsigned_expect = np.dtype(getattr(np, f"u{name_expect}")) - assert unsigned_c == unsigned_expect + unsigned_c: type[np.unsignedinteger] = getattr(np, f"u{name_c}") + unsigned_expect: type[np.unsignedinteger] = getattr(np, f"u{name_expect}") + assert np.dtype(unsigned_c) == np.dtype(unsigned_expect) @pytest.mark.parametrize( @@ -50,18 +50,12 @@ def test_alias_integer(name_c: str, name_expect: str) -> None: [("half", "float16"), ("single", "float32"), ("double", "float64")], ) def test_alias_floating_standard(name_c: str, name_expect: str) -> None: - floating_c = np.dtype(getattr(np, name_c)) - floating_expect = np.dtype(getattr(np, name_expect)) - assert floating_c == floating_expect + floating_c: type[np.floating] = getattr(np, name_c) + floating_expect: type[np.floating] = getattr(np, name_expect) + assert np.dtype(floating_c) == np.dtype(floating_expect) def test_alias_longdouble() -> None: - """ - Verify longdouble alias. - - Windows: float64 (MSVC) or float96 (MinGW). - - x86 Linux/Mac: float128 . - - ARM64 Linux/Mac: float64 . - """ ld_name = np.dtype(np.longdouble).name if IS_WIN: From 1ffcc7c3837799338b9773f8a1ddb694b5ca9535 Mon Sep 17 00:00:00 2001 From: jetsetbrand Date: Tue, 9 Dec 2025 11:31:57 +0530 Subject: [PATCH 10/10] style: fix ruff I001 import sorting and restore strict type hints --- src/numpy-stubs/@test/runtime/test_ctype_assumptions.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py b/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py index acaae19d..df7e5aa5 100644 --- a/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py +++ b/src/numpy-stubs/@test/runtime/test_ctype_assumptions.py @@ -4,9 +4,10 @@ import platform import sys -import numpy as np import pytest +import numpy as np + IS_WIN = sys.platform == "win32" IS_X86 = platform.machine().lower() in {"x86_64", "amd64", "i386", "i686"} SIZE_P = ct.sizeof(ct.c_ssize_t) * 8