8000 [3.13] gh-122792: Make IPv4-mapped IPv6 address properties consistent… · python/cpython@a63e06d · GitHub
[go: up one dir, main page]

Skip to content

Commit a63e06d

Browse files
[3.13] gh-122792: Make IPv4-mapped IPv6 address properties consistent with IPv4 (GH-122793) (GH-123815)
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 3479a71 commit a63e06d

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
@@ -2052,6 +2052,9 @@ def is_multicast(self):
20522052
See RFC 2373 2.7 for details.
20532053
20542054
"""
2055+
ipv4_mapped = self.ipv4_mapped
2056+
if ipv4_mapped is not None:
2057+
return ipv4_mapped.is_multicast
20552058
return self in self._constants._multicast_network
20562059

20572060
@property
@@ -2063,6 +2066,9 @@ def is_reserved(self):
20632066
reserved IPv6 Network ranges.
20642067
20652068
"""
2069+
ipv4_mapped = self.ipv4_mapped
2070+
if ipv4_mapped is not None:
2071+
return ipv4_mapped.is_reserved
20662072
return any(self in x for x in self._constants._reserved_networks)
20672073

20682074
@property
@@ -2073,6 +2079,9 @@ def is_link_local(self):
20732079
A boolean, True if the address is reserved per RFC 4291.
20742080
20752081
"""
2082+
ipv4_mapped = self.ipv4_mapped
2083+
if ipv4_mapped is not None:
2084+
return ipv4_mapped.is_link_local
20762085
return self in self._constants._linklocal_network
20772086

20782087
@property
@@ -2129,6 +2138,9 @@ def is_global(self):
21292138
``is_global`` has value opposite to :attr:`is_private`, except for the ``100.64.0.0/10``
21302139
IPv4 range where they are both ``False``.
21312140
"""
2141+
ipv4_mapped = self.ipv4_mapped
2142+
if ipv4_mapped is not None:
2143+
return ipv4_mapped.is_global
21322144
return not self.is_private
21332145

21342146
@property
@@ -2140,6 +2152,9 @@ def is_unspecified(self):
21402152
RFC 2373 2.5.2.
21412153
21422154
"""
2155+
ipv4_mapped = self.ipv4_mapped
2156+
if ipv4_mapped is not None:
2157+
return ipv4_mapped.is_unspecified
21432158
return self._ip == 0
21442159

21452160
@property

Lib/test/test_ipaddress.py

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

2445+
def testIpv4MappedProperties(self):
2446+
# Test that an IPv4 mapped IPv6 address has
2447+
# the same properties as an IPv4 address.
2448+
for addr4 in (
2449+
"178.62.3.251", # global
2450+
"169.254.169.254", # link local
2451+
"127.0.0.1", # loopback
2452+
"224.0.0.1", # multicast
2453+
"192.168.0.1", # private
2454+
"0.0.0.0", # unspecified
2455+
"100.64.0.1", # public and not global
2456+
):
2457+
with self.subTest(addr4):
2458+
ipv4 = ipaddress.IPv4Address(addr4)
2459+
ipv6 = ipaddress.IPv6Address(f"::ffff:{addr4}")
2460+
2461+
self.assertEqual(ipv4.is_global, ipv6.is_global)
2462+
self.assertEqual(ipv4.is_private, ipv6.is_private)
2463+
self.assertEqual(ipv4.is_reserved, ipv6.is_reserved)
2464+
self.assertEqual(ipv4.is_multicast, ipv6.is_multicast)
2465+
self.assertEqual(ipv4.is_unspecified, ipv6.is_unspecified)
2466+
self.assertEqual(ipv4.is_link_local, ipv6.is_link_local)
2467+
self.assertEqual(ipv4.is_loopback, ipv6.is_loopback)
2468+
24452469
def testIpv4MappedPrivateCheck(self):
24462470
self.assertEqual(
24472471
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