[issue32974] Add bitwise operations and other missing comparison methods to Python's IP address module

2018-02-28 Thread Ned Deily

Change by Ned Deily :


--
nosy: +pmoody

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue32974] Add bitwise operations and other missing comparison methods to Python's IP address module

2018-02-28 Thread bbayles

Change by bbayles :


--
nosy: +bbayles

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue32974] Add bitwise operations and other missing comparison methods to Python's IP address module

2018-02-28 Thread Kyle Agronick

New submission from Kyle Agronick :

I've recently had the experience of implementing a system for managing DNS 
records at a Fortune 10 company with ~10,000 stores. There were a number of 
things that I felt were missing from the IP address module and could be added 
without introducing any breaking changes.

The easiest changes I saw would be to implement bitwise operations without 
casting all the addresses to ints and then back to IP addresses.

Lets say you wanted to take the last octet from one address and put it on 
another:

Right now you need to do:
IPv6Address(int(v6('2001:db8:85a3:0:0:8a2e:370:7334')) & 
int(IPv6Address('0:0:0:0:0:0:0:')) | 
int(IPv6Address('1323:cf3:23df:0:0:32:44:0')))
# returns IPv6Address('1323:cf3:23df::32:44:7334')

You should be able to do:
(IPv6Address('2001:db8:85a3:0:0:8a2e:370:7334') & 
IPv6Address('0:0:0:0:0:0:0:')) | IPv6Address('1323:cf3:23df:0:0:32:44:0')
# returns TypeError: unsupported operand type(s) for &: 'IPv6Address' and 
'IPv6Address'

All that would be required is to do the casting to int automatically.

The other thing I saw that I would like would be to override the methods that 
return generators with iterables that provide more comparison operations.

Right now you can check if an IP is in a network with:
IPv4Address('192.168.1.12') in IPv4Network('192.168.1.0/24') 
# returns True

You should be able to do this with methods that return multiple networks.
ipaddress.summarize_address_range() is a method that returns a generator of 
IPv(4|6)Networks.

To see if an IP address is in one of multiple networks you need to do:
any(map(lambda i: IPv4Address('192.168.1.12') in i, 
ipaddress.summarize_address_range(IPv4Address('192.168.1.0'), 
IPv4Address('192.168.2.255'
# returns True

You should be able to do:
IPv4Address('192.168.1.12') in 
ipaddress.summarize_address_range(IPv4Address('192.168.1.0'), 
IPv4Address('192.168.2.255'))
# returns False

This should be the default for IPv(4|6)Addresses. IPv(4|6)Networks should check 
membership like they currently do.

You should be able to subtract ranges to make ranges that include some IPs but 
not others:
ipaddress.summarize_address_range(IPv4Address('192.168.1.0'), 
IPv4Address('192.168.2.255')) - 
ipaddress.summarize_address_range(IPv4Address('192.168.1.20'), 
IPv4Address('192.168.1.50'))
# returns TypeError: unsupported operand type(s) for -: 'generator' and 
'generator'

This should return a iterable that has networks that include 192.168.1.0 to 
192.168.1.20 and 192.168.1.50 to 192.168.2.255.

You should be able to do addition as well without casting to a list.

Methods like .hosts() should be able to be performed on the iterator instead of 
doing:
sum([list(i.hosts()) for i in 
ipaddress.summarize_address_range(IPv4Address('192.168.1.0'), 
IPv4Address('192.168.2.255'))], [])

do:
ipaddress.summarize_address_range(IPv4Address('192.168.1.0'), 
IPv4Address('192.168.2.255')).hosts()

Another great feature would be to allow division on networks and network 
generators giving you every xth host:
(i for i in IPv4Network('192.168.1.0/24').hosts() if int(i) % x == 0)

When x is 32 you get:
IPv4Address('192.168.1.32'), 
IPv4Address('192.168.1.64'), 
IPv4Address('192.168.1.96'), 
IPv4Address('192.168.1.128'), 
IPv4Address('192.168.1.160'), 
IPv4Address('192.168.1.192'), 
IPv4Address('192.168.1.224')

I would be happy to code this if the consensus was that this would be included.

--
components: Library (Lib)
messages: 313077
nosy: Kyle Agronick
priority: normal
severity: normal
status: open
title: Add bitwise operations and other missing comparison methods to Python's 
IP address module
type: enhancement
versions: Python 3.8

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com