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

provide more context to errors #92

Merged
merged 19 commits into from
Apr 24, 2021
Merged

Conversation

keewis
Copy link
Collaborator

@keewis keewis commented Apr 16, 2021

Inspired by #43, this collects all errors of a kind and raises a single error message. Not sure if the implementation is really the best way, though (one drawback is that the original traceback will be lost).

This also fixes the error message for operations like reindex when trying to specify indexers with incompatible units for data variables (it now displays the xarray error instead of complaining about the incompatible units).

examples for the new error messages
In [1]: import xarray as xr
   ...: import pint_xarray

In [2]: ds = xr.Dataset({"a": ("x", [0, 1]), "b": ("y", [1, 2, 3])})
   ...: ds
Out[2]: 
<xarray.Dataset>
Dimensions:  (x: 2, y: 3)
Dimensions without coordinates: x, y
Data variables:
    a        (x) int64 0 1
    b        (y) int64 1 2 3

In [3]: ds.pint.quantify({"a": "invalid", "b": "invalid2"})
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-3-273f907e75ca> in <module>
----> 1 ds.pint.quantify({"a": "invalid", "b": "invalid2"})

.../pint_xarray/accessors.py in quantify(self, units, unit_registry, **unit_kwargs)
    972 
    973         if invalid_units:
--> 974             raise ValueError(format_error_message(invalid_units, "parse"))
    975 
    976         return self.ds.pipe(conversion.strip_unit_attributes).pipe(

ValueError: Cannot parse units:
 -- invalid units for variable 'b': invalid2 (parameter) (reason: 'invalid2' is not defined in the unit registry)
 -- invalid units for variable 'a': invalid (parameter) (reason: 'invalid' is not defined in the unit registry)

In [4]: quantified = ds.pint.quantify({"a": "m", "b": "s"})
   ...: quantified
Out[4]: 
<xarray.Dataset>
Dimensions:  (x: 2, y: 3)
Dimensions without coordinates: x, y
Data variables:
    a        (x) int64 [m] 0 1
    b        (y) int64 [s] 1 2 3

In [5]: quantified.pint.to({"a": "ms", "b": "mm"})
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-5-254b9671693a> in <module>
----> 1 quantified.pint.to({"a": "ms", "b": "mm"})

.../pint_xarray/accessors.py in to(self, units, **unit_kwargs)
   1150         units = either_dict_or_kwargs(units, unit_kwargs, "to")
   1151 
-> 1152         return conversion.convert_units(self.ds, units)
   1153 
   1154     def chunk(self, chunks, name_prefix="xarray-", token=None, lock=False):

.../pint_xarray/conversion.py in convert_units(obj, units)
    213 
    214         if failed:
--> 215             raise ValueError(format_error_message(failed, "convert"))
    216 
    217         coords = {

ValueError: Cannot convert variables:
 -- incompatible units for variable 'a': Cannot convert from 'meter' ([length]) to 'millisecond' ([time])
 -- incompatible units for variable 'b': Cannot convert from 'second' ([time]) to 'millimeter' ([length])

cc @TomNicholas

  • Tests added
  • Passes pre-commit run --all-files
  • User visible changes (including notable bug fixes) are documented in whats-new.rst

@keewis keewis mentioned this pull request Apr 16, 2021
6 tasks
@TomNicholas
Copy link
Member

I'm also not really sure if this implementation is best (what would happen if pint throws a type of error you didn't realise it could throw?), but the result is pretty neat, and closer to what I had imagined for #43 originally.

@keewis
Copy link
Collaborator Author

keewis commented Apr 16, 2021

what would happen if pint throws a type of error you didn't realise it could throw?

I'd say that's a bug which can be fixed normally. I chose to catch pint.errors.PintTypeError, which is the base class of most exceptions pint will raise. The only exceptions which don't have that base class are related to defining or parsing units (the UndefinedUnitError we should catch in quantify). I guess this is pretty safe?

@keewis keewis requested a review from jthielen April 16, 2021 21:33
@keewis keewis merged commit 7bf1cc7 into xarray-contrib:master Apr 24, 2021
@keewis keewis deleted the error-context branch April 24, 2021 00:00
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.

2 participants