-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add warning for netCDF4 bug #1835
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
Conversation
Added a warning message to address a bug in netCDF4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! A good way to test this would be to use mock, e.g.,
with mock.patch('netCDF4.__version__', '1.2.4'):
with pytest.warns(Warning, match='segmentation fault'):
xarray.Dataset().to_netcdf('a' * 88)
xarray/backends/api.py
Outdated
@@ -281,6 +281,14 @@ def maybe_decode_store(store, lock=False): | |||
engine = _get_default_engine(filename_or_obj, | |||
allow_remote=True) | |||
if engine == 'netcdf4': | |||
import netCDF4 | |||
if len( filename_or_obj ) == 88 and float(netCDF4.__version__[:3]) < 1.3: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use LooseVersion()
here: https://stackoverflow.com/questions/11887762/compare-version-strings-in-python
xarray/backends/api.py
Outdated
@@ -281,6 +281,14 @@ def maybe_decode_store(store, lock=False): | |||
engine = _get_default_engine(filename_or_obj, | |||
allow_remote=True) | |||
if engine == 'netcdf4': | |||
import netCDF4 | |||
if len( filename_or_obj ) == 88 and float(netCDF4.__version__[:3]) < 1.3: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove spaces around filename_or_obj
, per pep8.
xarray/backends/api.py
Outdated
'to occur with version 1.2.4 of netCDF4 and can be \n' | ||
'addressed by upgrading netCDF4 to at least version 1.3.1. \n' | ||
'More details can be found here: \n' | ||
'https://github.com/pydata/xarray/issues/1745 \n') | ||
store = backends.NetCDF4DataStore.open(filename_or_obj, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you put this inside NetCDF4DataStore.open()
instead? We try to keep the backend specific logic in the backend classes.
Thanks for the advice @shoyer I've moved the warning to NetCDF4DataStore.open() and reverted backends/api.py back to the original. I've used LooseVersion for the version comparison and made the pep8 change. There is a problem with the test. I've added the test to NetCDF4DataTest. However, when the filename has 88 characters the seg fault occurs and the test gets stopped. The output from
is just:
If the filename doesn't have 88 characters then the test result is "Failed: DID NOT WARN.", which is fine as it shouldn't trigger the warning. I've been trying to see how people handle this issue, but haven't been able to find examples of people trying to trigger seg faults in a test yet |
There are some other small issues I need to deal with, I'll leave a message when I've sorted those out |
@braaannigan How about we turn warnings into errors, and then catch the appropriate error instead? e.g., with warnings.catch_warnings():
warnings.simplefilter("error")
with raises_regex(Warning, 'segmentation fault'):
... That should abort (due to the error) before the seg fault. |
xarray/backends/netCDF4_.py
Outdated
@@ -244,6 +245,16 @@ def __init__(self, netcdf4_dataset, mode='r', writer=None, opener=None, | |||
def open(cls, filename, mode='r', format='NETCDF4', group=None, | |||
writer=None, clobber=True, diskless=False, persist=False, | |||
autoclose=False): | |||
import netCDF4 as nc4 | |||
from distutils.version import LooseVersion |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can put this import at the top level. (We only import netCDF4 inside functions/methods to avoid the hard dependency, but disutils is part of Python's standard library.)
I've pushed an updated version with a successful test on my machine. I've modified the dataset name in the test case to ensure it has 88 characters (the filepath on github has to have less than 88 characters of course, this seems like a safe assumption). I've made some formatting changes to netCDF4_.py to pass the pyflake tests. I've moved the import statement for LooseVersion to the start of the script. Thanks for the reviews and advice @shoyer |
xarray/backends/api.py
Outdated
@@ -281,6 +281,14 @@ def maybe_decode_store(store, lock=False): | |||
engine = _get_default_engine(filename_or_obj, | |||
allow_remote=True) | |||
if engine == 'netcdf4': | |||
import netCDF4 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like you accidentally kept your changes in this file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought that I had checked out the original version again to replace all of my edits, but that doesn't seem to have worked. I'm looking for a solution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can simply revert this file (e.g., copy/paste from master) and then add another commit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was worried that would cause some new unforeseen problem. I've commited this now.
Merged in 47c3b62. Thanks! |
Closes #1745 by adding a warning message for a bug in netCDF4. The bug occurs when the filepath has 88 characters and the netCDF4 engine has been used with version less than 1.3.1.
The warning message has been added at the first point where the length of the file path is known and the netcdf4 version number is known.
I don't think there is any corresponding test, as the bug leads to a seg fault rather than a python output/exception.
Passes
git diff upstream/master **/*py | flake8 --diff
(remove if you did not edit any Python files)Updated
whats-new.rst