From db9f27ba953c828a858b381ef5b4750d1ec0722e Mon Sep 17 00:00:00 2001 From: Kosta Ilic Date: Fri, 9 Jan 2026 20:37:19 -0600 Subject: [PATCH 1/6] Started workaround for skipped documentation tests bug. Signed-off-by: Kosta Ilic --- src/nitypes/_arguments.py | 3 ++- src/nitypes/complex/__init__.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/nitypes/_arguments.py b/src/nitypes/_arguments.py index 948b729a..96d5344d 100644 --- a/src/nitypes/_arguments.py +++ b/src/nitypes/_arguments.py @@ -16,7 +16,8 @@ # Some of these doctests use types introduced in NumPy 2.0 (np.long and np.ulong) or highlight # formatting differences between NumPy 1.x and 2.x (e.g. dtype=int32, 1.23 vs. np.float64(1.23)). -__doctest_requires__ = {("arg_to_float", "is_dtype", "validate_dtype"): ["numpy>=2.0"]} +# The following line is commented out as workaround for technical debt #251. +# __doctest_requires__ = {("arg_to_float", "is_dtype", "validate_dtype"): ["numpy>=2.0"]} def arg_to_float( diff --git a/src/nitypes/complex/__init__.py b/src/nitypes/complex/__init__.py index e904f485..a15ca429 100644 --- a/src/nitypes/complex/__init__.py +++ b/src/nitypes/complex/__init__.py @@ -127,4 +127,5 @@ from nitypes.complex._dtypes import ComplexInt32Base, ComplexInt32DType __all__ = ["convert_complex", "ComplexInt32DType", "ComplexInt32Base"] -__doctest_requires__ = {".": ["numpy>=2.0"]} +# The following line is commented out as workaround for technical debt #251. +# __doctest_requires__ = {".": ["numpy>=2.0"]} From 12f005e04b8cdb56ef499e79b3096022963f098d Mon Sep 17 00:00:00 2001 From: Kosta Ilic Date: Fri, 9 Jan 2026 20:59:02 -0600 Subject: [PATCH 2/6] Completed the workaround. Improved comments. Signed-off-by: Kosta Ilic --- src/nitypes/_arguments.py | 7 ++++++- src/nitypes/complex/__init__.py | 4 ++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/nitypes/_arguments.py b/src/nitypes/_arguments.py index 96d5344d..5be5c107 100644 --- a/src/nitypes/_arguments.py +++ b/src/nitypes/_arguments.py @@ -18,13 +18,16 @@ # formatting differences between NumPy 1.x and 2.x (e.g. dtype=int32, 1.23 vs. np.float64(1.23)). # The following line is commented out as workaround for technical debt #251. # __doctest_requires__ = {("arg_to_float", "is_dtype", "validate_dtype"): ["numpy>=2.0"]} - +# When the technical debt is resolved, uncomment the line above +# and remove the lines similar to the one below: +# >>> import pytest; version_check = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0); pytest.skip("requires numpy>=2.0") if version_check else None # doctest: +SKIP def arg_to_float( arg_description: str, value: SupportsFloat | None, default_value: float | None = None ) -> float: """Convert an argument to a float. + >>> import pytest; version_check = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0); pytest.skip("requires numpy>=2.0") if version_check else None # doctest: +SKIP >>> arg_to_float("xyz", 1.234) 1.234 >>> arg_to_float("xyz", 1234) @@ -144,6 +147,7 @@ def is_dtype(dtype: npt.DTypeLike, supported_dtypes: tuple[npt.DTypeLike, ...]) Unlike :any:`numpy.isdtype`, this function supports structured data types. + >>> import pytest; version_check = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0); pytest.skip("requires numpy>=2.0") if version_check else None # doctest: +SKIP >>> is_dtype(np.float64, (np.float64, np.intc, np.long,)) True >>> is_dtype("float64", (np.float64, np.intc, np.long,)) @@ -173,6 +177,7 @@ def is_dtype(dtype: npt.DTypeLike, supported_dtypes: tuple[npt.DTypeLike, ...]) def validate_dtype(dtype: npt.DTypeLike, supported_dtypes: tuple[npt.DTypeLike, ...]) -> None: """Validate a dtype-like object against a tuple of supported dtype-like objects. + >>> import pytest; version_check = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0); pytest.skip("requires numpy>=2.0") if version_check else None # doctest: +SKIP >>> validate_dtype(np.float64, (np.float64, np.intc, np.long,)) >>> validate_dtype("float64", (np.float64, np.intc, np.long,)) >>> validate_dtype(np.float64, (np.byte, np.short, np.intc, np.int_, np.long, np.longlong)) diff --git a/src/nitypes/complex/__init__.py b/src/nitypes/complex/__init__.py index a15ca429..cf65e648 100644 --- a/src/nitypes/complex/__init__.py +++ b/src/nitypes/complex/__init__.py @@ -27,6 +27,7 @@ You can construct an array of complex integers from a sequence of tuples using :func:`numpy.array`: +>>> import pytest; version_check = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0); pytest.skip("requires numpy>=2.0") if version_check else None # doctest: +SKIP >>> import numpy as np >>> np.array([(1, 2), (3, 4)], dtype=ComplexInt32DType) array([(1, 2), (3, 4)], dtype=[('real', '=2.0"]} +# When the technical debt is resolved, uncomment the line above +# and remove the lines similar to the one below: +# >>> import pytest; version_check = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0); pytest.skip("requires numpy>=2.0") if version_check else None # doctest: +SKIP From 7a01b84d17980b190a05fe96beccb770576248c2 Mon Sep 17 00:00:00 2001 From: Kosta Ilic Date: Fri, 9 Jan 2026 21:38:26 -0600 Subject: [PATCH 3/6] Improving the workaround so it does not violate the style guide. Signed-off-by: Kosta Ilic --- docs/conf.py | 1 + src/nitypes/_arguments.py | 34 ++++++++++++++++++++++++++------- src/nitypes/complex/__init__.py | 13 ++++++++++--- 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index fc0964d3..44358848 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -13,6 +13,7 @@ "autoapi.extension", "m2r2", "sphinx.ext.autodoc", + "sphinx.ext.doctest", "sphinx.ext.intersphinx", "sphinx.ext.napoleon", "sphinx.ext.viewcode", diff --git a/src/nitypes/_arguments.py b/src/nitypes/_arguments.py index 5be5c107..473f2be7 100644 --- a/src/nitypes/_arguments.py +++ b/src/nitypes/_arguments.py @@ -19,17 +19,23 @@ # The following line is commented out as workaround for technical debt #251. # __doctest_requires__ = {("arg_to_float", "is_dtype", "validate_dtype"): ["numpy>=2.0"]} # When the technical debt is resolved, uncomment the line above -# and remove the lines similar to the one below: -# >>> import pytest; version_check = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0); pytest.skip("requires numpy>=2.0") if version_check else None # doctest: +SKIP +# and remove the lines similar to the ones below: +# >>> import pytest; version_check = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0) +# >>> pytest.skip("requires numpy>=2.0") if version_check else None # doctest: +SKIP def arg_to_float( arg_description: str, value: SupportsFloat | None, default_value: float | None = None ) -> float: """Convert an argument to a float. - >>> import pytest; version_check = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0); pytest.skip("requires numpy>=2.0") if version_check else None # doctest: +SKIP - >>> arg_to_float("xyz", 1.234) - 1.234 + .. testsetup:: + + import numpy as np + import pytest + v = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0) + pytest.skip("requires numpy>=2.0") if v else None + + >>> import numpy as np >>> arg_to_float("xyz", 1234) 1234.0 >>> arg_to_float("xyz", np.float64(1.234)) @@ -147,7 +153,14 @@ def is_dtype(dtype: npt.DTypeLike, supported_dtypes: tuple[npt.DTypeLike, ...]) Unlike :any:`numpy.isdtype`, this function supports structured data types. - >>> import pytest; version_check = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0); pytest.skip("requires numpy>=2.0") if version_check else None # doctest: +SKIP + .. testsetup:: + + import numpy as np + import pytest + v = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0) + pytest.skip("requires numpy>=2.0") if v else None + + >>> import numpy as np >>> is_dtype(np.float64, (np.float64, np.intc, np.long,)) True >>> is_dtype("float64", (np.float64, np.intc, np.long,)) @@ -177,7 +190,14 @@ def is_dtype(dtype: npt.DTypeLike, supported_dtypes: tuple[npt.DTypeLike, ...]) def validate_dtype(dtype: npt.DTypeLike, supported_dtypes: tuple[npt.DTypeLike, ...]) -> None: """Validate a dtype-like object against a tuple of supported dtype-like objects. - >>> import pytest; version_check = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0); pytest.skip("requires numpy>=2.0") if version_check else None # doctest: +SKIP + .. testsetup:: + + import numpy as np + import pytest + v = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0) + pytest.skip("requires numpy>=2.0") if v else None + + >>> import numpy as np >>> validate_dtype(np.float64, (np.float64, np.intc, np.long,)) >>> validate_dtype("float64", (np.float64, np.intc, np.long,)) >>> validate_dtype(np.float64, (np.byte, np.short, np.intc, np.int_, np.long, np.longlong)) diff --git a/src/nitypes/complex/__init__.py b/src/nitypes/complex/__init__.py index cf65e648..2d2e8d89 100644 --- a/src/nitypes/complex/__init__.py +++ b/src/nitypes/complex/__init__.py @@ -27,7 +27,13 @@ You can construct an array of complex integers from a sequence of tuples using :func:`numpy.array`: ->>> import pytest; version_check = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0); pytest.skip("requires numpy>=2.0") if version_check else None # doctest: +SKIP +.. testsetup:: + + import numpy as np + import pytest + v = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0) + pytest.skip("requires numpy>=2.0") if v else None + >>> import numpy as np >>> np.array([(1, 2), (3, 4)], dtype=ComplexInt32DType) array([(1, 2), (3, 4)], dtype=[('real', '=2.0"]} # When the technical debt is resolved, uncomment the line above -# and remove the lines similar to the one below: -# >>> import pytest; version_check = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0); pytest.skip("requires numpy>=2.0") if version_check else None # doctest: +SKIP +# and remove the lines similar to the ones below: +# >>> import pytest; version_check = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0) +# >>> pytest.skip("requires numpy>=2.0") if version_check else None # doctest: +SKIP From 331df5f0113b85bdb999017afa4d0ecd6453df7c Mon Sep 17 00:00:00 2001 From: Kosta Ilic Date: Fri, 9 Jan 2026 21:49:01 -0600 Subject: [PATCH 4/6] Minor changes to minimize changes from the original version of the code. Signed-off-by: Kosta Ilic --- src/nitypes/_arguments.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/nitypes/_arguments.py b/src/nitypes/_arguments.py index 473f2be7..59d9d715 100644 --- a/src/nitypes/_arguments.py +++ b/src/nitypes/_arguments.py @@ -35,11 +35,12 @@ def arg_to_float( v = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0) pytest.skip("requires numpy>=2.0") if v else None - >>> import numpy as np - >>> arg_to_float("xyz", 1234) - 1234.0 + >>> arg_to_float("xyz", 1.234) + 1.234 >>> arg_to_float("xyz", np.float64(1.234)) np.float64(1.234) + >>> arg_to_float("xyz", 1234) + 1234.0 >>> arg_to_float("xyz", np.float32(1.234)) # doctest: +ELLIPSIS 1.233999... >>> arg_to_float("xyz", 1.234, 5.0) @@ -160,7 +161,6 @@ def is_dtype(dtype: npt.DTypeLike, supported_dtypes: tuple[npt.DTypeLike, ...]) v = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0) pytest.skip("requires numpy>=2.0") if v else None - >>> import numpy as np >>> is_dtype(np.float64, (np.float64, np.intc, np.long,)) True >>> is_dtype("float64", (np.float64, np.intc, np.long,)) @@ -197,7 +197,6 @@ def validate_dtype(dtype: npt.DTypeLike, supported_dtypes: tuple[npt.DTypeLike, v = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0) pytest.skip("requires numpy>=2.0") if v else None - >>> import numpy as np >>> validate_dtype(np.float64, (np.float64, np.intc, np.long,)) >>> validate_dtype("float64", (np.float64, np.intc, np.long,)) >>> validate_dtype(np.float64, (np.byte, np.short, np.intc, np.int_, np.long, np.longlong)) From 95d08eb3d5201553b256d8fb5d822cc5c551cf61 Mon Sep 17 00:00:00 2001 From: Kosta Ilic Date: Fri, 9 Jan 2026 21:55:21 -0600 Subject: [PATCH 5/6] Improved comments. Reordered some tests to match the original order that made more sense. Signed-off-by: Kosta Ilic --- src/nitypes/_arguments.py | 11 +++++++---- src/nitypes/complex/__init__.py | 6 +++--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/nitypes/_arguments.py b/src/nitypes/_arguments.py index 59d9d715..b878bb22 100644 --- a/src/nitypes/_arguments.py +++ b/src/nitypes/_arguments.py @@ -19,8 +19,8 @@ # The following line is commented out as workaround for technical debt #251. # __doctest_requires__ = {("arg_to_float", "is_dtype", "validate_dtype"): ["numpy>=2.0"]} # When the technical debt is resolved, uncomment the line above -# and remove the lines similar to the ones below: -# >>> import pytest; version_check = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0) +# and remove testsetup blocks that include comments like the one below: +# # Workaround for technical debt #251: Skip doctest if numpy<2.0 # >>> pytest.skip("requires numpy>=2.0") if version_check else None # doctest: +SKIP def arg_to_float( @@ -30,6 +30,7 @@ def arg_to_float( .. testsetup:: + # Workaround for technical debt #251: Skip doctest if numpy<2.0 import numpy as np import pytest v = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0) @@ -37,10 +38,10 @@ def arg_to_float( >>> arg_to_float("xyz", 1.234) 1.234 - >>> arg_to_float("xyz", np.float64(1.234)) - np.float64(1.234) >>> arg_to_float("xyz", 1234) 1234.0 + >>> arg_to_float("xyz", np.float64(1.234)) + np.float64(1.234) >>> arg_to_float("xyz", np.float32(1.234)) # doctest: +ELLIPSIS 1.233999... >>> arg_to_float("xyz", 1.234, 5.0) @@ -156,6 +157,7 @@ def is_dtype(dtype: npt.DTypeLike, supported_dtypes: tuple[npt.DTypeLike, ...]) .. testsetup:: + # Workaround for technical debt #251: Skip doctest if numpy<2.0 import numpy as np import pytest v = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0) @@ -192,6 +194,7 @@ def validate_dtype(dtype: npt.DTypeLike, supported_dtypes: tuple[npt.DTypeLike, .. testsetup:: + # Workaround for technical debt #251: Skip doctest if numpy<2.0 import numpy as np import pytest v = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0) diff --git a/src/nitypes/complex/__init__.py b/src/nitypes/complex/__init__.py index 2d2e8d89..f8655ce8 100644 --- a/src/nitypes/complex/__init__.py +++ b/src/nitypes/complex/__init__.py @@ -29,6 +29,7 @@ .. testsetup:: + # Workaround for technical debt #251: Skip doctest if numpy<2.0 import numpy as np import pytest v = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0) @@ -137,6 +138,5 @@ # The following line is commented out as workaround for technical debt #251. # __doctest_requires__ = {".": ["numpy>=2.0"]} # When the technical debt is resolved, uncomment the line above -# and remove the lines similar to the ones below: -# >>> import pytest; version_check = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0) -# >>> pytest.skip("requires numpy>=2.0") if version_check else None # doctest: +SKIP +# and remove testsetup blocks that include comments like the one below: +# # Workaround for technical debt #251: Skip doctest if numpy<2.0 From f2c0f64837ae99a96dafc16691a57e01bac57e8d Mon Sep 17 00:00:00 2001 From: Kosta Ilic Date: Fri, 9 Jan 2026 21:59:10 -0600 Subject: [PATCH 6/6] Added a line per style guide check failure. Improved local variable names. Signed-off-by: Kosta Ilic --- src/nitypes/_arguments.py | 13 +++++++------ src/nitypes/complex/__init__.py | 4 ++-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/nitypes/_arguments.py b/src/nitypes/_arguments.py index b878bb22..9fd2a69e 100644 --- a/src/nitypes/_arguments.py +++ b/src/nitypes/_arguments.py @@ -23,6 +23,7 @@ # # Workaround for technical debt #251: Skip doctest if numpy<2.0 # >>> pytest.skip("requires numpy>=2.0") if version_check else None # doctest: +SKIP + def arg_to_float( arg_description: str, value: SupportsFloat | None, default_value: float | None = None ) -> float: @@ -33,8 +34,8 @@ def arg_to_float( # Workaround for technical debt #251: Skip doctest if numpy<2.0 import numpy as np import pytest - v = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0) - pytest.skip("requires numpy>=2.0") if v else None + numpy_version = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0) + pytest.skip("requires numpy>=2.0") if numpy_version else None >>> arg_to_float("xyz", 1.234) 1.234 @@ -160,8 +161,8 @@ def is_dtype(dtype: npt.DTypeLike, supported_dtypes: tuple[npt.DTypeLike, ...]) # Workaround for technical debt #251: Skip doctest if numpy<2.0 import numpy as np import pytest - v = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0) - pytest.skip("requires numpy>=2.0") if v else None + numpy_version = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0) + pytest.skip("requires numpy>=2.0") if numpy_version else None >>> is_dtype(np.float64, (np.float64, np.intc, np.long,)) True @@ -197,8 +198,8 @@ def validate_dtype(dtype: npt.DTypeLike, supported_dtypes: tuple[npt.DTypeLike, # Workaround for technical debt #251: Skip doctest if numpy<2.0 import numpy as np import pytest - v = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0) - pytest.skip("requires numpy>=2.0") if v else None + numpy_version = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0) + pytest.skip("requires numpy>=2.0") if numpy_version else None >>> validate_dtype(np.float64, (np.float64, np.intc, np.long,)) >>> validate_dtype("float64", (np.float64, np.intc, np.long,)) diff --git a/src/nitypes/complex/__init__.py b/src/nitypes/complex/__init__.py index f8655ce8..07e2a4e3 100644 --- a/src/nitypes/complex/__init__.py +++ b/src/nitypes/complex/__init__.py @@ -32,8 +32,8 @@ # Workaround for technical debt #251: Skip doctest if numpy<2.0 import numpy as np import pytest - v = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0) - pytest.skip("requires numpy>=2.0") if v else None + numpy_version = tuple(map(int, np.__version__.split(".")[:2])) < (2, 0) + pytest.skip("requires numpy>=2.0") if numpy_version else None >>> import numpy as np >>> np.array([(1, 2), (3, 4)], dtype=ComplexInt32DType)