Søren Løvborg added the comment:

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.

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue22941>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to