Repository: yt-project/unyt
Pull request #372 (2023-02-22 18:34:44)

REL: prepare release 2.9.5
backports #371

This was discussed with @ngoldbaum in the aforementioned PR, but given how fast this move has been, I will wait for an explicit approval before moving this forward.

(in particular: ping @jzuhone)


Patch:
diff --git a/HISTORY.rst b/HISTORY.rst
index d0c2b65..e455f4f 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -2,12 +2,26 @@
 History
 =======
 
+2.9.5 (2023-02-22)
+------------------
+
+* Fix a regression where arrays elements with dtype ``'int8'`` would not compare to floats
+  as intended. See `PR #371 <https://github.com/yt-project/unyt/pull/371>`_. Thank you to
+  Clément Robert (@neutrinoceros on GitHub) and Nathan Goldbaum (@ngoldbaum on GitHub) for
+  the contribution.
+
+* Raise an error in case an array element is assigned to a new value with incompatible
+  units. See `PR #375 <https://github.com/yt-project/unyt/pull/375>`_ and `PR #376
+  <https://github.com/yt-project/unyt/pull/376>`_. Thank you to Nathan Goldbaum
+  (@ngoldbaum on GitHub) for the contribution.
+
+
 2.9.4 (2023-02-06)
 ------------------
 
 * Make ``unyt_quantity.from_string`` parse ints.
   See `PR #278 <https://github.com/yt-project/unyt/pull/278>`_.
-  Thank you to Nahan Goldbaum (@ngoldbaum on GitHub) for the contribution.
+  Thank you to Nathan Goldbaum (@ngoldbaum on GitHub) for the contribution.
 * TST: migrate from tox-pyenv to tox-gh-actions #344
   See `PR #344 <https://github.com/yt-project/unyt/pull/344>`_.
   Thank you to Clément Robert (@neutrinoceros on GitHub) for the contribution.
diff --git a/unyt/array.py b/unyt/array.py
index e51066f..1e893ed 100644
--- a/unyt/array.py
+++ b/unyt/array.py
@@ -141,7 +141,14 @@ from unyt.unit_registry import (
 
 NULL_UNIT = Unit()
 POWER_MAPPING = {multiply: lambda x: x, divide: lambda x: 2 - x}
-DISALLOWED_DTYPES = ("S", "U", "a", "O", "M", "m", "b")
+DISALLOWED_DTYPES = (
+    "S",  # bytestring
+    "a",  # bytestring
+    "U",  # (unicode) bytes
+    "O",  # Python object
+    "M",  # datetime
+    "m",  # timedelta
+)
 
 __doctest_requires__ = {
     ("unyt_array.from_pint", "unyt_array.to_pint"): ["pint"],
@@ -1721,6 +1728,12 @@ class unyt_array(np.ndarray):
             pass
         return ret
 
+    def __setitem__(self, item, value):
+        if hasattr(value, "units"):
+            if value.units != self.units and value.units != NULL_UNIT:
+                value = value.to(self.units)
+        super().__setitem__(item, value)
+
     def __pow__(self, p, mod=None, /):
         """
         Power function, over-rides the ufunc as


Test patch:
diff --git a/unyt/tests/test_unyt_array.py b/unyt/tests/test_unyt_array.py
index dedcc64..38972b6 100644
--- a/unyt/tests/test_unyt_array.py
+++ b/unyt/tests/test_unyt_array.py
@@ -2739,3 +2739,28 @@ def test_string_comparison():
     a = 1 * cm
     assert not (a == "hello")
     assert a != "hello"
+
+
+def test_int8_comparison():
+    # see regression https://github.com/yt-project/unyt/issues/369
+    a = unyt_array(np.zeros(5, dtype=np.int8))
+    assert all(e == 0 for e in a)
+
+
+def test_setitem():
+    # see https://github.com/yt-project/unyt/issues/373
+    a = [1, 2, 3] * cm
+    a[1] = 2 * m
+    assert a[1].value == 200
+    assert a[1].units == cm
+
+    with pytest.raises(UnitConversionError):
+        a[1] = 2 * g
+
+    a[1] = 2
+    assert a[1].value == 2
+    assert a[1].units == cm
+
+    a[1] = unyt_quantity(2)
+    assert a[1].value == 2
+    assert a[1].units == cm