diff --git a/conda/environments/all_cuda-129_arch-aarch64.yaml b/conda/environments/all_cuda-129_arch-aarch64.yaml index 2df4089d56..797b08e55b 100644 --- a/conda/environments/all_cuda-129_arch-aarch64.yaml +++ b/conda/environments/all_cuda-129_arch-aarch64.yaml @@ -22,6 +22,7 @@ dependencies: - dask-cuda==26.4.*,>=0.0.0a0 - dask-cudf==26.4.*,>=0.0.0a0 - dask-ml>=2024 +- docstring_parser - doxygen=1.9.1 - gcc_linux-aarch64=14.* - graphviz @@ -46,8 +47,6 @@ dependencies: - numba-cuda>=0.22.1 - numba>=0.60.0,<0.62.0 - numpy>=1.23,<3.0 -- numpydoc -- numpydoc<1.9 - nvidia-ml-py>=12 - packaging - pre-commit diff --git a/conda/environments/all_cuda-129_arch-x86_64.yaml b/conda/environments/all_cuda-129_arch-x86_64.yaml index ca8bb3592e..381fda1272 100644 --- a/conda/environments/all_cuda-129_arch-x86_64.yaml +++ b/conda/environments/all_cuda-129_arch-x86_64.yaml @@ -22,6 +22,7 @@ dependencies: - dask-cuda==26.4.*,>=0.0.0a0 - dask-cudf==26.4.*,>=0.0.0a0 - dask-ml>=2024 +- docstring_parser - doxygen=1.9.1 - gcc_linux-64=14.* - graphviz @@ -46,8 +47,6 @@ dependencies: - numba-cuda>=0.22.1 - numba>=0.60.0,<0.62.0 - numpy>=1.23,<3.0 -- numpydoc -- numpydoc<1.9 - nvidia-ml-py>=12 - packaging - pre-commit diff --git a/conda/environments/all_cuda-131_arch-aarch64.yaml b/conda/environments/all_cuda-131_arch-aarch64.yaml index b665397cd1..e6764bd9b2 100644 --- a/conda/environments/all_cuda-131_arch-aarch64.yaml +++ b/conda/environments/all_cuda-131_arch-aarch64.yaml @@ -22,6 +22,7 @@ dependencies: - dask-cuda==26.4.*,>=0.0.0a0 - dask-cudf==26.4.*,>=0.0.0a0 - dask-ml>=2024 +- docstring_parser - doxygen=1.9.1 - gcc_linux-aarch64=14.* - graphviz @@ -46,8 +47,6 @@ dependencies: - numba-cuda>=0.22.1 - numba>=0.60.0,<0.62.0 - numpy>=1.23,<3.0 -- numpydoc -- numpydoc<1.9 - nvidia-ml-py>=12 - packaging - pre-commit diff --git a/conda/environments/all_cuda-131_arch-x86_64.yaml b/conda/environments/all_cuda-131_arch-x86_64.yaml index e9ab5a8931..7f91c09e2e 100644 --- a/conda/environments/all_cuda-131_arch-x86_64.yaml +++ b/conda/environments/all_cuda-131_arch-x86_64.yaml @@ -22,6 +22,7 @@ dependencies: - dask-cuda==26.4.*,>=0.0.0a0 - dask-cudf==26.4.*,>=0.0.0a0 - dask-ml>=2024 +- docstring_parser - doxygen=1.9.1 - gcc_linux-64=14.* - graphviz @@ -46,8 +47,6 @@ dependencies: - numba-cuda>=0.22.1 - numba>=0.60.0,<0.62.0 - numpy>=1.23,<3.0 -- numpydoc -- numpydoc<1.9 - nvidia-ml-py>=12 - packaging - pre-commit diff --git a/dependencies.yaml b/dependencies.yaml index 9b048fc664..d5a8ecc4d6 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -400,7 +400,6 @@ dependencies: - ipython - ipykernel - nbsphinx - - numpydoc # https://github.com/pydata/pydata-sphinx-theme/issues/1539 - pydata-sphinx-theme!=0.14.2 - recommonmark @@ -496,8 +495,7 @@ dependencies: - hdbscan>=0.8.39,<0.8.40 - hypothesis>=6.0,<7 - nltk - # upstream sklearn docstring tests require numpydoc<1.9 - - numpydoc<1.9 + - docstring_parser # 'nvidia-ml-py' provides the 'pynvml' module - nvidia-ml-py>=12 - pyyaml diff --git a/python/cuml/pyproject.toml b/python/cuml/pyproject.toml index 15bc292953..f163af4792 100644 --- a/python/cuml/pyproject.toml +++ b/python/cuml/pyproject.toml @@ -108,11 +108,11 @@ classifiers = [ test = [ "certifi", "cython>=3.0.0,<3.2.0", + "docstring_parser", "hdbscan>=0.8.39,<0.8.40", "hypothesis>=6.0,<7", "ipython>=7.32.0", "nltk", - "numpydoc<1.9", "nvidia-ml-py>=12", "pynndescent", "pytest-benchmark", diff --git a/python/cuml/tests/test_base.py b/python/cuml/tests/test_base.py index 39db1b7998..3a65ebddfa 100644 --- a/python/cuml/tests/test_base.py +++ b/python/cuml/tests/test_base.py @@ -4,10 +4,11 @@ import inspect import numpy as np -import numpydoc.docscrape import pandas as pd import pylibraft.common.handle import pytest +from docstring_parser import DocstringStyle +from docstring_parser import parse as parse_docstring from sklearn.datasets import ( make_classification, make_multilabel_classification, @@ -74,8 +75,8 @@ class that derives from `Base`, We ensure that 1) the base arguments exist # verbose: r"^[ ]{4}verbose :.*\n(^(?![ ]{0,4}(?![ ]{4,})).*(\n))+" # handle: r"^[ ]{4}handle :.*\n(^(?![ ]{0,4}(?![ ]{4,})).*(\n))+" - def get_param_doc(param_doc_obj, name: str): - found_doc = next((x for x in param_doc_obj if x.name == name), None) + def get_param_doc(param_list, name: str): + found_doc = next((x for x in param_list if x.arg_name == name), None) assert found_doc is not None, "Could not find {} in docstring".format( name @@ -85,13 +86,17 @@ def get_param_doc(param_doc_obj, name: str): # Load the base class signature, parse the docstring and pull out params base_sig = inspect.signature(cuml.Base, follow_wrapped=True) - base_doc = numpydoc.docscrape.NumpyDocString(cuml.Base.__doc__) - base_doc_params = base_doc["Parameters"] + base_parsed = parse_docstring( + cuml.Base.__doc__ or "", style=DocstringStyle.NUMPYDOC + ) + base_doc_params = base_parsed.params or [] # Load the current class signature, parse the docstring and pull out params klass_sig = inspect.signature(klass, follow_wrapped=True) - klass_doc = numpydoc.docscrape.NumpyDocString(klass.__doc__ or "") - klass_doc_params = klass_doc["Parameters"] + klass_parsed = parse_docstring( + klass.__doc__ or "", style=DocstringStyle.NUMPYDOC + ) + klass_doc_params = klass_parsed.params or [] for name, param in base_sig.parameters.items(): # Ensure the base param exists in the derived @@ -113,12 +118,13 @@ def get_param_doc(param_doc_obj, name: str): base_item_doc = get_param_doc(base_doc_params, name) - assert found_doc.type == base_item_doc.type, ( + assert found_doc.type_name == base_item_doc.type_name, ( f"Docstring mismatch for {name}" ) - found = " ".join(found_doc.desc) - expected = " ".join(base_item_doc.desc) + # Normalize whitespace for comparison (content only, not formatting) + found = " ".join((found_doc.description or "").split()) + expected = " ".join((base_item_doc.description or "").split()) assert found == expected, f"Docstring mismatch for {name}"