Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita897b4a

Browse files
ambvsethmlarson
andauthored
[3.9]gh-122792: Make IPv4-mapped IPv6 address properties consistent with IPv4 (GH-122793) (GH-123819) (GH-127571)
Make IPv4-mapped IPv6 address properties consistent with IPv4.(cherry picked from commit76a1c5d)(cherry picked from commitb58da40)Co-authored-by: Seth Michael Larson <seth@python.org>
1 parent08830c7 commita897b4a

File tree

3 files changed

+55
-5
lines changed

3 files changed

+55
-5
lines changed

‎Lib/ipaddress.py

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ def collapse_addresses(addresses):
309309
[IPv4Network('192.0.2.0/24')]
310310
311311
Args:
312-
addresses: Aniterator of IPv4Network or IPv6Network objects.
312+
addresses: Aniterable of IPv4Network or IPv6Network objects.
313313
314314
Returns:
315315
An iterator of the collapsed IPv(4|6)Network objects.
@@ -1839,9 +1839,6 @@ def _string_from_ip_int(cls, ip_int=None):
18391839
def_explode_shorthand_ip_string(self):
18401840
"""Expand a shortened IPv6 address.
18411841
1842-
Args:
1843-
ip_str: A string, the IPv6 address.
1844-
18451842
Returns:
18461843
A string, the expanded IPv6 address.
18471844
@@ -1985,6 +1982,9 @@ def is_multicast(self):
19851982
See RFC 2373 2.7 for details.
19861983
19871984
"""
1985+
ipv4_mapped=self.ipv4_mapped
1986+
ifipv4_mappedisnotNone:
1987+
returnipv4_mapped.is_multicast
19881988
returnselfinself._constants._multicast_network
19891989

19901990
@property
@@ -1996,6 +1996,9 @@ def is_reserved(self):
19961996
reserved IPv6 Network ranges.
19971997
19981998
"""
1999+
ipv4_mapped=self.ipv4_mapped
2000+
ifipv4_mappedisnotNone:
2001+
returnipv4_mapped.is_reserved
19992002
returnany(selfinxforxinself._constants._reserved_networks)
20002003

20012004
@property
@@ -2006,6 +2009,9 @@ def is_link_local(self):
20062009
A boolean, True if the address is reserved per RFC 4291.
20072010
20082011
"""
2012+
ipv4_mapped=self.ipv4_mapped
2013+
ifipv4_mappedisnotNone:
2014+
returnipv4_mapped.is_link_local
20092015
returnselfinself._constants._linklocal_network
20102016

20112017
@property
@@ -2062,6 +2068,9 @@ def is_global(self):
20622068
``is_global`` has value opposite to :attr:`is_private`, except for the ``100.64.0.0/10``
20632069
IPv4 range where they are both ``False``.
20642070
"""
2071+
ipv4_mapped=self.ipv4_mapped
2072+
ifipv4_mappedisnotNone:
2073+
returnipv4_mapped.is_global
20652074
returnnotself.is_private
20662075

20672076
@property
@@ -2073,6 +2082,9 @@ def is_unspecified(self):
20732082
RFC 2373 2.5.2.
20742083
20752084
"""
2085+
ipv4_mapped=self.ipv4_mapped
2086+
ifipv4_mappedisnotNone:
2087+
returnipv4_mapped.is_unspecified
20762088
returnself._ip==0
20772089

20782090
@property
@@ -2084,6 +2096,9 @@ def is_loopback(self):
20842096
RFC 2373 2.5.3.
20852097
20862098
"""
2099+
ipv4_mapped=self.ipv4_mapped
2100+
ifipv4_mappedisnotNone:
2101+
returnipv4_mapped.is_loopback
20872102
returnself._ip==1
20882103

20892104
@property
@@ -2200,7 +2215,7 @@ def is_unspecified(self):
22002215

22012216
@property
22022217
defis_loopback(self):
2203-
returnself._ip==1andself.network.is_loopback
2218+
returnsuper().is_loopbackandself.network.is_loopback
22042219

22052220

22062221
classIPv6Network(_BaseV6,_BaseNetwork):
@@ -2313,6 +2328,8 @@ class _IPv6Constants:
23132328
IPv6Network('2001:db8::/32'),
23142329
# IANA says N/A, let's consider it not globally reachable to be safe
23152330
IPv6Network('2002::/16'),
2331+
# RFC 9637: https://www.rfc-editor.org/rfc/rfc9637.html#section-6-2.2
2332+
IPv6Network('3fff::/20'),
23162333
IPv6Network('fc00::/7'),
23172334
IPv6Network('fe80::/10'),
23182335
]

‎Lib/test/test_ipaddress.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2415,6 +2415,36 @@ def testIpv4Mapped(self):
24152415
self.assertEqual(ipaddress.ip_address('::ffff:c0a8:101').ipv4_mapped,
24162416
ipaddress.ip_address('192.168.1.1'))
24172417

2418+
deftestIpv4MappedProperties(self):
2419+
# Test that an IPv4 mapped IPv6 address has
2420+
# the same properties as an IPv4 address.
2421+
foraddr4in (
2422+
"178.62.3.251",# global
2423+
"169.254.169.254",# link local
2424+
"127.0.0.1",# loopback
2425+
"224.0.0.1",# multicast
2426+
"192.168.0.1",# private
2427+
"0.0.0.0",# unspecified
2428+
"100.64.0.1",# public and not global
2429+
):
2430+
withself.subTest(addr4):
2431+
ipv4=ipaddress.IPv4Address(addr4)
2432+
ipv6=ipaddress.IPv6Address(f"::ffff:{addr4}")
2433+
2434+
self.assertEqual(ipv4.is_global,ipv6.is_global)
2435+
self.assertEqual(ipv4.is_private,ipv6.is_private)
2436+
self.assertEqual(ipv4.is_reserved,ipv6.is_reserved)
2437+
self.assertEqual(ipv4.is_multicast,ipv6.is_multicast)
2438+
self.assertEqual(ipv4.is_unspecified,ipv6.is_unspecified)
2439+
self.assertEqual(ipv4.is_link_local,ipv6.is_link_local)
2440+
self.assertEqual(ipv4.is_loopback,ipv6.is_loopback)
2441+
2442+
deftestIpv4MappedPrivateCheck(self):
2443+
self.assertEqual(
2444+
True,ipaddress.ip_address('::ffff:192.168.1.1').is_private)
2445+
self.assertEqual(
2446+
False,ipaddress.ip_address('::ffff:172.32.0.0').is_private)
2447+
24182448
deftestAddrExclude(self):
24192449
addr1=ipaddress.ip_network('10.1.1.0/24')
24202450
addr2=ipaddress.ip_network('10.1.1.0/26')
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)

[8]ページ先頭

©2009-2025 Movatter.jp