8000 gh-122792: Make IPv4-mapped IPv6 address properties consistent with I… · miss-islington/cpython@abecf3f · GitHub
[go: up one dir, main page]

Skip to content

Commit abecf3f

Browse files
sethmlarsonmiss-islington
authored andcommitted
pythongh-122792: Make IPv4-mapped IPv6 address properties consistent with IPv4 (pythonGH-122793)
Make IPv4-mapped IPv6 address properties consistent with IPv4. (cherry picked from commit 76a1c5d) Co-authored-by: Seth Michael Larson <seth@python.org>
1 parent 8b275e7 commit abecf3f

File tree

3 files changed

+42
-0
lines changed

3 files changed

+42
-0
lines changed

Lib/ipaddress.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2004,6 +2004,9 @@ def is_multicast(self):
20042004
See RFC 2373 2.7 for details.
20052005
20062006
"""
2007+
ipv4_mapped = self.ipv4_mapped
2008+
if ipv4_mapped is not None:
2009+
return ipv4_mapped.is_multicast
20072010
return self in self._constants._multicast_network
20082011

20092012
@property
@@ -2015,6 +2018,9 @@ def is_reserved(self):
20152018
reserved IPv6 Network ranges.
20162019
20172020
"""
2021+
ipv4_mapped = self.ipv4_mapped
2022+
if ipv4_mapped is not None:
2023+
return ipv4_mapped.is_reserved
20182024
return any(self in x for x in self._constants._reserved_networks)
20192025

20202026
@property
@@ -2025,6 +2031,9 @@ def is_link_local(self):
20252031
A boolean, True if the address is reserved per RFC 4291.
20262032
20272033
"""
2034+
ipv4_mapped = self.ipv4_mapped
2035+
if ipv4_mapped is not None:
2036+
return ipv4_mapped.is_link_local
20282037
return self in self._constants._linklocal_network
20292038

20302039
@property
@@ -2081,6 +2090,9 @@ def is_global(self):
20812090
``is_global`` has value opposite to :attr:`is_private`, except for the ``100.64.0.0/10``
20822091
IPv4 range where they are both ``False``.
20832092
"""
2093+
ipv4_mapped = self.ipv4_mapped
2094+
if ipv4_mapped is not None:
2095+
return ipv4_mapped.is_global
20842096
return not self.is_private
20852097

20862098
@property
@@ -2092,6 +2104,9 @@ def is_unspecified(self):
20922104
RFC 2373 2.5.2.
20932105
20942106
"""
2107+
ipv4_mapped = self.ipv4_mapped
2108+
if ipv4_mapped is not None:
2109+
return ipv4_mapped.is_unspecified
20952110
return self._ip == 0
20962111

20972112
@property

Lib/test/test_ipaddress.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2421,6 +2421,30 @@ def testIpv4Mapped(self):
24212421
self.assertEqual(ipaddress.ip_address('::ffff:c0a8:101').ipv4_mapped,
24222422
ipaddress.ip_address('192.168.1.1'))
24232423

2424+
def testIpv4MappedProperties(self):
2425+
# Test that an IPv4 mapped IPv6 address has
2426+
# the same properties as an IPv4 address.
2427+
for addr4 in (
2428+
"178.62.3.251", # global
2429+
"169.254.169.254", # link local
2430+
"127.0.0.1", # loopback
2431+
"224.0.0.1", # multicast
2432+
"192.168.0.1", # private
2433+
"0.0.0.0", # unspecified
2434+
"100.64.0.1", # public and not global
2435+
):
2436+
with self.subTest(addr4):
2437+
ipv4 = ipaddress.IPv4Address(addr4)
2438+
ipv6 = ipaddress.IPv6Address(f"::ffff:{addr4}")
2439+
2440+
self.assertEqual(ipv4.is_global, ipv6.is_global)
2441+
self.assertEqual(ipv4.is_private, ipv6.is_private)
2442+
self.assertEqual(ipv4.is_reserved, ipv6.is_reserved)
2443+
self.assertEqual(ipv4.is_multicast, ipv6.is_multicast)
2444+
self.assertEqual(ipv4.is_unspecified, ipv6.is_unspecified)
2445+
self.assertEqual(ipv4.is_link_local, ipv6.is_link_local)
2446+
self.assertEqual(ipv4.is_loopback, ipv6.is_loopback)
2447+
24242448
def testIpv4MappedPrivateCheck(self):
24252449
self.assertEqual(
24262450
True, ipaddress.ip_address('::ffff:192.168.1.1').is_private)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Changed IPv4-mapped ``ipaddress.IPv6Address`` to consistently use the mapped IPv4
2+
address value for deciding properties. Properties which have their behavior fixed
3+
are ``is_multicast``, ``is_reserved``, ``is_link_local``, ``is_global``, and ``is_unspecified``.

0 commit comments

Comments
 (0)
0