Repository: pydata/xarray

Issue:
Dataset.copy() drops encoding
```
ds = Dataset()
ds.encoding = {"unlimited_dims": 'x'}
ds.copy().encoding
{}
```
By looking at dataset.py, there's a lot of calls to ``Dataset._construct_direct`` that omit the encoding. Is it correct to add it in all cases?

Discussion:
crusaderky: Ready for merge if there's no objections
jhamman: Pending the outcome of our conversation on #1586, this looks good to me.

Patch:
diff --git a/doc/whats-new.rst b/doc/whats-new.rst
index 1b2fe3fb..5f3e855f 100644
--- a/doc/whats-new.rst
+++ b/doc/whats-new.rst
@@ -209,6 +209,10 @@ Bug fixes
   when objects other than  ``Dataset`` are provided (:issue:`1555`).
   By `Joe Hamman <https://github.com/jhamman>`_.
 
+- :py:func:`xarray.Dataset.copy` would not preserve the encoding property
+  (:issue:`1586`).
+  By `Guido Imperiale <https://github.com/crusaderky>`_.
+
 - :py:func:`xarray.concat` would eagerly load dask variables into memory if
   the first argument was a numpy variable (:issue:`1588`).
   By `Guido Imperiale <https://github.com/crusaderky>`_.
diff --git a/xarray/core/dataset.py b/xarray/core/dataset.py
index 5d975ffd..8eaecdde 100644
--- a/xarray/core/dataset.py
+++ b/xarray/core/dataset.py
@@ -634,7 +634,8 @@ class Dataset(Mapping, ImplementsDatasetReduce, BaseDataObject,
                                 for k, v in iteritems(self._variables))
         # skip __init__ to avoid costly validation
         return self._construct_direct(variables, self._coord_names.copy(),
-                                      self._dims.copy(), self._attrs_copy())
+                                      self._dims.copy(), self._attrs_copy(),
+                                      encoding=self.encoding)
 
     def _subset_with_all_valid_coords(self, variables, coord_names, attrs):
         needed_dims = set()


Test patch:
diff --git a/xarray/tests/test_dataset.py b/xarray/tests/test_dataset.py
index eda3b03a..b0cad11e 100644
--- a/xarray/tests/test_dataset.py
+++ b/xarray/tests/test_dataset.py
@@ -50,6 +50,7 @@ def create_test_data(seed=None):
         obj[v] = (dims, data, {'foo': 'variable'})
     obj.coords['numbers'] = ('dim3', np.array([0, 1, 2, 0, 0, 1, 1, 2, 2, 3],
                                               dtype='int64'))
+    obj.encoding = {'foo': 'bar'}
     assert all(obj.data.flags.writeable for obj in obj.values())
     return obj
 
@@ -1434,6 +1435,7 @@ class TestDataset(TestCase):
 
         for copied in [data.copy(deep=False), copy(data)]:
             self.assertDatasetIdentical(data, copied)
+            self.assertEqual(data.encoding, copied.encoding)
             # Note: IndexVariable objects with string dtype are always
             # copied because of xarray.core.util.safe_cast_to_index.
             # Limiting the test to data variables.