Repository: cupy/cupy

Issue:
Several modules and classes are missing in comparison table
* modules: `numpy.polynomials.*`, `scipy.signal`, `scipy.stats`
* classes e.g. `numpy.vectorize`
* objects, e.g. `numpy.s_`


Discussion:

Resolving patch:
diff --git a/docs/source/_comparison_generator.py b/docs/source/_comparison_generator.py
--- a/docs/source/_comparison_generator.py
+++ b/docs/source/_comparison_generator.py
@@ -1,14 +1,24 @@
 import importlib
+import inspect
 
+import numpy
 
-def _get_functions(obj):
+
+def _get_functions(obj, exclude=[]):
     return set([
-        n for n in dir(obj)
-        if (n not in ['test']  # not in blacklist
-            and callable(getattr(obj, n))  # callable
-            and not isinstance(getattr(obj, n), type)  # not class
-            and n[0].islower()  # starts with lower char
-            and not n.startswith('__')  # not special methods
+        n for n, target in [(n, getattr(obj, n)) for n in dir(obj)]
+        if (
+            # not in exclude list
+            (exclude is None or n not in exclude)
+            # not module:
+            and not inspect.ismodule(target)
+            # not constant:
+            and not isinstance(target, (int, float, bool, str, numpy.bool_))
+            # not exceptions or warning classes:
+            and (not inspect.isclass(target) or
+                 not issubclass(target, (BaseException,)))
+            # not private/special method:
+            and not n.startswith('_')
             )
     ])
 
@@ -17,16 +27,16 @@ def _import(mod, klass):
     obj = importlib.import_module(mod)
     if klass:
         obj = getattr(obj, klass)
-        return obj, ':meth:`{}.{}.{{}}`'.format(mod, klass)
+        return obj, ':obj:`{}.{}.{{}}`'.format(mod, klass)
     else:
         # ufunc is not a function
         return obj, ':obj:`{}.{{}}`'.format(mod)
 
 
 def _generate_comparison_rst(
-        base_mod, cupy_mod, base_type, klass, exclude_mod):
+        base_mod, cupy_mod, base_type, klass, exclude_mod, exclude):
     base_obj, base_fmt = _import(base_mod, klass)
-    base_funcs = _get_functions(base_obj)
+    base_funcs = _get_functions(base_obj, exclude)
     cp_obj, cp_fmt = _import(cupy_mod, klass)
     cp_funcs = _get_functions(cp_obj)
 
@@ -60,20 +70,20 @@ def _generate_comparison_rst(
             len(cp_funcs & base_funcs)),
         '   CuPy specific functions:',
     ] + [
-        '   - {}'.format(f) for f in (cp_funcs - base_funcs)
+        '   - {}'.format(f) for f in sorted(cp_funcs - base_funcs)
     ]
     return buf
 
 
 def _section(
         header, base_mod, cupy_mod,
-        base_type='NumPy', klass=None, exclude=None):
+        base_type='NumPy', klass=None, exclude_mod=None, exclude=None):
     return [
         header,
         '~' * len(header),
         '',
     ] + _generate_comparison_rst(
-        base_mod, cupy_mod, base_type, klass, exclude
+        base_mod, cupy_mod, base_type, klass, exclude_mod, exclude
     ) + [
         '',
     ]
@@ -89,19 +99,27 @@ def generate():
     ]
     buf += _section(
         'Module-Level',
-        'numpy', 'cupy')
+        'numpy', 'cupy', exclude=[
+            'add_docstring',
+            'add_newdoc',
+            'add_newdoc_ufunc',
+            '_add_newdoc_ufunc',
+            'fastCopyAndTranspose',
+            'test',
+            'Tester',
+        ])
     buf += _section(
         'Multi-Dimensional Array',
         'numpy', 'cupy', klass='ndarray')
     buf += _section(
         'Linear Algebra',
-        'numpy.linalg', 'cupy.linalg')
+        'numpy.linalg', 'cupy.linalg', exclude=['test'])
     buf += _section(
         'Discrete Fourier Transform',
-        'numpy.fft', 'cupy.fft')
+        'numpy.fft', 'cupy.fft', exclude=['test'])
     buf += _section(
         'Random Sampling',
-        'numpy.random', 'cupy.random')
+        'numpy.random', 'cupy.random', exclude=['test'])
 
     buf += [
         'SciPy / CuPy APIs',
@@ -110,25 +128,39 @@ def generate():
     ]
     buf += _section(
         'Discrete Fourier Transform',
-        'scipy.fft', 'cupyx.scipy.fft', 'SciPy')
+        'scipy.fft', 'cupyx.scipy.fft', 'SciPy', exclude=['test'])
+    buf += _section(
+        'Legacy Discrete Fourier Transform',
+        'scipy.fftpack', 'cupyx.scipy.fftpack', 'SciPy', exclude=['test'])
+    buf += _section(
+        'Advanced Linear Algebra',
+        'scipy.linalg', 'cupyx.scipy.linalg', 'SciPy',
+        exclude_mod='numpy.linalg', exclude=['test'])
+    buf += _section(
+        'Multidimensional Image Processing',
+        'scipy.ndimage', 'cupyx.scipy.ndimage', 'SciPy', exclude=['test'])
     buf += _section(
-        'Discrete Fourier Transform (legacy fftpack module)',
-        'scipy.fftpack', 'cupyx.scipy.fftpack', 'SciPy')
+        'Signal processing',
+        'scipy.signal', 'cupyx.scipy.signal', 'SciPy', exclude=['test'])
     buf += _section(
         'Sparse Matrices',
-        'scipy.sparse', 'cupyx.scipy.sparse', 'SciPy')
+        'scipy.sparse', 'cupyx.scipy.sparse', 'SciPy', exclude=['test'])
     buf += _section(
         'Sparse Linear Algebra',
-        'scipy.sparse.linalg', 'cupyx.scipy.sparse.linalg', 'SciPy')
+        'scipy.sparse.linalg', 'cupyx.scipy.sparse.linalg', 'SciPy',
+        exclude=['test'])
     buf += _section(
-        'Advanced Linear Algebra',
-        'scipy.linalg', 'cupyx.scipy.linalg', 'SciPy', exclude='numpy.linalg')
-    buf += _section(
-        'Multidimensional Image Processing',
-        'scipy.ndimage', 'cupyx.scipy.ndimage', 'SciPy')
+        'Compressed sparse graph routines',
+        'scipy.sparse.csgraph', 'cupyx.scipy.sparse.csgraph', 'SciPy',
+        exclude=['test'])
     buf += _section(
         'Special Functions',
-        'scipy.special', 'cupyx.scipy.special', 'SciPy')
+        'scipy.special', 'cupyx.scipy.special', 'SciPy',
+        exclude=['test'])
+    buf += _section(
+        'Statistical Functions',
+        'scipy.stats', 'cupyx.scipy.stats', 'SciPy',
+        exclude=['test'])
 
     # numpy.array_api is not ready yet...
     #    buf += [


Test patch: