> 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/