Hello community, here is the log from the commit of package python3-ipaddr for openSUSE:Factory checked in at 2015-01-14 11:44:43 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python3-ipaddr (Old) and /work/SRC/openSUSE:Factory/.python3-ipaddr.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python3-ipaddr" Changes: -------- --- /work/SRC/openSUSE:Factory/python3-ipaddr/python3-ipaddr.changes 2013-06-21 19:01:48.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.python3-ipaddr.new/python3-ipaddr.changes 2015-01-14 11:44:46.000000000 +0100 @@ -1,0 +2,23 @@ +Sun Jan 22 00:51:53 UTC 2015 - [email protected] + +- specfile: + * update copyright year + * remove python(abi) requirement + +------------------------------------------------------------------- +Sat Jan 10 17:54:54 UTC 2015 - [email protected] + +- specfile: + * update copyright year + * update source url to pypi + +- update to version 2.1.11: + * hostmask parsing bug fixed by pmarks (a nearly complete rewrite of + the mask parsing code) + * i97, incorrectly parses some v6 addresses. + * docstring typos. + * i95, refer to the nets in the exception raised by + collapse_address_list + * add license to boilerplate to test-2to3.sh + +------------------------------------------------------------------- Old: ---- ipaddr-2.1.10.tar.gz New: ---- ipaddr-2.1.11.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python3-ipaddr.spec ++++++ --- /var/tmp/diff_new_pack.uwO9Ik/_old 2015-01-14 11:44:47.000000000 +0100 +++ /var/tmp/diff_new_pack.uwO9Ik/_new 2015-01-14 11:44:47.000000000 +0100 @@ -1,7 +1,7 @@ # # spec file for package python3-ipaddr # -# Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,20 +17,19 @@ Name: python3-ipaddr -Version: 2.1.10 +Version: 2.1.11 Release: 0 Url: http://code.google.com/p/ipaddr-py/ Summary: Google's IP address manipulation library License: Apache-2.0 Group: Development/Languages/Python -Source: ipaddr-%{version}.tar.gz +Source: https://pypi.python.org/packages/source/i/ipaddr/ipaddr-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRequires: python3-2to3 BuildRequires: python3-devel BuildRequires: python3-distribute BuildRequires: python3-nose BuildArch: noarch -Requires: python(abi) = %{py3_ver} %description Google's IP address manipulation library. An IPv4/IPv6 manipulation library ++++++ ipaddr-2.1.10.tar.gz -> ipaddr-2.1.11.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipaddr-2.1.10/COPYING new/ipaddr-2.1.11/COPYING --- old/ipaddr-2.1.10/COPYING 2011-11-24 21:54:17.000000000 +0100 +++ new/ipaddr-2.1.11/COPYING 2014-01-31 22:02:24.000000000 +0100 @@ -187,7 +187,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright 2008 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipaddr-2.1.10/PKG-INFO new/ipaddr-2.1.11/PKG-INFO --- old/ipaddr-2.1.10/PKG-INFO 2012-01-21 04:05:52.000000000 +0100 +++ new/ipaddr-2.1.11/PKG-INFO 2014-01-31 22:27:22.000000000 +0100 @@ -1,6 +1,6 @@ -Metadata-Version: 1.0 +Metadata-Version: 1.1 Name: ipaddr -Version: 2.1.10 +Version: 2.1.11 Summary: UNKNOWN Home-page: http://code.google.com/p/ipaddr-py/ Author: Google diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipaddr-2.1.10/RELEASENOTES new/ipaddr-2.1.11/RELEASENOTES --- old/ipaddr-2.1.10/RELEASENOTES 2012-01-21 04:02:42.000000000 +0100 +++ new/ipaddr-2.1.11/RELEASENOTES 2014-01-31 22:36:16.000000000 +0100 @@ -4,6 +4,16 @@ Here are the visible changes for each release. +== 2.1.11 == + +(2014-01-31) + + * hostmask parsing bug fixed by pmarks (a nearly complete rewrite of the mask parsing code) + * i97, incorrectly parses some v6 addresses. + * docstring typos. + * i95, refer to the nets in the exception raised by collapse_address_list + * add license to boilerplate to test-2to3.sh + == 2.1.10 == (2012-01-20) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipaddr-2.1.10/ipaddr.py new/ipaddr-2.1.11/ipaddr.py --- old/ipaddr-2.1.10/ipaddr.py 2012-01-21 04:03:17.000000000 +0100 +++ new/ipaddr-2.1.11/ipaddr.py 2014-01-31 22:22:32.000000000 +0100 @@ -22,7 +22,7 @@ """ -__version__ = '2.1.10' +__version__ = '2.1.11' import struct @@ -141,7 +141,7 @@ """The binary representation of this address. Args: - address: An integer representation of an IPv4 IP address. + address: An integer representation of an IPv6 IP address. Returns: The binary representation of this address. @@ -350,7 +350,7 @@ else: if nets and nets[-1]._version != ip._version: raise TypeError("%s and %s are not of the same version" % ( - str(ip), str(ips[-1]))) + str(ip), str(nets[-1]))) nets.append(ip) # sort and dedup @@ -839,8 +839,8 @@ """ return (self._version, self.network, self.netmask) - def _ip_int_from_prefix(self, prefixlen=None): - """Turn the prefix length netmask into a int for comparison. + def _ip_int_from_prefix(self, prefixlen): + """Turn the prefix length into a bitwise netmask. Args: prefixlen: An integer, the prefix length. @@ -849,42 +849,90 @@ An integer. """ - if not prefixlen and prefixlen != 0: - prefixlen = self._prefixlen return self._ALL_ONES ^ (self._ALL_ONES >> prefixlen) - def _prefix_from_ip_int(self, ip_int, mask=32): - """Return prefix length from the decimal netmask. + def _prefix_from_ip_int(self, ip_int): + """Return prefix length from a bitwise netmask. Args: - ip_int: An integer, the IP address. - mask: The netmask. Defaults to 32. + ip_int: An integer, the netmask in expanded bitwise format. Returns: An integer, the prefix length. + Raises: + NetmaskValueError: If the input is not a valid netmask. + """ - while mask: - if ip_int & 1 == 1: + prefixlen = self._max_prefixlen + while prefixlen: + if ip_int & 1: break ip_int >>= 1 - mask -= 1 + prefixlen -= 1 - return mask + if ip_int == (1 << prefixlen) - 1: + return prefixlen + else: + raise NetmaskValueError('Bit pattern does not match /1*0*/') - def _ip_string_from_prefix(self, prefixlen=None): - """Turn a prefix length into a dotted decimal string. + def _prefix_from_prefix_string(self, prefixlen_str): + """Turn a prefix length string into an integer. Args: - prefixlen: An integer, the netmask prefix length. + prefixlen_str: A decimal string containing the prefix length. Returns: - A string, the dotted decimal netmask string. + The prefix length as an integer. + + Raises: + NetmaskValueError: If the input is malformed or out of range. """ - if not prefixlen: - prefixlen = self._prefixlen - return self._string_from_ip_int(self._ip_int_from_prefix(prefixlen)) + try: + if not _BaseV4._DECIMAL_DIGITS.issuperset(prefixlen_str): + raise ValueError + prefixlen = int(prefixlen_str) + if not (0 <= prefixlen <= self._max_prefixlen): + raise ValueError + except ValueError: + raise NetmaskValueError('%s is not a valid prefix length' % + prefixlen_str) + return prefixlen + + def _prefix_from_ip_string(self, ip_str): + """Turn a netmask/hostmask string into a prefix length. + + Args: + ip_str: A netmask or hostmask, formatted as an IP address. + + Returns: + The prefix length as an integer. + + Raises: + NetmaskValueError: If the input is not a netmask or hostmask. + + """ + # Parse the netmask/hostmask like an IP address. + try: + ip_int = self._ip_int_from_string(ip_str) + except AddressValueError: + raise NetmaskValueError('%s is not a valid netmask' % ip_str) + + # Try matching a netmask (this would be /1*0*/ as a bitwise regexp). + # Note that the two ambiguous cases (all-ones and all-zeroes) are + # treated as netmasks. + try: + return self._prefix_from_ip_int(ip_int) + except NetmaskValueError: + pass + + # Invert the bits, and try matching a /0+1+/ hostmask instead. + ip_int ^= self._ALL_ONES + try: + return self._prefix_from_ip_int(ip_int) + except NetmaskValueError: + raise NetmaskValueError('%s is not a valid netmask' % ip_str) def iter_subnets(self, prefixlen_diff=1, new_prefix=None): """The subnets which join to make the current subnet. @@ -927,7 +975,7 @@ raise ValueError('prefix length diff must be > 0') new_prefixlen = self._prefixlen + prefixlen_diff - if not self._is_valid_netmask(str(new_prefixlen)): + if new_prefixlen > self._max_prefixlen: raise ValueError( 'prefix length diff %d is invalid for netblock %s' % ( new_prefixlen, str(self))) @@ -1227,9 +1275,6 @@ """ - # the valid octets for host and netmasks. only useful for IPv4. - _valid_mask_octets = set((255, 254, 252, 248, 240, 224, 192, 128, 0)) - def __init__(self, address, strict=False): """Instantiate a new IPv4 network object. @@ -1292,31 +1337,18 @@ self.ip = IPv4Address(self._ip) if len(addr) == 2: - mask = addr[1].split('.') - if len(mask) == 4: - # We have dotted decimal netmask. - if self._is_valid_netmask(addr[1]): - self.netmask = IPv4Address(self._ip_int_from_string( - addr[1])) - elif self._is_hostmask(addr[1]): - self.netmask = IPv4Address( - self._ip_int_from_string(addr[1]) ^ self._ALL_ONES) - else: - raise NetmaskValueError('%s is not a valid netmask' - % addr[1]) - - self._prefixlen = self._prefix_from_ip_int(int(self.netmask)) - else: - # We have a netmask in prefix length form. - if not self._is_valid_netmask(addr[1]): - raise NetmaskValueError(addr[1]) - self._prefixlen = int(addr[1]) - self.netmask = IPv4Address(self._ip_int_from_prefix( - self._prefixlen)) + try: + # Check for a netmask in prefix length form. + self._prefixlen = self._prefix_from_prefix_string(addr[1]) + except NetmaskValueError: + # Check for a netmask or hostmask in dotted-quad form. + # This may raise NetmaskValueError. + self._prefixlen = self._prefix_from_ip_string(addr[1]) else: self._prefixlen = self._max_prefixlen - self.netmask = IPv4Address(self._ip_int_from_prefix( - self._prefixlen)) + + self.netmask = IPv4Address(self._ip_int_from_prefix(self._prefixlen)) + if strict: if self.ip != self.network: raise ValueError('%s has host bits set' % @@ -1324,53 +1356,6 @@ if self._prefixlen == (self._max_prefixlen - 1): self.iterhosts = self.__iter__ - def _is_hostmask(self, ip_str): - """Test if the IP string is a hostmask (rather than a netmask). - - Args: - ip_str: A string, the potential hostmask. - - Returns: - A boolean, True if the IP string is a hostmask. - - """ - bits = ip_str.split('.') - try: - parts = [int(x) for x in bits if int(x) in self._valid_mask_octets] - except ValueError: - return False - if len(parts) != len(bits): - return False - if parts[0] < parts[-1]: - return True - return False - - def _is_valid_netmask(self, netmask): - """Verify that the netmask is valid. - - Args: - netmask: A string, either a prefix or dotted decimal - netmask. - - Returns: - A boolean, True if the prefix represents a valid IPv4 - netmask. - - """ - mask = netmask.split('.') - if len(mask) == 4: - if [x for x in mask if int(x) not in self._valid_mask_octets]: - return False - if [y for idx, y in enumerate(mask) if idx > 0 and - y > mask[idx - 1]]: - return False - return True - try: - netmask = int(netmask) - except ValueError: - return False - return 0 <= netmask <= self._max_prefixlen - # backwards compatibility IsRFC1918 = lambda self: self.is_private IsMulticast = lambda self: self.is_multicast @@ -1490,6 +1475,8 @@ # Whitelist the characters, since int() allows a lot of bizarre stuff. if not self._HEX_DIGITS.issuperset(hextet_str): raise ValueError + if len(hextet_str) > 4: + raise ValueError hextet_int = int(hextet_str, 16) if hextet_int > 0xFFFF: raise ValueError @@ -1859,10 +1846,8 @@ self.ip = IPv6Address(self._ip) if len(addr) == 2: - if self._is_valid_netmask(addr[1]): - self._prefixlen = int(addr[1]) - else: - raise NetmaskValueError(addr[1]) + # This may raise NetmaskValueError + self._prefixlen = self._prefix_from_prefix_string(addr[1]) else: self._prefixlen = self._max_prefixlen @@ -1875,23 +1860,6 @@ if self._prefixlen == (self._max_prefixlen - 1): self.iterhosts = self.__iter__ - def _is_valid_netmask(self, prefixlen): - """Verify that the netmask/prefixlen is valid. - - Args: - prefixlen: A string, the netmask in prefix length format. - - Returns: - A boolean, True if the prefix represents a valid IPv6 - netmask. - - """ - try: - prefixlen = int(prefixlen) - except ValueError: - return False - return 0 <= prefixlen <= self._max_prefixlen - @property def with_netmask(self): return self.with_prefixlen diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipaddr-2.1.10/ipaddr_test.py new/ipaddr-2.1.11/ipaddr_test.py --- old/ipaddr-2.1.10/ipaddr_test.py 2012-01-21 04:03:02.000000000 +0100 +++ new/ipaddr-2.1.11/ipaddr_test.py 2014-01-31 22:02:28.000000000 +0100 @@ -133,6 +133,7 @@ AssertInvalidIP(":1:2:3:4:5:6:") AssertInvalidIP("192.0.2.1/32") AssertInvalidIP("2001:db8::1/128") + AssertInvalidIP("02001:db8::") self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv4Network, '') self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv4Network, @@ -157,7 +158,6 @@ self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv4Address(1)._ip_int_from_string, '1.a.2.3') - self.assertEqual(False, ipaddr.IPv4Network(1)._is_hostmask('1.a.2.3')) def testGetNetwork(self): self.assertEqual(int(self.ipv4.network), 16909056) @@ -276,11 +276,11 @@ def testZeroNetmask(self): ipv4_zero_netmask = ipaddr.IPv4Network('1.2.3.4/0') self.assertEqual(int(ipv4_zero_netmask.netmask), 0) - self.assertTrue(ipv4_zero_netmask._is_valid_netmask(str(0))) + self.assertEqual(ipv4_zero_netmask._prefix_from_prefix_string('0'), 0) ipv6_zero_netmask = ipaddr.IPv6Network('::1/0') self.assertEqual(int(ipv6_zero_netmask.netmask), 0) - self.assertTrue(ipv6_zero_netmask._is_valid_netmask(str(0))) + self.assertEqual(ipv6_zero_netmask._prefix_from_prefix_string('0'), 0) def testGetBroadcast(self): self.assertEqual(int(self.ipv4.broadcast), 16909311L) @@ -434,20 +434,83 @@ self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv6Network, '10/8') + def testGoodNetmaskIPv4(self): + self.assertEqual(str(ipaddr.IPv4Network('192.0.2.0/255.255.255.0')), + '192.0.2.0/24') + for i in range(0, 33): + # Generate and re-parse the CIDR format (trivial). + net_str = '0.0.0.0/%d' % i + net = ipaddr.IPv4Network(net_str) + self.assertEqual(str(net), net_str) + + # Generate and re-parse the expanded netmask. + self.assertEqual( + str(ipaddr.IPv4Network('0.0.0.0/%s' % net.netmask)), + net_str) + + # Zero prefix is treated as decimal. + self.assertEqual(str(ipaddr.IPv4Network('0.0.0.0/0%d' % i)), + net_str) + + # Generate and re-parse the expanded hostmask. The ambiguous cases + # (/0 and /32) are treated as netmasks. + if i in (32, 0): + net_str = '0.0.0.0/%d' % (32 - i) + self.assertEqual( + str(ipaddr.IPv4Network('0.0.0.0/%s' % net.hostmask)), + net_str) + + def testGoodNetmaskIPv6(self): + # We only support CIDR for IPv6, because expanded netmasks are not + # standard notation. + self.assertEqual(str(ipaddr.IPv6Network('2001:db8::/32')), + '2001:db8::/32') + for i in range(0, 129): + # Generate and re-parse the CIDR format (trivial). + net_str = '::/%d' % i + self.assertEqual(str(ipaddr.IPv6Network(net_str)), net_str) - def testBadNetMask(self): + # Zero prefix is treated as decimal. + self.assertEqual(str(ipaddr.IPv6Network('::/0%d' % i)), net_str) + + def testBadNetmask(self): self.assertRaises(ipaddr.NetmaskValueError, ipaddr.IPv4Network, '1.2.3.4/') self.assertRaises(ipaddr.NetmaskValueError, + ipaddr.IPv4Network, '1.2.3.4/-1') + self.assertRaises(ipaddr.NetmaskValueError, + ipaddr.IPv4Network, '1.2.3.4/+1') + self.assertRaises(ipaddr.NetmaskValueError, + ipaddr.IPv4Network, '1.2.3.4/0x1') + self.assertRaises(ipaddr.NetmaskValueError, ipaddr.IPv4Network, '1.2.3.4/33') self.assertRaises(ipaddr.NetmaskValueError, ipaddr.IPv4Network, '1.2.3.4/254.254.255.256') self.assertRaises(ipaddr.NetmaskValueError, ipaddr.IPv4Network, '1.1.1.1/240.255.0.0') self.assertRaises(ipaddr.NetmaskValueError, + ipaddr.IPv4Network, '1.1.1.1/255.254.128.0') + self.assertRaises(ipaddr.NetmaskValueError, + ipaddr.IPv4Network, '1.1.1.1/0.1.127.255') + self.assertRaises(ipaddr.NetmaskValueError, + ipaddr.IPv4Network, '1.2.3.4/1.a.2.3') + self.assertRaises(ipaddr.NetmaskValueError, + ipaddr.IPv4Network, '1.1.1.1/::') + self.assertRaises(ipaddr.NetmaskValueError, ipaddr.IPv6Network, '::1/') self.assertRaises(ipaddr.NetmaskValueError, + ipaddr.IPv6Network, '::1/-1') + self.assertRaises(ipaddr.NetmaskValueError, + ipaddr.IPv6Network, '::1/+1') + self.assertRaises(ipaddr.NetmaskValueError, + ipaddr.IPv6Network, '::1/0x1') + self.assertRaises(ipaddr.NetmaskValueError, ipaddr.IPv6Network, '::1/129') + self.assertRaises(ipaddr.NetmaskValueError, + ipaddr.IPv6Network, '::1/1.2.3.4') + # IPv6 expanded form is currently not supported. + self.assertRaises(ipaddr.NetmaskValueError, + ipaddr.IPv6Network, '::/::') def testNth(self): self.assertEqual(str(self.ipv4[5]), '1.2.3.5') @@ -761,11 +824,6 @@ self.assertEqual(ipaddr.IPv6Network('::1:0:0:0:0').packed, _cb('\x00' * 6 + '\x00\x01' + '\x00' * 8)) - def testIpStrFromPrefixlen(self): - ipv4 = ipaddr.IPv4Network('1.2.3.4/24') - self.assertEqual(ipv4._ip_string_from_prefix(), '255.255.255.0') - self.assertEqual(ipv4._ip_string_from_prefix(28), '255.255.255.240') - def testIpType(self): ipv4net = ipaddr.IPNetwork('1.2.3.4') ipv4addr = ipaddr.IPAddress('1.2.3.4') -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
