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

Wrap check_axis unit checking to not fail on bad unit #1116

Merged
merged 1 commit into from Jul 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions metpy/tests/test_xarray.py
Expand Up @@ -583,3 +583,10 @@ def test_dataset_parse_cf_keep_attrs(test_ds):

assert parsed_ds.attrs # Must be non-empty
assert parsed_ds.attrs == test_ds.attrs # Must match


def test_check_axis_with_bad_unit(test_ds_generic):
"""Test that check_axis does not raise an exception when provided a bad unit."""
var = test_ds_generic['e']
var.attrs['units'] = 'nondimensional'
assert not check_axis(var, 'x', 'y', 'vertical', 'time')
31 changes: 19 additions & 12 deletions metpy/xarray.py
Expand Up @@ -12,7 +12,7 @@
import xarray as xr

from ._vendor.xarray import either_dict_or_kwargs, expanded_indexer, is_dict_like
from .units import DimensionalityError, units
from .units import DimensionalityError, UndefinedUnitError, units

__all__ = []
readable_to_cf_axes = {'time': 'T', 'vertical': 'Z', 'y': 'Y', 'x': 'X'}
Expand Down Expand Up @@ -427,22 +427,29 @@ def check_axis(var, *axes):
return True

# Check for units, either by dimensionality or name
if (axis in coordinate_criteria['units'] and (
(
coordinate_criteria['units'][axis]['match'] == 'dimensionality'
and (units.get_dimensionality(var.attrs.get('units'))
== units.get_dimensionality(
coordinate_criteria['units'][axis]['units']))
) or (
coordinate_criteria['units'][axis]['match'] == 'name'
and var.attrs.get('units') in coordinate_criteria['units'][axis]['units']
))):
return True
try:
if (axis in coordinate_criteria['units'] and (
(
coordinate_criteria['units'][axis]['match'] == 'dimensionality'
and (units.get_dimensionality(var.attrs.get('units'))
== units.get_dimensionality(
coordinate_criteria['units'][axis]['units']))
) or (
coordinate_criteria['units'][axis]['match'] == 'name'
and var.attrs.get('units')
in coordinate_criteria['units'][axis]['units']
))):
return True
except UndefinedUnitError:
pass

# Check if name matches regular expression (non-CF failsafe)
if re.match(coordinate_criteria['regular_expression'][axis], var.name.lower()):
return True

# If no match has been made, return False (rather than None)
return False


def preprocess_xarray(func):
"""Decorate a function to convert all DataArray arguments to pint.Quantities.
Expand Down