Repository: astropy/astropy

Issue:
Mask from MaskedColumn is not copied
When copying a masked table, the mask of MaskedColumn objects is not copied, which leads to weird result:

```
In [1]: %astropy
Numpy 1.14.2
Astropy 3.1.dev21681

In [2]: t = Table([[2,4,1,3,6], [3.,2.,np.nan,4,6]], names=('a', 'b'), masked=True)

In [3]: t['b'] = np.ma.masked_invalid(t['b'])

In [4]: t
Out[4]: 
<Table masked=True length=5>
  a      b   
int64 float64
----- -------
    2     3.0
    4     2.0
    1      --
    3     4.0
    6     6.0

In [5]: t2 = t.copy()

In [6]: t2.sort('a')

In [7]: t2
Out[7]: 
<Table masked=True length=5>
  a      b   
int64 float64
----- -------
    1      --
    2     3.0
    3     4.0
    4     2.0
    6     6.0

In [8]: t
Out[8]: 
<Table masked=True length=5>
  a      b   
int64 float64
----- -------
    2      --
    4     2.0
    1     nan
    3     4.0
    6     6.0
```

Looking at https://github.com/astropy/astropy/blob/master/astropy/table/column.py#L1122-L1133, It seems that the data is copied but not the mask. Maybe @mhvk ?

Discussion:

Patch:
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 5682ca2454..cdc2f339b4 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -8,7 +8,7 @@ jobs:
       - checkout
       - run:
           name: Install dependencies
-          command: /opt/python/cp36-cp36m/bin/pip install numpy scipy pytest-astropy pytest-xdist Cython jinja2
+          command: /opt/python/cp36-cp36m/bin/pip install numpy scipy "pytest<3.6" pytest-astropy pytest-xdist Cython jinja2
       - run:
           name: Run tests
           command: PYTHONHASHSEED=42 /opt/python/cp36-cp36m/bin/python setup.py test --parallel=4
diff --git a/CHANGES.rst b/CHANGES.rst
index 03066f86ca..5202a710b1 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -1039,6 +1039,10 @@ astropy.table
 
 - Fix printing table row indexed with unsigned integer. [#7469]
 
+- Fix copy of mask when copying a Table, as this is no more done systematically
+  by Numpy since version 1.14. Also fixed a problem when MaskedColumn was
+  initialized with ``mask=np.ma.nomask``. [#7486]
+
 astropy.tests
 ^^^^^^^^^^^^^
 
diff --git a/astropy/table/column.py b/astropy/table/column.py
index 4a5da021d0..c9cf19ab99 100644
--- a/astropy/table/column.py
+++ b/astropy/table/column.py
@@ -1115,13 +1115,17 @@ class MaskedColumn(Column, _MaskedColumnGetitemShim, ma.MaskedArray):
                 copy=False, copy_indices=True):
 
         if mask is None:
-            if hasattr(data, 'mask'):
-                mask = data.mask
-            else:
-                # Issue #7399 with fix #7422.  Passing mask=None to ma.MaskedArray
-                # is extremely slow (~3 seconds for 1e7 elements), while mask=False
-                # gets quickly broadcast to the expected bool array of False.
-                mask = False
+            # Issue #7399 with fix #7422.  Passing mask=None to ma.MaskedArray
+            # is extremely slow (~3 seconds for 1e7 elements), while mask=False
+            # gets quickly broadcast to the expected bool array of False.
+            mask = getattr(data, 'mask', False)
+            if mask is not False:
+                mask = np.array(mask, copy=copy)
+        elif mask is np.ma.nomask:
+            # Force the creation of a full mask array as nomask is tricky to
+            # use and will fail in an unexpected manner when setting a value
+            # to the mask.
+            mask = False
         else:
             mask = deepcopy(mask)
 


Test patch:
diff --git a/astropy/table/tests/test_masked.py b/astropy/table/tests/test_masked.py
index 571e335b73..06b8dc4480 100644
--- a/astropy/table/tests/test_masked.py
+++ b/astropy/table/tests/test_masked.py
@@ -414,3 +414,13 @@ def test_coercing_fill_value_type():
     c.set_fill_value('0')
     c2 = MaskedColumn(c, dtype=np.int32)
     assert isinstance(c2.fill_value, np.int32)
+
+
+def test_mask_copy():
+    """Test that the mask is copied when copying a table (issue #7362)."""
+
+    c = MaskedColumn([1, 2], mask=[False, True])
+    c2 = MaskedColumn(c, copy=True)
+    c2.mask[0] = True
+    assert np.all(c.mask == [False, True])
+    assert np.all(c2.mask == [True, True])