From 1084535dfbb0884c5d94bc3c09dbf1152432401d Mon Sep 17 00:00:00 2001 From: David Rebbe Date: Tue, 15 Sep 2026 23:04:42 -0400 Subject: [PATCH] fix: include serial in device equality --- src/ics/py_neo_device_ex.py | 5 +++- tests/test_neo_device_ex.py | 59 +++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/ics/py_neo_device_ex.py b/src/ics/py_neo_device_ex.py index e21c0270..59214417 100644 --- a/src/ics/py_neo_device_ex.py +++ b/src/ics/py_neo_device_ex.py @@ -26,8 +26,11 @@ def __repr__(self): return f"" def __eq__(self, other) -> bool: + if not isinstance(other, PyNeoDeviceEx): + return NotImplemented return \ self.DeviceType == other.DeviceType and \ + self.SerialNumber == other.SerialNumber and \ self.Handle == other.Handle and \ self.NumberOfClients == other.NumberOfClients and \ self.MaxAllowedClients == other.MaxAllowedClients and \ @@ -514,4 +517,4 @@ def request_set_neovi_miscio(self, *args, **kwargs): def get_firmware_variant(self, *args, **kwargs): "see ics.get_firmware_variant for details on arguments." - return ics.get_firmware_variant(self, *args, **kwargs) \ No newline at end of file + return ics.get_firmware_variant(self, *args, **kwargs) diff --git a/tests/test_neo_device_ex.py b/tests/test_neo_device_ex.py index bd969250..c08815e5 100644 --- a/tests/test_neo_device_ex.py +++ b/tests/test_neo_device_ex.py @@ -39,5 +39,64 @@ def test_serial_number_out_of_range_raises(): _make_device(ics.MAX_SERIAL + 1).serial_number +@pytest.mark.parametrize("serial", [100, ics.MAX_SERIAL]) +def test_equal_device_snapshots(serial): + first, second = _make_device(serial), _make_device(serial) + assert first is not second + assert first == second + assert second == first + assert not (first != second) + assert second in [first] + + +@pytest.mark.parametrize("serials", [(100, 200), (0x7FFFFFFF, 0x80000000)]) +def test_different_serials_are_distinct_devices(serials): + first, second = map(_make_device, serials) + assert first != second + assert second != first + assert not (first == second) + assert second not in [first] + devices = [first] + if second not in devices: + devices.append(second) + assert len(devices) == 2 + + +@pytest.mark.parametrize("field", ["DeviceType", "Handle", "NumberOfClients", "MaxAllowedClients"]) +def test_device_snapshot_fields_still_affect_equality(field): + first, second = _make_device(100), _make_device(100) + setattr(second.neoDevice, field, 1) + assert first != second + + +@pytest.mark.parametrize("field", [ + "FirmwareMajor", "FirmwareMinor", "Status", "Options", "pAvailWIFINetwork", + "isEthernetDevice", "hardwareRev", "revReserved", "tcpPort", +]) +def test_extended_snapshot_fields_still_affect_equality(field): + first, second = _make_device(100), _make_device(100) + setattr(second, field, 1) + assert first != second + + +@pytest.mark.parametrize("other", [None, object(), 100, "100"]) +def test_unrelated_objects_compare_unequal(other): + device = _make_device(100) + assert device.__eq__(other) is NotImplemented + assert not (device == other) + assert not (other == device) + assert device != other + assert other != device + + +def test_equality_allows_reflected_comparison(): + class AcceptsDevice: + def __eq__(self, other): + return isinstance(other, ics.PyNeoDeviceEx) + + device = _make_device(100) + assert device == AcceptsDevice() + + if __name__ == "__main__": pytest.main(args=[__file__, "--verbose", "-s"])