Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 8 additions & 9 deletions Lib/ipaddress.py
Original file line number Diff line number Diff line change
Expand Up @@ -1026,15 +1026,14 @@ def is_multicast(self):

@staticmethod
def _is_subnet_of(a, b):
try:
# Always false if one is v4 and the other is v6.
if a.version != b.version:
raise TypeError(f"{a} and {b} are not of the same version")
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}")
if not (isinstance(a, _BaseNetwork) and isinstance(b, _BaseNetwork)):
raise TypeError(f"Unable to test subnet containment between "
f"{a} and {b}: both must be network objects")
# Always false if one is v4 and the other is v6.
if a.version != b.version:
raise TypeError(f"{a} and {b} are not of the same version")
return (b.network_address <= a.network_address and
b.broadcast_address >= a.broadcast_address)

def subnet_of(self, other):
"""Return True if this network is a subnet of other."""
Expand Down
14 changes: 14 additions & 0 deletions Lib/test/test_ipaddress.py
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,20 @@ 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 error should not be a swallowed AttributeError.
self.assertNotIsInstance(cm.exception.__context__,
AttributeError)


class NetmaskTestMixin_v6(CommonTestMixin_v6):
"""Input validation on interfaces and networks is very similar"""
Expand Down
1 change: 1 addition & 0 deletions Misc/ACKS
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
:meth:`~ipaddress.IPv4Network.subnet_of` and
:meth:`~ipaddress.IPv4Network.supernet_of` now raise a clear
:exc:`TypeError` when passed an argument that is not a network object,
such as an address, instead of a confusing error that masked an internal
:exc:`AttributeError`.
Loading