On 3/22/2021 8:51 PM, Senthil Kumaran wrote:
Given this discussion, I am motivated to review this and merge this
into stdlib. The conversation was helpful to me to understand for
utility value of the method introduced by the patch.
I had stated in the PR as well.

Thank you, both, Faisal and Jakub.

Yes, thank you.

I've also needed the "next network of a given prefix size" feature.

Eric


On Mon, Mar 22, 2021 at 5:40 PM Jakub Stasiak <ja...@stasiak.at> wrote:


On 22 Mar 2021, at 13:07, Faisal Mahmood <fasial.mahmoo...@gmail.com> wrote:

Thanks Jakub, I wasn't aware of the netaddr library but just gave it a play and 
it does seem very similar and I think it's very useful and completely valid.

I think the subtle difference is also that my implementation allows you to 
specify the next prefix as well, so it won't just find the next prefix of the 
same size.  This is a common use case when you are trying to find free address 
spaces, you will need to look for networks of different sizes depending on what 
you are doing.

Currently, you could say that you were given a network of 10.200.20.0/24 and 
asked to split this network into a bunch of /26 networks, you can do this 
easily using the subnets method:
list(IPv4Network("10.200.20.0/24").subnets(prefixlen_diff=2))
[IPv4Network('10.200.20.0/26'), IPv4Network('10.200.20.64/26'), 
IPv4Network('10.200.20.128/26'), IPv4Network('10.200.20.192/26')]

That is very simple and effective, but not a very realistic example of how you 
would split networks up.  Given how limited the IPv4 address space is, normally 
you may have to use that /24 block for multiple things, so can't just simply 
split it up into /26's, you may need to instead get two /30's, one /27 and one 
/25.  Currently, I don't think there is any straightforward way to do this 
without a 'next_network' method that I have implemented.

Example, given a network of 10.200.20.0/24, to get two /30's out of it, one /27 
and one /25, I would do the following with my method:
first_network = IPv4Network("10.200.20.0/30")
# first_network = IPv4Network("10.200.20.0/30")

Then get the next one (note not specifying prefix just gives me another /30 - 
i.e. same prefix size):
second_network = first_network.next_network()
# second_network = IPv4Network("10.200.20.4/30")

Then I would need to get the /27, so do this:
third_network = second_network.next_network(new_prefixlen=27)
# third_network = IPv4Network("10.200.20.32/27)

Finally the /25:
fourth_network = third_network.next_network(new_prefixlen=25)
# fourth_network = IPv4Network("10.200.20.128/25)

When you are dealing with the same prefix size for each new network, I think 
it's just a simple case of adding 1 to the broadcast address each time, but 
when you have different prefix sizes it's a bit more complicated.

On Sat, 20 Mar 2021 at 22:04, Jakub Stasiak <ja...@stasiak.at> wrote:



I don’t know if this is gonna support Faisal’s cause (“It’s used in a third 
party library in the wild, that means stdlib could use it!”) or the exact 
opposite (“it’s provided by a third party library, so may as well use third 
party library and stdlib doesn’t necessarily need this”) but the quite popular 
netaddr library that I’m a maintainer of does have IPNetwork.next() and 
IPNetwork.previous() methods[1][2]. The main difference is that in netaddr:

* next() and previous() can produce networks arbitrary number of steps away, 
not just the first closest network forwards or backwards
* going from a network to its supernetwork or subnetwork is done through a 
separate set of supernet() and subnet() methods[3][4]

I can’t say how many library users actually consume this particular section of 
the API, of course, but I expect this API to be used and it seems rather useful.

Best,
Jakub

[1] https://netaddr.readthedocs.io/en/latest/api.html#netaddr.IPNetwork.next
[2] https://netaddr.readthedocs.io/en/latest/api.html#netaddr.IPNetwork.previous
[3] https://netaddr.readthedocs.io/en/latest/api.html#netaddr.IPNetwork.subnet
[4] https://netaddr.readthedocs.io/en/latest/api.html#netaddr.IPNetwork.supernet
Thank you for the explanation – now I understand better how that prefix 
parameter is useful.

It’s not *that* difficult to emulate this using netaddr, there’s an extra 
switch-to-supernet or switch-to-subnet step but that’s about it:

from netaddr import IPNetwork
first_network = IPNetwork("10.200.20.0/30")
second_network = first_network.next()
second_network
IPNetwork('10.200.20.4/30')
third_network = second_network.supernet(27)[0].next()
third_network
IPNetwork('10.200.20.32/27')
fourth_network = third_network.supernet(25)[0].next()
fourth_network
IPNetwork('10.200.20.128/25’)

That said, if merging this into the Python stdlib doesn’t work out I’m open to 
improving netaddr’s interface to better serve this use case.

Best wishes,
Jakub
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/LPCY3R4WINI5XCMWGPDA3EI52HMCPJTS/
Code of Conduct: http://python.org/psf/codeofconduct/

--
Eric V. Smith

_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/MDXFNG6QV5GKBCGVGYV2W6NLUM6DR2LQ/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to