Skip to content

Commit efc4772

Browse files
authored
Fix the units and dimensionality properties (#31)
* return None if the wrapped data is not a quantity * fix the units setattr * add docstrings to the units and dimensionality properties * return a dimensionality of None for non-quantities * fix the magnitude property * update whats-new.rst * shorten the property docstrings * fix the name of the unitless tests * mention that units can only be set if the data is not a quantity * reword the docstring dealing with setting the units * don't assign a name to the constructed quantity
1 parent 10e87f2 commit efc4772

File tree

3 files changed

+47
-9
lines changed

3 files changed

+47
-9
lines changed

docs/whats-new.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,7 @@ What's new
99
- rewrite :py:meth:`DataArray.pint.quantify`,
1010
:py:meth:`Dataset.pint.quantify`, :py:meth:`DataArray.pint.dequantify` and
1111
:py:meth:`Dataset.pint.dequantify` (:pull:`17`)
12-
- expose :py:func:`pint_xarray.testing.assert_units_equal` as public API (:pull:`24`)
12+
- expose :py:func:`pint_xarray.testing.assert_units_equal` as public API (:pull:`24`)
13+
- fix the :py:attr:`DataArray.pint.units`, :py:attr:`DataArray.pint.magnitude`
14+
and :py:attr:`DataArray.pint.dimensionality` properties and add docstrings for
15+
all three. (:pull:`31`)

pint_xarray/accessors.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import pint
55
from pint.quantity import Quantity
66
from pint.unit import Unit
7-
from xarray import DataArray, register_dataarray_accessor, register_dataset_accessor
7+
from xarray import register_dataarray_accessor, register_dataset_accessor
88

99
from . import conversion
1010

@@ -230,22 +230,26 @@ def dequantify(self):
230230

231231
@property
232232
def magnitude(self):
233-
return self.da.data.magnitude
233+
"""the magnitude of the data or the data itself if not a quantity."""
234+
data = self.da.data
235+
return getattr(data, "magnitude", data)
234236

235237
@property
236238
def units(self):
237-
return self.da.data.units
239+
"""the units of the data or :py:obj:`None` if not a quantity.
240+
241+
Setting the units is possible, but only if the data is not already a quantity.
242+
"""
243+
return getattr(self.da.data, "units", None)
238244

239245
@units.setter
240246
def units(self, units):
241-
quantity = conversion.array_attach_units(self.da.data, units)
242-
self.da = DataArray(
243-
dim=self.da.dims, data=quantity, coords=self.da.coords, attrs=self.da.attrs
244-
)
247+
self.da.data = conversion.array_attach_units(self.da.data, units)
245248

246249
@property
247250
def dimensionality(self):
248-
return self.da.data.dimensionality
251+
"""get the dimensionality of the data or :py:obj:`None` if not a quantity."""
252+
return getattr(self.da.data, "dimensionality", None)
249253

250254
@property
251255
def registry(self):

pint_xarray/tests/test_accessors.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,37 @@ def test_roundtrip_data(self, example_unitless_da):
123123
assert_equal(result, orig)
124124

125125

126+
class TestPropertiesDataArray:
127+
def test_magnitude_getattr(self, example_quantity_da):
128+
da = example_quantity_da
129+
actual = da.pint.magnitude
130+
assert not isinstance(actual, Quantity)
131+
132+
def test_magnitude_getattr_unitless(self, example_unitless_da):
133+
da = example_unitless_da
134+
xr.testing.assert_duckarray_equal(da.pint.magnitude, da.data)
135+
136+
def test_units_getattr(self, example_quantity_da):
137+
da = example_quantity_da
138+
actual = da.pint.units
139+
assert isinstance(actual, Unit)
140+
assert actual == unit_registry.m
141+
142+
def test_units_setattr(self, example_quantity_da):
143+
da = example_quantity_da
144+
with pytest.raises(ValueError):
145+
da.pint.units = "s"
146+
147+
def test_units_getattr_unitless(self, example_unitless_da):
148+
da = example_unitless_da
149+
assert da.pint.units is None
150+
151+
def test_units_setattr_unitless(self, example_unitless_da):
152+
da = example_unitless_da
153+
da.pint.units = unit_registry.s
154+
assert da.pint.units == unit_registry.s
155+
156+
126157
@pytest.fixture()
127158
def example_unitless_ds():
128159
users = np.linspace(0, 10, 20)

0 commit comments

Comments
 (0)