Skip to content

Commit

Permalink
bpo-46415: Use f-string for ValueError in ipaddress.ip_{address,netwo…
Browse files Browse the repository at this point in the history
…rk,interface} helper functions (GH-30642)

`IPv*Network` and `IPv*Interface` constructors accept a 2-tuple of
(address description, netmask) as the address parameter.
When the tuple-based address is used errors are not propagated
correctly through the `ipaddress.ip_*` helper because of the %-formatting now expecting several arguments:

	In [7]: ipaddress.ip_network(("192.168.100.0", "fooo"))
        ...
	TypeError: not all arguments converted during string formatting

Compared to:

	In [8]: ipaddress.IPv4Network(("192.168.100.0", "foo"))
        ...
	NetmaskValueError: 'foo' is not a valid netmask

Use an f-string to make sure the error is always properly formatted.

Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
(cherry picked from commit 52dc9c3)

Co-authored-by: Thomas Cellerier <thomascellerier@gmail.com>
  • Loading branch information
miss-islington and thomascellerier committed May 3, 2022
1 parent 62ddbbc commit 5f709bd
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 9 deletions.
15 changes: 6 additions & 9 deletions Lib/ipaddress.py
Expand Up @@ -51,8 +51,7 @@ def ip_address(address):
except (AddressValueError, NetmaskValueError):
pass

raise ValueError('%r does not appear to be an IPv4 or IPv6 address' %
address)
raise ValueError(f'{address!r} does not appear to be an IPv4 or IPv6 address')


def ip_network(address, strict=True):
Expand Down Expand Up @@ -81,8 +80,7 @@ def ip_network(address, strict=True):
except (AddressValueError, NetmaskValueError):
pass

raise ValueError('%r does not appear to be an IPv4 or IPv6 network' %
address)
raise ValueError(f'{address!r} does not appear to be an IPv4 or IPv6 network')


def ip_interface(address):
Expand Down Expand Up @@ -116,8 +114,7 @@ def ip_interface(address):
except (AddressValueError, NetmaskValueError):
pass

raise ValueError('%r does not appear to be an IPv4 or IPv6 interface' %
address)
raise ValueError(f'{address!r} does not appear to be an IPv4 or IPv6 interface')


def v4_int_to_packed(address):
Expand Down Expand Up @@ -160,7 +157,7 @@ def _split_optional_netmask(address):
"""Helper to split the netmask and raise AddressValueError if needed"""
addr = str(address).split('/')
if len(addr) > 2:
raise AddressValueError("Only one '/' permitted in %r" % address)
raise AddressValueError(f"Only one '/' permitted in {address!r}")
return addr


Expand Down Expand Up @@ -1304,7 +1301,7 @@ def __init__(self, address):
# which converts into a formatted IP string.
addr_str = str(address)
if '/' in addr_str:
raise AddressValueError("Unexpected '/' in %r" % address)
raise AddressValueError(f"Unexpected '/' in {address!r}")
self._ip = self._ip_int_from_string(addr_str)

@property
Expand Down Expand Up @@ -1913,7 +1910,7 @@ def __init__(self, address):
# which converts into a formatted IP string.
addr_str = str(address)
if '/' in addr_str:
raise AddressValueError("Unexpected '/' in %r" % address)
raise AddressValueError(f"Unexpected '/' in {address!r}")
addr_str, self._scope_id = self._split_scope_id(addr_str)

self._ip = self._ip_int_from_string(addr_str)
Expand Down
16 changes: 16 additions & 0 deletions Lib/test/test_ipaddress.py
Expand Up @@ -1133,6 +1133,14 @@ def testIPv4Tuple(self):
self.assertEqual(ipaddress.IPv4Interface((3221225985, 24)),
ipaddress.IPv4Interface('192.0.2.1/24'))

# Invalid netmask
with self.assertRaises(ValueError):
ipaddress.IPv4Network(('192.0.2.1', '255.255.255.255.0'))

# Invalid netmask using factory
with self.assertRaises(ValueError):
ipaddress.ip_network(('192.0.2.1', '255.255.255.255.0'))

# issue #16531: constructing IPv6Network from an (address, mask) tuple
def testIPv6Tuple(self):
# /128
Expand Down Expand Up @@ -1192,6 +1200,14 @@ def testIPv6Tuple(self):
ipaddress.IPv6Network((ip_scoped, 96))
# strict=False and host bits set

# Invalid netmask
with self.assertRaises(ValueError):
ipaddress.IPv6Network(('2001:db8::1', '255.255.255.0'))

# Invalid netmask using factory
with self.assertRaises(ValueError):
ipaddress.ip_network(('2001:db8::1', '255.255.255.0'))

# issue57
def testAddressIntMath(self):
self.assertEqual(ipaddress.IPv4Address('1.1.1.1') + 255,
Expand Down
@@ -0,0 +1,2 @@
Fix ipaddress.ip_{address,interface,network} raising TypeError instead of
ValueError if given invalid tuple as address parameter.

0 comments on commit 5f709bd

Please sign in to comment.