Repository: numpy/numpy

Issue:
DOC: numpy.ma.sort and copying behaviour
I started out thinking I've found a docbug but I'm becoming less sure. The problem is that [the documentation of `numpy.ma.sort`](https://docs.scipy.org/doc/numpy/reference/generated/numpy.ma.sort.html) ([devdocs version](https://numpy.org/devdocs/reference/generated/numpy.ma.sort.html#numpy.ma.sort)) says
> Sort the array, in-place
> [...]
> Returns: `sorted_array`

Whereas the behaviour seems to be the opposite:
```py
>>> import numpy as np
>>> arr = np.arange(5)[::-1]
>>> np.ma.sort(arr)
array([0, 1, 2, 3, 4])
>>> arr
array([4, 3, 2, 1, 0])
```

The weird thing is that I've found https://github.com/numpy/numpy/issues/1966 which suggests that until 2010 the docs had mentioned a copy and the behaviour was mutating, and the docstring was subsequently fixed. However looking at the git blame even [in commit 5cb370e923 from 2008](https://github.com/numpy/numpy/blob/5cb370e9234582f62231384c26a426301dad3331/numpy/ma/core.py#L2859) I can see
```py
from numpy import array as narray
# [...]
def sort(...):
    a = narray(a, copy=True, subok=True)
```
This seems to me that even in 2008 it should have returned a copy, which makes the linked docbug issue very confusing. What am I missing?

Ultimately I think this is a docbug, because `np.ma.sort` should match `np.sort` which copies (and is documented as such), whereas the corresponding instance methods should sort in-place.


Discussion:
You are right, the documentation is incorrect. The issue is that the function `np.ma.sort()` does and should copy, while the method `np.ma.MaskedArray.sort()` does not, and should not, copy.

The issue is that the documentation for both function is identical (the function just uses the methods documentation), which is incorrect with respect to the in-place behaviour.
@seberg thanks for the feedback. I was expecting some deep magic deciding which docstring to use, but then I noticed
```py
sort.__doc__ = MaskedArray.sort.__doc__
```

The question is whether the rest of the docstring could/should be copied over to `np.ma.sort` instead. I've never had to use masked arrays before, but it seems to me that `np.ma.sort` falls back on `np.ma.MaskedArray.sort` (after the copy). So unless there are some subtleties with the `axis` kwarg then I suspect the two docstrings _can_ agree. But then they have to be maintained independently.

And I've just noticed that some links to other sort functions are missing in "See also" and the "Notes" (see doc links in my first post). If these are missing as an oversight then these could also be fixed at the same time.

Resolving patch:
diff --git a/numpy/ma/core.py b/numpy/ma/core.py
--- a/numpy/ma/core.py
+++ b/numpy/ma/core.py
@@ -6824,7 +6824,18 @@ def argsort(a, axis=np._NoValue, kind=None, order=None, endwith=True, fill_value
 argsort.__doc__ = MaskedArray.argsort.__doc__
 
 def sort(a, axis=-1, kind=None, order=None, endwith=True, fill_value=None):
-    "Function version of the eponymous method."
+    """
+    Return a sorted copy of the masked array.
+
+    Equivalent to creating a copy of the array
+    and applying the  MaskedArray ``sort()`` method.
+
+    Refer to ``MaskedArray.sort`` for the full documentation
+
+    See Also
+    --------
+    MaskedArray.sort : equivalent method
+    """
     a = np.array(a, copy=True, subok=True)
     if axis is None:
         a = a.flatten()
@@ -6836,7 +6847,6 @@ def sort(a, axis=-1, kind=None, order=None, endwith=True, fill_value=None):
     else:
         a.sort(axis=axis, kind=kind, order=order)
     return a
-sort.__doc__ = MaskedArray.sort.__doc__
 
 
 def compressed(x):


Test patch: