Skip to content

Commit 8b67308

Browse files
miss-islingtonohwgilesserhiy-storchakaclaude
authored
[3.14] gh-88178: Fix exploded IPv6 addresses with a scope ID (GH-25824) (GH-155656)
IPv6Address.exploded raised AddressValueError, and IPv6Interface.exploded omitted the scope ID. (cherry picked from commit a2104b7) Co-authored-by: Oliver Giles <ohw.giles@gmail.com> Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 14d1280 commit 8b67308

3 files changed

Lines changed: 20 additions & 5 deletions

File tree

Lib/ipaddress.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1869,14 +1869,18 @@ def _explode_shorthand_ip_string(self):
18691869
elif isinstance(self, IPv6Interface):
18701870
ip_str = str(self.ip)
18711871
else:
1872-
ip_str = str(self)
1872+
ip_str = self._string_from_ip_int(self._ip)
18731873

18741874
ip_int = self._ip_int_from_string(ip_str)
18751875
hex_str = '%032x' % ip_int
1876-
parts = [hex_str[x:x+4] for x in range(0, 32, 4)]
1877-
if isinstance(self, (_BaseNetwork, IPv6Interface)):
1878-
return '%s/%d' % (':'.join(parts), self._prefixlen)
1879-
return ':'.join(parts)
1876+
exploded = ':'.join([hex_str[x:x+4] for x in range(0, 32, 4)])
1877+
if isinstance(self, _BaseNetwork):
1878+
return '%s/%d' % (exploded, self._prefixlen)
1879+
if self._scope_id:
1880+
exploded = '%s%%%s' % (exploded, self._scope_id)
1881+
if isinstance(self, IPv6Interface):
1882+
return '%s/%d' % (exploded, self._prefixlen)
1883+
return exploded
18801884

18811885
def _reverse_pointer(self):
18821886
"""Return the reverse DNS pointer name for the IPv6 address.

Lib/test/test_ipaddress.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2673,6 +2673,12 @@ def testExplodeShortHandIpStr(self):
26732673
addr1.exploded)
26742674
self.assertEqual('0000:0000:0000:0000:0000:0000:0000:0001/128',
26752675
ipaddress.IPv6Interface('::1/128').exploded)
2676+
self.assertEqual('fe80:0000:0000:0000:0000:0000:0000:0001%1',
2677+
ipaddress.IPv6Address('fe80::1%1').exploded)
2678+
self.assertEqual('fe80:0000:0000:0000:0000:0000:0000:0001%eth0',
2679+
ipaddress.IPv6Address('fe80::1%eth0').exploded)
2680+
self.assertEqual('fe80:0000:0000:0000:0000:0000:0000:0001%1/64',
2681+
ipaddress.IPv6Interface('fe80::1%1/64').exploded)
26762682
# issue 77
26772683
self.assertEqual('2001:0000:5ef5:79fd:0000:059d:a0e5:0ba1',
26782684
addr2.exploded)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
The ``exploded`` attribute of :class:`ipaddress.IPv6Address` and
2+
:class:`ipaddress.IPv6Interface` now supports addresses with a scope ID
3+
(link-local addresses).
4+
Previously the former raised :exc:`~ipaddress.AddressValueError`
5+
and the latter omitted the scope ID.

0 commit comments

Comments
 (0)