Skip to content

Commit

Permalink
Adhere to PEP8 with the help of flake8
Browse files Browse the repository at this point in the history
  • Loading branch information
lukeyeager committed Jan 5, 2016
1 parent e3e26c5 commit 8981685
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 62 deletions.
24 changes: 16 additions & 8 deletions compare_versions/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,37 @@
from . import core
from . import schemes


class InputError(Exception):
# Denotes bad program input
pass


def main():
"""
Module entry point
Run with "python -m compare_versions"
"""
parser = argparse.ArgumentParser(description='compare_versions %s' % version.__version__)
parser.add_argument('versions', nargs='*', help='version strings to compare')
parser.add_argument('-s', '--scheme', default='semver', help='versioning scheme - semver[default]/string')
parser.add_argument('-l', '--list', action='store_true', help='verify that a list of versions is in order according to "comparison"')
parser.add_argument('-c', '--comparison', default='lt', help='expected ordering for "list" - one of eq/ne/lt[default]/gt/le/ge')
parser = argparse.ArgumentParser(
description='compare_versions %s' % version.__version__)
parser.add_argument('versions', nargs='*',
help='version strings to compare')
parser.add_argument('-s', '--scheme', default='semver',
help='versioning scheme - semver[default]/string')
parser.add_argument('-l', '--list', action='store_true',
help='verify that a list of versions is in order according to "comparison"')
parser.add_argument('-c', '--comparison', default='lt',
help='expected ordering for "list" - one of eq/ne/lt[default]/gt/le/ge')
args = parser.parse_args()

if args.scheme not in schemes.schemes:
raise InputError('Invalid versioning scheme "%s" - options are %s' % (args.scheme, '/'.join(s for s in schemes.schemes)))
raise InputError('Invalid versioning scheme "%s" - options are %s' %
(args.scheme, '/'.join(s for s in schemes.schemes)))

if args.comparison not in core.VALID_COMPARISONS:
raise InputError('Invalid comparison "%s" - options are %s' % (args.comparison, '/'.join(c for c in core.VALID_COMPARISONS)))
raise InputError('Invalid comparison "%s" - options are %s' %
(args.comparison, '/'.join(c for c in core.VALID_COMPARISONS)))

if len(args.versions) == 0:
# Read from stdin until EOF
Expand Down Expand Up @@ -57,4 +66,3 @@ def main():
except Exception as e:
sys.stderr.write('%s: %s\n' % (type(e).__name__, e.message))
sys.exit(1)

18 changes: 12 additions & 6 deletions compare_versions/core.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
from . import schemes

VALID_COMPARISONS=['eq','ne','lt','gt','le','ge']
VALID_COMPARISONS = ['eq', 'ne', 'lt', 'gt', 'le', 'ge']


def is_valid(version, scheme='semver'):
if scheme not in schemes.schemes:
raise ValueError('Invalid scheme "%s" - options are %s' % (scheme, '/'.join(s for s in schemes.schemes)))
raise ValueError('Invalid scheme "%s" - options are %s' %
(scheme, '/'.join(s for s in schemes.schemes)))

try:
schemes.schemes[scheme](version)
except schemes.InvalidVersionError:
return False
return True


def verify_list(versions, comparison='lt', scheme='semver'):
"""
Verify that a list of versions all match comparison
Expand All @@ -26,10 +29,12 @@ def verify_list(versions, comparison='lt', scheme='semver'):
raise ValueError('You must provide at least two versions to compare')

if comparison not in VALID_COMPARISONS:
raise ValueError('Invalid comparison "%s" - options are %s' % (comparison, '/'.join(c for c in VALID_COMPARISONS)))
raise ValueError('Invalid comparison "%s" - options are %s' %
(comparison, '/'.join(c for c in VALID_COMPARISONS)))

if scheme not in schemes.schemes:
raise ValueError('Invalid scheme "%s" - options are %s' % (scheme, '/'.join(s for s in schemes.schemes)))
raise ValueError('Invalid scheme "%s" - options are %s' %
(scheme, '/'.join(s for s in schemes.schemes)))

prev = schemes.schemes[scheme](versions[0])
for curr in versions[1:]:
Expand All @@ -47,12 +52,14 @@ def verify_list(versions, comparison='lt', scheme='semver'):
elif comparison == 'ge':
res = prev >= curr
if not res:
print('ERROR: %s %s %s' % (prev, comparison_symbol(prev, curr), curr))
print('ERROR: %s %s %s' %
(prev, comparison_symbol(prev, curr), curr))
return False
prev = curr
print(True)
return True


def comparison_symbol(v1, v2):
"""
Returns a character representation of the relationship between two objects
Expand All @@ -69,4 +76,3 @@ def comparison_symbol(v1, v2):
return '<'
else:
return '?'

1 change: 1 addition & 0 deletions compare_versions/schemes/_string.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from .base import BaseScheme


class String(BaseScheme):
"""
Performs naive string comparisons
Expand Down
13 changes: 10 additions & 3 deletions compare_versions/schemes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ class BaseScheme(object):
def __init__(self, comparable, printable=None):
"""
Arguments:
comparable -- some object which can be compared to other objects of the same type
comparable -- some object which can be compared to other objects of the
same type
printable -- a printable representation of the verison
"""
self._c = comparable
Expand All @@ -19,6 +20,7 @@ def __init__(self, comparable, printable=None):

def __str__(self):
return str(self._p)

def __repr__(self):
return repr(self._p)

Expand All @@ -27,16 +29,21 @@ def __repr__(self):
def __eq__(self, other):
self.check_type(other)
return self._c == other._c

def __gt__(self, other):
self.check_type(other)
return self._c > other._c

def __lt__(self, other):
self.check_type(other)
return self._c < other._c

def __ne__(self, other):
return not self == other

def __ge__(self, other):
return self == other or self > other

def __le__(self, other):
return self == other or self < other

Expand All @@ -47,5 +54,5 @@ def check_type(self, other):
Asserts that the version to be compared is of the same type
"""
if type(self) != type(other):
raise TypeError('Cannot compare "%s" and "%s"' % (type(self), type(other)))

raise TypeError('Cannot compare "%s" and "%s"' %
(type(self), type(other)))
24 changes: 15 additions & 9 deletions compare_versions/schemes/semver.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from . import InvalidVersionError
from .base import BaseScheme


class SemVer(BaseScheme):
"""
http://semver.org/spec/v2.0.0.html
Expand All @@ -15,18 +16,19 @@ def __init__(self, s):
major, minor, patch = s.split('.', 2)

if not re.match('(0|[1-9]\d*)$', major):
raise InvalidVersionError('MAJOR version must be a non-negative integer, and must not contain leading zeros - "%s"' % major)
raise InvalidVersionError('MAJOR version must be a non-negative integer, '
'and must not contain leading zeros - "%s"' % major)
major = int(major)

if not re.match('(0|[1-9]\d*)$', minor):
raise InvalidVersionError('MINOR version must be a non-negative integer, and must not contain leading zeros - "%s"' % minor)
raise InvalidVersionError('MINOR version must be a non-negative integer, '
'and must not contain leading zeros - "%s"' % minor)
minor = int(minor)

patch = self.PatchVersion(patch)

super(SemVer, self).__init__((major, minor, patch), s)


class PatchVersion(BaseScheme):
def __init__(self, s):
"""
Expand All @@ -39,7 +41,8 @@ def __init__(self, s):
extra = match.group(2)

if not re.match('(0|[1-9]\d*)$', version):
raise InvalidVersionError('PATCH version must begin with a non-negative integer, and must not contain leading zeros - "%s"' % s)
raise InvalidVersionError('PATCH version must begin with a non-negative integer, '
'and must not contain leading zeros - "%s"' % s)
version = int(version)

match = re.match('(.*)\+(.*)', extra)
Expand All @@ -54,9 +57,11 @@ def __init__(self, s):

if prerelease:
if prerelease.startswith('.'):
raise InvalidVersionError('Four top-level version identifiers are not allowed - required format is MAJOR.MINOR.PATCH[-PRERELEASE][+BUILD]')
raise InvalidVersionError('Four top-level version identifiers are not allowed - '
'required format is MAJOR.MINOR.PATCH[-PRERELEASE][+BUILD]')
if not prerelease.startswith('-'):
raise RuntimeError('Something went wrong when parsing "%s" - prerelease version should start with a "-"' % s)
raise RuntimeError('Something went wrong when parsing "%s" - '
'prerelease version should start with a "-"' % s)
sort_order = (version, 0, SemVer.PrereleaseVersion(prerelease[1:]))
else:
sort_order = (version, 1)
Expand All @@ -71,15 +76,16 @@ def __init__(self, s):
values = ()
for identifier in s.split('.'):
if not re.match('[0-9A-Za-z-]+', identifier):
raise InvalidVersionError('Invalid identifier "%s" in prerelease section of PATCH version' % identifier)
raise InvalidVersionError('Invalid identifier "%s" in prerelease section of PATCH version' %
identifier)
if re.match('\d+$', identifier):
if not re.match('(0|[1-9]\d*)$', identifier):
raise InvalidVersionError('Numeric identifiers in prerelease version must not contain leading zeros - "%s"' % identifier)
raise InvalidVersionError('Numeric identifiers in prerelease version must not contain leading '
'zeros - "%s"' % identifier)
# sort numerically (lower than strings)
values += (1, int(identifier))
else:
# sort lexically (higher than numbers)
values += (2, identifier)

super(SemVer.PrereleaseVersion, self).__init__(values)

24 changes: 12 additions & 12 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
#!/usr/bin/env python

from setuptools import setup, find_packages
import os.path

# Get version
with open('compare_versions/version.py') as f:
exec(f.read())


# Get documentation
def readme():
with open('README.rst') as f:
return f.read()

setup(
name = 'compare_versions',
version = __version__,
author = 'Luke Yeager',
author_email = 'luke.yeager@gmail.com',
url = 'https://github.com/lukeyeager/compare-versions',
description = 'Compare versions using various versioning schemes',
long_description = readme(),
scripts = [
name='compare_versions',
version=__version__,
author='Luke Yeager',
author_email='luke.yeager@gmail.com',
url='https://github.com/lukeyeager/compare-versions',
description='Compare versions using various versioning schemes',
long_description=readme(),
scripts=[
'bin/compare_versions',
],
packages = find_packages(exclude=['tests', 'tests.*']),
test_suite = 'tests',
classifiers = [
packages=find_packages(exclude=['tests', 'tests.*']),
test_suite='tests',
classifiers=[
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
'Programming Language :: Python',
Expand Down
32 changes: 17 additions & 15 deletions tests/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from compare_versions import core


class TestIsValid(unittest.TestCase):

def testValid(self):
Expand All @@ -13,33 +14,35 @@ def testInvalid(self):
self.assertFalse(core.is_valid('1.0.0.0'))
self.assertFalse(core.is_valid('1 0 0'))


class TestVerifyList(unittest.TestCase):

def testShortList(self):
self.assertRaises(ValueError, core.verify_list, [])
self.assertRaises(ValueError, core.verify_list, ['1.0.0'])

def testInvalidComparison(self):
self.assertRaises(ValueError, core.verify_list, ['1.0.0','1.1.0'], comparison='not-a-comparison')
self.assertRaises(ValueError, core.verify_list, ['1.0.0', '1.1.0'], comparison='not-a-comparison')

def testInvalidScheme(self):
self.assertRaises(ValueError, core.verify_list, ['1.0.0','1.1.0'], scheme='not-a-scheme')
self.assertRaises(ValueError, core.verify_list, ['1.0.0', '1.1.0'], scheme='not-a-scheme')

def testComparisonsGood(self):
self.assertTrue(core.verify_list(['1.0.0','1.0.0'], comparison='eq'))
self.assertTrue(core.verify_list(['1.0.0','1.1.0'], comparison='ne'))
self.assertTrue(core.verify_list(['1.0.0','1.1.0'], comparison='lt'))
self.assertTrue(core.verify_list(['1.1.0','1.0.0'], comparison='gt'))
self.assertTrue(core.verify_list(['1.0.0','1.0.0','1.1.0'], comparison='le'))
self.assertTrue(core.verify_list(['1.1.0','1.0.0','1.0.0'], comparison='ge'))
self.assertTrue(core.verify_list(['1.0.0', '1.0.0'], comparison='eq'))
self.assertTrue(core.verify_list(['1.0.0', '1.1.0'], comparison='ne'))
self.assertTrue(core.verify_list(['1.0.0', '1.1.0'], comparison='lt'))
self.assertTrue(core.verify_list(['1.1.0', '1.0.0'], comparison='gt'))
self.assertTrue(core.verify_list(['1.0.0', '1.0.0', '1.1.0'], comparison='le'))
self.assertTrue(core.verify_list(['1.1.0', '1.0.0', '1.0.0'], comparison='ge'))

def testComparisonsBad(self):
self.assertFalse(core.verify_list(['1.0.0','1.1.0'], comparison='eq'))
self.assertFalse(core.verify_list(['1.0.0','1.0.0'], comparison='ne'))
self.assertFalse(core.verify_list(['1.1.0','1.0.0'], comparison='lt'))
self.assertFalse(core.verify_list(['1.0.0','1.1.0'], comparison='gt'))
self.assertFalse(core.verify_list(['1.1.0','1.0.0','1.0.0'], comparison='le'))
self.assertFalse(core.verify_list(['1.0.0','1.0.0','1.1.0'], comparison='ge'))
self.assertFalse(core.verify_list(['1.0.0', '1.1.0'], comparison='eq'))
self.assertFalse(core.verify_list(['1.0.0', '1.0.0'], comparison='ne'))
self.assertFalse(core.verify_list(['1.1.0', '1.0.0'], comparison='lt'))
self.assertFalse(core.verify_list(['1.0.0', '1.1.0'], comparison='gt'))
self.assertFalse(core.verify_list(['1.1.0', '1.0.0', '1.0.0'], comparison='le'))
self.assertFalse(core.verify_list(['1.0.0', '1.0.0', '1.1.0'], comparison='ge'))


class TestComparisonSymbol(unittest.TestCase):

Expand All @@ -50,4 +53,3 @@ def testSymbols(self):

def testInvalid(self):
self.assertRaises(TypeError, core.comparison_symbol, 1, 'two')

8 changes: 4 additions & 4 deletions tests/schemes/_string.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

from compare_versions import core


class TestString(unittest.TestCase):

def testAlpha(self):
self.assertTrue(core.verify_list(['a','b','c'], scheme='string'))
self.assertTrue(core.verify_list(['a', 'b', 'c'], scheme='string'))

def testNumeric(self):
self.assertTrue(core.verify_list(['1','2','3'], scheme='string'))
self.assertTrue(core.verify_list(['1', '2', '3'], scheme='string'))

def testStandard(self):
self.assertTrue(core.verify_list(['1.0.0','1.0.1','2.0.0'], scheme='string'))

self.assertTrue(core.verify_list(['1.0.0', '1.0.1', '2.0.0'], scheme='string'))
11 changes: 6 additions & 5 deletions tests/schemes/semver.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

from compare_versions import core


class TestSemVer(unittest.TestCase):

def testSpec2(self):
self.assertTrue(core.verify_list(['1.9.0','1.10.0','1.11.0'], 'lt'))
self.assertTrue(core.verify_list(['1.9.0', '1.10.0', '1.11.0'], 'lt'))
self.assertFalse(core.is_valid('01.1.1'))
self.assertFalse(core.is_valid('-1.1.1'))
self.assertFalse(core.is_valid('1.1'))
Expand All @@ -21,9 +22,9 @@ def testSpec10(self):
self.assertTrue(core.is_valid('1.0.0-alpha+001'))
self.assertTrue(core.is_valid('1.0.0+20130313144700'))
self.assertTrue(core.is_valid('1.0.0-beta+exp.sha.5114f85'))
self.assertTrue(core.verify_list(['1.0.0','1.0.0+1','1.0.0+2'], 'eq'))
self.assertTrue(core.verify_list(['1.0.0', '1.0.0+1', '1.0.0+2'], 'eq'))

def testSpec11(self):
self.assertTrue(core.verify_list(['1.0.0','2.0.0','2.1.0','2.1.1'], 'lt'))
self.assertTrue(core.verify_list(['1.0.0-alpha','1.0.0-alpha.1','1.0.0-alpha.beta','1.0.0-beta','1.0.0-beta.2','1.0.0-beta.11','1.0.0-rc.1','1.0.0'], 'lt'))

self.assertTrue(core.verify_list(['1.0.0', '2.0.0', '2.1.0', '2.1.1'], 'lt'))
self.assertTrue(core.verify_list(['1.0.0-alpha', '1.0.0-alpha.1', '1.0.0-alpha.beta', '1.0.0-beta',
'1.0.0-beta.2', '1.0.0-beta.11', '1.0.0-rc.1', '1.0.0'], 'lt'))

0 comments on commit 8981685

Please sign in to comment.