Thanks for the feedback, and apologies for my late reply. I have to say, I'm not entirely sold on the argument for raising an exception on subnet "overflow".
First, I'll 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
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, I would welcome an exception, as it would certainly be an error if I overflowed the subnet.
However, there are also 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.42/24') >>> ip + ip.network.num_addresses IPv4Interface('10.0.1.42/24')
It's not even a hypothetical example; I've been working on a distributed embedded system where all the hosts have two (redundant) addresses differing only by their subnet; this could be a convenient way calculate one address from the other.
There's an additional issue with raising an exception, and that is that it still won't catch overflow errors in my example use case:
>>> host = ipaddress.IPv4Interface('10.0.0.254/24') >>> peer = host + 1 >>> peer IPv4Interface('10.0.0.255/24')
This doesn't overflow and does not trigger an exception, but the resulting peer address is still invalid (it's the subnet broadcast address, not a host address). As such, the exception isn't even useful as an error detection tool. (I'll not suggest raising an exception when hitting the broadcast or network address; that way lies madness.)
As for consistency with IPv4Address, I can argue either way:
"Overflowing an IPv4Interface raises AddressValueError just like with IPv4Address."
"An IPv4Interface behaves exactly like an IPv4Address, except that it also has an associated subnet mask." (This is essentially how the type is currently documented).
Best regards, Søren Løvborg