Skip to content

ipaddress.IPv6Address.is_loopback broken for IPv4-mapped addresses #117566

Description

@paravoid

Bug 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

Activity

  1. added 2 commits that reference this issue on Apr 5, 2024
  2. added
    stdlibStandard Library Python modules in the Lib/ directory
    on Apr 6, 2024
  3. added a commit that references this issue on Apr 25, 2024
  4. added a commit that references this issue on Apr 25, 2024
  5. paravoid commented on Apr 26, 2024

    @paravoid
    ContributorAuthor

    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 :)

  6. encukou commented on Apr 29, 2024

    @encukou
    Member

    The answer is not obvious.
    But given a similar PR is being backported, I say this one should be backported as well.

  7. added a commit that references this issue on Apr 29, 2024
  8. added a commit that references this issue on Apr 29, 2024
  9. paravoid commented on May 1, 2024

    @paravoid
    ContributorAuthor

    @encukou thanks so much for the review, good feedback, merge & backport -- much appreciated! ❤️

  10. jstasiak commented on May 21, 2024

    @jstasiak
    Contributor

    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

  11. encukou commented on May 30, 2024

    @encukou
    Member

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions