> 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/NA422HQIN232FSCHSO3QQMGOPVZ4QM6W/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to