diff --git a/Lib/ipaddress.py b/Lib/ipaddress.py index aa0cf4a0620cd0..b4408373e51d2c 100644 --- a/Lib/ipaddress.py +++ b/Lib/ipaddress.py @@ -567,11 +567,10 @@ def __int__(self): return self._ip def __eq__(self, other): - try: - return (self._ip == other._ip - and self.version == other.version) - except AttributeError: + if not isinstance(other, _BaseAddress): return NotImplemented + return (self._ip == other._ip + and self.version == other.version) def __lt__(self, other): if not isinstance(other, _BaseAddress): @@ -718,12 +717,11 @@ def __lt__(self, other): return False def __eq__(self, other): - try: - return (self.version == other.version and - self.network_address == other.network_address and - int(self.netmask) == int(other.netmask)) - except AttributeError: + if not isinstance(other, _BaseNetwork): return NotImplemented + return (self.version == other.version + and self.network_address == other.network_address + and int(self.netmask) == int(other.netmask)) def __hash__(self): return hash((int(self.network_address), int(self.netmask))) diff --git a/Lib/test/test_ipaddress.py b/Lib/test/test_ipaddress.py index 11721a59972672..dcfa66dc9fbbc3 100644 --- a/Lib/test/test_ipaddress.py +++ b/Lib/test/test_ipaddress.py @@ -1078,6 +1078,41 @@ def test_incompatible_versions(self): self.assertRaises(TypeError, v6net_scoped.__lt__, v4net) self.assertRaises(TypeError, v6net_scoped.__gt__, v4net) + def test_address_eq_with_faux_object(self): + class AlwaysTrue: + def __init__(self, ip_value): + self._ip = ip_value + self.version = 42 + + def __eq__(self, other): + return True + + addr4 = ipaddress.IPv4Address('192.168.1.1') + always_true4 = AlwaysTrue(addr4._ip) + self.assertEqual(addr4, always_true4) + + addr6 = ipaddress.IPv6Address('::1') + always_true6 = AlwaysTrue(addr6._ip) + self.assertEqual(addr6, always_true6) + + intf4 = ipaddress.IPv4Interface('192.168.1.1/24') + always_true_intf4 = AlwaysTrue(intf4._ip) + self.assertEqual(intf4, always_true_intf4) + + intf6 = ipaddress.IPv6Interface('::1/128') + always_true_intf6 = AlwaysTrue(intf6._ip) + self.assertEqual(intf6, always_true_intf6) + + def test_network_eq_with_faux_object(self): + class AlwaysTrue: + version = 42 + def __eq__(self, other): + return True + + always_true = AlwaysTrue() + self.assertEqual(ipaddress.IPv4Network('43.48.0.0/12'), always_true) + self.assertEqual(ipaddress.IPv6Network('::eeff:ae3f:d473/128'), always_true) + class IpaddrUnitTest(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Library/2025-11-17-17-06-56.gh-issue-131647.tyafol.rst b/Misc/NEWS.d/next/Library/2025-11-17-17-06-56.gh-issue-131647.tyafol.rst new file mode 100644 index 00000000000000..7978b70e186c18 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-11-17-17-06-56.gh-issue-131647.tyafol.rst @@ -0,0 +1,4 @@ +:mod:`ipaddress`: fix equality testing for :class:`~ipaddress.IPv4Address`, +:class:`~ipaddress.IPv6Address`, :class:`~ipaddress.IPv4Network`, and +:class:`~ipaddress.IPv6Network` to avoid comparing instances of incorrect +types.