From 0f47044bdad5361140f0110cf3301d9b53c919f5 Mon Sep 17 00:00:00 2001 From: Frederic Date: Wed, 7 Nov 2012 11:32:41 -0500 Subject: [PATCH 01/11] speed ipv4.is_{link_local,loopback,unspecified,multicast,private,reserved}(). --- ipaddr.py | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/ipaddr.py b/ipaddr.py index c30f298..0017203 100644 --- a/ipaddr.py +++ b/ipaddr.py @@ -1180,7 +1180,7 @@ def is_reserved(self): reserved IPv4 Network range. """ - return self in IPv4Network('240.0.0.0/4') + return self in _BaseV4._IP_RESERVED @property def is_private(self): @@ -1190,9 +1190,9 @@ def is_private(self): A boolean, True if the address is reserved per RFC 1918. """ - return (self in IPv4Network('10.0.0.0/8') or - self in IPv4Network('172.16.0.0/12') or - self in IPv4Network('192.168.0.0/16')) + return (self in _BaseV4._IP_PRIVATE_10 or + self in _BaseV4._IP_PRIVATE_172_16 or + self in _BaseV4._IP_PRIVATE_192_168 ) @property def is_multicast(self): @@ -1203,7 +1203,7 @@ def is_multicast(self): See RFC 3171 for details. """ - return self in IPv4Network('224.0.0.0/4') + return self in _BaseV4._IP_MULTICAST @property def is_unspecified(self): @@ -1214,7 +1214,7 @@ def is_unspecified(self): RFC 5735 3. """ - return self in IPv4Network('0.0.0.0') + return self in _BaseV4._IP_UNSPECIFIED @property def is_loopback(self): @@ -1224,7 +1224,7 @@ def is_loopback(self): A boolean, True if the address is a loopback per RFC 3330. """ - return self in IPv4Network('127.0.0.0/8') + return self in _BaseV4._IP_LOOKBACK @property def is_link_local(self): @@ -1234,7 +1234,7 @@ def is_link_local(self): A boolean, True if the address is link-local per RFC 3927. """ - return self in IPv4Network('169.254.0.0/16') + return self in _BaseV4._IP_LINK_LOCAL class IPv4Address(_BaseV4, _BaseIP): @@ -1401,6 +1401,15 @@ def __init__(self, address, strict=False): IsLoopback = lambda self: self.is_loopback IsLinkLocal = lambda self: self.is_link_local +#Those are used to speed up functions from _BaseV4 +_BaseV4._IP_PRIVATE_10 = IPv4Network('10.0.0.0/8') +_BaseV4._IP_PRIVATE_172_16 = IPv4Network('172.16.0.0/12') +_BaseV4._IP_PRIVATE_192_168 = IPv4Network('192.168.0.0/16') +_BaseV4._IP_RESERVED = IPv4Network('240.0.0.0/4') +_BaseV4._IP_MULTICAST = IPv4Network('224.0.0.0/4') +_BaseV4._IP_UNSPECIFIED = IPv4Network('0.0.0.0') +_BaseV4._IP_LOOKBACK = IPv4Network('127.0.0.0/8') +_BaseV4._IP_LINK_LOCAL = IPv4Network('169.254.0.0/16') class _BaseV6(object): From d4c12894767fbf332b7c0422a060b047ebf6de12 Mon Sep 17 00:00:00 2001 From: Frederic Date: Wed, 7 Nov 2012 11:33:36 -0500 Subject: [PATCH 02/11] use 4 spaces align as else where in the file. --- ipaddr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipaddr.py b/ipaddr.py index 0017203..27a910c 100644 --- a/ipaddr.py +++ b/ipaddr.py @@ -1524,7 +1524,7 @@ def _parse_hextet(self, hextet_str): if not self._HEX_DIGITS.issuperset(hextet_str): raise ValueError if len(hextet_str) > 4: - raise ValueError + raise ValueError hextet_int = int(hextet_str, 16) if hextet_int > 0xFFFF: raise ValueError From 83ec832a968d589c8ba65114be88d737db6225b5 Mon Sep 17 00:00:00 2001 From: Frederic Date: Wed, 7 Nov 2012 11:45:42 -0500 Subject: [PATCH 03/11] speed up ipv6.is_{private,multicast,link_local,site_local,reserved} --- ipaddr.py | 58 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 19 deletions(-) diff --git a/ipaddr.py b/ipaddr.py index 27a910c..b0ab655 100644 --- a/ipaddr.py +++ b/ipaddr.py @@ -1651,7 +1651,7 @@ def is_multicast(self): See RFC 2373 2.7 for details. """ - return self in IPv6Network('ff00::/8') + return self in _BaseV6._IP_MULTICAST @property def is_reserved(self): @@ -1662,21 +1662,21 @@ def is_reserved(self): reserved IPv6 Network ranges. """ - return (self in IPv6Network('::/8') or - self in IPv6Network('100::/8') or - self in IPv6Network('200::/7') or - self in IPv6Network('400::/6') or - self in IPv6Network('800::/5') or - self in IPv6Network('1000::/4') or - self in IPv6Network('4000::/3') or - self in IPv6Network('6000::/3') or - self in IPv6Network('8000::/3') or - self in IPv6Network('A000::/3') or - self in IPv6Network('C000::/3') or - self in IPv6Network('E000::/4') or - self in IPv6Network('F000::/5') or - self in IPv6Network('F800::/6') or - self in IPv6Network('FE00::/9')) + return (self in _BaseV6._IP_RESERVED0 or + self in _BaseV6._IP_RESERVED1 or + self in _BaseV6._IP_RESERVED2 or + self in _BaseV6._IP_RESERVED4 or + self in _BaseV6._IP_RESERVED8 or + self in _BaseV6._IP_RESERVED10 or + self in _BaseV6._IP_RESERVED40 or + self in _BaseV6._IP_RESERVED60 or + self in _BaseV6._IP_RESERVED80 or + self in _BaseV6._IP_RESERVEDA0 or + self in _BaseV6._IP_RESERVEDC0 or + self in _BaseV6._IP_RESERVEDE0 or + self in _BaseV6._IP_RESERVEDF0 or + self in _BaseV6._IP_RESERVEDF8 or + self in _BaseV6._IP_RESERVEDFE) @property def is_unspecified(self): @@ -1708,7 +1708,7 @@ def is_link_local(self): A boolean, True if the address is reserved per RFC 4291. """ - return self in IPv6Network('fe80::/10') + return self in _BaseV6._IP_LINK_LOCAL @property def is_site_local(self): @@ -1722,7 +1722,7 @@ def is_site_local(self): A boolean, True if the address is reserved per RFC 3513 2.5.6. """ - return self in IPv6Network('fec0::/10') + return self in _BaseV6._IP_SITE_LOCAL @property def is_private(self): @@ -1732,7 +1732,7 @@ def is_private(self): A boolean, True if the address is reserved per RFC 4193. """ - return self in IPv6Network('fc00::/7') + return self in _BaseV6._IP_PRIVATE @property def ipv4_mapped(self): @@ -1930,3 +1930,23 @@ def __init__(self, address, strict=False): @property def with_netmask(self): return self.with_prefixlen + +_BaseV6._IP_PRIVATE = IPv6Network('fc00::/7') +_BaseV6._IP_MULTICAST = IPv6Network('ff00::/8') +_BaseV6._IP_LINK_LOCAL = IPv6Network('fe80::/10') +_BaseV6._IP_SITE_LOCAL = IPv6Network('fec0::/10') +_BaseV6._IP_RESERVED0 = IPv6Network('::/8') +_BaseV6._IP_RESERVED1 = IPv6Network('100::/8') +_BaseV6._IP_RESERVED2 = IPv6Network('200::/7') +_BaseV6._IP_RESERVED4 = IPv6Network('400::/6') +_BaseV6._IP_RESERVED8 = IPv6Network('800::/5') +_BaseV6._IP_RESERVED10 = IPv6Network('1000::/4') +_BaseV6._IP_RESERVED40 = IPv6Network('4000::/3') +_BaseV6._IP_RESERVED60 = IPv6Network('6000::/3') +_BaseV6._IP_RESERVED80 = IPv6Network('8000::/3') +_BaseV6._IP_RESERVEDA0 = IPv6Network('A000::/3') +_BaseV6._IP_RESERVEDC0 = IPv6Network('C000::/3') +_BaseV6._IP_RESERVEDE0 = IPv6Network('E000::/4') +_BaseV6._IP_RESERVEDF0 = IPv6Network('F000::/5') +_BaseV6._IP_RESERVEDF8 = IPv6Network('F800::/6') +_BaseV6._IP_RESERVEDFE = IPv6Network('FE00::/9') From a3efe903a1950c85edf0a941021520aeaffdcf4c Mon Sep 17 00:00:00 2001 From: Frederic Date: Wed, 7 Nov 2012 12:38:23 -0500 Subject: [PATCH 04/11] speed up IP in NET, this speed up ip.is_*(). --- ipaddr.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ipaddr.py b/ipaddr.py index b0ab655..f23ddae 100644 --- a/ipaddr.py +++ b/ipaddr.py @@ -645,8 +645,9 @@ def __contains__(self, other): self.broadcast >= other.broadcast) # dealing with another address else: - return (int(self.network) <= int(other._ip) <= - int(self.broadcast)) + # I use this syntax that is faster then calling + # int(...) + return self._ip <= other._ip <= self.broadcast._ip def overlaps(self, other): """Tell if self is partly contained in other.""" From 9e43f1cbeb1f663ef0997c931db64278bcde28a4 Mon Sep 17 00:00:00 2001 From: Frederic Date: Wed, 7 Nov 2012 12:38:57 -0500 Subject: [PATCH 05/11] Allow to use "python setup.py develop" --- setup.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 3356432..2572204 100755 --- a/setup.py +++ b/setup.py @@ -14,7 +14,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -from distutils.core import setup +try: + #To support python setup.py develop + from setuptools import setup +except ImportError: + from distutils.core import setup + import ipaddr From c9f1d95063006e4b258ccdad353b66e26c1bb13c Mon Sep 17 00:00:00 2001 From: Frederic Date: Wed, 7 Nov 2012 13:31:35 -0500 Subject: [PATCH 06/11] optimized again _is_private. It is 2x faster with this commit. --- ipaddr.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/ipaddr.py b/ipaddr.py index f23ddae..1fb7801 100644 --- a/ipaddr.py +++ b/ipaddr.py @@ -1191,9 +1191,15 @@ def is_private(self): A boolean, True if the address is reserved per RFC 1918. """ - return (self in _BaseV4._IP_PRIVATE_10 or - self in _BaseV4._IP_PRIVATE_172_16 or - self in _BaseV4._IP_PRIVATE_192_168 ) +# return (self in _BaseV4._IP_PRIVATE_10 or +# self in _BaseV4._IP_PRIVATE_172_16 or +# self in _BaseV4._IP_PRIVATE_192_168 ) + + # The following is equivalent to the above, but faster as it + # remove function calls. + return (_BaseV4._IP_PRIVATE_10._ip <= self._ip <= _BaseV4._IP_PRIVATE_10.broadcast._ip or + _BaseV4._IP_PRIVATE_172_16._ip <= self._ip <= _BaseV4._IP_PRIVATE_172_16.broadcast._ip or + _BaseV4._IP_PRIVATE_192_168._ip <= self._ip <= _BaseV4._IP_PRIVATE_192_168.broadcast._ip) @property def is_multicast(self): From 978979ef304b697e49d034a7bc593908619dc870 Mon Sep 17 00:00:00 2001 From: Frederic Date: Thu, 22 Nov 2012 11:33:25 -0500 Subject: [PATCH 07/11] remove useless conversion to string. --- ipaddr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipaddr.py b/ipaddr.py index 1fb7801..933bf27 100644 --- a/ipaddr.py +++ b/ipaddr.py @@ -513,7 +513,7 @@ def __repr__(self): return '%s(%r)' % (self.__class__.__name__, str(self)) def __str__(self): - return '%s' % self._string_from_ip_int(self._ip) + return self._string_from_ip_int(self._ip) def __hash__(self): return hash(hex(long(self._ip))) From 79fced2c01556be765b4691cfccbe62f70c305ae Mon Sep 17 00:00:00 2001 From: Frederic Date: Thu, 22 Nov 2012 11:34:20 -0500 Subject: [PATCH 08/11] Optimized again is_{multicast,unspecified,loopback,link_local}. --- ipaddr.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/ipaddr.py b/ipaddr.py index 933bf27..cddd32c 100644 --- a/ipaddr.py +++ b/ipaddr.py @@ -1210,6 +1210,9 @@ def is_multicast(self): See RFC 3171 for details. """ + # Optimized version of following line + return (_BaseV4._IP_MULTICAST._ip <= self._ip <= + _BaseV4._IP_MULTICAST.broadcast._ip) return self in _BaseV4._IP_MULTICAST @property @@ -1221,6 +1224,9 @@ def is_unspecified(self): RFC 5735 3. """ + # Optimized version of following line + return (_BaseV4._IP_UNSPECIFIED._ip <= self._ip <= + _BaseV4._IP_UNSPECIFIED.broadcast._ip) return self in _BaseV4._IP_UNSPECIFIED @property @@ -1231,6 +1237,9 @@ def is_loopback(self): A boolean, True if the address is a loopback per RFC 3330. """ + # Optimized version of following line + return (_BaseV4._IP_LOOKBACK._ip <= self._ip <= + _BaseV4._IP_LOOKBACK.broadcast._ip) return self in _BaseV4._IP_LOOKBACK @property @@ -1241,6 +1250,9 @@ def is_link_local(self): A boolean, True if the address is link-local per RFC 3927. """ + # Optimized version of following line + return (_BaseV4._IP_LINK_LOCAL._ip <= self._ip <= + _BaseV4._IP_LINK_LOCAL.broadcast._ip) return self in _BaseV4._IP_LINK_LOCAL From ad6bd0ceef19f6409e4e319763167178c5cf57f9 Mon Sep 17 00:00:00 2001 From: Frederic Date: Thu, 22 Nov 2012 11:52:09 -0500 Subject: [PATCH 09/11] make ipv4 _string_from_ip_int 40% faster. --- ipaddr.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/ipaddr.py b/ipaddr.py index cddd32c..dc62b25 100644 --- a/ipaddr.py +++ b/ipaddr.py @@ -1153,10 +1153,14 @@ def _string_from_ip_int(self, ip_int): The IP address as a string in dotted decimal notation. """ - octets = [] - for _ in xrange(4): - octets.insert(0, str(ip_int & 0xFF)) - ip_int >>= 8 + octets = [None, None, None, None] + octets[3] = str(ip_int & 0xFF) + ip_int >>= 8 + octets[2] = str(ip_int & 0xFF) + ip_int >>= 8 + octets[1] = str(ip_int & 0xFF) + ip_int >>= 8 + octets[0] = str(ip_int & 0xFF) return '.'.join(octets) @property From e24d470599518a20897586212aa7547882af2bf5 Mon Sep 17 00:00:00 2001 From: Frederic Date: Mon, 26 Nov 2012 15:26:59 -0500 Subject: [PATCH 10/11] more speed up. --- ipaddr.py | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/ipaddr.py b/ipaddr.py index dc62b25..edc337a 100644 --- a/ipaddr.py +++ b/ipaddr.py @@ -1185,6 +1185,8 @@ def is_reserved(self): reserved IPv4 Network range. """ + return 4026531840 <= self._ip <= 4294967295 + return _BaseV4._IP_RESERVED._ip <= self._ip <= _BaseV4._IP_RESERVED.broadcast._ip return self in _BaseV4._IP_RESERVED @property @@ -1201,9 +1203,12 @@ def is_private(self): # The following is equivalent to the above, but faster as it # remove function calls. - return (_BaseV4._IP_PRIVATE_10._ip <= self._ip <= _BaseV4._IP_PRIVATE_10.broadcast._ip or - _BaseV4._IP_PRIVATE_172_16._ip <= self._ip <= _BaseV4._IP_PRIVATE_172_16.broadcast._ip or - _BaseV4._IP_PRIVATE_192_168._ip <= self._ip <= _BaseV4._IP_PRIVATE_192_168.broadcast._ip) + return ((167772160 <= self._ip <= 184549375) or + (2886729728 <= self._ip <= 2887778303) or + (3232235520 <= self._ip <= 3232301055)) + return ((_BaseV4._IP_PRIVATE_10._ip <= self._ip <= _BaseV4._IP_PRIVATE_10.broadcast._ip )or + (_BaseV4._IP_PRIVATE_172_16._ip <= self._ip <= _BaseV4._IP_PRIVATE_172_16.broadcast._ip) or + (_BaseV4._IP_PRIVATE_192_168._ip <= self._ip <= _BaseV4._IP_PRIVATE_192_168.broadcast._ip)) @property def is_multicast(self): @@ -1215,6 +1220,7 @@ def is_multicast(self): """ # Optimized version of following line + return (3758096384 <= self._ip <= 4026531839) return (_BaseV4._IP_MULTICAST._ip <= self._ip <= _BaseV4._IP_MULTICAST.broadcast._ip) return self in _BaseV4._IP_MULTICAST @@ -1229,6 +1235,7 @@ def is_unspecified(self): """ # Optimized version of following line + return self._ip == 0 return (_BaseV4._IP_UNSPECIFIED._ip <= self._ip <= _BaseV4._IP_UNSPECIFIED.broadcast._ip) return self in _BaseV4._IP_UNSPECIFIED @@ -1242,9 +1249,10 @@ def is_loopback(self): """ # Optimized version of following line - return (_BaseV4._IP_LOOKBACK._ip <= self._ip <= - _BaseV4._IP_LOOKBACK.broadcast._ip) - return self in _BaseV4._IP_LOOKBACK + return 2130706432 <= self._ip <= 2147483647 + return (_BaseV4._IP_LOOPBACK._ip <= self._ip <= + _BaseV4._IP_LOOPBACK.broadcast._ip) + return self in _BaseV4._IP_LOOPBACK @property def is_link_local(self): @@ -1255,6 +1263,7 @@ def is_link_local(self): """ # Optimized version of following line + return 2851995648 <= self._ip <= 2852061183 return (_BaseV4._IP_LINK_LOCAL._ip <= self._ip <= _BaseV4._IP_LINK_LOCAL.broadcast._ip) return self in _BaseV4._IP_LINK_LOCAL @@ -1431,7 +1440,7 @@ def __init__(self, address, strict=False): _BaseV4._IP_RESERVED = IPv4Network('240.0.0.0/4') _BaseV4._IP_MULTICAST = IPv4Network('224.0.0.0/4') _BaseV4._IP_UNSPECIFIED = IPv4Network('0.0.0.0') -_BaseV4._IP_LOOKBACK = IPv4Network('127.0.0.0/8') +_BaseV4._IP_LOOPBACK = IPv4Network('127.0.0.0/8') _BaseV4._IP_LINK_LOCAL = IPv4Network('169.254.0.0/16') class _BaseV6(object): From 0d9c93fe47c17bd5d1b4ef02a5162d38b094edf9 Mon Sep 17 00:00:00 2001 From: Frederic Date: Mon, 26 Nov 2012 15:29:09 -0500 Subject: [PATCH 11/11] pep8 --- ipaddr.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/ipaddr.py b/ipaddr.py index edc337a..a1e55d8 100644 --- a/ipaddr.py +++ b/ipaddr.py @@ -1178,16 +1178,17 @@ def version(self): @property def is_reserved(self): - """Test if the address is otherwise IETF reserved. + """Test if the address is otherwise IETF reserved. Returns: A boolean, True if the address is within the reserved IPv4 Network range. - """ - return 4026531840 <= self._ip <= 4294967295 - return _BaseV4._IP_RESERVED._ip <= self._ip <= _BaseV4._IP_RESERVED.broadcast._ip - return self in _BaseV4._IP_RESERVED + """ + return 4026531840 <= self._ip <= 4294967295 + return (_BaseV4._IP_RESERVED._ip <= self._ip <= + _BaseV4._IP_RESERVED.broadcast._ip) + return self in _BaseV4._IP_RESERVED @property def is_private(self):