summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaphaël Barrois <raphael.barrois@polytechnique.org>2019-08-29 11:31:57 +0200
committerRaphaël Barrois <raphael.barrois@polytechnique.org>2019-08-29 11:38:14 +0200
commite1ea37642d0fd9bffb865da4122706e7349afec1 (patch)
tree4a18c2f26f95333dc9e6c7016e2eb44b174599b5
parent1655f9cdd72dd3e6dcaf071e84aa5e897e06d39d (diff)
downloadsemantic-version-rbarrois/restore-py2.tar.gz
Restore Python2 support.rbarrois/restore-py2
-rw-r--r--.travis.yml5
-rw-r--r--ChangeLog4
-rw-r--r--semantic_version/base.py27
-rw-r--r--semantic_version/django_fields.py12
-rwxr-xr-xsetup.py3
-rwxr-xr-xtests/test_base.py39
-rwxr-xr-xtests/test_match.py7
-rw-r--r--tests/test_npm.py7
-rwxr-xr-xtests/test_parsing.py13
-rw-r--r--tox.ini2
10 files changed, 94 insertions, 25 deletions
diff --git a/.travis.yml b/.travis.yml
index 735e554..258275e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,12 +9,13 @@ install:
matrix:
include:
+ - python: "2.7"
+ env: TOXENV=py27-django111
- python: "3.4"
env: TOXENV=py34-django111
- - python: "3.5"
- env: TOXENV=py35-django22
- python: "3.6"
env: TOXENV=py36-django111
+ - python: "3.6"
env: TOXENV=py36-django22
# Pypy
diff --git a/ChangeLog b/ChangeLog
index f85a228..aac3bb7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,7 +4,9 @@ ChangeLog
2.7.2 (unreleased)
------------------
-- Nothing changed yet.
+*New:*
+
+ * Restore support for Python 2.
2.7.1 (2019-08-28)
diff --git a/semantic_version/base.py b/semantic_version/base.py
index 1c4b01d..d7061c0 100644
--- a/semantic_version/base.py
+++ b/semantic_version/base.py
@@ -14,7 +14,7 @@ def _has_leading_zero(value):
and value != '0')
-class MaxIdentifier:
+class MaxIdentifier(object):
__slots__ = []
def __repr__(self):
@@ -25,7 +25,7 @@ class MaxIdentifier:
@functools.total_ordering
-class NumericIdentifier:
+class NumericIdentifier(object):
__slots__ = ['value']
def __init__(self, value):
@@ -51,7 +51,7 @@ class NumericIdentifier:
@functools.total_ordering
-class AlphaIdentifier:
+class AlphaIdentifier(object):
__slots__ = ['value']
def __init__(self, value):
@@ -76,7 +76,7 @@ class AlphaIdentifier:
return NotImplemented
-class Version:
+class Version(object):
version_re = re.compile(r'^(\d+)\.(\d+)\.(\d+)(?:-([0-9a-zA-Z.-]+))?(?:\+([0-9a-zA-Z.-]+))?$')
partial_version_re = re.compile(r'^(\d+)(?:\.(\d+)(?:\.(\d+))?)?(?:-([0-9a-zA-Z.-]*))?(?:\+([0-9a-zA-Z.-]*))?$')
@@ -84,7 +84,6 @@ class Version:
def __init__(
self,
version_string=None,
- *,
major=None,
minor=None,
patch=None,
@@ -404,7 +403,7 @@ class Version:
def precedence_key(self):
if self.prerelease:
prerelease_key = tuple(
- NumericIdentifier(part) if part.isdecimal() else AlphaIdentifier(part)
+ NumericIdentifier(part) if re.match(r'^[0-9]+$', part) else AlphaIdentifier(part)
for part in self.prerelease
)
else:
@@ -468,7 +467,7 @@ class Version:
return self.precedence_key >= other.precedence_key
-class SpecItem:
+class SpecItem(object):
"""A requirement specification."""
KIND_ANY = '*'
@@ -576,7 +575,7 @@ def validate(version_string):
DEFAULT_SYNTAX = 'simple'
-class BaseSpec:
+class BaseSpec(object):
"""A specification of compatible versions.
Usage:
@@ -606,7 +605,7 @@ class BaseSpec:
return subclass
def __init__(self, expression):
- super().__init__()
+ super(BaseSpec, self).__init__()
self.expression = expression
self.clause = self._parse_to_clause(expression)
@@ -659,7 +658,7 @@ class BaseSpec:
return '<%s: %r>' % (self.__class__.__name__, self.expression)
-class Clause:
+class Clause(object):
__slots__ = []
def match(self, version):
@@ -685,7 +684,7 @@ class AnyOf(Clause):
__slots__ = ['clauses']
def __init__(self, *clauses):
- super().__init__()
+ super(AnyOf, self).__init__()
self.clauses = frozenset(clauses)
def match(self, version):
@@ -739,7 +738,7 @@ class AllOf(Clause):
__slots__ = ['clauses']
def __init__(self, *clauses):
- super().__init__()
+ super(AllOf, self).__init__()
self.clauses = frozenset(clauses)
def match(self, version):
@@ -878,7 +877,7 @@ class Range(Matcher):
__slots__ = ['operator', 'target', 'prerelease_policy', 'build_policy']
def __init__(self, operator, target, prerelease_policy=PRERELEASE_NATURAL, build_policy=BUILD_IMPLICIT):
- super().__init__()
+ super(Range, self).__init__()
if target.build and operator not in (self.OP_EQ, self.OP_NEQ):
raise ValueError(
"Invalid range %s%s: build numbers have no ordering."
@@ -1155,7 +1154,7 @@ class LegacySpec(SimpleSpec):
stacklevel=2,
)
expression = ','.join(expressions)
- super().__init__(expression)
+ super(LegacySpec, self).__init__(expression)
def __iter__(self):
warnings.warn(
diff --git a/semantic_version/django_fields.py b/semantic_version/django_fields.py
index db7e606..97f9ce1 100644
--- a/semantic_version/django_fields.py
+++ b/semantic_version/django_fields.py
@@ -14,7 +14,7 @@ class SemVerField(models.CharField):
def __init__(self, *args, **kwargs):
kwargs.setdefault('max_length', 200)
- super().__init__(*args, **kwargs)
+ super(SemVerField, self).__init__(*args, **kwargs)
def from_db_value(self, value, expression, connection, context):
"""Convert from the database format.
@@ -36,7 +36,7 @@ class SemVerField(models.CharField):
return str(value)
def run_validators(self, value):
- return super().run_validators(str(value))
+ return super(SemVerField, self).run_validators(str(value))
class VersionField(SemVerField):
@@ -54,11 +54,11 @@ class VersionField(SemVerField):
stacklevel=2,
)
self.coerce = kwargs.pop('coerce', False)
- super().__init__(*args, **kwargs)
+ super(VersionField, self).__init__(*args, **kwargs)
def deconstruct(self):
"""Handle django.db.migrations."""
- name, path, args, kwargs = super().deconstruct()
+ name, path, args, kwargs = super(VersionField, self).deconstruct()
kwargs['partial'] = self.partial
kwargs['coerce'] = self.coerce
return name, path, args, kwargs
@@ -83,11 +83,11 @@ class SpecField(SemVerField):
def __init__(self, *args, **kwargs):
self.syntax = kwargs.pop('syntax', base.DEFAULT_SYNTAX)
- super().__init__(*args, **kwargs)
+ super(SpecField, self).__init__(*args, **kwargs)
def deconstruct(self):
"""Handle django.db.migrations."""
- name, path, args, kwargs = super().deconstruct()
+ name, path, args, kwargs = super(SpecField, self).deconstruct()
if self.syntax != base.DEFAULT_SYNTAX:
kwargs['syntax'] = self.syntax
return name, path, args, kwargs
diff --git a/setup.py b/setup.py
index 2c52217..7ad8d5f 100755
--- a/setup.py
+++ b/setup.py
@@ -49,7 +49,7 @@ setup(
url='https://github.com/rbarrois/python-semanticversion',
download_url='http://pypi.python.org/pypi/semantic_version/',
packages=['semantic_version'],
- python_requires=">=3.4",
+ python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*",
setup_requires=[
'setuptools>=0.8',
],
@@ -61,6 +61,7 @@ setup(
'Topic :: Software Development :: Libraries :: Python Modules',
'Operating System :: OS Independent',
'Programming Language :: Python',
+ 'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
diff --git a/tests/test_base.py b/tests/test_base.py
index 5a6497b..cd0b5f5 100755
--- a/tests/test_base.py
+++ b/tests/test_base.py
@@ -6,6 +6,7 @@
"""Test the various functions from 'base'."""
import unittest
+import sys
from semantic_version import base
@@ -13,6 +14,12 @@ from semantic_version import base
class TopLevelTestCase(unittest.TestCase):
"""Test module-level functions."""
+ if sys.version_info[0] <= 2:
+ import contextlib
+ @contextlib.contextmanager
+ def subTest(self, **kwargs):
+ yield
+
versions = (
('0.1.0', '0.1.1', -1),
('0.1.1', '0.1.1', 0),
@@ -89,6 +96,12 @@ class TopLevelTestCase(unittest.TestCase):
class VersionTestCase(unittest.TestCase):
+ if sys.version_info[0] <= 2:
+ import contextlib
+ @contextlib.contextmanager
+ def subTest(self, **kwargs):
+ yield
+
versions = {
'1.0.0-alpha': (1, 0, 0, ('alpha',), ()),
'1.0.0-alpha.1': (1, 0, 0, ('alpha', '1'), ()),
@@ -199,6 +212,7 @@ class VersionTestCase(unittest.TestCase):
]))
)
+ @unittest.skipIf(sys.version_info[0] <= 2, "Comparisons don't raise TypeError in Python 2")
def test_invalid_comparisons(self):
v = base.Version('0.1.0')
with self.assertRaises(TypeError):
@@ -367,6 +381,12 @@ class VersionTestCase(unittest.TestCase):
class SpecItemTestCase(unittest.TestCase):
+ if sys.version_info[0] <= 2:
+ import contextlib
+ @contextlib.contextmanager
+ def subTest(self, **kwargs):
+ yield
+
invalids = [
'<=0.1.1+build3',
'<=0.1.1+',
@@ -540,6 +560,12 @@ class SpecItemTestCase(unittest.TestCase):
class CoerceTestCase(unittest.TestCase):
+ if sys.version_info[0] <= 2:
+ import contextlib
+ @contextlib.contextmanager
+ def subTest(self, **kwargs):
+ yield
+
examples = {
# Dict of target: [list of equivalents]
'0.0.0': ('0', '0.0', '0.0.0', '0.0.0+', '0-'),
@@ -564,6 +590,19 @@ class CoerceTestCase(unittest.TestCase):
class SpecTestCase(unittest.TestCase):
+ if sys.version_info[0] <= 2:
+ import contextlib
+ @contextlib.contextmanager
+ def subTest(self, **kwargs):
+ yield
+
+ def assertCountEqual(self, a, b):
+ import collections
+ self.assertEqual(
+ collections.Counter(a),
+ collections.Counter(b),
+ )
+
examples = {
'>=0.1.1,<0.1.2': ['>=0.1.1', '<0.1.2'],
'>=0.1.0,!=0.1.3-rc1,<0.1.3': ['>=0.1.0', '!=0.1.3-rc1', '<0.1.3'],
diff --git a/tests/test_match.py b/tests/test_match.py
index 4bf7162..f807828 100755
--- a/tests/test_match.py
+++ b/tests/test_match.py
@@ -4,11 +4,18 @@
# This code is distributed under the two-clause BSD License.
import unittest
+import sys
import semantic_version
class MatchTestCase(unittest.TestCase):
+ if sys.version_info[0] <= 2:
+ import contextlib
+ @contextlib.contextmanager
+ def subTest(self, **kwargs):
+ yield
+
invalid_specs = [
'',
'!0.1',
diff --git a/tests/test_npm.py b/tests/test_npm.py
index 86cbc76..7bed337 100644
--- a/tests/test_npm.py
+++ b/tests/test_npm.py
@@ -6,11 +6,18 @@
"""Test NPM-style specifications."""
import unittest
+import sys
from semantic_version import base
class NpmSpecTests(unittest.TestCase):
+ if sys.version_info[0] <= 2:
+ import contextlib
+ @contextlib.contextmanager
+ def subTest(self, **kwargs):
+ yield
+
examples = {
# range: [matchings], [failings]
'>=1.2.7': (
diff --git a/tests/test_parsing.py b/tests/test_parsing.py
index 0da679f..01b7b5e 100755
--- a/tests/test_parsing.py
+++ b/tests/test_parsing.py
@@ -5,11 +5,18 @@
import itertools
import unittest
+import sys
import semantic_version
class ParsingTestCase(unittest.TestCase):
+ if sys.version_info[0] <= 2:
+ import contextlib
+ @contextlib.contextmanager
+ def subTest(self, **kwargs):
+ yield
+
invalids = [
None,
'',
@@ -66,6 +73,12 @@ class ParsingTestCase(unittest.TestCase):
class ComparisonTestCase(unittest.TestCase):
+ if sys.version_info[0] <= 2:
+ import contextlib
+ @contextlib.contextmanager
+ def subTest(self, **kwargs):
+ yield
+
order = [
'1.0.0-alpha',
'1.0.0-alpha.1',
diff --git a/tox.ini b/tox.ini
index 9ec0fb3..2841dbb 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,6 +1,6 @@
[tox]
envlist =
- py{34,35,36,37}-django111
+ py{27,34,35,36,37}-django111
py{35,36,37}-django22
pypy3-django{111,22}
lint