Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0324feb

Browse files
opavlyukblurb-it[bot]asvetlov
authored andcommitted
gh-87799: Improve the textual representation of IPv4-mapped IPv6 addresses (GH-29345)
Represent IPv4-mapped IPv6 address as x:x:x:x:x:x:d.d.d.d, where the 'x's are the hexadecimal values of the six high-order 16-bit pieces of the address, and the 'd's are the decimal values of the four low-order 8-bit pieces of the address (standard IPv4 representation). --------- (cherry picked from commit f22bf8e) Co-authored-by: opavliuk <[email protected]> Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> Co-authored-by: Andrew Svetlov <[email protected]>
1 parent 00af979 commit 0324feb

File tree

3 files changed

+45
-1
lines changed

3 files changed

+45
-1
lines changed

Lib/ipaddress.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1941,8 +1941,40 @@ def __init__(self, address):
19411941

19421942
self._ip = self._ip_int_from_string(addr_str)
19431943

1944+
def _explode_shorthand_ip_string(self):
1945+
ipv4_mapped = self.ipv4_mapped
1946+
if ipv4_mapped is None:
1947+
long_form = super()._explode_shorthand_ip_string()
1948+
else:
1949+
prefix_len = 30
1950+
raw_exploded_str = super()._explode_shorthand_ip_string()
1951+
long_form = "%s%s" % (raw_exploded_str[:prefix_len], str(ipv4_mapped))
1952+
return long_form
1953+
1954+
def _ipv4_mapped_ipv6_to_str(self):
1955+
"""Return convenient text representation of IPv4-mapped IPv6 address
1956+
1957+
See RFC 4291 2.5.5.2, 2.2 p.3 for details.
1958+
1959+
Returns:
1960+
A string, 'x:x:x:x:x:x:d.d.d.d', where the 'x's are the hexadecimal values of
1961+
the six high-order 16-bit pieces of the address, and the 'd's are
1962+
the decimal values of the four low-order 8-bit pieces of the
1963+
address (standard IPv4 representation) as defined in RFC 4291 2.2 p.3.
1964+
1965+
"""
1966+
ipv4_mapped = self.ipv4_mapped
1967+
if ipv4_mapped is None:
1968+
raise AddressValueError("Can not apply to non-IPv4-mapped IPv6 address %s" % str(self))
1969+
high_order_bits = self._ip >> 32
1970+
return "%s:%s" % (self._string_from_ip_int(high_order_bits), str(ipv4_mapped))
1971+
19441972
def __str__(self):
1945-
ip_str = super().__str__()
1973+
ipv4_mapped = self.ipv4_mapped
1974+
if ipv4_mapped is None:
1975+
ip_str = super().__str__()
1976+
else:
1977+
ip_str = self._ipv4_mapped_ipv6_to_str()
19461978
return ip_str + '%' + self._scope_id if self._scope_id else ip_str
19471979

19481980
def __hash__(self):

Lib/test/test_ipaddress.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,6 +1322,17 @@ def testGetIp(self):
13221322
self.assertEqual(str(self.ipv6_scoped_interface.ip),
13231323
'2001:658:22a:cafe:200::1')
13241324

1325+
def testIPv6IPv4MappedStringRepresentation(self):
1326+
long_prefix = '0000:0000:0000:0000:0000:ffff:'
1327+
short_prefix = '::ffff:'
1328+
ipv4 = '1.2.3.4'
1329+
ipv6_ipv4_str = short_prefix + ipv4
1330+
ipv6_ipv4_addr = ipaddress.IPv6Address(ipv6_ipv4_str)
1331+
ipv6_ipv4_iface = ipaddress.IPv6Interface(ipv6_ipv4_str)
1332+
self.assertEqual(str(ipv6_ipv4_addr), ipv6_ipv4_str)
1333+
self.assertEqual(ipv6_ipv4_addr.exploded, long_prefix + ipv4)
1334+
self.assertEqual(str(ipv6_ipv4_iface.ip), ipv6_ipv4_str)
1335+
13251336
def testGetScopeId(self):
13261337
self.assertEqual(self.ipv6_address.scope_id,
13271338
None)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improve the textual representation of IPv4-mapped IPv6 addresses (:rfc:`4291` Sections 2.2, 2.5.5.2) in :mod:`ipaddress`. Patch by Oleksandr Pavliuk.

0 commit comments

Comments
 (0)