diff options
author | Charles Harris <charlesr.harris@gmail.com> | 2017-05-09 08:12:53 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-09 08:12:53 -0600 |
commit | beb4ae2b994d5315397211daab51431c611cce8c (patch) | |
tree | 3a9f7b47c1ea67662c5d999e7be27f142e6f15d7 | |
parent | c11628abd820a1f44b052ea87af810f8f00cf2e4 (diff) | |
parent | 2e3202649692815e973f0e72820d25d5e536910d (diff) | |
download | python-numpy-beb4ae2b994d5315397211daab51431c611cce8c.tar.gz python-numpy-beb4ae2b994d5315397211daab51431c611cce8c.tar.bz2 python-numpy-beb4ae2b994d5315397211daab51431c611cce8c.zip |
Merge pull request #9026 from eric-wieser/ufunc_docstrings
ENH: Show full PEP 457 argument lists for ufuncs
-rw-r--r-- | doc/source/reference/ufuncs.rst | 2 | ||||
-rw-r--r-- | numpy/add_newdocs.py | 58 | ||||
-rw-r--r-- | numpy/core/_internal.py | 45 | ||||
-rw-r--r-- | numpy/core/code_generators/ufunc_docstrings.py | 207 | ||||
-rw-r--r-- | numpy/core/src/umath/ufunc_object.c | 77 | ||||
-rw-r--r-- | numpy/core/tests/test_umath.py | 9 |
6 files changed, 197 insertions, 201 deletions
diff --git a/doc/source/reference/ufuncs.rst b/doc/source/reference/ufuncs.rst index 34ad36a0b..b3fb4d384 100644 --- a/doc/source/reference/ufuncs.rst +++ b/doc/source/reference/ufuncs.rst @@ -286,6 +286,8 @@ them by defining certain special methods. For details, see :class:`ufunc` ============== +.. _ufuncs.kwargs: + Optional keyword arguments -------------------------- diff --git a/numpy/add_newdocs.py b/numpy/add_newdocs.py index df79ae136..449196efb 100644 --- a/numpy/add_newdocs.py +++ b/numpy/add_newdocs.py @@ -5421,40 +5421,19 @@ add_newdoc('numpy.core', 'ufunc', """ Functions that operate element by element on whole arrays. - To see the documentation for a specific ufunc, use np.info(). For - example, np.info(np.sin). Because ufuncs are written in C + To see the documentation for a specific ufunc, use `info`. For + example, ``np.info(np.sin)``. Because ufuncs are written in C (for speed) and linked into Python with NumPy's ufunc facility, Python's help() function finds this page whenever help() is called on a ufunc. - A detailed explanation of ufuncs can be found in the "ufuncs.rst" - file in the NumPy reference guide. + A detailed explanation of ufuncs can be found in the docs for :ref:`ufuncs`. - Unary ufuncs: - ============= + Calling ufuncs: + =============== - op(X, out=None) - Apply op to X elementwise - - Parameters - ---------- - X : array_like - Input array. - out : array_like - An array to store the output. Must be the same shape as `X`. - - Returns - ------- - r : array_like - `r` will have the same shape as `X`; if out is provided, `r` - will be equal to out. - - Binary ufuncs: - ============== - - op(X, Y, out=None) - Apply `op` to `X` and `Y` elementwise. May "broadcast" to make - the shapes of `X` and `Y` congruent. + op(*x[, out], where=True, **kwargs) + Apply `op` to the arguments `*x` elementwise, broadcasting the arguments. The broadcasting rules are: @@ -5463,18 +5442,23 @@ add_newdoc('numpy.core', 'ufunc', Parameters ---------- - X : array_like - First input array. - Y : array_like - Second input array. - out : array_like - An array to store the output. Must be the same shape as the - output would have. + *x : array_like + Input arrays. + out : ndarray or tuple of ndarray, optional + Alternate array object(s) in which to put the result; if provided, it + must have a shape that the inputs broadcast to. + where : array_like, optional + Values of True indicate to calculate the ufunc at that position, values + of False indicate to leave the value in the output alone. + **kwargs + For other keyword-only arguments, see the :ref:`ufunc docs <ufuncs.kwargs>`. Returns ------- - r : array_like - The return value; if out is provided, `r` will be equal to out. + r : ndarray or tuple of ndarray + `r` will have the shape that the arrays in `x` broadcast to; if `out` is + provided, `r` will be equal to `out`. If the function has more than one + output, then the result will be a tuple of arrays. """) diff --git a/numpy/core/_internal.py b/numpy/core/_internal.py index f2f24bcc5..c890eba17 100644 --- a/numpy/core/_internal.py +++ b/numpy/core/_internal.py @@ -670,3 +670,48 @@ def array_ufunc_errmsg_formatter(ufunc, method, *inputs, **kwargs): return ('operand type(s) do not implement __array_ufunc__' '({!r}, {!r}, {}): {}' .format(ufunc, method, args_string, types_string)) + +def _ufunc_doc_signature_formatter(ufunc): + """ + Builds a signature string which resembles PEP 457 + + This is used to construct the first line of the docstring + """ + + # input arguments are simple + if ufunc.nin == 1: + in_args = 'x' + else: + in_args = ', '.join('x{}'.format(i+1) for i in range(ufunc.nin)) + + # output arguments are both keyword or positional + if ufunc.nout == 0: + out_args = ', /, out=()' + elif ufunc.nout == 1: + out_args = ', /, out=None' + else: + out_args = '[, {positional}], / [, out={default}]'.format( + positional=', '.join( + 'out{}'.format(i+1) for i in range(ufunc.nout)), + default=repr((None,)*ufunc.nout) + ) + + # keyword only args depend on whether this is a gufunc + kwargs = ( + ", casting='same_kind'" + ", order='K'" + ", dtype=None" + ", subok=True" + "[, signature" + ", extobj]" + ) + if ufunc.signature is None: + kwargs = ", where=True" + kwargs + + # join all the parts together + return '{name}({in_args}{out_args}, *{kwargs})'.format( + name=ufunc.__name__, + in_args=in_args, + out_args=out_args, + kwargs=kwargs + ) diff --git a/numpy/core/code_generators/ufunc_docstrings.py b/numpy/core/code_generators/ufunc_docstrings.py index 11f956b81..7beda59f2 100644 --- a/numpy/core/code_generators/ufunc_docstrings.py +++ b/numpy/core/code_generators/ufunc_docstrings.py @@ -10,13 +10,30 @@ at compile time. """ from __future__ import division, absolute_import, print_function +import textwrap docdict = {} def get(name): return docdict.get(name) +# common parameter text to all ufuncs +_params_text = textwrap.dedent(""" + out : ndarray or tuple of ndarray, optional + Alternate array object(s) in which to put the result; if provided, it + must have a shape that the inputs broadcast to. + where : array_like, optional + Values of True indicate to calculate the ufunc at that position, values + of False indicate to leave the value in the output alone. + **kwargs + For other keyword-only arguments, see the + :ref:`ufunc docs <ufuncs.kwargs>`. +""").strip() + def add_newdoc(place, name, doc): + doc = textwrap.dedent(doc).strip() + doc = doc.replace('$PARAMS', _params_text) + docdict['.'.join((place, name))] = doc @@ -28,6 +45,7 @@ add_newdoc('numpy.core.umath', 'absolute', ---------- x : array_like Input array. + $PARAMS Returns ------- @@ -70,6 +88,7 @@ add_newdoc('numpy.core.umath', 'add', The arrays to be added. If ``x1.shape != x2.shape``, they must be broadcastable to a common shape (which may be the shape of one or the other). + $PARAMS Returns ------- @@ -105,10 +124,7 @@ add_newdoc('numpy.core.umath', 'arccos', x : array_like `x`-coordinate on the unit circle. For real arguments, the domain is [-1, 1]. - - out : ndarray, optional - Array of the same shape as `a`, to store results in. See - `doc.ufuncs` (Section "Output arguments") for more details. + $PARAMS Returns ------- @@ -168,10 +184,7 @@ add_newdoc('numpy.core.umath', 'arccosh', ---------- x : array_like Input array. - out : ndarray, optional - Array of the same shape as `x`, to store results in. - See `doc.ufuncs` (Section "Output arguments") for details. - + $PARAMS Returns ------- @@ -221,10 +234,7 @@ add_newdoc('numpy.core.umath', 'arcsin', ---------- x : array_like `y`-coordinate on the unit circle. - - out : ndarray, optional - Array of the same shape as `x`, in which to store the results. - See `doc.ufuncs` (Section "Output arguments") for more details. + $PARAMS Returns ------- @@ -278,9 +288,7 @@ add_newdoc('numpy.core.umath', 'arcsinh', ---------- x : array_like Input array. - out : ndarray, optional - Array into which the output is placed. Its type is preserved and it - must be of the right shape to hold the output. See `doc.ufuncs`. + $PARAMS Returns ------- @@ -326,7 +334,7 @@ add_newdoc('numpy.core.umath', 'arctan', Parameters ---------- x : array_like - Input values. `arctan` is applied to each element of `x`. + $PARAMS Returns ------- @@ -406,6 +414,7 @@ add_newdoc('numpy.core.umath', 'arctan2', x2 : array_like, real-valued `x`-coordinates. `x2` must be broadcastable to match the shape of `x1` or vice versa. + $PARAMS Returns ------- @@ -473,6 +482,7 @@ add_newdoc('numpy.core.umath', 'arctanh', ---------- x : array_like Input array. + $PARAMS Returns ------- @@ -525,6 +535,7 @@ add_newdoc('numpy.core.umath', 'bitwise_and', ---------- x1, x2 : array_like Only integer and boolean types are handled. + $PARAMS Returns ------- @@ -576,9 +587,7 @@ add_newdoc('numpy.core.umath', 'bitwise_or', ---------- x1, x2 : array_like Only integer and boolean types are handled. - out : ndarray, optional - Array into which the output is placed. Its type is preserved and it - must be of the right shape to hold the output. See doc.ufuncs. + $PARAMS Returns ------- @@ -635,6 +644,7 @@ add_newdoc('numpy.core.umath', 'bitwise_xor', ---------- x1, x2 : array_like Only integer and boolean types are handled. + $PARAMS Returns ------- @@ -683,6 +693,7 @@ add_newdoc('numpy.core.umath', 'ceil', ---------- x : array_like Input data. + $PARAMS Returns ------- @@ -713,6 +724,7 @@ add_newdoc('numpy.core.umath', 'trunc', ---------- x : array_like Input data. + $PARAMS Returns ------- @@ -746,6 +758,7 @@ add_newdoc('numpy.core.umath', 'conjugate', ---------- x : array_like Input value. + $PARAMS Returns ------- @@ -772,19 +785,13 @@ add_newdoc('numpy.core.umath', 'cos', ---------- x : array_like Input array in radians. - out : ndarray, optional - Output array of same shape as `x`. + $PARAMS Returns ------- y : ndarray The corresponding cosine values. - Raises - ------ - ValueError: invalid return array shape - if `out` is provided and `out.shape` != `x.shape` (See Examples) - Notes ----- If `out` is provided, the function writes the result into it, @@ -823,6 +830,7 @@ add_newdoc('numpy.core.umath', 'cosh', ---------- x : array_like Input array. + $PARAMS Returns ------- @@ -851,8 +859,7 @@ add_newdoc('numpy.core.umath', 'degrees', ---------- x : array_like Input array in radians. - out : ndarray, optional - Output array of same shape as x. + $PARAMS Returns ------- @@ -888,9 +895,7 @@ add_newdoc('numpy.core.umath', 'rad2deg', ---------- x : array_like Angle in radians. - out : ndarray, optional - Array into which the output is placed. Its type is preserved and it - must be of the right shape to hold the output. See doc.ufuncs. + $PARAMS Returns ------- @@ -931,11 +936,10 @@ add_newdoc('numpy.core.umath', 'heaviside', ---------- x : array_like Input values. + $PARAMS h0 : array_like The value of the function at x = 0. - out : ndarray, optional - Array into which the output is placed. Its type is preserved and it - must be of the right shape to hold the output. See doc.ufuncs. + $PARAMS Returns ------- @@ -969,9 +973,7 @@ add_newdoc('numpy.core.umath', 'divide', Dividend array. x2 : array_like Divisor array. - out : ndarray, optional - Array into which the output is placed. Its type is preserved and it - must be of the right shape to hold the output. See doc.ufuncs. + $PARAMS Returns ------- @@ -1040,6 +1042,7 @@ add_newdoc('numpy.core.umath', 'equal', ---------- x1, x2 : array_like Input arrays of the same shape. + $PARAMS Returns ------- @@ -1071,6 +1074,7 @@ add_newdoc('numpy.core.umath', 'exp', ---------- x : array_like Input values. + $PARAMS Returns ------- @@ -1134,9 +1138,7 @@ add_newdoc('numpy.core.umath', 'exp2', ---------- x : array_like Input values. - - out : ndarray, optional - Array to insert results into. + $PARAMS Returns ------- @@ -1168,6 +1170,7 @@ add_newdoc('numpy.core.umath', 'expm1', ---------- x : array_like Input values. + $PARAMS Returns ------- @@ -1210,9 +1213,7 @@ add_newdoc('numpy.core.umath', 'fabs', x : array_like The array of numbers for which the absolute values are required. If `x` is a scalar, the result `y` will also be a scalar. - out : ndarray, optional - Array into which the output is placed. Its type is preserved and it - must be of the right shape to hold the output. See doc.ufuncs. + $PARAMS Returns ------- @@ -1243,6 +1244,7 @@ add_newdoc('numpy.core.umath', 'floor', ---------- x : array_like Input data. + $PARAMS Returns ------- @@ -1280,6 +1282,7 @@ add_newdoc('numpy.core.umath', 'floor_divide', Numerator. x2 : array_like Denominator. + $PARAMS Returns ------- @@ -1319,6 +1322,7 @@ add_newdoc('numpy.core.umath', 'fmod', Dividend. x2 : array_like Divisor. + $PARAMS Returns ------- @@ -1369,6 +1373,7 @@ add_newdoc('numpy.core.umath', 'greater', Input arrays. If ``x1.shape != x2.shape``, they must be broadcastable to a common shape (which may be the shape of one or the other). + $PARAMS Returns ------- @@ -1404,6 +1409,7 @@ add_newdoc('numpy.core.umath', 'greater_equal', Input arrays. If ``x1.shape != x2.shape``, they must be broadcastable to a common shape (which may be the shape of one or the other). + $PARAMS Returns ------- @@ -1434,9 +1440,7 @@ add_newdoc('numpy.core.umath', 'hypot', ---------- x1, x2 : array_like Leg of the triangle(s). - out : ndarray, optional - Array into which the output is placed. Its type is preserved and it - must be of the right shape to hold the output. See doc.ufuncs. + $PARAMS Returns ------- @@ -1476,8 +1480,9 @@ add_newdoc('numpy.core.umath', 'invert', Parameters ---------- - x1 : array_like + x : array_like Only integer and boolean types are handled. + $PARAMS Returns ------- @@ -1549,9 +1554,7 @@ add_newdoc('numpy.core.umath', 'isfinite', ---------- x : array_like Input values. - out : ndarray, optional - Array into which the output is placed. Its type is preserved and it - must be of the right shape to hold the output. See `doc.ufuncs`. + $PARAMS Returns ------- @@ -1617,8 +1620,7 @@ add_newdoc('numpy.core.umath', 'isinf', ---------- x : array_like Input values - out : array_like, optional - An array with the same shape as `x` to store the result. + $PARAMS Returns ------- @@ -1677,6 +1679,7 @@ add_newdoc('numpy.core.umath', 'isnan', ---------- x : array_like Input array. + $PARAMS Returns ------- @@ -1758,6 +1761,7 @@ add_newdoc('numpy.core.umath', 'left_shift', Input values. x2 : array_like of integer type Number of zeros to append to `x1`. Has to be non-negative. + $PARAMS Returns ------- @@ -1794,6 +1798,7 @@ add_newdoc('numpy.core.umath', 'less', Input arrays. If ``x1.shape != x2.shape``, they must be broadcastable to a common shape (which may be the shape of one or the other). + $PARAMS Returns ------- @@ -1821,6 +1826,7 @@ add_newdoc('numpy.core.umath', 'less_equal', Input arrays. If ``x1.shape != x2.shape``, they must be broadcastable to a common shape (which may be the shape of one or the other). + $PARAMS Returns ------- @@ -1850,6 +1856,7 @@ add_newdoc('numpy.core.umath', 'log', ---------- x : array_like Input value. + $PARAMS Returns ------- @@ -1896,6 +1903,7 @@ add_newdoc('numpy.core.umath', 'log10', ---------- x : array_like Input values. + $PARAMS Returns ------- @@ -1943,6 +1951,7 @@ add_newdoc('numpy.core.umath', 'log2', ---------- x : array_like Input values. + $PARAMS Returns ------- @@ -1996,6 +2005,7 @@ add_newdoc('numpy.core.umath', 'logaddexp', ---------- x1, x2 : array_like Input values. + $PARAMS Returns ------- @@ -2036,8 +2046,7 @@ add_newdoc('numpy.core.umath', 'logaddexp2', ---------- x1, x2 : array_like Input values. - out : ndarray, optional - Array to store results in. + $PARAMS Returns ------- @@ -2074,6 +2083,7 @@ add_newdoc('numpy.core.umath', 'log1p', ---------- x : array_like Input values. + $PARAMS Returns ------- @@ -2125,7 +2135,7 @@ add_newdoc('numpy.core.umath', 'logical_and', ---------- x1, x2 : array_like Input arrays. `x1` and `x2` must be of the same shape. - + $PARAMS Returns ------- @@ -2159,6 +2169,7 @@ add_newdoc('numpy.core.umath', 'logical_not', ---------- x : array_like Logical NOT is applied to the elements of `x`. + $PARAMS Returns ------- @@ -2192,6 +2203,7 @@ add_newdoc('numpy.core.umath', 'logical_or', x1, x2 : array_like Logical OR is applied to the elements of `x1` and `x2`. They have to be of the same shape. + $PARAMS Returns ------- @@ -2226,6 +2238,7 @@ add_newdoc('numpy.core.umath', 'logical_xor', x1, x2 : array_like Logical XOR is applied to the elements of `x1` and `x2`. They must be broadcastable to the same shape. + $PARAMS Returns ------- @@ -2273,6 +2286,7 @@ add_newdoc('numpy.core.umath', 'maximum', x1, x2 : array_like The arrays holding the elements to be compared. They must have the same shape, or shapes that can be broadcast to a single shape. + $PARAMS Returns ------- @@ -2331,6 +2345,7 @@ add_newdoc('numpy.core.umath', 'minimum', x1, x2 : array_like The arrays holding the elements to be compared. They must have the same shape, or shapes that can be broadcast to a single shape. + $PARAMS Returns ------- @@ -2389,6 +2404,7 @@ add_newdoc('numpy.core.umath', 'fmax', x1, x2 : array_like The arrays holding the elements to be compared. They must have the same shape. + $PARAMS Returns ------- @@ -2446,6 +2462,7 @@ add_newdoc('numpy.core.umath', 'fmin', x1, x2 : array_like The arrays holding the elements to be compared. They must have the same shape. + $PARAMS Returns ------- @@ -2498,6 +2515,7 @@ add_newdoc('numpy.core.umath', 'modf', ---------- x : array_like Input array. + $PARAMS Returns ------- @@ -2532,6 +2550,7 @@ add_newdoc('numpy.core.umath', 'multiply', ---------- x1, x2 : array_like Input arrays to be multiplied. + $PARAMS Returns ------- @@ -2565,6 +2584,7 @@ add_newdoc('numpy.core.umath', 'negative', ---------- x : array_like or scalar Input array. + $PARAMS Returns ------- @@ -2609,9 +2629,7 @@ add_newdoc('numpy.core.umath', 'not_equal', ---------- x1, x2 : array_like Input arrays. - out : ndarray, optional - A placeholder the same shape as `x1` to store the result. - See `doc.ufuncs` (Section "Output arguments") for more details. + $PARAMS Returns ------- @@ -2660,6 +2678,7 @@ add_newdoc('numpy.core.umath', 'power', The bases. x2 : array_like The exponents. + $PARAMS Returns ------- @@ -2717,6 +2736,7 @@ add_newdoc('numpy.core.umath', 'float_power', The bases. x2 : array_like The exponents. + $PARAMS Returns ------- @@ -2763,8 +2783,7 @@ add_newdoc('numpy.core.umath', 'radians', ---------- x : array_like Input array in degrees. - out : ndarray, optional - Output array of same shape as `x`. + $PARAMS Returns ------- @@ -2800,6 +2819,7 @@ add_newdoc('numpy.core.umath', 'deg2rad', ---------- x : array_like Angles in degrees. + $PARAMS Returns ------- @@ -2834,6 +2854,7 @@ add_newdoc('numpy.core.umath', 'reciprocal', ---------- x : array_like Input array. + $PARAMS Returns ------- @@ -2873,9 +2894,7 @@ add_newdoc('numpy.core.umath', 'remainder', Dividend array. x2 : array_like Divisor array. - out : ndarray, optional - Array into which the output is placed. Its type is preserved and it - must be of the right shape to hold the output. See doc.ufuncs. + $PARAMS Returns ------- @@ -2920,9 +2939,7 @@ add_newdoc('numpy.core.umath', 'divmod', Dividend array. x2 : array_like Divisor array. - out : tuple of ndarray, optional - Arrays into which the output is placed. Their types are preserved and - must be of the right shape to hold the output. + $PARAMS Returns ------- @@ -2959,6 +2976,7 @@ add_newdoc('numpy.core.umath', 'right_shift', Input values. x2 : array_like, int Number of bits to remove at the right of `x1`. + $PARAMS Returns ------- @@ -2993,6 +3011,7 @@ add_newdoc('numpy.core.umath', 'rint', ---------- x : array_like Input array. + $PARAMS Returns ------- @@ -3027,6 +3046,7 @@ add_newdoc('numpy.core.umath', 'sign', ---------- x : array_like Input values. + $PARAMS Returns ------- @@ -3058,9 +3078,7 @@ add_newdoc('numpy.core.umath', 'signbit', ---------- x : array_like The input value(s). - out : ndarray, optional - Array into which the output is placed. Its type is preserved and it - must be of the right shape to hold the output. See `doc.ufuncs`. + $PARAMS Returns ------- @@ -3090,9 +3108,7 @@ add_newdoc('numpy.core.umath', 'copysign', Values to change the sign of. x2 : array_like The sign of `x2` is copied to `x1`. - out : ndarray, optional - Array into which the output is placed. Its type is preserved and it - must be of the right shape to hold the output. See doc.ufuncs. + $PARAMS Returns ------- @@ -3125,9 +3141,7 @@ add_newdoc('numpy.core.umath', 'nextafter', Values to find the next representable value of. x2 : array_like The direction where to look for the next representable value of `x1`. - out : ndarray, optional - Array into which the output is placed. Its type is preserved and it - must be of the right shape to hold the output. See `doc.ufuncs`. + $PARAMS Returns ------- @@ -3150,8 +3164,9 @@ add_newdoc('numpy.core.umath', 'spacing', Parameters ---------- - x1 : array_like + x : array_like Values to find the spacing of. + $PARAMS Returns ------- @@ -3182,6 +3197,7 @@ add_newdoc('numpy.core.umath', 'sin', ---------- x : array_like Angle, in radians (:math:`2 \\pi` rad equals 360 degrees). + $PARAMS Returns ------- @@ -3241,19 +3257,13 @@ add_newdoc('numpy.core.umath', 'sinh', ---------- x : array_like Input array. - out : ndarray, optional - Output array of same shape as `x`. + $PARAMS Returns ------- y : ndarray The corresponding hyperbolic sine values. - Raises - ------ - ValueError: invalid return array shape - if `out` is provided and `out.shape` != `x.shape` (See Examples) - Notes ----- If `out` is provided, the function writes the result into it, @@ -3295,9 +3305,7 @@ add_newdoc('numpy.core.umath', 'sqrt', ---------- x : array_like The values whose square-roots are required. - out : ndarray, optional - Alternate array object in which to put the result; if provided, it - must have the same shape as `x` + $PARAMS Returns ------- @@ -3344,9 +3352,7 @@ add_newdoc('numpy.core.umath', 'cbrt', ---------- x : array_like The values whose cube-roots are required. - out : ndarray, optional - Alternate array object in which to put the result; if provided, it - must have the same shape as `x` + $PARAMS Returns ------- @@ -3371,6 +3377,7 @@ add_newdoc('numpy.core.umath', 'square', ---------- x : array_like Input data. + $PARAMS Returns ------- @@ -3399,6 +3406,7 @@ add_newdoc('numpy.core.umath', 'subtract', ---------- x1, x2 : array_like The arrays to be subtracted from each other. + $PARAMS Returns ------- @@ -3434,19 +3442,13 @@ add_newdoc('numpy.core.umath', 'tan', ---------- x : array_like Input array. - out : ndarray, optional - Output array of same shape as `x`. + $PARAMS Returns ------- y : ndarray The corresponding tangent values. - Raises - ------ - ValueError: invalid return array shape - if `out` is provided and `out.shape` != `x.shape` (See Examples) - Notes ----- If `out` is provided, the function writes the result into it, @@ -3487,19 +3489,13 @@ add_newdoc('numpy.core.umath', 'tanh', ---------- x : array_like Input array. - out : ndarray, optional - Output array of same shape as `x`. + $PARAMS Returns ------- y : ndarray The corresponding hyperbolic tangent values. - Raises - ------ - ValueError: invalid return array shape - if `out` is provided and `out.shape` != `x.shape` (See Examples) - Notes ----- If `out` is provided, the function writes the result into it, @@ -3547,6 +3543,7 @@ add_newdoc('numpy.core.umath', 'true_divide', Dividend array. x2 : array_like Divisor array. + $PARAMS Returns ------- @@ -3599,6 +3596,7 @@ add_newdoc('numpy.core.umath', 'frexp', Output array for the mantissa. Must have the same shape as `x`. out2 : ndarray, optional Output array for the exponent. Must have the same shape as `x`. + $PARAMS Returns ------- @@ -3641,8 +3639,7 @@ add_newdoc('numpy.core.umath', 'ldexp', Array of multipliers. x2 : array_like, int Array of twos exponents. - out : ndarray, optional - Output array for the result. + $PARAMS Returns ------- diff --git a/numpy/core/src/umath/ufunc_object.c b/numpy/core/src/umath/ufunc_object.c index 3a6c8e297..e1219039c 100644 --- a/numpy/core/src/umath/ufunc_object.c +++ b/numpy/core/src/umath/ufunc_object.c @@ -45,6 +45,7 @@ #include "ufunc_object.h" #include "override.h" +#include "npy_import.h" /********** PRINTF DEBUG TRACING **************/ #define NPY_UF_DBG_TRACING 0 @@ -5559,29 +5560,6 @@ static struct PyMethodDef ufunc_methods[] = { *****************************************************************************/ -/* construct the string y1,y2,...,yn */ -static PyObject * -_makeargs(int num, char *ltr, int null_if_none) -{ - PyObject *str; - int i; - - switch (num) { - case 0: - if (null_if_none) { - return NULL; - } - return PyString_FromString(""); - case 1: - return PyString_FromString(ltr); - } - str = PyString_FromFormat("%s1, %s2", ltr, ltr); - for (i = 3; i <= num; ++i) { - PyString_ConcatAndDel(&str, PyString_FromFormat(", %s%d", ltr, i)); - } - return str; -} - static char _typecharfromnum(int num) { PyArray_Descr *descr; @@ -5596,47 +5574,30 @@ _typecharfromnum(int num) { static PyObject * ufunc_get_doc(PyUFuncObject *ufunc) { + static PyObject *_sig_formatter; + PyObject *doc; + + npy_cache_import( + "numpy.core._internal", + "_ufunc_doc_signature_formatter", + &_sig_formatter); + + if (_sig_formatter == NULL) { + return NULL; + } + /* * Put docstring first or FindMethod finds it... could so some * introspection on name and nin + nout to automate the first part * of it the doc string shouldn't need the calling convention - * construct name(x1, x2, ...,[ out1, out2, ...]) __doc__ */ - PyObject *outargs, *inargs, *doc; - outargs = _makeargs(ufunc->nout, "out", 1); - inargs = _makeargs(ufunc->nin, "x", 0); - - if (ufunc->doc == NULL) { - if (outargs == NULL) { - doc = PyUString_FromFormat("%s(%s)\n\n", - ufunc->name, - PyString_AS_STRING(inargs)); - } - else { - doc = PyUString_FromFormat("%s(%s[, %s])\n\n", - ufunc->name, - PyString_AS_STRING(inargs), - PyString_AS_STRING(outargs)); - Py_DECREF(outargs); - } - } - else { - if (outargs == NULL) { - doc = PyUString_FromFormat("%s(%s)\n\n%s", - ufunc->name, - PyString_AS_STRING(inargs), - ufunc->doc); - } - else { - doc = PyUString_FromFormat("%s(%s[, %s])\n\n%s", - ufunc->name, - PyString_AS_STRING(inargs), - PyString_AS_STRING(outargs), - ufunc->doc); - Py_DECREF(outargs); - } + doc = PyObject_CallFunctionObjArgs( + _sig_formatter, (PyObject *)ufunc, NULL); + if (doc == NULL) { + return NULL; } - Py_DECREF(inargs); + PyUString_ConcatAndDel(&doc, + PyUString_FromFormat("\n\n%s", ufunc->doc)); return doc; } diff --git a/numpy/core/tests/test_umath.py b/numpy/core/tests/test_umath.py index 51bf7c942..13f29504a 100644 --- a/numpy/core/tests/test_umath.py +++ b/numpy/core/tests/test_umath.py @@ -2314,13 +2314,20 @@ class TestAttributes(TestCase): def test_attributes(self): add = ncu.add assert_equal(add.__name__, 'add') - assert_(add.__doc__.startswith('add(x1, x2[, out])\n\n')) self.assertTrue(add.ntypes >= 18) # don't fail if types added self.assertTrue('ii->i' in add.types) assert_equal(add.nin, 2) assert_equal(add.nout, 1) assert_equal(add.identity, 0) + def test_doc(self): + # don't bother checking the long list of kwargs, which are likely to + # change + assert_(ncu.add.__doc__.startswith( + "add(x1, x2, /, out=None, *, where=True")) + assert_(ncu.frexp.__doc__.startswith( + "frexp(x[, out1, out2], / [, out=(None, None)], *, where=True")) + class TestSubclass(TestCase): |