Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement setncattr_string for attributes that are lists of strings #2045

Merged
merged 1 commit into from
Apr 17, 2018

Conversation

dnowacki-usgs
Copy link
Contributor

@dnowacki-usgs dnowacki-usgs commented Apr 9, 2018

  • Closes Feature request: writing xarray list-type attributes to netCDF #2044
  • Tests added (for all bug fixes or enhancements)
  • Tests passed (for all non-documentation changes)
  • Fully documented, including whats-new.rst for all changes and api.rst for new API (remove if this change should not be visible to users, e.g., if it is an internal clean-up, or if this is part of a larger project that will be documented later)

@@ -343,11 +343,22 @@ def set_dimension(self, name, length, is_unlimited=False):
dim_length = length if not is_unlimited else None
self.ds.createDimension(name, size=dim_length)

def is_list_of_strings(self, value):
if (np.asarray(value).dtype.kind in ['U', 'S'] and
np.asarray(value).size > 1):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

E129 visually indented line with same indent as next logical line

@dnowacki-usgs
Copy link
Contributor Author

OK, after some false starts, I think this is working, but the CI build is failing on CONDA_ENV=py35 and py36... but it's failing on a different test (specific to netcdf3, complaining about a temp file) and I can't see how it is impacted by my changes... thoughts?

Copy link
Member

@shoyer shoyer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, the CI failures are unrelated (#2050).

Can you also add this for attributes on variables? That would be helpful for consistency.

self.ds.setncattr(key, value)
if self.is_list_of_strings(value) and (self.format == 'NETCDF4'):
# encode as NC_STRING if attr is list of strings and NETCDF4
self.ds.setncattr_string(key, value)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we adjust this to raise a sensible error message if the user has an old version of netCDF4-python installed which doesn't have this method?

def set_attribute(self, key, value):
with self.ensure_open(autoclose=False):
if self.format != 'NETCDF4':
value = encode_nc3_attr_value(value)
self.ds.setncattr(key, value)
if self.is_list_of_strings(value) and (self.format == 'NETCDF4'):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably want to use this in all cases, even if a different format from NETCDF4 is selected. It's better to error than to improperly serialize data.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I tested with netCDF4 1.2.2 (last release before setncattr_string was introduced) and successfully catch the error with this latest commit. Is this along the lines of what you were thinking?

'upgrade to netCDF4-python 1.2.4 or greater.')
raise AttributeError(msg)
else:
nc4_var.setncattr(k, v)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you consolidate this logic into a helper function (e.g., _set_attribute()) rather than repeating it twice?

@dnowacki-usgs
Copy link
Contributor Author

I only have a vague grasp of proper object oriented programming practices; not sure if the helper functions should be within the class or what, but it does seem to work this way.

Copy link
Member

@shoyer shoyer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please merge in the latest changes from master, then we can easily verify that all tests pass with continuous integration.

@@ -552,6 +552,19 @@ def test_ondisk_after_print(self):
repr(on_disk)
assert not on_disk['var1']._in_memory

def test_setncattr_string(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might need to add this test specifically for the class with netCDF4 tests, making use of the self.roundtrip() method. Otherwise this is also going to run for cases where the list of strings attribute cannot be roundtripped (e.g., writing a netCDF3 file).

"""
Test to ensure setncattr_string is called on lists of strings
with NetCDF4
"""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: we generally avoid writing docstrings for test method unless they add substantial information beyond what's already obvious from the class/method name.

@dnowacki-usgs dnowacki-usgs force-pushed the nc_string branch 3 times, most recently from 92110dc to 92224e0 Compare April 16, 2018 20:22
@dnowacki-usgs
Copy link
Contributor Author

@shoyer Thank you for the helpful feedback. I think I addressed all of your comments, and also expanded the tests.

Copy link
Member

@shoyer shoyer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, after one small doc change

@@ -34,6 +34,10 @@ v0.10.4 (unreleased)
Enhancements
~~~~~~~~~~~~

- Support reading and writing lists of strings as attributes to netCDF
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nit: this should be "Support writing lists" only. We can already read lists of strings.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@shoyer
Copy link
Member

shoyer commented Apr 17, 2018

thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature request: writing xarray list-type attributes to netCDF
3 participants