From 504d86bde771b75b0fdabbdb35fdda48b6ec15d8 Mon Sep 17 00:00:00 2001 From: Justin Riley Date: Fri, 26 Jul 2013 11:44:01 -0400 Subject: [PATCH 01/26] MANIFEST.in: add entire docs folder (not just rst) When a release gets created the docs folder is missing the sphinx Makefile, config, static, and template folders which means it's not possible to build the docs with sphinx. This patch adds the missing pieces. --- MANIFEST.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MANIFEST.in b/MANIFEST.in index 866941d..b43f791 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -4,5 +4,5 @@ include INSTALL include LICENSE include MANIFEST.in include README.md -recursive-include docs *.rst +recursive-include docs * prune docs/_build From 468ce162fb93bb5eb2696247dd4489e009af8f7f Mon Sep 17 00:00:00 2001 From: Justin Riley Date: Mon, 14 Oct 2013 13:39:04 -0400 Subject: [PATCH 02/26] MANIFEST.in: exclude docs/_build from packaging --- MANIFEST.in | 1 + 1 file changed, 1 insertion(+) diff --git a/MANIFEST.in b/MANIFEST.in index b43f791..83c87ed 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -5,4 +5,5 @@ include LICENSE include MANIFEST.in include README.md recursive-include docs * +recursive-exclude docs/_build prune docs/_build From 4766cb7c2e37920a4cdc336aa1dce68af00f167b Mon Sep 17 00:00:00 2001 From: Bryan Davis Date: Sat, 1 Mar 2014 10:17:12 -0700 Subject: [PATCH 03/26] Avoid OverflowError with large ranges Use `IpRange.__len__()` directly rather than calling `len(IpRange())` when computing the length of an IpRangeList. This won't stop OverflowErrors in calling code such as `len(IpRangeList('fe80::/10'))`, but it will provide a method to work around the overflow by direct use of `IpRangeList.__len__()`. Issue: #12 --- iptools/__init__.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/iptools/__init__.py b/iptools/__init__.py index 384fed1..46dde7b 100644 --- a/iptools/__init__.py +++ b/iptools/__init__.py @@ -219,6 +219,8 @@ def __len__(self): 2 >>> len(IpRange('127/22')) 1024 + >>> IpRange('fe80::/10').__len__() + 332306998946228968225951765070086144L """ return self._len #end __len__ @@ -510,8 +512,10 @@ def __len__(self): 256 >>> len(IpRangeList('192.168.0.0/22')) 1024 + >>> IpRangeList('fe80::/10').__len__() + 332306998946228968225951765070086144L """ - return sum([len(r) for r in self.ips]) + return sum(r.__len__() for r in self.ips) #end __len__ #end class IpRangeList From 37d33587dc5de15719bfcef5ef3dd3df02a2d17c Mon Sep 17 00:00:00 2001 From: Bryan Davis Date: Sat, 1 Mar 2014 10:39:18 -0700 Subject: [PATCH 04/26] Make doctest output portable Python 3.x dropped the `L` suffix for the repr of long integers. --- iptools/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iptools/__init__.py b/iptools/__init__.py index 46dde7b..c01e4e2 100644 --- a/iptools/__init__.py +++ b/iptools/__init__.py @@ -219,8 +219,8 @@ def __len__(self): 2 >>> len(IpRange('127/22')) 1024 - >>> IpRange('fe80::/10').__len__() - 332306998946228968225951765070086144L + >>> IpRange('fe80::/10').__len__() == 2**118 + True """ return self._len #end __len__ @@ -512,8 +512,8 @@ def __len__(self): 256 >>> len(IpRangeList('192.168.0.0/22')) 1024 - >>> IpRangeList('fe80::/10').__len__() - 332306998946228968225951765070086144L + >>> IpRangeList('fe80::/10').__len__() == 2**118 + True """ return sum(r.__len__() for r in self.ips) #end __len__ From 000119955a658e63896e8ae5e19189d6797593ed Mon Sep 17 00:00:00 2001 From: Bryan Davis Date: Sat, 1 Mar 2014 10:44:14 -0700 Subject: [PATCH 05/26] Remove Python 2.5 tests on Travis CI As of 2013-11-20 Travis CI removed support for testing using python 2.5 See http://blog.travis-ci.com/2013-11-18-upcoming-build-environment-updates/. --- .travis.yml | 1 - README.md | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8fec26e..6091156 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,5 @@ language: python python: - - "2.5" - "2.6" - "2.7" - "3.2" diff --git a/README.md b/README.md index fe62eb4..932796a 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ Local documentation can be built using [Sphinx][]: Python Version Compatibility ---------------------------- -[Travis CI][ci-home] automatically runs tests against python 2.5, 2.6, 2.7, 3.2, 3.3 and pypy. +[Travis CI][ci-home] automatically runs tests against python 2.6, 2.7, 3.2, 3.3 and pypy. Installation ------------ From a016ed0c7488cd0b7a05677d49b6e7f50d9fd6e0 Mon Sep 17 00:00:00 2001 From: Bryan Davis Date: Sat, 1 Mar 2014 10:59:22 -0700 Subject: [PATCH 06/26] Bump copyright year to 2014 --- LICENSE | 2 +- iptools/__init__.py | 2 +- iptools/ipv4.py | 2 +- iptools/ipv6.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/LICENSE b/LICENSE index 6b00376..deaf0fb 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2008-2013, Bryan Davis and iptools contributors +Copyright (c) 2008-2014, Bryan Davis and iptools contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/iptools/__init__.py b/iptools/__init__.py index c01e4e2..9ef1841 100644 --- a/iptools/__init__.py +++ b/iptools/__init__.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright (c) 2008-2013, Bryan Davis +# Copyright (c) 2008-2014, Bryan Davis # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/iptools/ipv4.py b/iptools/ipv4.py index 5696e7d..561d30b 100644 --- a/iptools/ipv4.py +++ b/iptools/ipv4.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright (c) 2008-2013, Bryan Davis +# Copyright (c) 2008-2014, Bryan Davis # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/iptools/ipv6.py b/iptools/ipv6.py index 4cbf9c7..53654f1 100644 --- a/iptools/ipv6.py +++ b/iptools/ipv6.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright (c) 2008-2013, Bryan Davis +# Copyright (c) 2008-2014, Bryan Davis # All rights reserved. # # Redistribution and use in source and binary forms, with or without From bb0a82d820b0e0006875f573216effa85a03038b Mon Sep 17 00:00:00 2001 From: Bryan Davis Date: Sat, 1 Mar 2014 11:08:30 -0700 Subject: [PATCH 07/26] Use flake8 everywhere Correct flake8 warnings in setup.py and change Travis CI test to run flake8 on the whole distribution. --- .travis.yml | 3 +-- setup.cfg | 1 + setup.py | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6091156..79a101a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,8 +9,7 @@ install: - pip install . --use-mirrors - pip install -r tests/requirements.txt --use-mirrors script: - - flake8 iptools - - flake8 tests + - flake8 - nosetests notifications: email: diff --git a/setup.cfg b/setup.cfg index 5f890db..dc76948 100644 --- a/setup.cfg +++ b/setup.cfg @@ -12,3 +12,4 @@ count=1 show-pep8=1 show-source=1 statistics=1 +exclude=build,dist,doc,*.egg,*.egg-info diff --git a/setup.py b/setup.py index 9d59adf..996ba0c 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ if 'nosetests' in sys.argv[1:]: setup_requires.append('nose>=1.0') -tests_require=['nose>=1.0'] +tests_require = ['nose>=1.0'] setup( name='iptools', @@ -45,13 +45,13 @@ Utilities for manipulating IPv4 and IPv6 addresses including a class that can be used to include CIDR network blocks in Django's INTERNAL_IPS setting. - + Full documentation at http://python-iptools.readthedocs.org/ """, zip_safe=False, extras_require={ - 'testing':tests_require, - }, + 'testing': tests_require, + }, ) # vim: set sw=4 ts=4 sts=4 et : From ac26946670d901807f38f6be7a86a52ec2a875ca Mon Sep 17 00:00:00 2001 From: Bryan Davis Date: Sat, 1 Mar 2014 11:10:47 -0700 Subject: [PATCH 08/26] Use tuple instead of list in IpRange._cast() --- iptools/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iptools/__init__.py b/iptools/__init__.py index 9ef1841..2c3dbcb 100644 --- a/iptools/__init__.py +++ b/iptools/__init__.py @@ -243,7 +243,7 @@ def __hash__(self): def _cast(self, item): if isinstance(item, basestring): item = _address2long(item) - if type(item) not in [type(1), type(ipv4.MAX_IP), type(ipv6.MAX_IP)]: + if type(item) not in (type(1), type(ipv4.MAX_IP), type(ipv6.MAX_IP)): raise TypeError( "expected ip address, 32-bit integer or 128-bit integer") From 994085161b625f8bf57af0cf64096133016a97a3 Mon Sep 17 00:00:00 2001 From: Bryan Davis Date: Sat, 1 Mar 2014 11:19:29 -0700 Subject: [PATCH 09/26] Remove mention of 2.5 testing from docs Travis CI testing against python 2.5 was removed in 0001199. --- docs/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.rst b/docs/index.rst index a796ffd..27dccb1 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -55,7 +55,7 @@ implements the magic method ``__contains__`` which python calls when the Python Version Compatibility **************************** -`Travis CI`_ automatically runs tests against python 2.5, 2.6, 2.7, 3.2, 3.3 and pypy. +`Travis CI`_ automatically runs tests against python 2.6, 2.7, 3.2, 3.3 and pypy. Current test status: |build status| From 18bb9b252f87bbf3b988add037975f8375485244 Mon Sep 17 00:00:00 2001 From: Bryan Davis Date: Sat, 1 Mar 2014 11:21:21 -0700 Subject: [PATCH 10/26] Make copyright statements agree with LICENSE Add "and iptools contributors" joint copyright recognition to copyright headers and documentation. --- docs/conf.py | 2 +- iptools/__init__.py | 2 +- iptools/ipv4.py | 2 +- iptools/ipv6.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 8e81cee..05d75ed 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -12,7 +12,7 @@ source_suffix = '.rst' master_doc = 'index' project = 'iptools' -copyright = '%s, Bryan Davis. All Rights Reserved' % date.today().year +copyright = '2008-%s, Bryan Davis and iptools contributors. All Rights Reserved' % date.today().year version = iptools.__version__ release = version exclude_patterns = ['_build'] diff --git a/iptools/__init__.py b/iptools/__init__.py index 2c3dbcb..42cc0c3 100644 --- a/iptools/__init__.py +++ b/iptools/__init__.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright (c) 2008-2014, Bryan Davis +# Copyright (c) 2008-2014, Bryan Davis and iptools contributors # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/iptools/ipv4.py b/iptools/ipv4.py index 561d30b..f1160a0 100644 --- a/iptools/ipv4.py +++ b/iptools/ipv4.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright (c) 2008-2014, Bryan Davis +# Copyright (c) 2008-2014, Bryan Davis and iptools contributors # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/iptools/ipv6.py b/iptools/ipv6.py index 53654f1..319c4b5 100644 --- a/iptools/ipv6.py +++ b/iptools/ipv6.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright (c) 2008-2014, Bryan Davis +# Copyright (c) 2008-2014, Bryan Davis and iptools contributors # All rights reserved. # # Redistribution and use in source and binary forms, with or without From 3e314bb2a5da8b59bb2c3dc8d3874831b1ea0422 Mon Sep 17 00:00:00 2001 From: Bryan Davis Date: Sat, 1 Mar 2014 12:46:01 -0700 Subject: [PATCH 11/26] Fix flake8 warning in sphinx conf --- docs/conf.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 05d75ed..ea2f026 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -12,7 +12,10 @@ source_suffix = '.rst' master_doc = 'index' project = 'iptools' -copyright = '2008-%s, Bryan Davis and iptools contributors. All Rights Reserved' % date.today().year +copyright = ( + '2008-%s, Bryan Davis and iptools contributors. ' + 'All Rights Reserved' +) % date.today().year version = iptools.__version__ release = version exclude_patterns = ['_build'] From 80a356f964895e571584f619bda433e412fc5f43 Mon Sep 17 00:00:00 2001 From: Bryan Davis Date: Fri, 4 Mar 2016 12:06:58 -0700 Subject: [PATCH 12/26] Add wheels support Closes #17 --- setup.cfg | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup.cfg b/setup.cfg index dc76948..d1c3771 100644 --- a/setup.cfg +++ b/setup.cfg @@ -13,3 +13,6 @@ show-pep8=1 show-source=1 statistics=1 exclude=build,dist,doc,*.egg,*.egg-info + +[wheel] +universal = 1 From f86734a6897fb09330b6c9b566e13e47b6d8635a Mon Sep 17 00:00:00 2001 From: Bryan Davis Date: Fri, 4 Mar 2016 12:20:08 -0700 Subject: [PATCH 13/26] Fix flake8 warnings * Ignore E402 (not happy about my py2/3 compat layer) * Fix comments --- iptools/__init__.py | 46 +++++++++++++++++------------------ iptools/ipv4.py | 28 ++++++++++----------- iptools/ipv6.py | 16 ++++++------ setup.cfg | 4 +-- tests/iptools/iptools_test.py | 8 +++--- 5 files changed, 51 insertions(+), 51 deletions(-) diff --git a/iptools/__init__.py b/iptools/__init__.py index 42cc0c3..52074ba 100644 --- a/iptools/__init__.py +++ b/iptools/__init__.py @@ -64,7 +64,7 @@ def _address2long(address): if parsed is None: parsed = ipv6.ip2long(address) return parsed -#end _addess2long +# end _addess2long class IpRange (Sequence): @@ -164,7 +164,7 @@ def __init__(self, start, end=None): self._ipver = ipv4 if self.endIp > ipv4.MAX_IP: self._ipver = ipv6 - #end __init__ + # end __init__ def __repr__(self): """ @@ -178,7 +178,7 @@ def __repr__(self): return "IpRange(%r, %r)" % ( self._ipver.long2ip(self.startIp), self._ipver.long2ip(self.endIp)) - #end __repr__ + # end __repr__ def __str__(self): """ @@ -192,7 +192,7 @@ def __str__(self): return ( self._ipver.long2ip(self.startIp), self._ipver.long2ip(self.endIp)).__repr__() - #end __str__ + # end __str__ def __eq__(self, other): """ @@ -206,7 +206,7 @@ def __eq__(self, other): return isinstance(other, IpRange) and \ self.startIp == other.startIp and \ self.endIp == other.endIp - #end __eq__ + # end __eq__ def __len__(self): """ @@ -223,7 +223,7 @@ def __len__(self): True """ return self._len - #end __len__ + # end __len__ def __hash__(self): """ @@ -238,7 +238,7 @@ def __hash__(self): False """ return hash((self.startIp, self.endIp)) - #end __hash__ + # end __hash__ def _cast(self, item): if isinstance(item, basestring): @@ -252,10 +252,10 @@ def _cast(self, item): # downcast to ipv4 iff address is in the IPv4 mapped block if item in IpRange(ipv6.IPV4_MAPPED): item = item & ipv4.MAX_IP - #end if + # end if return item - #end _cast + # end _cast def index(self, item): """ @@ -282,11 +282,11 @@ def index(self, item): if offset >= 0 and offset < self._len: return offset raise ValueError('%s is not in range' % self._ipver.long2ip(item)) - #end index + # end index def count(self, item): return int(item in self) - #end count + # end count def __contains__(self, item): """ @@ -313,7 +313,7 @@ def __contains__(self, item): """ item = self._cast(item) return self.startIp <= item <= self.endIp - #end __contains__ + # end __contains__ def __getitem__(self, index): """ @@ -348,7 +348,7 @@ def __getitem__(self, index): """ if isinstance(index, slice): if index.step not in (None, 1): - #TODO: return an IpRangeList + # TODO: return an IpRangeList raise ValueError('slice step not supported') start = index.start or 0 if start < 0: @@ -371,7 +371,7 @@ def __getitem__(self, index): if index < 0 or index >= self._len: raise IndexError('index out of range') return self._ipver.long2ip(self.startIp + index) - #end __getitem__ + # end __getitem__ def __iter__(self): """ @@ -392,8 +392,8 @@ def __iter__(self): while i <= self.endIp: yield self._ipver.long2ip(i) i += 1 - #end __iter__ -#end class IpRange + # end __iter__ +# end class IpRange class IpRangeList (object): @@ -410,7 +410,7 @@ class IpRangeList (object): """ def __init__(self, *args): self.ips = tuple(map(IpRange, args)) - #end __init__ + # end __init__ def __repr__(self): """ @@ -429,7 +429,7 @@ def __repr__(self): IpRange('192.168.0.0', '192.168.255.255'))" """ return "IpRangeList%r" % (self.ips,) - #end __repr__ + # end __repr__ def __str__(self): """ @@ -440,7 +440,7 @@ def __str__(self): ('192.168.0.0', '192.168.255.255'))" """ return "(%s)" % ", ".join(str(i) for i in self.ips) - #end __str__ + # end __str__ def __contains__(self, item): """ @@ -469,7 +469,7 @@ def __contains__(self, item): if item in r: return True return False - #end __contains__ + # end __contains__ def __iter__(self): """ @@ -497,7 +497,7 @@ def __iter__(self): for r in self.ips: for ip in r: yield ip - #end __iter__ + # end __iter__ def __len__(self): """ @@ -516,7 +516,7 @@ def __len__(self): True """ return sum(r.__len__() for r in self.ips) - #end __len__ -#end class IpRangeList + # end __len__ +# end class IpRangeList # vim: set sw=4 ts=4 sts=4 et : diff --git a/iptools/ipv4.py b/iptools/ipv4.py index f1160a0..c3d0127 100644 --- a/iptools/ipv4.py +++ b/iptools/ipv4.py @@ -93,7 +93,7 @@ def bin(x): except NameError: out.reverse() return '0b' + ''.join(out) - #end bin + # end bin # end compatibility "fixes' @@ -223,7 +223,7 @@ def validate_ip(s): return False return True return False -#end validate_ip +# end validate_ip def validate_cidr(s): @@ -266,7 +266,7 @@ def validate_cidr(s): return False return True return False -#end validate_cidr +# end validate_cidr def validate_netmask(s): @@ -305,7 +305,7 @@ def validate_netmask(s): return True else: return False -#end validate_netmask +# end validate_netmask def validate_subnet(s): @@ -348,7 +348,7 @@ def validate_subnet(s): else: return False raise TypeError("expected string or unicode") -#end validate_subnet +# end validate_subnet def ip2long(ip): @@ -385,7 +385,7 @@ def ip2long(ip): for q in quads: lngip = (lngip << 8) | int(q) return lngip -#end ip2long +# end ip2long def ip2network(ip): @@ -406,7 +406,7 @@ def ip2network(ip): for i in range(4): netw = (netw << 8) | int(len(quads) > i and quads[i] or 0) return netw -#end ip2network +# end ip2network def long2ip(l): @@ -448,7 +448,7 @@ def long2ip(l): "expected int between %d and %d inclusive" % (MIN_IP, MAX_IP)) return '%d.%d.%d.%d' % ( l >> 24 & 255, l >> 16 & 255, l >> 8 & 255, l & 255) -#end long2ip +# end long2ip def ip2hex(addr): @@ -478,7 +478,7 @@ def ip2hex(addr): if netip is None: return None return "%08x" % netip -#end ip2hex +# end ip2hex def hex2ip(hex_str): @@ -506,7 +506,7 @@ def hex2ip(hex_str): except ValueError: return None return long2ip(netip) -#end hex2ip +# end hex2ip def cidr2block(cidr): @@ -543,7 +543,7 @@ def cidr2block(cidr): network = ip2network(ip) return _block_from_ip_and_prefix(network, prefix) -#end cidr2block +# end cidr2block def netmask2prefix(mask): @@ -571,7 +571,7 @@ def netmask2prefix(mask): if validate_netmask(mask): return bin(ip2network(mask)).count('1') return 0 -#end netmask2prefix +# end netmask2prefix def subnet2block(subnet): @@ -609,7 +609,7 @@ def subnet2block(subnet): network = ip2network(ip) return _block_from_ip_and_prefix(network, prefix) -#end subnet2block +# end subnet2block def _block_from_ip_and_prefix(ip, prefix): @@ -630,6 +630,6 @@ def _block_from_ip_and_prefix(ip, prefix): mask = (1 << shift) - 1 block_end = block_start | mask return (long2ip(block_start), long2ip(block_end)) -#end _block_from_ip_and_prefix +# end _block_from_ip_and_prefix # vim: set sw=4 ts=4 sts=4 et : diff --git a/iptools/ipv6.py b/iptools/ipv6.py index 319c4b5..9fab832 100644 --- a/iptools/ipv6.py +++ b/iptools/ipv6.py @@ -190,7 +190,7 @@ def validate_ip(s): return False return True return False -#end validate_ip +# end validate_ip def ip2long(ip): @@ -247,7 +247,7 @@ def ip2long(ip): hextets.append('0') for h in h2: hextets.append(h) - #end if + # end if lngip = 0 for h in hextets: @@ -255,7 +255,7 @@ def ip2long(ip): h = '0' lngip = (lngip << 16) | int(h, 16) return lngip -#end ip2long +# end ip2long def long2ip(l): @@ -311,7 +311,7 @@ def long2ip(l): dc_len, dc_start = (run_len, run_start) else: run_len, run_start = (0, -1) - #end for + # end for if dc_len > 1: dc_end = dc_start + dc_len if dc_end == len(hextets): @@ -319,10 +319,10 @@ def long2ip(l): hextets[dc_start:dc_end] = [''] if dc_start == 0: hextets = [''] + hextets - #end if + # end if return ':'.join(hextets) -#end long2ip +# end long2ip def validate_cidr(s): @@ -365,7 +365,7 @@ def validate_cidr(s): return False return True return False -#end validate_cidr +# end validate_cidr def cidr2block(cidr): @@ -399,6 +399,6 @@ def cidr2block(cidr): mask = (1 << shift) - 1 block_end = block_start | mask return (long2ip(block_start), long2ip(block_end)) -#end cidr2block +# end cidr2block # vim: set sw=4 ts=4 sts=4 et : diff --git a/setup.cfg b/setup.cfg index d1c3771..ec2d4e2 100644 --- a/setup.cfg +++ b/setup.cfg @@ -7,12 +7,12 @@ cover-html=1 cover-html-dir=docs/_build/cover [flake8] -ignore=F821 +ignore=F821,E402 count=1 show-pep8=1 show-source=1 statistics=1 -exclude=build,dist,doc,*.egg,*.egg-info +exclude=build,dist,docs,*.egg,*.egg-info [wheel] universal = 1 diff --git a/tests/iptools/iptools_test.py b/tests/iptools/iptools_test.py index ff23586..a1c8c88 100644 --- a/tests/iptools/iptools_test.py +++ b/tests/iptools/iptools_test.py @@ -35,7 +35,7 @@ def testMixedRange(self): self.assertFalse('209.19.170.129' in INTERNAL_IPS) # end testMixedRange -#end class IpRangeListTests +# end class IpRangeListTests class IpRangeTests(unittest.TestCase): @@ -44,7 +44,7 @@ def testIPv6Range(self): fixture = iptools.IpRange('::ffff:0:0/96') self.assertTrue('::ffff:172.16.11.12' in fixture) self.assertFalse('209.19.170.129' in fixture) - #end testIPv6Range + # end testIPv6Range def testV4MappedAddressInIPv6Range(self): """ @@ -60,7 +60,7 @@ def testV4MappedAddressInIPv6Range(self): self.assertTrue('::ffff:192.168.0.12' in fixture) self.assertFalse('::ffff:192.168.1.12' in fixture) - #end test6to4AddressInIPv6Range -#end class IpRangeTests + # end test6to4AddressInIPv6Range +# end class IpRangeTests # vim:se sw=4 ts=4 sts=4 et: From f047b4e1de2061d1de6df3ea12345a19a7a5af88 Mon Sep 17 00:00:00 2001 From: Piotr Skamruk Date: Wed, 17 Feb 2016 20:34:03 +0100 Subject: [PATCH 14/26] Provide methods for comparison of IpRangeList objects --- iptools/__init__.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/iptools/__init__.py b/iptools/__init__.py index 52074ba..608ea4b 100644 --- a/iptools/__init__.py +++ b/iptools/__init__.py @@ -517,6 +517,38 @@ def __len__(self): """ return sum(r.__len__() for r in self.ips) # end __len__ + + def __hash__(self): + """ + Return correct hash for IpRangeList object + + >>> a = IpRange('127.0.0.0/8') + >>> b = IpRange('127.0.0.0', '127.255.255.255') + >>> IpRangeList(a, b).__hash__() == IpRangeList(a, b).__hash__() + True + >>> IpRangeList(a, b).__hash__() == IpRangeList(b, a).__hash__() + True + >>> c = IpRange('10.0.0.0/8') + >>> IpRangeList(a, c).__hash__() == IpRangeList(c, a).__hash__() + False + """ + return hash(self.ips) + # end __hash__ + + def __eq__(self, other): + """ + >>> a = IpRange('127.0.0.0/8') + >>> b = IpRange('127.0.0.0', '127.255.255.255') + >>> IpRangeList(a, b) == IpRangeList(a, b) + True + >>> IpRangeList(a, b) == IpRangeList(b, a) + True + >>> c = IpRange('10.0.0.0/8') + >>> IpRangeList(a, c) == IpRangeList(c, a) + False + """ + return hash(self) == hash(other) + # end __eq__ # end class IpRangeList # vim: set sw=4 ts=4 sts=4 et : From 33954e7d605cb709c020433565b105a591245249 Mon Sep 17 00:00:00 2001 From: Bryan Davis Date: Sat, 20 Aug 2016 23:33:13 -0600 Subject: [PATCH 15/26] travis: remove --use-mirrors --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 79a101a..eada3f2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,8 +6,8 @@ python: - "3.3" - "pypy" install: - - pip install . --use-mirrors - - pip install -r tests/requirements.txt --use-mirrors + - pip install . + - pip install -r tests/requirements.txt script: - flake8 - nosetests From 285fe5c96685615cf41e4c835df477ec8a39d445 Mon Sep 17 00:00:00 2001 From: Bryan Davis Date: Sun, 21 Aug 2016 12:21:57 -0600 Subject: [PATCH 16/26] validate_netmask: ensure 32 bit expansion Ensure that the bit string representation of a netmask is the full 32 bits before validating the left most bits are 1s. See #18 --- iptools/ipv4.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/iptools/ipv4.py b/iptools/ipv4.py index c3d0127..08f199d 100644 --- a/iptools/ipv4.py +++ b/iptools/ipv4.py @@ -285,6 +285,10 @@ def validate_netmask(s): True >>> validate_netmask('128.0.0.1') False + >>> validate_netmask('1.255.255.0') + False + >>> validate_netmask('0.255.255.0') + False :param s: String to validate as a dotted-quad notation netmask. @@ -293,7 +297,8 @@ def validate_netmask(s): :raises: TypeError """ if validate_ip(s): - mask = bin(ip2network(s))[2:] + # Convert to binary string, strip '0b' prefix, 0 pad to 32 bits + mask = bin(ip2network(s))[2:].zfill(32) # all left most bits must be 1, all right most must be 0 seen0 = False for c in mask: From 51b9e84c72e2dd077d8ff4995e9389b1b4614185 Mon Sep 17 00:00:00 2001 From: Bryan Davis Date: Sun, 21 Aug 2016 12:25:55 -0600 Subject: [PATCH 17/26] Move imports before exports --- iptools/__init__.py | 15 +++++----- iptools/ipv4.py | 71 ++++++++++++++++++++++----------------------- iptools/ipv6.py | 8 ++--- 3 files changed, 44 insertions(+), 50 deletions(-) diff --git a/iptools/__init__.py b/iptools/__init__.py index 608ea4b..181f845 100644 --- a/iptools/__init__.py +++ b/iptools/__init__.py @@ -22,13 +22,6 @@ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -__version__ = '0.7.0-dev' - -__all__ = ( - 'IpRange', - 'IpRangeList', -) - # sniff for python2.x / python3k compatibility "fixes' try: @@ -51,10 +44,16 @@ def next(iterable): Sequence = object # end compatibility "fixes' - from . import ipv4 from . import ipv6 +__version__ = '0.7.0-dev' + +__all__ = ( + 'IpRange', + 'IpRangeList', +) + def _address2long(address): """ diff --git a/iptools/ipv4.py b/iptools/ipv4.py index 08f199d..3243482 100644 --- a/iptools/ipv4.py +++ b/iptools/ipv4.py @@ -23,6 +23,40 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +import re + +# sniff for python2.x / python3k compatibility "fixes' +try: + basestring = basestring +except NameError: + # 'basestring' is undefined, must be python3k + basestring = str + +try: + bin = bin +except NameError: + # builtin bin function doesn't exist + def bin(x): + """ + From http://code.activestate.com/recipes/219300/#c7 + """ + if x < 0: + return '-' + bin(-x) + out = [] + if x == 0: + out.append('0') + while x > 0: + out.append('01'[x & 1]) + x >>= 1 + pass + try: + return '0b' + ''.join(reversed(out)) + except NameError: + out.reverse() + return '0b' + ''.join(out) + # end bin +# end compatibility "fixes' + __all__ = ( 'cidr2block', 'hex2ip', @@ -60,43 +94,6 @@ 'TEST_NET_3', ) - -import re - - -# sniff for python2.x / python3k compatibility "fixes' -try: - basestring = basestring -except NameError: - # 'basestring' is undefined, must be python3k - basestring = str - -try: - bin = bin -except NameError: - # builtin bin function doesn't exist - def bin(x): - """ - From http://code.activestate.com/recipes/219300/#c7 - """ - if x < 0: - return '-' + bin(-x) - out = [] - if x == 0: - out.append('0') - while x > 0: - out.append('01'[x & 1]) - x >>= 1 - pass - try: - return '0b' + ''.join(reversed(out)) - except NameError: - out.reverse() - return '0b' + ''.join(out) - # end bin -# end compatibility "fixes' - - #: Regex for validating an IPv4 address _DOTTED_QUAD_RE = re.compile(r'^(\d{1,3}\.){0,3}\d{1,3}$') diff --git a/iptools/ipv6.py b/iptools/ipv6.py index 9fab832..97d00ee 100644 --- a/iptools/ipv6.py +++ b/iptools/ipv6.py @@ -23,6 +23,9 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +import re +from . import ipv4 + __all__ = ( 'cidr2block', 'ip2long', @@ -52,11 +55,6 @@ 'UNSPECIFIED_ADDRESS', ) - -import re -from . import ipv4 - - #: Regex for validating an IPv6 in hex notation _HEX_RE = re.compile(r'^([0-9a-f]{0,4}:){2,7}[0-9a-f]{0,4}$') From 041628d6d5860d39825302c4b2a6f68aec7014b2 Mon Sep 17 00:00:00 2001 From: Bryan Davis Date: Sun, 21 Aug 2016 14:08:12 -0600 Subject: [PATCH 18/26] Travis: use tox for testing * Update the Travis CI testing configuration to use tox. * Drop testing of Python 2.6, 3.2, 3.3 * Add Python 3.4, 3.5, pypy3 --- .gitignore | 13 +++++++------ .travis.yml | 20 +++++++++++++------- setup.cfg | 5 +++-- tox.ini | 8 ++++++++ 4 files changed, 31 insertions(+), 15 deletions(-) create mode 100644 tox.ini diff --git a/.gitignore b/.gitignore index 71b79d3..b11bdd6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,9 @@ +*.egg-info *.pyc -.coverage -.venv -build -dist -extras -iptools.egg-info +/.coverage +/.tox/ +/.venv/ +/build/ +/dist/ +/extras/ setuptools-*.egg diff --git a/.travis.yml b/.travis.yml index eada3f2..70c1d3c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,16 +1,22 @@ language: python python: - - "2.6" - "2.7" - - "3.2" - - "3.3" + - "3.4" + - "3.5" - "pypy" + - "pypy3" +sudo: false +matrix: + fast_finish: true + install: - - pip install . - - pip install -r tests/requirements.txt + - pip install wheel tox-travis + - python setup.py install bdist_wheel + - pip install ./dist/iptools-*.whl script: - - flake8 - - nosetests + - tox + - tox --installpkg ./dist/iptools-*.whl + notifications: email: - travis-ci+python-iptools@bd808.com diff --git a/setup.cfg b/setup.cfg index ec2d4e2..85d3e9c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,18 +1,19 @@ [nosetests] +verbosity=2 detailed-errors=1 with-coverage=1 with-doctest=1 cover-package=iptools cover-html=1 cover-html-dir=docs/_build/cover +cover-branches=1 [flake8] -ignore=F821,E402 count=1 show-pep8=1 show-source=1 statistics=1 -exclude=build,dist,docs,*.egg,*.egg-info +exclude=.tox,.venv,build,dist,docs,*.egg,*.egg-info [wheel] universal = 1 diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..a99d698 --- /dev/null +++ b/tox.ini @@ -0,0 +1,8 @@ +[tox] +envlist = py27, py34, py35, pypy, pypy3 + +[testenv] +deps = -r{toxinidir}/tests/requirements.txt +commands = + flake8 + nosetests From d698b0008316760f74290862344d9626398fb4af Mon Sep 17 00:00:00 2001 From: Bryan Davis Date: Sun, 21 Aug 2016 14:34:01 -0600 Subject: [PATCH 19/26] Cast input to IpRangeList (#15) Reduce the overhead of testing for membership in a long IpRangeList by ensuring that the provided input has been cast to an integer before checking each contained range. Closes #14 --- iptools/__init__.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/iptools/__init__.py b/iptools/__init__.py index 181f845..8d21ce9 100644 --- a/iptools/__init__.py +++ b/iptools/__init__.py @@ -249,7 +249,7 @@ def _cast(self, item): if ipv4 == self._ipver and item > ipv4.MAX_IP: # casting an ipv6 in an ipv4 range # downcast to ipv4 iff address is in the IPv4 mapped block - if item in IpRange(ipv6.IPV4_MAPPED): + if item in _IPV6_MAPPED_IPV4: item = item & ipv4.MAX_IP # end if @@ -395,6 +395,9 @@ def __iter__(self): # end class IpRange +_IPV6_MAPPED_IPV4 = IpRange(ipv6.IPV4_MAPPED) + + class IpRangeList (object): """ List of IpRange objects. @@ -464,6 +467,11 @@ def __contains__(self, item): :type item: str :returns: ``True`` if address is in list, ``False`` otherwise. """ + if isinstance(item, basestring): + item = _address2long(item) + if type(item) not in (type(1), type(ipv4.MAX_IP), type(ipv6.MAX_IP)): + raise TypeError( + "expected ip address, 32-bit integer or 128-bit integer") for r in self.ips: if item in r: return True From fcdc8f1a28861961045c3e484e03f0d6596d555c Mon Sep 17 00:00:00 2001 From: Bryan Davis Date: Sun, 21 Aug 2016 15:56:47 -0600 Subject: [PATCH 20/26] Implement RFC 1924 IPv6 encoding/decoding Just for fun really. RFC 1924 encodings are not allowed by most existing methods. New long2rfc1924 and rfc19242long allow encoding/decoding to the 20 character ASCII encoding specified in RFC 1924. Closes #9 --- iptools/ipv6.py | 101 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 99 insertions(+), 2 deletions(-) diff --git a/iptools/ipv6.py b/iptools/ipv6.py index 97d00ee..9e4c696 100644 --- a/iptools/ipv6.py +++ b/iptools/ipv6.py @@ -30,6 +30,8 @@ 'cidr2block', 'ip2long', 'long2ip', + 'long2rfc1924', + 'rfc19242long', 'validate_cidr', 'validate_ip', 'DOCUMENTATION_NETWORK', @@ -56,7 +58,7 @@ ) #: Regex for validating an IPv6 in hex notation -_HEX_RE = re.compile(r'^([0-9a-f]{0,4}:){2,7}[0-9a-f]{0,4}$') +_HEX_RE = re.compile(r'^([0-9a-fA-F]{0,4}:){2,7}[0-9a-fA-F]{0,4}$') #: Regex for validating an IPv6 in dotted-quad notation _DOTTED_QUAD_RE = re.compile(r'^([0-9a-f]{0,4}:){2,6}(\d{1,3}\.){0,3}\d{1,3}$') @@ -136,6 +138,21 @@ #: All DHCP servers and relay agents on the local site MULTICAST_SITE_DHCP = "ff05::1:3" +#: RFC 1924 alphabet +_RFC1924_ALPHABET = [ + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '!', '#', '$', '%', '&', '(', ')', '*', '+', '-', ';', '<', '=', + '>', '?', '@', '^', '_', '`', '{', '|', '}', '~', +] +#: RFC 1924 reverse lookup +_RFC1924_REV = None +#: Regex for validating an IPv6 in hex notation +_RFC1924_RE = re.compile(r'^[0-9A-Za-z!#$%&()*+-;<=>?@^_`{|}~]{20}$') + def validate_ip(s): """Validate a hexidecimal IPv6 ip address. @@ -167,6 +184,8 @@ def validate_ip(s): Traceback (most recent call last): ... TypeError: expected string or buffer + >>> validate_ip('1080:0:0:0:8:800:200c:417a') + True :param s: String to validate as a hexidecimal IPv6 ip address. @@ -218,6 +237,9 @@ def ip2long(ip): True >>> ip2long('ff::ff::ff') == None True + >>> expect = 21932261930451111902915077091070067066 + >>> ip2long('1080:0:0:0:8:800:200C:417A') == expect + True :param ip: Hexidecimal IPv6 address @@ -256,7 +278,7 @@ def ip2long(ip): # end ip2long -def long2ip(l): +def long2ip(l, rfc1924=False): """Convert a network byte order 128-bit integer to a canonical IPv6 address. @@ -281,10 +303,16 @@ def long2ip(l): Traceback (most recent call last): ... TypeError: expected int between 0 and inclusive + >>> long2ip(ip2long('1080::8:800:200C:417A'), rfc1924=True) + '4)+k&C#VzJ4br>0wv%Yp' + >>> long2ip(ip2long('::'), rfc1924=True) + '00000000000000000000' :param l: Network byte order 128-bit integer. :type l: int + :param rfc1924: Encode in RFC 1924 notation (base 85) + :type rfc1924: bool :returns: Canonical IPv6 address (eg. '::1'). :raises: TypeError """ @@ -292,6 +320,9 @@ def long2ip(l): raise TypeError( "expected int between %d and %d inclusive" % (MIN_IP, MAX_IP)) + if rfc1924: + return long2rfc1924(l) + # format as one big hex value hex_str = '%032x' % l # split into double octet chunks without padding zeros @@ -323,6 +354,72 @@ def long2ip(l): # end long2ip +def long2rfc1924(l): + """Convert a network byte order 128-bit integer to an rfc1924 IPv6 + address. + + + >>> long2rfc1924(ip2long('1080::8:800:200C:417A')) + '4)+k&C#VzJ4br>0wv%Yp' + >>> long2rfc1924(ip2long('::')) + '00000000000000000000' + >>> long2rfc1924(MAX_IP) + '=r54lj&NUUO~Hi%c2ym0' + + + :param l: Network byte order 128-bit integer. + :type l: int + :returns: RFC 1924 IPv6 address + :raises: TypeError + """ + if MAX_IP < l or l < MIN_IP: + raise TypeError( + "expected int between %d and %d inclusive" % (MIN_IP, MAX_IP)) + o = [] + r = l + while r > 85: + o.append(_RFC1924_ALPHABET[r % 85]) + r = r // 85 + o.append(_RFC1924_ALPHABET[r]) + return ''.join(reversed(o)).zfill(20) + + +def rfc19242long(s): + """Convert an RFC 1924 IPv6 address to a network byte order 128-bit + integer. + + + >>> expect = 0 + >>> rfc19242long('00000000000000000000') == expect + True + >>> expect = 21932261930451111902915077091070067066 + >>> rfc19242long('4)+k&C#VzJ4br>0wv%Yp') == expect + True + >>> rfc19242long('pizza') == None + True + >>> rfc19242long('~~~~~~~~~~~~~~~~~~~~') == None + True + >>> rfc19242long('=r54lj&NUUO~Hi%c2ym0') == MAX_IP + True + + + :param ip: RFC 1924 IPv6 address + :type ip: str + :returns: Network byte order 128-bit integer or ``None`` if ip is invalid. + """ + global _RFC1924_REV + if not _RFC1924_RE.match(s): + return None + if _RFC1924_REV is None: + _RFC1924_REV = {v: k for k, v in enumerate(_RFC1924_ALPHABET)} + l = 0 + for c in s: + l = l * 85 + _RFC1924_REV[c] + if l > MAX_IP: + return None + return l + + def validate_cidr(s): """Validate a CIDR notation ip address. From 96df2e8f9df052bb680ab7b043bfa883fdae28ba Mon Sep 17 00:00:00 2001 From: Bryan Davis Date: Sun, 21 Aug 2016 16:22:48 -0600 Subject: [PATCH 21/26] Update README description of tested versions --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 932796a..8ce94c8 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,8 @@ Local documentation can be built using [Sphinx][]: Python Version Compatibility ---------------------------- -[Travis CI][ci-home] automatically runs tests against python 2.6, 2.7, 3.2, 3.3 and pypy. +[Travis CI][ci-home] automatically runs tests against python 2.7, 3.4, 3.5, +pypy, and pypy3, Installation ------------ From 8d8c140a1d7863388c04180c893fce8c8d082297 Mon Sep 17 00:00:00 2001 From: cclauss Date: Thu, 6 Dec 2018 05:06:00 +0100 Subject: [PATCH 22/26] Travis CI: Add Python 3.6 and 3.7 to the testing --- .travis.yml | 4 ++++ tox.ini | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 70c1d3c..23adb1b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,11 +3,15 @@ python: - "2.7" - "3.4" - "3.5" + - "3.6" - "pypy" - "pypy3" sudo: false matrix: fast_finish: true + include: + - python: "3.7" + dist: xenial # required for Python >= 3.7 (travis-ci/travis-ci#9069) install: - pip install wheel tox-travis diff --git a/tox.ini b/tox.ini index a99d698..f11b876 100644 --- a/tox.ini +++ b/tox.ini @@ -4,5 +4,5 @@ envlist = py27, py34, py35, pypy, pypy3 [testenv] deps = -r{toxinidir}/tests/requirements.txt commands = - flake8 + flake8 --ignore=E741,W605 nosetests From 5a0ebd9afd659cc1c8f06d241fcd80cd138164bc Mon Sep 17 00:00:00 2001 From: cclauss Date: Thu, 6 Dec 2018 08:48:14 +0100 Subject: [PATCH 23/26] Placate flake8 --- iptools/__init__.py | 2 +- iptools/ipv6.py | 8 ++++---- tox.ini | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/iptools/__init__.py b/iptools/__init__.py index 8d21ce9..dd0fd67 100644 --- a/iptools/__init__.py +++ b/iptools/__init__.py @@ -399,7 +399,7 @@ def __iter__(self): class IpRangeList (object): - """ + r""" List of IpRange objects. Converts a list of ip address and/or CIDR addresses into a list of IpRange diff --git a/iptools/ipv6.py b/iptools/ipv6.py index 9e4c696..073a427 100644 --- a/iptools/ipv6.py +++ b/iptools/ipv6.py @@ -412,12 +412,12 @@ def rfc19242long(s): return None if _RFC1924_REV is None: _RFC1924_REV = {v: k for k, v in enumerate(_RFC1924_ALPHABET)} - l = 0 + x = 0 for c in s: - l = l * 85 + _RFC1924_REV[c] - if l > MAX_IP: + x = x * 85 + _RFC1924_REV[c] + if x > MAX_IP: return None - return l + return x def validate_cidr(s): diff --git a/tox.ini b/tox.ini index f11b876..a99d698 100644 --- a/tox.ini +++ b/tox.ini @@ -4,5 +4,5 @@ envlist = py27, py34, py35, pypy, pypy3 [testenv] deps = -r{toxinidir}/tests/requirements.txt commands = - flake8 --ignore=E741,W605 + flake8 nosetests From b4398244355d46dae161a791102ed4a0f48e0d83 Mon Sep 17 00:00:00 2001 From: cclauss Date: Tue, 11 Dec 2018 04:09:20 +0100 Subject: [PATCH 24/26] tox.ini: Add py36, py37 --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index a99d698..4189f95 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py27, py34, py35, pypy, pypy3 +envlist = py27, py34, py35, py36, py37, pypy, pypy3 [testenv] deps = -r{toxinidir}/tests/requirements.txt From 5d3fae0056297540355bb7c6c112703cfaa4b6ce Mon Sep 17 00:00:00 2001 From: Bryan Davis Date: Sun, 6 Jan 2019 21:50:08 -0700 Subject: [PATCH 25/26] Prep for 0.7.0 release --- .gitignore | 1 + iptools/__init__.py | 2 +- setup.py | 8 ++++---- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index b11bdd6..33baecb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ *.egg-info *.pyc /.coverage +/.python-version /.tox/ /.venv/ /build/ diff --git a/iptools/__init__.py b/iptools/__init__.py index dd0fd67..3a966f7 100644 --- a/iptools/__init__.py +++ b/iptools/__init__.py @@ -47,7 +47,7 @@ def next(iterable): from . import ipv4 from . import ipv6 -__version__ = '0.7.0-dev' +__version__ = '0.7.0' __all__ = ( 'IpRange', diff --git a/setup.py b/setup.py index 996ba0c..a09de1c 100644 --- a/setup.py +++ b/setup.py @@ -32,11 +32,11 @@ 'License :: OSI Approved :: BSD License', 'Operating System :: OS Independent', 'Programming Language :: Python', - 'Programming Language :: Python :: 2.5', - 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3.2', - 'Programming Language :: Python :: 3.3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', 'Topic :: Utilities', 'Topic :: Internet', ], From e1cf5b12bc2e305b0525757baed3e2be6f6cbb92 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Thu, 23 Jan 2020 00:37:14 +0100 Subject: [PATCH 26/26] Travis CI: Python 2.7, 3.5, 3.6, 3.7, 3.8 (#24) * Travis CI: Python 2.7, 3.5, 3.6, 3.7, 3.8 * tox.ini: Drop py34 and Add py38 * Setup.py: Drop Py34 and Add Py38 * README.md: Python 2.7, 3.5, 3.6, 3.7, 3.8, pypy, and pypy3 Implementation by @cclauss --- .travis.yml | 9 ++------- README.md | 4 ++-- setup.py | 2 +- tox.ini | 2 +- 4 files changed, 6 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index 23adb1b..6a3e3ea 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,12 @@ language: python python: - "2.7" - - "3.4" - "3.5" - "3.6" + - "3.7" + - "3.8" - "pypy" - "pypy3" -sudo: false -matrix: - fast_finish: true - include: - - python: "3.7" - dist: xenial # required for Python >= 3.7 (travis-ci/travis-ci#9069) install: - pip install wheel tox-travis diff --git a/README.md b/README.md index 8ce94c8..3b3b4c4 100644 --- a/README.md +++ b/README.md @@ -64,8 +64,8 @@ Local documentation can be built using [Sphinx][]: Python Version Compatibility ---------------------------- -[Travis CI][ci-home] automatically runs tests against python 2.7, 3.4, 3.5, -pypy, and pypy3, +[Travis CI][ci-home] automatically runs tests against Python 2.7, 3.5, 3.6, +3.7, 3.8, pypy, and pypy3. Installation ------------ diff --git a/setup.py b/setup.py index a09de1c..551a951 100644 --- a/setup.py +++ b/setup.py @@ -33,10 +33,10 @@ 'Operating System :: OS Independent', 'Programming Language :: Python', 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', 'Topic :: Utilities', 'Topic :: Internet', ], diff --git a/tox.ini b/tox.ini index 4189f95..446681b 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py27, py34, py35, py36, py37, pypy, pypy3 +envlist = py27, py35, py36, py37, py38, pypy, pypy3 [testenv] deps = -r{toxinidir}/tests/requirements.txt