gh-156680: Raise the documented error from IPv6Network.next_network() - #156681
Conversation
…work() next_network() guarded address-space exhaustion with except OverflowError, which only int.to_bytes() on the IPv4 path raises. _BaseV6._string_from_ip_int() raises ValueError instead, so the handler never ran for IPv6 and the internal 'IPv6 address is too large' message escaped. Range-check next_ip against _ALL_ONES before formatting it, which decides the outcome for both address families before either path runs.
|
Also, reviewing fadb785 please fix the docstring of |
|
Oh and one more thing. I don't quite understand why we're doing this little dance with Apologies for all the changes I've asked you to make, indeed it grew to be quite a long list. As such, here's a patch instead: --- a/Lib/ipaddress.py
+++ b/Lib/ipaddress.py
@@ -1124,11 +1124,15 @@ def next_network(self, next_prefix=None):
Args:
next_prefix: The desired next prefix length, if not specified the
- same self.prefixlen will be used
+ same self.prefixlen will be used.
Returns:
An IPv(4|6) Network object of the next closest network.
+ Raises:
+ ValueError: If next_prefix is outside the range of valid prefix
+ lengths, or if no further network of that size exists.
+
"""
if next_prefix is None:
next_prefix = self.prefixlen
@@ -1150,15 +1154,13 @@ def next_network(self, next_prefix=None):
((new_netmask._ip & self.network_address._ip) >> bit_shift) + 1
) << bit_shift
- try:
- return self.__class__(
- f"{self._string_from_ip_int(next_ip)}/{next_prefix}"
- )
- except OverflowError:
+ if next_ip > self._ALL_ONES:
raise ValueError(
f"out of address space, cannot make another /{next_prefix} "
"network"
- ) from None
+ )
+
+ return self.__class__((next_ip, next_prefix)) |
Finish the next_network() docstring: a period on the argument sentence and a Raises section for the two ValueError cases. Build the result from an (address, prefix) tuple rather than formatting and reparsing a string. Give the What's New and NEWS entries explicit link titles so the IPv4Network and IPv6Network methods no longer both render as next_network().
Documentation build overview
|
|
@StanFromIreland Thanks for the comments! Implemented all. |
StanFromIreland
left a comment
There was a problem hiding this comment.
Thanks, this looks good to me. @orsenthil can you please take a look as well?
| ) from None | ||
| ) | ||
|
|
||
| return self.__class__((next_ip, next_prefix)) |
There was a problem hiding this comment.
While technically this style can be used self.__class__((next_ip, next_prefix)) m because IPv4Network and IPv6Network do the _split_addr_prefix, we do not advertise or mention about this the value of the address argument. This styled tripped me a bit.
I would prefer the previous style.
return self.__class__(
f"{self._string_from_ip_int(next_ip)}/{next_prefix}"
)
Because of what we say address can be in the doc strings of the class.
There was a problem hiding this comment.
I realize that public docs document that.
https://docs.python.org/3/library/ipaddress.html#ipaddress.IPv4Network
https://docs.python.org/3/library/ipaddress.html#ipaddress.IPv6Network
The change might simply be a follow up doc string patch on here.
Lines 2301 to 2319 in a6d25db
|
Thanks for the patch @fedonman and review and ping @StanFromIreland . |
|
@StanFromIreland - could you please review this follow up PR #157280 |
…work() (python#156681) * pythongh-156680: Raise the documented error from IPv6Network.next_network() next_network() guarded address-space exhaustion with except OverflowError, which only int.to_bytes() on the IPv4 path raises. _BaseV6._string_from_ip_int() raises ValueError instead, so the handler never ran for IPv6 and the internal 'IPv6 address is too large' message escaped. Build the result from an (address, prefix) tuple rather than formatting and reparsing a string.

Range-check
next_ipagainst_ALL_ONESinnext_network()instead of catchingOverflowError, which only the IPv4 path raises. The IPv6 path went through_BaseV6._string_from_ip_int(), whoseValueErrorescaped uncaught.next_network()is new in 3.16 and unreleased, so this is folded into the entry the method landed with and needs no NEWS fragment.IPv6Network.next_network()raises the wrong error when addresses run out #156680