diff --git a/Lib/ipaddress.py b/Lib/ipaddress.py index 9c7a0a46f4f0e1f..8f686c1c9e20f49 100644 --- a/Lib/ipaddress.py +++ b/Lib/ipaddress.py @@ -1033,8 +1033,9 @@ def _is_subnet_of(a, b): return (b.network_address <= a.network_address and b.broadcast_address >= a.broadcast_address) except AttributeError: - raise TypeError(f"Unable to test subnet containment " - f"between {a} and {b}") + raise TypeError( + f"Unable to test subnet containment between {a} and {b}: " + f"both must be network objects") from None def subnet_of(self, other): """Return True if this network is a subnet of other.""" diff --git a/Lib/test/test_ipaddress.py b/Lib/test/test_ipaddress.py index a74b692784eb594..ab2f15fd3b1f9c6 100644 --- a/Lib/test/test_ipaddress.py +++ b/Lib/test/test_ipaddress.py @@ -723,6 +723,19 @@ def test_subnet_of_mixed_types(self): ipaddress.IPv6Network('::1/128').subnet_of( ipaddress.IPv4Network('10.0.0.0/30')) + def test_subnet_of_non_network(self): + # Passing something that is not a network object (e.g. an address) + # must raise a clear TypeError rather than masking an internal + # AttributeError (gh-153769). + net = ipaddress.IPv4Network('10.0.0.0/30') + for other in (ipaddress.IPv4Address('10.0.0.1'), '10.0.0.0/30', 42): + for method in (net.subnet_of, net.supernet_of): + with self.assertRaises(TypeError) as cm: + method(other) + self.assertIn('network', str(cm.exception)) + # The internal AttributeError is not shown to the caller. + self.assertTrue(cm.exception.__suppress_context__) + class NetmaskTestMixin_v6(CommonTestMixin_v6): """Input validation on interfaces and networks is very similar""" diff --git a/Misc/ACKS b/Misc/ACKS index fec00c1b272f4ea..5fe1d8cd1121ee4 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -2008,6 +2008,7 @@ Wm. Keith van der Meulen Eric N. Vander Weele Andrew Vant Atul Varma +Vyron Vasileiadis Dmitry Vasiliev Sebastian Ortiz Vasquez Alexandre Vassalotti diff --git a/Misc/NEWS.d/next/Library/2026-07-19-16-30-00.gh-issue-153769.STygbq.rst b/Misc/NEWS.d/next/Library/2026-07-19-16-30-00.gh-issue-153769.STygbq.rst new file mode 100644 index 000000000000000..039b4c1df99a079 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-07-19-16-30-00.gh-issue-153769.STygbq.rst @@ -0,0 +1,4 @@ +:meth:`~ipaddress.IPv4Network.subnet_of` and +:meth:`~ipaddress.IPv4Network.supernet_of` now say that both arguments must be +network objects when passed something else, such as an address, and no longer +show the internal :exc:`AttributeError` behind it.