Skip to content

Commit 52dc9c3

Browse files
bpo-46415: Use f-string for ValueError in ipaddress.ip_{address,network,interface} helper functions (#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 <[email protected]>
1 parent ec8d3ad commit 52dc9c3

File tree

3 files changed

+24
-9
lines changed

3 files changed

+24
-9
lines changed

Lib/ipaddress.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@ def ip_address(address):
5151
except (AddressValueError, NetmaskValueError):
5252
pass
5353

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

5756

5857
def ip_network(address, strict=True):
@@ -81,8 +80,7 @@ def ip_network(address, strict=True):
8180
except (AddressValueError, NetmaskValueError):
8281
pass
8382

84-
raise ValueError('%r does not appear to be an IPv4 or IPv6 network' %
85-
address)
83+
raise ValueError(f'{address!r} does not appear to be an IPv4 or IPv6 network')
8684

8785

8886
def ip_interface(address):
@@ -116,8 +114,7 @@ def ip_interface(address):
116114
except (AddressValueError, NetmaskValueError):
117115
pass
118116

119-
raise ValueError('%r does not appear to be an IPv4 or IPv6 interface' %
120-
address)
117+
raise ValueError(f'{address!r} does not appear to be an IPv4 or IPv6 interface')
121118

122119

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

166163

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

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

19191916
self._ip = self._ip_int_from_string(addr_str)

Lib/test/test_ipaddress.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,6 +1132,14 @@ def testIPv4Tuple(self):
11321132
self.assertEqual(ipaddress.IPv4Interface((3221225985, 24)),
11331133
ipaddress.IPv4Interface('192.0.2.1/24'))
11341134

1135+
# Invalid netmask
1136+
with self.assertRaises(ValueError):
1137+
ipaddress.IPv4Network(('192.0.2.1', '255.255.255.255.0'))
1138+
1139+
# Invalid netmask using factory
1140+
with self.assertRaises(ValueError):
1141+
ipaddress.ip_network(('192.0.2.1', '255.255.255.255.0'))
1142+
11351143
# issue #16531: constructing IPv6Network from an (address, mask) tuple
11361144
def testIPv6Tuple(self):
11371145
# /128
@@ -1191,6 +1199,14 @@ def testIPv6Tuple(self):
11911199
ipaddress.IPv6Network((ip_scoped, 96))
11921200
# strict=False and host bits set
11931201

1202+
# Invalid netmask
1203+
with self.assertRaises(ValueError):
1204+
ipaddress.IPv6Network(('2001:db8::1', '255.255.255.0'))
1205+
1206+
# Invalid netmask using factory
1207+
with self.assertRaises(ValueError):
1208+
ipaddress.ip_network(('2001:db8::1', '255.255.255.0'))
1209+
11941210
# issue57
11951211
def testAddressIntMath(self):
11961212
self.assertEqual(ipaddress.IPv4Address('1.1.1.1') + 255,
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix ipaddress.ip_{address,interface,network} raising TypeError instead of
2+
ValueError if given invalid tuple as address parameter.

0 commit comments

Comments
 (0)