Skip to content
This repository was archived by the owner on Jun 12, 2024. It is now read-only.
136 changes: 99 additions & 37 deletions ipaddr.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)))
Expand Down Expand Up @@ -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."""
Expand Down Expand Up @@ -1152,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
Expand All @@ -1173,14 +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 self in IPv4Network('240.0.0.0/4')
"""
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):
Expand All @@ -1190,9 +1198,18 @@ 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 )

# The following is equivalent to the above, but faster as it
# remove function calls.
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):
Expand All @@ -1203,7 +1220,11 @@ def is_multicast(self):
See RFC 3171 for details.

"""
return self in IPv4Network('224.0.0.0/4')
# 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

@property
def is_unspecified(self):
Expand All @@ -1214,7 +1235,11 @@ def is_unspecified(self):
RFC 5735 3.

"""
return self in IPv4Network('0.0.0.0')
# 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

@property
def is_loopback(self):
Expand All @@ -1224,7 +1249,11 @@ 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')
# Optimized version of following line
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):
Expand All @@ -1234,7 +1263,11 @@ 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')
# 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


class IPv4Address(_BaseV4, _BaseIP):
Expand Down Expand Up @@ -1401,6 +1434,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_LOOPBACK = IPv4Network('127.0.0.0/8')
_BaseV4._IP_LINK_LOCAL = IPv4Network('169.254.0.0/16')

class _BaseV6(object):

Expand Down Expand Up @@ -1515,7 +1557,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
Expand Down Expand Up @@ -1642,7 +1684,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):
Expand All @@ -1653,21 +1695,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):
Expand Down Expand Up @@ -1699,7 +1741,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):
Expand All @@ -1713,7 +1755,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):
Expand All @@ -1723,7 +1765,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):
Expand Down Expand Up @@ -1921,3 +1963,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')
7 changes: 6 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down