GeezerVison is showing github.com — ipaddress.IPv6Address.is_loopback broken for IPv4-mapped addresses · Issue #117566 · python/cpython
ipaddress.IPv6Address.is_loopback broken for IPv4-mapped addresses #117566DescriptionBug report
Bug description:
While properties like is_private account for IPv4-mapped IPv6 addresses, such as for example:
>>> ipaddress.ip_address("192.168.0.1").is_private
True
>>> ipaddress.ip_address("::ffff:192.168.0.1").is_private
True
...the same doesn't currently apply to the is_loopback property:
>>> ipaddress.ip_address("127.0.0.1").is_loopback
True
>>> ipaddress.ip_address("::ffff:127.0.0.1").is_loopback
False
At minimum, this inconsistency between different properties is counter-intuitive. Moreover, ::ffff:127.0.0.0/104 is for all intents and purposes a loopback address, and should be treated as such.
For the record, this will now match the behavior of other languages such as Rust, Go and .NET, cf. rust-lang/rust#69772.
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Linked PRs
Activityparavoid commented on Apr 26, 2024 ContributorAuthor More actions This was fixed in main, as @encukou merged the PR. The only outstanding question I have is whether this warrants a backport to 3.12.x or not. Depending on the answer, this may be resolved :) encukou commented on Apr 29, 2024 The answer is not obvious.
But given a similar PR is being backported, I say this one should be backported as well. paravoid commented on May 1, 2024 ContributorAuthor More actions @encukou thanks so much for the review, good feedback, merge & backport -- much appreciated! ❤️ jstasiak commented on May 21, 2024 Hey all, sorry for a late comment but I only now saw this issue randomly.
For the record, this will now match the behavior of other languages such as Rust, Go and .NET, cf. rust-lang/rust#69772.
Just to clarify, Rust's behavior is deliberately the opposite of this, as in it doesn't interpret IPv4-mapped IPv6 addresses like that[1][2].
I would argue that
Moreover, ::ffff:127.0.0.0/104 is for all intents and purposes a loopback address, and should be treated as such.
is not necessarily the only or even the most natural approach. For example with this patch there's no built-in way to check strictly for the IPv6 loopback address and nothing else.
And yes, I'd argue that is_private and is_global interpreting IPv4-mapped IPv6 addresses is IMO a mistake too and the decision is best left to the developer (the ipv4_mapped property can be used to convert if/when needed).
[1] rust-lang/rust#86335
[2] https://doc.rust-lang.org/std/net/struct.Ipv6Addr.html#ipv4-mapped-ipv6-addresses encukou commented on May 30, 2024 Noted.
I'll also opine that this API is, in hindsight, too coarse-grained and opinionated to be a good match for stdlib. Everyone has different expectations of what the edge cases should be.
See this point in the linked Rust discussion: “A point in favour of not supporting IPv4-in-IPv6 addresses is that that is the behaviour Rust has always had, and that supporting it would require changing already stable functions”
IMO, the most important thing we should go for here is consistency within the module: either all the functions should unwrap IPv4-mapped addresses, or none of them should.
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|