This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author kwi.dk
Recipients kwi.dk, ncoghlan, pitrou, pmoody
Date 2015-03-29.19:09:33
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1427656174.29.0.81501760101.issue22941@psf.upfronthosting.co.za>
In-reply-to
Content
As mentioned python-dev, I'm not entirely sold on raising an exception on overflow.

To recap the mailing list discussion, there was general agreement that the current behavior is a bug, suggesting that there's no need to go through the depreciation process. There's been three proposals for correct behavior, though:

A) To simply ignore the subnet mask: 10.0.0.255/24 + 1 = 10.0.1.0/24
B) To "wrap around" inside the subnet: 10.0.0.255/24 + 1 = 10.0.0.0/24
C) To raise exception.

First, note what happens if we overflow an IPv4Address:

    >>> ipaddress.IPv4Address('255.255.255.255') + 1
    Traceback (most recent call last):
    ...
    ipaddress.AddressValueError: 4294967296 (>= 2**32) is not permitted
    as an IPv4 address

At least that suggests a type of exception to use in proposal C.
    
There was not much support for the idea of wrapping (B); for which I see three reasons:

1) No identified use case where this effect would be desirable.
2) It's implicit rather than explicit: The addition operator usually does not imply modular arithmetic.
3) It's inconsistent with IPv4Address, which doesn't wrap.

That leaves the question of raising an exception (C), or not (A).

Now, I used "IPv4Interface + 1" to mean "Give me the IP next to the current one in the current subnet", knowing from the context that the address would be valid and available.

    >>> host = ipaddress.IPv4Interface('10.0.0.2/24')
    >>> peer = host + 1
    
In this context, an exception makes a lot of sense, as it would certainly have been an error if I'd overflowed the subnet.

However, I can also imagine situations in which overflowing would be valid and expected, e.g. as a way to skip to the "same" IP in the next subnet:

    >>> ip = ipaddress.IPv4Interface('10.0.0.1/24')
    >>> ip + ip.network.num_addresses
    IPv4Interface('10.0.1.1/24')

There's an additional issue with raising an exception, and that is that it still won't catch the errors as intended. In my use case:

    >>> host = ipaddress.IPv4Interface('10.0.0.254/24')
    >>> peer = host + 1

This wouldn't overflow and not trigger an exception, but the resulting peer address is still invalid (it's the subnet broadcast address, not a host address).

As for consistency with IPv4Address, I can argue for either proposal:

A) "An IPv4Interface behaves exactly like an IPv4Address, except that it also has an associated subnet mask." (This is essentially how it's currently documented).

C) "Overflowing an IPv4Interface raises AddressValueError just like with IPv4Address."

All in all, I'm in favor of keeping things simple and go with solution A, since C prevents a reasonable use, and doesn't actually catch out of bounds errors anyway. I'm open to being convinced otherwise, though.
History
Date User Action Args
2015-03-29 19:09:34kwi.dksetrecipients: + kwi.dk, ncoghlan, pitrou, pmoody
2015-03-29 19:09:34kwi.dksetmessageid: <1427656174.29.0.81501760101.issue22941@psf.upfronthosting.co.za>
2015-03-29 19:09:34kwi.dklinkissue22941 messages
2015-03-29 19:09:33kwi.dkcreate