Skip to content

Commit dc367a9

Browse files
miss-islingtonohwgilesserhiy-storchakaclaude
authored
[3.15] gh-88178: Fix exploded IPv6 addresses with a scope ID (GH-25824) (GH-155655)
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 3e00075 commit dc367a9

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
@@ -1870,14 +1870,18 @@ def _explode_shorthand_ip_string(self):
18701870
elif isinstance(self, IPv6Interface):
18711871
ip_str = str(self.ip)
18721872
else:
1873-
ip_str = str(self)
1873+
ip_str = self._string_from_ip_int(self._ip)
18741874

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

18821886
def _reverse_pointer(self):
18831887
"""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
@@ -2677,6 +2677,12 @@ def testExplodeShortHandIpStr(self):
26772677
addr1.exploded)
26782678
self.assertEqual('0000:0000:0000:0000:0000:0000:0000:0001/128',
26792679
ipaddress.IPv6Interface('::1/128').exploded)
2680+
self.assertEqual('fe80:0000:0000:0000:0000:0000:0000:0001%1',
2681+
ipaddress.IPv6Address('fe80::1%1').exploded)
2682+
self.assertEqual('fe80:0000:0000:0000:0000:0000:0000:0001%eth0',
2683+
ipaddress.IPv6Address('fe80::1%eth0').exploded)
2684+
self.assertEqual('fe80:0000:0000:0000:0000:0000:0000:0001%1/64',
2685+
ipaddress.IPv6Interface('fe80::1%1/64').exploded)
26802686
# issue 77
26812687
self.assertEqual('2001:0000:5ef5:79fd:0000:059d:a0e5:0ba1',
26822688
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)