Skip to content

Commit

Permalink
Merge pull request #1387 from headtr1ck/pathlike
Browse files Browse the repository at this point in the history
support Pathlike in Dataset.fromcdl
  • Loading branch information
jswhit authored Nov 16, 2024
2 parents b04f3ad + d419ea8 commit a371621
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 3 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ netcdftime/_netcdftime.c
venv/
.eggs/
.idea/
.vscode/
2 changes: 2 additions & 0 deletions Changelog
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
since version 1.7.2 release
===========================
* support os.PathLike arguments for `Dataset.fromcdl` and raise a `FileNotFoundError`
if the cdl is missing and a `FileExistsError` if the nc file already exists (PR #1387)
* raise more informative error when trying to iterate or
perform a membership operation on a Dataset (issue #1383)
* fix type hint for createEnumType (issue #1378)
Expand Down
2 changes: 1 addition & 1 deletion src/netCDF4/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ class Dataset:
def get_variables_by_attributes(self, **kwargs: Callable[[Any], bool] | Any) -> list[Variable]: ...
@staticmethod
def fromcdl(
cdlfilename: str, ncfilename: str | None = None, mode: AccessMode = "a", format: Format = "NETCDF4"
cdlfilename: str | os.PathLike, ncfilename: str | os.PathLike | None = None, mode: AccessMode = "a", format: Format = "NETCDF4"
) -> Dataset: ...
@overload
def tocdl(self, coordvars: bool = False, data: bool = False, outfile: None = None) -> str: ...
Expand Down
12 changes: 10 additions & 2 deletions src/netCDF4/_netCDF4.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -3502,19 +3502,27 @@ Dataset instance for `ncfilename` is returned.
[ncgen]: https://www.unidata.ucar.edu/software/netcdf/docs/netcdf_utilities_guide.html#ncgen_guide
[cdl]: https://www.unidata.ucar.edu/software/netcdf/docs/netcdf_utilities_guide.html#cdl_guide
"""
filepath = pathlib.Path(cdlfilename)
if ncfilename is None:
filepath = pathlib.Path(cdlfilename)
ncfilename = filepath.with_suffix('.nc')
else:
ncfilename = pathlib.Path(ncfilename)
formatcodes = {'NETCDF4': 4,
'NETCDF4_CLASSIC': 7,
'NETCDF3_CLASSIC': 3,
'NETCDF3_64BIT': 6, # legacy
'NETCDF3_64BIT_OFFSET': 6,
'NETCDF3_64BIT_DATA': 5}

if format not in formatcodes:
raise ValueError('illegal format requested')
if not filepath.exists():
raise FileNotFoundError(filepath)
if ncfilename.exists():
raise FileExistsError(ncfilename)

ncgenargs="-knc%s" % formatcodes[format]
subprocess.run(["ncgen", ncgenargs, "-o", ncfilename, cdlfilename], check=True)
subprocess.run(["ncgen", ncgenargs, "-o", str(ncfilename), str(filepath)], check=True)
return Dataset(ncfilename, mode=mode)

def tocdl(self,coordvars=False,data=False,outfile=None):
Expand Down
10 changes: 10 additions & 0 deletions test/test_cdl.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,18 @@ def test_fromcdl(self):
assert len(f1.dimensions["d"]) == len(f2.dimensions["d"])
assert (f1["ub"][:] == f2["ub"][:]).all()
assert (f1["sb"][:] == f2["sb"][:]).all()

# test if os.PathLike works
with netCDF4.Dataset.fromcdl(pathlib.Path("ubyte.cdl"), ncfilename=pathlib.Path("ubyte3.nc")) as f3:
assert f1.variables.keys() == f3.variables.keys()

# check if correct errors are raised
self.assertRaises(FileNotFoundError, netCDF4.Dataset.fromcdl, "doesnotexist.cdl")
self.assertRaises(FileExistsError, netCDF4.Dataset.fromcdl, "ubyte.cdl", ncfilename="ubyte2.nc")

# cleanup
os.remove("ubyte2.nc")
os.remove("ubyte3.nc")

def tearDown(self):
# Remove the temporary files
Expand Down

0 comments on commit a371621

Please sign in to comment.