Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Napoleon Raises mutli-line description parsing #13126

Open
BalzaniEdoardo opened this issue Nov 12, 2024 · 1 comment
Open

Napoleon Raises mutli-line description parsing #13126

BalzaniEdoardo opened this issue Nov 12, 2024 · 1 comment

Comments

@BalzaniEdoardo
Copy link

Describe the bug

Multi-line description of Raises messages are concatenared into a single string interleaved by \n, this doesn't ultimately render in html (i.e. it renders as a single string).
I have napoleon

How to Reproduce

>>> from sphinx.ext.napoleon.docstring import NumpyDocstring
>>> import numpy as np
>>> out = NumpyDocstring(np.matmul.__doc__, obj=np.matmul)
>>> out._parsed_lines
["matmul(x1, x2, /, out=None, *, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj, axes, axis])",
 '',
 'Matrix product of two arrays.',
 '',
 ':param x1: Input arrays, scalars not allowed.',
 ':type x1: array_like',
 ':param x2: Input arrays, scalars not allowed.',
 ':type x2: array_like',
 ':param out: A location into which the result is stored. If provided, it must have',
 '            a shape that matches the signature `(n,k),(k,m)->(n,m)`. If not',
 '            provided or None, a freshly-allocated array is returned.',
 ':type out: ndarray, optional',
 ':param \\*\\*kwargs: For other keyword-only arguments, see the',
 '                   :ref:`ufunc docs <ufuncs.kwargs>`.',
 '',
 '                   .. versionadded:: 1.16',
 '                      Now handles ufunc kwargs',
 '',
 ':returns: **y** -- The matrix product of the inputs.',
 '          This is a scalar only when both x1, x2 are 1-d vectors.',
 ':rtype: ndarray',
 '',
 ':raises ValueError: If the last dimension of `x1` is not the same size as\n    the second-to-last dimension of `x2`.\n    \n    If a scalar value is passed in.',
 '',
 '.. seealso::',
 '',
 '   :obj:`vdot`',
 '       Complex-conjugating dot product.',
 '   ',
 '   :obj:`tensordot`',
 '       Sum products over arbitrary axes.',
 '   ',
 '   :obj:`einsum`',
 '       Einstein summation convention.',
 '   ',
 '   :obj:`dot`',
 '       alternative matrix product with different broadcasting rules.',
 '',
 '.. rubric:: Notes',
 '',
 'The behavior depends on the arguments in the following way.',
 '',
 '- If both arguments are 2-D they are multiplied like conventional',
 '  matrices.',
 '- If either argument is N-D, N > 2, it is treated as a stack of',
 '  matrices residing in the last two indexes and broadcast accordingly.',
 '- If the first argument is 1-D, it is promoted to a matrix by',
 '  prepending a 1 to its dimensions. After matrix multiplication',
 '  the prepended 1 is removed.',
 '- If the second argument is 1-D, it is promoted to a matrix by',
 '  appending a 1 to its dimensions. After matrix multiplication',
 '  the appended 1 is removed.',
 '',
 '``matmul`` differs from ``dot`` in two important ways:',
 '',
 '- Multiplication by scalars is not allowed, use ``*`` instead.',
 '- Stacks of matrices are broadcast together as if the matrices',
 '  were elements, respecting the signature ``(n,k),(k,m)->(n,m)``:',
 '',
 '  >>> a = np.ones([9, 5, 7, 4])',
 '  >>> c = np.ones([9, 5, 4, 3])',
 '  >>> np.dot(a, c).shape',
 '  (9, 5, 7, 9, 5, 3)',
 '  >>> np.matmul(a, c).shape',
 '  (9, 5, 7, 3)',
 '  >>> # n is 7, k is 4, m is 3',
 '',
 'The matmul function implements the semantics of the ``@`` operator',
 'introduced in Python 3.5 following :pep:`465`.',
 '',
 'It uses an optimized BLAS library when possible (see `numpy.linalg`).',
 '',
 '.. rubric:: Examples',
 '',
 'For 2-D arrays it is the matrix product:',
 '',
 '>>> a = np.array([[1, 0],',
 '...               [0, 1]])',
 '>>> b = np.array([[4, 1],',
 '...               [2, 2]])',
 '>>> np.matmul(a, b)',
 'array([[4, 1],',
 '       [2, 2]])',
 '',
 'For 2-D mixed with 1-D, the result is the usual.',
 '',
 '>>> a = np.array([[1, 0],',
 '...               [0, 1]])',
 '>>> b = np.array([1, 2])',
 '>>> np.matmul(a, b)',
 'array([1, 2])',
 '>>> np.matmul(b, a)',
 'array([1, 2])',
 '',
 'Broadcasting is conventional for stacks of arrays',
 '',
 '>>> a = np.arange(2 * 2 * 4).reshape((2, 2, 4))',
 '>>> b = np.arange(2 * 2 * 4).reshape((2, 4, 2))',
 '>>> np.matmul(a,b).shape',
 '(2, 2, 2)',
 '>>> np.matmul(a, b)[0, 1, 1]',
 '98',
 '>>> sum(a[0, 1, :] * b[0 , :, 1])',
 '98',
 '',
 'Vector, vector returns the scalar inner product, but neither argument',
 'is complex-conjugated:',
 '',
 '>>> np.matmul([2j, 3j], [2j, 3j])',
 '(-13+0j)',
 '',
 'Scalar multiplication raises an error.',
 '',
 '>>> np.matmul([1,2], 3)',
 'Traceback (most recent call last):',
 '...',
 'ValueError: matmul: Input operand 1 does not have enough dimensions ...',
 '',
 'The ``@`` operator can be used as a shorthand for ``np.matmul`` on',
 'ndarrays.',
 '',
 '>>> x1 = np.array([2j, 3j])',
 '>>> x2 = np.array([2j, 3j])',
 '>>> x1 @ x2',
 '(-13+0j)',
 '',
 '.. versionadded:: 1.10.0']

Here you can see the ValueError description differs form the out parameter description, the former is a single string, the latter has multiple list entry with proper indent.

Environment Information

Platform:              darwin; (macOS-14.7-arm64-arm-64bit)
Python version:        3.10.11 (main, Feb 21 2024, 15:26:02) [Clang 15.0.0 (clang-1500.1.0.2.5)])
Python implementation: CPython
Sphinx version:        8.1.3
Docutils version:      0.21.2
Jinja2 version:        3.1.4
Pygments version:      2.18.0

Sphinx extensions

>>> from sphinx.ext.napoleon.docstring import NumpyDocstring
>>> import numpy as np
>>> out = NumpyDocstring(np.matmul.__doc__, obj=np.matmul)
>>> out._parsed_lines

As shown before, the output of the ValueError description is a single string which ultimately won't render as multi-line in HTML

Additional context

No response

@BalzaniEdoardo
Copy link
Author

The processing happens in sphinx/ext/napoleon/doscring.py, in the _parse_raises_section function, line 800.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants