Skip to content

Commit addadc9

Browse files
authored
fix upstream-dev (#97)
* don't convert if units are None * don't copy the variable if we don't need to change it * update whats-new.rst [skip-ci] * [test-upstream] * add a more informative error message * use testing.assert_units_equal * set the units attr to a unit object after converting * [test-upstream] * fix whats-new.rst [skip-ci]
1 parent f2ad1d4 commit addadc9

File tree

5 files changed

+82
-17
lines changed

5 files changed

+82
-17
lines changed

docs/whats-new.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ What's new
3838
:py:meth:`DataArray.pint.reindex` and :py:meth:`DataArray.pint.reindex_like` (:pull:`69`).
3939
By `Justus Magin <https://github.com/keewis>`_.
4040
- implement :py:meth:`Dataset.pint.interp`, :py:meth:`Dataset.pint.interp_like`,
41-
:py:meth:`DataArray.pint.interp` and :py:meth:`DataArray.pint.interp_like` (:pull:`72`, :pull:`76`).
41+
:py:meth:`DataArray.pint.interp` and :py:meth:`DataArray.pint.interp_like`
42+
(:pull:`72`, :pull:`76`, :pull:`97`).
4243
By `Justus Magin <https://github.com/keewis>`_.
4344
- implement :py:meth:`Dataset.pint.ffill`, :py:meth:`Dataset.pint.bfill`,
4445
:py:meth:`DataArray.pint.ffill` and :py:meth:`DataArray.pint.bfill` (:pull:`78`).

pint_xarray/conversion.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -173,12 +173,16 @@ def convert_units_variable(variable, units):
173173
# don't try to convert MultiIndexes
174174
return variable
175175

176-
quantity = array_attach_units(
177-
variable.data, variable.attrs.get(unit_attribute_name)
178-
)
179-
converted = array_convert_units(quantity, units)
180-
new_obj = variable.copy(data=array_strip_units(converted))
181-
new_obj.attrs[unit_attribute_name] = array_extract_units(converted)
176+
if units is not None:
177+
quantity = array_attach_units(
178+
variable.data, variable.attrs.get(unit_attribute_name)
179+
)
180+
converted = array_convert_units(quantity, units)
181+
new_obj = variable.copy(data=array_strip_units(converted))
182+
183+
new_obj.attrs[unit_attribute_name] = array_extract_units(converted)
184+
else:
185+
new_obj = variable
182186
elif isinstance(variable, Variable):
183187
converted = array_convert_units(variable.data, units)
184188
new_obj = variable.copy(data=converted)

pint_xarray/formatting.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from itertools import zip_longest
22

33
import numpy as np
4+
from xarray.core.options import OPTIONS
45

56

67
# vendored from xarray.core.formatting
@@ -11,6 +12,16 @@ def maybe_truncate(obj, maxlen=500):
1112
return s
1213

1314

15+
# vendored from xarray.core.formatting
16+
def pretty_print(x, numchars: int):
17+
"""Given an object `x`, call `str(x)` and format the returned string so
18+
that it is numchars long, padding with trailing spaces or truncating with
19+
ellipses as necessary
20+
"""
21+
s = maybe_truncate(x, numchars)
22+
return s + " " * max(numchars - len(s), 0)
23+
24+
1425
# vendored from xarray.core.formatting
1526
def _get_indexer_at_least_n_items(shape, n_desired, from_end):
1627
assert 0 < n_desired <= np.prod(shape)
@@ -80,6 +91,53 @@ def format_items(x):
8091
return formatted
8192

8293

94+
def summarize_attr(key, value, col_width=None):
95+
"""Summary for __repr__ - use ``X.attrs[key]`` for full value."""
96+
# Indent key and add ':', then right-pad if col_width is not None
97+
k_str = f" {key}:"
98+
if col_width is not None:
99+
k_str = pretty_print(k_str, col_width)
100+
# Replace tabs and newlines, so we print on one line in known width
101+
v_str = str(value).replace("\t", "\\t").replace("\n", "\\n")
102+
# Finally, truncate to the desired display width
103+
return maybe_truncate(f"{k_str} {v_str}", OPTIONS["display_width"])
104+
105+
106+
# adapted from xarray.core.formatting
107+
def _diff_mapping_repr(a_mapping, b_mapping, title, summarizer, col_width=None):
108+
def extra_items_repr(extra_keys, mapping, ab_side):
109+
extra_repr = [summarizer(k, mapping[k], col_width) for k in extra_keys]
110+
if extra_repr:
111+
header = f"{title} only on the {ab_side} object:"
112+
return [header] + extra_repr
113+
else:
114+
return []
115+
116+
a_keys = set(a_mapping)
117+
b_keys = set(b_mapping)
118+
119+
summary = []
120+
121+
diff_items = []
122+
123+
for k in a_keys & b_keys:
124+
compatible = a_mapping[k] == b_mapping[k]
125+
if not compatible:
126+
temp = [
127+
summarizer(k, vars[k], col_width) for vars in (a_mapping, b_mapping)
128+
]
129+
130+
diff_items += [ab_side + s[1:] for ab_side, s in zip(("L", "R"), temp)]
131+
132+
if diff_items:
133+
summary += [f"Differing {title.lower()}:"] + diff_items
134+
135+
summary += extra_items_repr(a_keys - b_keys, a_mapping, "left")
136+
summary += extra_items_repr(b_keys - a_keys, b_mapping, "right")
137+
138+
return "\n".join(summary)
139+
140+
83141
# vendored from xarray.core.formatting
84142
def format_array_flat(array, max_width: int):
85143
"""Return a formatted string for as many items in the flattened version of

pint_xarray/testing.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from . import conversion
1+
from . import conversion, formatting
22

33

44
def assert_units_equal(a, b):
@@ -16,7 +16,14 @@ def assert_units_equal(a, b):
1616

1717
__tracebackhide__ = True
1818

19-
assert conversion.extract_units(a) == conversion.extract_units(b)
20-
assert conversion.extract_unit_attributes(a) == conversion.extract_unit_attributes(
21-
b
19+
units_a = conversion.extract_units(a)
20+
units_b = conversion.extract_units(b)
21+
assert units_a == units_b, formatting._diff_mapping_repr(
22+
units_a, units_b, "Units", formatting.summarize_attr
23+
)
24+
25+
unit_attrs_a = conversion.extract_unit_attributes(a)
26+
unit_attrs_b = conversion.extract_unit_attributes(b)
27+
assert unit_attrs_a == unit_attrs_b, formatting._diff_mapping_repr(
28+
unit_attrs_a, unit_attrs_b, "Unit attrs", formatting.summarize_attr
2229
)

pint_xarray/tests/utils.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
from ..conversion import (
1111
array_strip_units,
1212
extract_indexer_units,
13-
extract_units,
1413
strip_units,
1514
strip_units_variable,
1615
)
16+
from ..testing import assert_units_equal # noqa: F401
1717

1818

1919
def importorskip(name):
@@ -104,8 +104,3 @@ def assert_indexer_units_equal(a, b):
104104
units_b = extract_indexer_units(b)
105105

106106
assert units_a == units_b, f"different units: {units_a!r} ←→ {units_b!r}"
107-
108-
109-
def assert_units_equal(a, b):
110-
__tracebackhide__ = True
111-
assert extract_units(a) == extract_units(b)

0 commit comments

Comments
 (0)