Repository: NCAS-CMS/cfdm

Issue:
File name expansions do not work in `cfdm.write`
At cfdm 1.8.9.0, tilde and environment variable file name  expansions no longer work in `cfdm.write`:

```python
>>> import cfdm
>>> f = cfdm.example_field(0)
>>> cfdm.write(f, 'test_file.nc')  # OK
>>> cfdm.write(f, '~/test_file.nc')  # Not OK
    ...
PermissionError: [Errno 13] Permission denied: b'/home/david/~/test_file.nc'
>>> cfdm.write(f, ''$HOME/test_file.nc')  # Not OK
    ...
PermissionError: [Errno 13] Permission denied: b'/home/david/$HOME/test_file.nc'
```
PR fix to follow.

Discussion:

Patch:
diff --git a/Changelog.rst b/Changelog.rst
index 166631ac5..dda759411 100644
--- a/Changelog.rst
+++ b/Changelog.rst
@@ -25,7 +25,9 @@ version 1.9.0.0
   reference parameters (https://github.com/NCAS-CMS/cfdm/issues/148)
 * Interpret format specifiers for size 1 `cfdm.Data` arrays
   (https://github.com/NCAS-CMS/cfdm/issues/152)
-
+* Fix file name expansions in `cfdm.write`
+  (https://github.com/NCAS-CMS/cfdm/issues/157)
+  
 version 1.8.9.0
 ---------------
 ----
diff --git a/cfdm/read_write/netcdf/netcdfwrite.py b/cfdm/read_write/netcdf/netcdfwrite.py
index 5f7f1ec5b..b59bc0853 100644
--- a/cfdm/read_write/netcdf/netcdfwrite.py
+++ b/cfdm/read_write/netcdf/netcdfwrite.py
@@ -4641,11 +4641,14 @@ class NetCDFWrite(IOWrite):
         """
         logger.info(f"Writing to {fmt}")  # pragma: no cover
 
+        # Expand file name
+        filename = os.path.expanduser(os.path.expandvars(filename))
+
         # ------------------------------------------------------------
         # Initialise netCDF write parameters
         # ------------------------------------------------------------
         self.write_vars = {
-            "filename": os.path.expanduser(os.path.expandvars(filename)),
+            "filename": filename,
             # Format of output file
             "fmt": None,
             # netCDF4.Dataset instance
diff --git a/docs/source/tutorial.rst b/docs/source/tutorial.rst
index a538ebd9e..dcba560e8 100644
--- a/docs/source/tutorial.rst
+++ b/docs/source/tutorial.rst
@@ -124,6 +124,9 @@ read [#caveat]_.
 
 All formats of netCDF3 and netCDF4 files can be read.
 
+The file name may describe relative paths, and standard tilde and
+shell parameter expansions are applied to it.
+
 The following file types can be read:
 
 * All formats of netCDF3 and netCDF4 files can be read, containing
@@ -3336,6 +3339,9 @@ field constructs, to a netCDF file on disk:
                    : time(1) = [2019-01-01 00:00:00]
    >>> cfdm.write(q, 'q_file.nc')
 
+The file name may describe relative paths, and standard tilde and
+shell parameter expansions are applied to it.
+
 The new dataset is structured as follows:
 
 .. code-block:: console
@@ -3892,6 +3898,9 @@ however, be incorporated into the field constructs of the dataset, as
 if they had actually been stored in the same file, simply by providing
 the external file names to the `cfdm.read` function.
 
+An external variables file name may describe relative paths, and
+standard tilde and shell parameter expansions are applied to it.
+
 This is illustrated with the files ``parent.nc`` (found in the
 :ref:`sample datasets <Sample-datasets>`):
 


Test patch:
diff --git a/cfdm/test/test_read_write.py b/cfdm/test/test_read_write.py
index 2b4c4ed0e..8f60c6a3f 100644
--- a/cfdm/test/test_read_write.py
+++ b/cfdm/test/test_read_write.py
@@ -847,6 +847,12 @@ class read_writeTest(unittest.TestCase):
 
         cfdm.write(f, tmpfile)
 
+    def test_write_filename_expansion(self):
+        """Test the writing to a file name that requires expansions."""
+        f = cfdm.example_field(0)
+        filename = os.path.join("$PWD", os.path.basename(tmpfile))
+        cfdm.write(f, filename)
+
 
 if __name__ == "__main__":
     print("Run date:", datetime.datetime.now())