Hello community,
here is the log from the commit of package python-dephell-specifier for
openSUSE:Factory checked in at 2019-09-13 15:03:35
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-dephell-specifier (Old)
and /work/SRC/openSUSE:Factory/.python-dephell-specifier.new.7948 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-dephell-specifier"
Fri Sep 13 15:03:35 2019 rev:2 rq:730640 version:0.2.1
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-dephell-specifier/python-dephell-specifier.changes
2019-08-13 13:26:59.389327985 +0200
+++
/work/SRC/openSUSE:Factory/.python-dephell-specifier.new.7948/python-dephell-specifier.changes
2019-09-13 15:05:06.657259382 +0200
@@ -1,0 +2,6 @@
+Fri Sep 13 09:01:42 UTC 2019 - Tomáš Chvátal <[email protected]>
+
+- Update to 0.2.1:
+ * no upstream changelog
+
+-------------------------------------------------------------------
Old:
----
dephell_specifier-0.1.5.tar.gz
New:
----
dephell_specifier-0.2.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-dephell-specifier.spec ++++++
--- /var/tmp/diff_new_pack.xemgOs/_old 2019-09-13 15:05:07.297259246 +0200
+++ /var/tmp/diff_new_pack.xemgOs/_new 2019-09-13 15:05:07.301259245 +0200
@@ -12,30 +12,31 @@
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
+#
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
%define skip_python2 1
Name: python-dephell-specifier
-Version: 0.1.5
+Version: 0.2.1
Release: 0
-License: MIT
Summary: Dephell library for Python package version specifiers
-Url: https://github.com/dephell/dephell_specifier
+License: MIT
Group: Development/Languages/Python
-Source:
https://files.pythonhosted.org/packages/source/d/dephell-specifier/dephell_specifier-%{version}.tar.gz
-BuildRequires: python-rpm-macros
+URL: https://github.com/dephell/dephell_specifier
+Source:
https://files.pythonhosted.org/packages/source/d/dephell_specifier/dephell_specifier-%{version}.tar.gz
BuildRequires: %{python_module base >= 3.5}
BuildRequires: %{python_module setuptools}
-# SECTION test requirements
-BuildRequires: %{python_module packaging}
-# /SECTION
BuildRequires: fdupes
+BuildRequires: python-rpm-macros
Requires: python-base >= 3.5
Requires: python-packaging
BuildArch: noarch
-
+# SECTION test requirements
+BuildRequires: %{python_module packaging >= 17.1}
+BuildRequires: %{python_module pytest}
+# /SECTION
%python_subpackages
%description
@@ -51,6 +52,9 @@
%python_install
%python_expand %fdupes %{buildroot}%{$python_sitelib}
+%check
+%pytest
+
%files %{python_files}
%license LICENSE
%doc README.md
++++++ dephell_specifier-0.1.5.tar.gz -> dephell_specifier-0.2.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dephell_specifier-0.1.5/PKG-INFO
new/dephell_specifier-0.2.1/PKG-INFO
--- old/dephell_specifier-0.1.5/PKG-INFO 1970-01-01 01:00:00.000000000
+0100
+++ new/dephell_specifier-0.2.1/PKG-INFO 1970-01-01 01:00:00.000000000
+0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
-Name: dephell_specifier
-Version: 0.1.5
+Name: dephell-specifier
+Version: 0.2.1
Summary: Work with version specifiers.
Author: orsinium
Requires-Python: >=3.5
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/dephell_specifier-0.1.5/dephell_specifier/constants.py
new/dephell_specifier-0.2.1/dephell_specifier/constants.py
--- old/dephell_specifier-0.1.5/dephell_specifier/constants.py 2019-03-20
14:09:31.000000000 +0100
+++ new/dephell_specifier-0.2.1/dephell_specifier/constants.py 2019-07-07
17:57:48.000000000 +0200
@@ -12,3 +12,5 @@
PYTHONS_POPULAR = ('3.5', '3.6', '3.7')
PYTHONS_UNRELEASED = ('3.8', '4.0')
PYTHONS = PYTHONS_POPULAR + PYTHONS_DEPRECATED + PYTHONS_UNRELEASED
+
+OPERATOR_SYMBOLS = '!><=[]()~^,'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/dephell_specifier-0.1.5/dephell_specifier/range_specifier.py
new/dephell_specifier-0.2.1/dephell_specifier/range_specifier.py
--- old/dephell_specifier-0.1.5/dephell_specifier/range_specifier.py
2019-04-21 09:26:43.000000000 +0200
+++ new/dephell_specifier-0.2.1/dephell_specifier/range_specifier.py
2019-07-07 17:57:48.000000000 +0200
@@ -1,13 +1,20 @@
+import re
+from typing import Set, List
+
# external
from packaging.specifiers import InvalidSpecifier
from packaging.version import LegacyVersion, parse, Version
# app
-from .constants import PYTHONS, JoinTypes
+from .constants import PYTHONS, JoinTypes, OPERATOR_SYMBOLS
from .git_specifier import GitSpecifier
from .specifier import Specifier
+REX_MAVEN_INTERVAL = re.compile(r'([\]\)])\,([\[\(])')
+REX_TRIM_OPERATOR =
re.compile(r'([{}])\s+'.format(re.escape(OPERATOR_SYMBOLS)))
+
+
class RangeSpecifier:
def __init__(self, spec=None):
@@ -16,30 +23,33 @@
self.join_type = JoinTypes.AND
return
+ # split `>2 || <1` on `>2` and `<1`
subspecs = str(spec).split('||')
if len(subspecs) > 1:
self._specs = {type(self)(subspec) for subspec in subspecs}
self.join_type = JoinTypes.OR
return
+ # split `(,1),(2,)` on `(,1)` and `(2,)`
+ subspecs = REX_MAVEN_INTERVAL.sub(r'\1|\2', str(spec)).split('|')
+ if len(subspecs) > 1:
+ self._specs = {type(self)(subspec) for subspec in subspecs}
+ self.join_type = JoinTypes.OR
+ return
+
self._specs = self._parse(spec)
self.join_type = JoinTypes.AND
return
- @staticmethod
- def _parse(spec) -> set:
- if not isinstance(spec, (list, tuple)):
- spec = str(spec).split(',')
+ @classmethod
+ def _parse(cls, spec) -> Set[Specifier]:
+ spec = cls._split_specifier(spec)
result = set()
for constr in spec:
- constr = constr.strip()
- if constr in ('', '*'):
+ constr = cls._clean_constraint(constr)
+ if not constr:
continue
- constr = constr.replace('.x', '.*')
- constr = constr.replace('.X', '.*')
-
- # https://docs.npmjs.com/misc/semver#advanced-range-syntax
-
+ # parse npm's version range (`1.2.3 - 2.3.0`)
if ' - ' in constr:
if '.*' in constr:
raise InvalidSpecifier('cannot mix ranges and starred
notation')
@@ -47,35 +57,116 @@
result.add(Specifier('>=' + left))
result.add(Specifier('<=' + right))
continue
-
+ # parse mixed stars and operators like `<=1.2.*`
+ if constr[0] in '<>' and '.*' in constr:
+ result.add(cls._parse_star_and_operator(constr))
+ continue
+ # parse npm-style semver specifiers
if constr[0] in '~^':
- version = parse(constr.lstrip('~^=').replace('.*', '.0'))
- if isinstance(version, LegacyVersion):
- raise InvalidSpecifier(constr)
- parts = version.release + (0, 0)
- parts = tuple(map(str, parts))
- left = '.'.join(parts[:3])
-
- if constr[:2] == '~=': # ~=1.2 := >=1.2 <2.0; ~=1.2.2 :=
>=1.2.2 <1.3.0
- if len(version.release) == 1:
- msg = '`~=` MUST NOT be used with a single segment
version: '
- raise ValueError(msg + str(version))
- #
https://www.python.org/dev/peps/pep-0440/#compatible-release
- right = '.'.join(map(str, version.release[:3][:-1])) + '.*'
- elif constr[0] == '^': # ^1.2.3 := >=1.2.3 <2.0.0
- #
https://www.npmjs.com/package/semver#caret-ranges-123-025-004
- right = '.'.join([parts[0], '*'])
- elif constr[0] == '~': # ~1.2.3 := >=1.2.3 <1.3.0
- #
https://www.npmjs.com/package/semver#tilde-ranges-123-12-1
- right = '.'.join([parts[0], parts[1], '*'])
-
- result.add(Specifier('>=' + left))
- result.add(Specifier('==' + right))
+ result.update(cls._parse_npm(constr))
continue
-
+ # parse maven-style interval specifiers
+ if constr[0] in '[(' or constr[-1] in ')]':
+ result.update(cls._parse_maven(constr))
+ continue
+ # parse classic python specifier
result.add(Specifier(constr))
return result
+ @staticmethod
+ def _split_specifier(spec) -> List[str]:
+ if isinstance(spec, (list, tuple)):
+ return list(spec)
+ spec = str(spec)
+
+ # pep-style comma-separated
+ if ',' in spec:
+ return spec.split(',')
+
+ # single specifier
+ spec = REX_TRIM_OPERATOR.sub(r'\1', spec)
+ if ' ' not in spec:
+ return [spec]
+
+ # npm-style space-separated
+ spec = spec.replace(' - ', '|').split()
+ spec = [constr.replace('|', ' - ') for constr in spec]
+ return spec
+
+ @staticmethod
+ def _clean_constraint(constr: str) -> str:
+ constr = constr.strip()
+ if constr in ('', '*'):
+ return ''
+ constr = constr.replace('.x', '.*')
+ constr = constr.replace('.X', '.*')
+ constr = constr.replace('.*.*', '.*')
+ if constr.lstrip(OPERATOR_SYMBOLS).lower() in ('x', '*'):
+ return ''
+
+ # add operator to constraint without operator
+ if ' - ' in constr:
+ return constr
+ if constr[0] not in OPERATOR_SYMBOLS and constr[-1] not in
OPERATOR_SYMBOLS:
+ constr = '==' + constr
+ # replace `=` operator by `==`
+ if len(constr) > 1 and constr[0] == '=' and constr[1] not in
OPERATOR_SYMBOLS:
+ constr = '==' + constr[1:]
+ return constr
+
+ @staticmethod
+ def _parse_star_and_operator(constr: str) -> Specifier:
+ if constr[:2] in {'<', '>', '>='}:
+ return Specifier(constr.replace('.*', '.0'))
+
+ version = parse(constr.lstrip(OPERATOR_SYMBOLS).rstrip('.*'))
+ parts = version.release[:-1] + (version.release[-1] + 1, )
+ return Specifier(constr[:2] + '.'.join(map(str, parts)))
+
+ @staticmethod
+ def _parse_maven(constr: str) -> Set[Specifier]:
+ if constr in '[]()':
+ return set()
+ if constr[0] == '[' and constr[-1] == ']':
+ return {Specifier('==' + constr[1:-1])}
+ if constr[0] == '[':
+ return {Specifier('>=' + constr[1:])}
+ if constr[0] == '(':
+ return {Specifier('>' + constr[1:])}
+ if constr[-1] == ']':
+ return {Specifier('<=' + constr[:-1])}
+ if constr[-1] == ')':
+ return {Specifier('<' + constr[:-1])}
+ raise ValueError('non maven constraint: {}'.format(constr))
+
+ @staticmethod
+ def _parse_npm(constr: str) -> Set[Specifier]:
+ version = parse(constr.lstrip(OPERATOR_SYMBOLS).replace('.*', '.0'))
+ if isinstance(version, LegacyVersion):
+ raise InvalidSpecifier(constr)
+ parts = version.release + (0, 0)
+ parts = tuple(map(str, parts))
+
+ if constr[:2] == '~=': # ~=1.2 := >=1.2 <2.0; ~=1.2.2 := >=1.2.2
<1.3.0
+ if len(version.release) == 1:
+ msg = '`~=` MUST NOT be used with a single segment version: '
+ raise ValueError(msg + str(version))
+ # https://www.python.org/dev/peps/pep-0440/#compatible-release
+ right = '.'.join(map(str, version.release[:3][:-1])) + '.*'
+ elif constr[0] == '^': # ^1.2.3 := >=1.2.3 <2.0.0
+ # https://www.npmjs.com/package/semver#caret-ranges-123-025-004
+ right = '.'.join([parts[0], '*'])
+ elif constr[0] == '~': # ~1.2.3 (or ~>1.2.3 for ruby) := >=1.2.3
<1.3.0
+ # https://www.npmjs.com/package/semver#tilde-ranges-123-12-1
+ # https://thoughtbot.com/blog/rubys-pessimistic-operator
+ if len(version.release) == 1:
+ right = '{}.*'.format(version.release[0])
+ else:
+ right = '.'.join([parts[0], parts[1], '*'])
+
+ left = '.'.join(parts[:3])
+ return {Specifier('>=' + left), Specifier('==' + right)}
+
def attach_time(self, releases) -> bool:
"""Attach time to all specifiers if possible
"""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/dephell_specifier-0.1.5/dephell_specifier/specifier.py
new/dephell_specifier-0.2.1/dephell_specifier/specifier.py
--- old/dephell_specifier-0.1.5/dephell_specifier/specifier.py 2019-03-31
17:08:02.000000000 +0200
+++ new/dephell_specifier-0.2.1/dephell_specifier/specifier.py 2019-07-07
17:57:48.000000000 +0200
@@ -1,9 +1,10 @@
# built-in
import operator
+from typing import Any, Callable, Optional, Union
# external
from packaging import specifiers
-from packaging.version import LegacyVersion, parse
+from packaging.version import LegacyVersion, Version, parse
# app
from .utils import cached_property
@@ -68,7 +69,7 @@
return True
return False
- def _check_version(self, version):
+ def _check_version(self, version) -> bool:
"""
https://www.python.org/dev/peps/pep-0440/
"""
@@ -100,16 +101,20 @@
return self._spec.operator
@property
- def operation(self):
+ def operation(self) -> Optional[Callable[[Any, Any], bool]]:
return OPERATIONS.get(self._spec.operator)
+ @property
+ def raw_version(self) -> str:
+ return self._spec.version
+
@cached_property
- def version(self):
- return parse(self._spec.version)
+ def version(self) -> Union[Version, LegacyVersion]:
+ return parse(self.raw_version)
# magic methods
- def __contains__(self, release):
+ def __contains__(self, release) -> bool:
# compare version
# check that this is Release without imports
if not hasattr(release, 'time'):
@@ -125,10 +130,10 @@
# compare release by version
return self._check_version(version=release.version)
- def __str__(self):
+ def __str__(self) -> str:
return str(self._spec)
- def __repr__(self):
+ def __repr__(self) -> str:
return '{name}({spec})'.format(
name=self.__class__.__name__,
spec=str(self._spec),
@@ -165,11 +170,11 @@
return NotImplemented
- def __lt__(self, other):
+ def __lt__(self, other) -> bool:
return self.version < other.version
- def __eq__(self, other):
+ def __eq__(self, other) -> bool:
return self.version == other.version and self.operator ==
other.operator
- def __hash__(self):
+ def __hash__(self) -> int:
return hash(self._spec)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/dephell_specifier-0.1.5/dephell_specifier.egg-info/PKG-INFO
new/dephell_specifier-0.2.1/dephell_specifier.egg-info/PKG-INFO
--- old/dephell_specifier-0.1.5/dephell_specifier.egg-info/PKG-INFO
1970-01-01 01:00:00.000000000 +0100
+++ new/dephell_specifier-0.2.1/dephell_specifier.egg-info/PKG-INFO
1970-01-01 01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
-Name: dephell_specifier
-Version: 0.1.5
+Name: dephell-specifier
+Version: 0.2.1
Summary: Work with version specifiers.
Author: orsinium
Requires-Python: >=3.5
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/dephell_specifier-0.1.5/dephell_specifier.egg-info/requires.txt
new/dephell_specifier-0.2.1/dephell_specifier.egg-info/requires.txt
--- old/dephell_specifier-0.1.5/dephell_specifier.egg-info/requires.txt
1970-01-01 01:00:00.000000000 +0100
+++ new/dephell_specifier-0.2.1/dephell_specifier.egg-info/requires.txt
1970-01-01 01:00:00.000000000 +0100
@@ -1 +1 @@
-packaging
\ No newline at end of file
+packaging>=17.1
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dephell_specifier-0.1.5/setup.py
new/dephell_specifier-0.2.1/setup.py
--- old/dephell_specifier-0.1.5/setup.py 2019-05-19 12:19:57.000000000
+0200
+++ new/dephell_specifier-0.2.1/setup.py 2019-07-07 19:54:08.000000000
+0200
@@ -13,17 +13,19 @@
readme = ''
here = os.path.abspath(os.path.dirname(__file__))
-with open(os.path.join(here, 'README.rst'), 'rb') as stream:
- readme = stream.read().decode('utf8')
+readme_path = os.path.join(here, 'README.rst')
+if os.path.exists(readme_path):
+ with open(readme_path, 'rb') as stream:
+ readme = stream.read().decode('utf8')
setup(
long_description=readme,
name='dephell_specifier',
- version='0.1.5',
+ version='0.2.1',
description='Work with version specifiers.',
python_requires='>=3.5',
author='orsinium',
packages=['dephell_specifier'],
package_data={},
- install_requires=['packaging'],
+ install_requires=['packaging>=17.1'],
)
Binary files
old/dephell_specifier-0.1.5/tests/__pycache__/__init__.cpython-37.pyc and
new/dephell_specifier-0.2.1/tests/__pycache__/__init__.cpython-37.pyc differ
Binary files
old/dephell_specifier-0.1.5/tests/__pycache__/test_range_npm.cpython-37-PYTEST.pyc
and
new/dephell_specifier-0.2.1/tests/__pycache__/test_range_npm.cpython-37-PYTEST.pyc
differ
Binary files
old/dephell_specifier-0.1.5/tests/__pycache__/test_range_specifier.cpython-37-PYTEST.pyc
and
new/dephell_specifier-0.2.1/tests/__pycache__/test_range_specifier.cpython-37-PYTEST.pyc
differ
Binary files
old/dephell_specifier-0.1.5/tests/__pycache__/test_specifier.cpython-37-PYTEST.pyc
and
new/dephell_specifier-0.2.1/tests/__pycache__/test_specifier.cpython-37-PYTEST.pyc
differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dephell_specifier-0.1.5/tests/test_range_npm.py
new/dephell_specifier-0.2.1/tests/test_range_npm.py
--- old/dephell_specifier-0.1.5/tests/test_range_npm.py 1970-01-01
01:00:00.000000000 +0100
+++ new/dephell_specifier-0.2.1/tests/test_range_npm.py 2019-07-07
17:20:10.000000000 +0200
@@ -0,0 +1,191 @@
+# external
+import pytest
+
+# project
+from dephell_specifier import RangeSpecifier
+
+
+# https://github.com/npm/node-semver/blob/master/test/index.js
[email protected]('spec, version', [
+ # simple version
+ ('1.0.0 - 2.0.0', '1.2.3'),
+ ('^1.2.3+build', '1.2.3'),
+ ('^1.2.3+build', '1.3.0'),
+ ('1.2.3-pre+asdf - 2.4.3-pre+asdf', '1.2.3'),
+ ('1.2.3-pre+asdf - 2.4.3-pre+asdf', '1.2.3-pre.2'),
+ ('1.2.3-pre+asdf - 2.4.3-pre+asdf', '2.4.3-alpha'),
+ ('1.2.3+asdf - 2.4.3+asdf', '1.2.3'),
+ ('1.0.0', '1.0.0'),
+
+ # open ranges
+ ('>=*', '0.2.4'),
+ ('', '1.0.0'),
+ ('>1.0.0', '1.1.0'),
+ ('<=2.0.0', '2.0.0'),
+ ('<=2.0.0', '1.9999.9999'),
+ ('<=2.0.0', '0.2.9'),
+ ('<2.0.0', '1.9999.9999'),
+ ('<2.0.0', '0.2.9'),
+ ('>= 1.0.0', '1.0.0'),
+ ('>= 1.0.0', '1.0.1'),
+ ('>= 1.0.0', '1.1.0'),
+ ('> 1.0.0', '1.0.1'),
+ ('> 1.0.0', '1.1.0'),
+ ('<= 2.0.0', '2.0.0'),
+ ('<= 2.0.0', '1.9999.9999'),
+ ('<= 2.0.0', '0.2.9'),
+ ('< 2.0.0', '1.9999.9999'),
+ ('<\t2.0.0', '0.2.9'),
+ ('>=0.1.97', '0.1.97'),
+
+ # or's
+ ('0.1.20 || 1.2.4', '1.2.4'),
+ ('>=0.2.3 || <0.0.1', '0.0.0'),
+ ('>=0.2.3 || <0.0.1', '0.2.3'),
+ ('>=0.2.3 || <0.0.1', '0.2.4'),
+ ('||', '1.3.4'),
+ ('1.2.x || 2.x', '2.1.3'),
+ ('1.2.x || 2.x', '1.2.3'),
+
+ # stars
+ ('2.x.x', '2.1.3'),
+ ('1.2.x', '1.2.3'),
+ ('x', '1.2.3'),
+ ('2.*.*', '2.1.3'),
+ ('1.2.*', '1.2.3'),
+ ('1.2.* || 2.*', '2.1.3'),
+ ('1.2.* || 2.*', '1.2.3'),
+ ('*', '1.2.3'),
+ # ('2', '2.1.2'),
+ # ('2.3', '2.3.1'),
+
+ ('~0.0.1', '0.0.1'),
+ ('~0.0.1', '0.0.2'),
+ ('~x', '0.0.9'),
+ ('~2', '2.0.9'),
+ ('~2.4', '2.4.0'),
+ ('~2.4', '2.4.5'),
+ ('~>3.2.1', '3.2.2'),
+ ('~1', '1.2.3'),
+ ('~>1', '1.2.3'),
+ ('~> 1', '1.2.3'),
+ ('~1.0', '1.0.2'),
+ ('~ 1.0', '1.0.2'),
+ ('~ 1.0.3', '1.0.12'),
+ ('~ 1.0.3alpha', '1.0.12'),
+
+ ('>=1', '1.0.0'),
+ ('>= 1', '1.0.0'),
+ ('<1.2', '1.1.1'),
+ ('< 1.2', '1.1.1'),
+ ('~v0.5.4-pre', '0.5.5'),
+ ('~v0.5.4-pre', '0.5.4'),
+ ('=0.7.x', '0.7.2'),
+ ('<=0.7.x', '0.7.2'),
+ ('>=0.7.x', '0.7.2'),
+ ('<=0.7.x', '0.6.2'),
+
+ ('~1.2.1 >=1.2.3', '1.2.3'),
+ ('~1.2.1 =1.2.3', '1.2.3'),
+ ('~1.2.1 1.2.3', '1.2.3'),
+ ('~1.2.1 >=1.2.3 1.2.3', '1.2.3'),
+ ('~1.2.1 1.2.3 >=1.2.3', '1.2.3'),
+ ('~1.2.1 1.2.3', '1.2.3'),
+ ('>=1.2.1 1.2.3', '1.2.3'),
+ ('1.2.3 >=1.2.1', '1.2.3'),
+ ('>=1.2.3 >=1.2.1', '1.2.3'),
+ ('>=1.2.1 >=1.2.3', '1.2.3'),
+
+ ('>=1.2', '1.2.8'),
+ ('^1.2.3', '1.8.1'),
+ ('^0.1.2', '0.1.2'),
+ ('^0.1', '0.1.2'),
+ ('^0.0.1', '0.0.1'),
+ ('^1.2', '1.4.2'),
+ ('^1.2 ^1', '1.4.2'),
+ # ('^1.2.3-alpha', '1.2.3-pre'),
+ # ('^1.2.0-alpha', '1.2.0-pre'),
+ # ('^0.0.1-alpha', '0.0.1-beta'),
+ # ('^0.0.1-alpha', '0.0.1'),
+ # ('^0.1.1-alpha', '0.1.1-beta'),
+
+ # ('^x', '1.2.3'),
+ # ('x - 1.0.0', '0.9.7'),
+ # ('x - 1.x', '0.9.7'),
+ # ('1.0.0 - x', '1.9.7'),
+ # ('1.x - x', '1.9.7'),
+ # ('<=7.x', '7.9.9'),
+])
+def test_included(spec, version):
+ assert version in RangeSpecifier(spec)
+
+
[email protected]('spec, version', [
+ ['1.0.0 - 2.0.0', '2.2.3'],
+ # ['1.2.3+asdf - 2.4.3+asdf', '1.2.3-pre.2'],
+ # ['1.2.3+asdf - 2.4.3+asdf', '2.4.3-alpha'],
+ ['^1.2.3+build', '2.0.0'],
+ ['^1.2.3+build', '1.2.0'],
+ ['^1.2.3', '1.2.3-pre'],
+ ['^1.2', '1.2.0-pre'],
+ # ['>1.2', '1.3.0-beta'],
+ # ['<=1.2.3', '1.2.3-beta'],
+ ['^1.2.3', '1.2.3-beta'],
+ ['=0.7.x', '0.7.0-asdf'],
+ ['>=0.7.x', '0.7.0-asdf'],
+
+ ['1.0.0', '1.0.1'],
+ ['>=1.0.0', '0.0.0'],
+ ['>=1.0.0', '0.0.1'],
+ ['>=1.0.0', '0.1.0'],
+ ['>1.0.0', '0.0.1'],
+ ['>1.0.0', '0.1.0'],
+ ['<=2.0.0', '3.0.0'],
+ ['<=2.0.0', '2.9999.9999'],
+ ['<=2.0.0', '2.2.9'],
+ ['<2.0.0', '2.9999.9999'],
+ ['<2.0.0', '2.2.9'],
+ ['>=0.1.97', '0.1.93'],
+ ['0.1.20 || 1.2.4', '1.2.3'],
+ ['>=0.2.3 || <0.0.1', '0.0.3'],
+ ['>=0.2.3 || <0.0.1', '0.2.2'],
+
+ ['2.x.x', '3.1.3'],
+ ['1.2.x', '1.3.3'],
+ ['1.2.x || 2.x', '3.1.3'],
+ ['1.2.x || 2.x', '1.1.3'],
+ ['2.*.*', '1.1.3'],
+ ['2.*.*', '3.1.3'],
+ ['1.2.*', '1.3.3'],
+ ['1.2.* || 2.*', '3.1.3'],
+ ['1.2.* || 2.*', '1.1.3'],
+ ['2', '1.1.2'],
+ ['2.3', '2.4.1'],
+
+ ['~0.0.1', '0.1.0-alpha'],
+ ['~0.0.1', '0.1.0'],
+ ['~2.4', '2.5.0'],
+ ['~2.4', '2.3.9'],
+ ['~>3.2.1', '3.3.2'],
+ ['~>3.2.1', '3.2.0'],
+ ['~1', '0.2.3'],
+ ['~>1', '2.2.3'],
+ ['~1.0', '1.1.0'],
+ ['<1', '1.0.0'],
+ ['>=1.2', '1.1.1'],
+ ['~v0.5.4-beta', '0.5.4-alpha'],
+ ['=0.7.x', '0.8.2'],
+ ['>=0.7.x', '0.6.2'],
+ # ['<0.7.x', '0.7.2'],
+ ['<1.2.3', '1.2.3-beta'],
+ ['=1.2.3', '1.2.3-beta'],
+ # ['>1.2', '1.2.8'],
+ # ['^0.0.1', '0.0.2-alpha'],
+ # ['^0.0.1', '0.0.2'],
+ ['^1.2.3', '2.0.0-alpha'],
+ ['^1.2.3', '1.2.2'],
+ ['^1.2', '1.1.9'],
+
+])
+def test_excluded(spec, version):
+ assert version not in RangeSpecifier(spec)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/dephell_specifier-0.1.5/tests/test_range_specifier.py
new/dephell_specifier-0.2.1/tests/test_range_specifier.py
--- old/dephell_specifier-0.1.5/tests/test_range_specifier.py 1970-01-01
01:00:00.000000000 +0100
+++ new/dephell_specifier-0.2.1/tests/test_range_specifier.py 2019-07-07
17:57:48.000000000 +0200
@@ -0,0 +1,289 @@
+# external
+import pytest
+
+# project
+from dephell_specifier import RangeSpecifier
+
+
[email protected]('operator, mask', [
+ ('<', [1, 0, 0]),
+ ('<=', [1, 1, 0]),
+ ('==', [0, 1, 0]),
+ ('===', [0, 1, 0]),
+ ('>=', [0, 1, 1]),
+ ('>', [0, 0, 1]),
+ ('!=', [1, 0, 1]),
+])
+def test_simple(operator, mask):
+ versions = ('1.2.3', '1.3.2', '1.4.1')
+ spec = RangeSpecifier(operator + '1.3.2')
+ for version, ok in zip(versions, mask):
+ assert (version in spec) == ok
+
+
[email protected]('version, spec, ok', [
+ ('2.7', '<=3.4', True),
+ ('2.7.1', '<=3.4', True),
+ ('2.7.1rc1', '<=3.4', True),
+ ('2.7.15', '<=3.4', True),
+ ('2.7.15rc1', '<=3.4', True),
+
+ ('2.7', '>=3.4', False),
+ ('2.7.1', '>=3.4', False),
+ ('2.7.1rc1', '>=3.4', False),
+ ('2.7.15', '>=3.4', False),
+ ('2.7.15rc1', '>=3.4', False),
+])
+def test_cases(version, spec, ok):
+ assert (version in RangeSpecifier(spec)) is ok
+
+
[email protected]('op1, op2, mask', [
+ # left
+ ('<', '<', [1, 0, 0, 0, 0]),
+ ('<', '<=', [1, 0, 0, 0, 0]),
+ ('<=', '<', [1, 1, 0, 0, 0]),
+ ('<=', '<=', [1, 1, 0, 0, 0]),
+ ('==', '<', [0, 1, 0, 0, 0]),
+ ('==', '<=', [0, 1, 0, 0, 0]),
+
+ # center
+ ('>=', '<', [0, 1, 1, 0, 0]),
+ ('>', '<', [0, 0, 1, 0, 0]),
+ ('>', '<=', [0, 0, 1, 1, 0]),
+ ('>=', '<=', [0, 1, 1, 1, 0]),
+
+ # right
+ ('>=', '==', [0, 0, 0, 1, 0]),
+ ('>', '==', [0, 0, 0, 1, 0]),
+ ('>', '>=', [0, 0, 0, 1, 1]),
+ ('>=', '>=', [0, 0, 0, 1, 1]),
+ ('>=', '>', [0, 0, 0, 0, 1]),
+ ('>', '>', [0, 0, 0, 0, 1]),
+
+ # incompat
+ ('<=', '>=', [0, 0, 0, 0, 0]),
+ ('<', '>=', [0, 0, 0, 0, 0]),
+ ('<=', '>', [0, 0, 0, 0, 0]),
+ ('<', '>', [0, 0, 0, 0, 0]),
+ ('==', '==', [0, 0, 0, 0, 0]),
+ ('==', '>', [0, 0, 0, 0, 0]),
+ ('==', '>=', [0, 0, 0, 0, 0]),
+ ('<', '==', [0, 0, 0, 0, 0]),
+ ('<=', '==', [0, 0, 0, 0, 0]),
+])
+def test_range(op1, op2, mask):
+ versions = ('1.2.3', '1.3.2', '1.4.1', '1.5.1', '1.6.1')
+ spec = RangeSpecifier(op1 + '1.3.2,' + op2 + '1.5.1')
+ for version, ok in zip(versions, mask):
+ assert (version in spec) == ok
+
+
+# ^1.2.3 := >=1.2.3 <2.0.0
[email protected]('specv, version, ok', [
+ ('1.2.3', '1.2.3', True),
+ ('1.2.3', '1.2.4', True),
+ ('1.2.3', '1.3.1', True),
+ ('1.2.3', '1.3.0', True),
+
+ ('1.2.3', '1.2.2', False),
+ ('1.2.3', '1.1.9', False),
+ ('1.2.3', '1.0.0', False),
+ ('1.2.3', '2.0.0', False),
+ ('1.2.3', '3.0.0', False),
+
+ ('1.2.0', '1.2.0', True),
+ ('1.2.0', '1.2.1', True),
+ ('1.2.0', '1.3.2', True),
+
+ ('1.2.0', '1.1.0', False),
+ ('1.2.0', '0.9.0', False),
+ ('1.2.0', '2.0.0', False),
+
+ ('1.0.0', '1.0.0', True),
+ ('1.0.0', '1.0.1', True),
+ ('1.0.0', '1.1.0', True),
+ ('1.0.0', '2.0.0', False),
+ ('1.0.0', '0.9.0', False),
+
+ ('1.0', '1.0.0', True),
+ ('1.0', '1.0.1', True),
+ ('1.0', '1.1.0', True),
+ ('1.0', '2.0.0', False),
+ ('1.0', '0.9.0', False),
+
+ ('1', '1.0.0', True),
+ ('1', '1.0.1', True),
+ ('1', '1.1.0', True),
+ ('1', '2.0.0', False),
+ ('1', '0.9.0', False),
+])
+def test_caret(specv, version, ok):
+ spec = RangeSpecifier('^' + specv)
+ assert (version in spec) is ok
+
+
+# ~1.2.3 := >=1.2.3 <1.3.0
[email protected]('specv, version, ok', [
+ ('1.2.3', '1.2.3', True),
+ ('1.2.3', '1.2.4', True),
+
+ ('1.2.3', '1.3.1', False),
+ ('1.2.3', '1.3.0', False),
+ ('1.2.3', '1.2.2', False),
+ ('1.2.3', '1.1.9', False),
+ ('1.2.3', '1.0.0', False),
+ ('1.2.3', '2.0.0', False),
+ ('1.2.3', '3.0.0', False),
+
+ ('1.2.0', '1.2.0', True),
+ ('1.2.0', '1.2.1', True),
+
+ ('1.2.0', '1.3.2', False),
+ ('1.2.0', '1.1.0', False),
+ ('1.2.0', '0.9.0', False),
+ ('1.2.0', '2.0.0', False),
+
+ ('1.0.0', '1.0.0', True),
+ ('1.0.0', '1.0.1', True),
+ ('1.0.0', '1.1.0', False),
+ ('1.0.0', '2.0.0', False),
+ ('1.0.0', '0.9.0', False),
+
+ ('1.0', '1.0.0', True),
+ ('1.0', '1.0.1', True),
+ ('1.0', '1.1.0', False),
+ ('1.0', '2.0.0', False),
+ ('1.0', '0.9.0', False),
+
+ ('1', '1.0.0', True),
+ ('1', '1.0.1', True),
+ ('1', '1.1.0', True),
+ ('1', '2.0.0', False),
+ ('1', '0.9.0', False),
+])
+def test_tilda(specv, version, ok):
+ spec = RangeSpecifier('~' + specv)
+ assert (version in spec) is ok
+
+ # Ruby's pessimistic operator (~>) has the same behavior
+ spec = RangeSpecifier('~>' + specv)
+ assert (version in spec) is ok
+
+
+# ~=1.2.3 := >=1.2.3 <1.3.0
+# ~=1.2 := >=1.2 <2.0
[email protected]('specv, version, ok', [
+ ('1.2.3', '1.2.3', True),
+ ('1.2.3', '1.2.4', True),
+
+ ('1.2.3', '1.3.1', False),
+ ('1.2.3', '1.3.0', False),
+ ('1.2.3', '1.2.2', False),
+ ('1.2.3', '1.1.9', False),
+ ('1.2.3', '1.0.0', False),
+ ('1.2.3', '2.0.0', False),
+ ('1.2.3', '3.0.0', False),
+
+ ('1.2.0', '1.2.0', True),
+ ('1.2.0', '1.2.1', True),
+
+ ('1.2.0', '1.3.2', False),
+ ('1.2.0', '1.1.0', False),
+ ('1.2.0', '0.9.0', False),
+ ('1.2.0', '2.0.0', False),
+
+ ('1.0.0', '1.0.0', True),
+ ('1.0.0', '1.0.1', True),
+ ('1.0.0', '1.1.0', False),
+ ('1.0.0', '2.0.0', False),
+ ('1.0.0', '0.9.0', False),
+
+ ('1.0', '1.0.0', True),
+ ('1.0', '1.0.1', True),
+ ('1.0', '1.1.0', True),
+ ('1.0', '2.0.0', False),
+ ('1.0', '0.9.0', False),
+])
+def test_compat(specv, version, ok):
+ spec = RangeSpecifier('~=' + specv)
+ assert (version in spec) is ok
+
+
[email protected]('version, ok', [
+ ('2.7', True),
+ ('2.7.1', True),
+ ('2.7.6', True),
+
+ ('2.8', False),
+ ('2.8.0', False),
+ ('3.0', False),
+
+ ('3.2', True),
+ ('3.2.1', True),
+ ('3.3', True),
+ ('3.7', True),
+
+ ('4.0', False),
+])
+def test_or(version, ok):
+ spec = RangeSpecifier('~2.7 || ^3.2')
+ assert (version in spec) is ok
+
+
[email protected]('spec, marker', [
+ ('>=2.7', 'm >= "2.7"'),
+ ('>=2.7,<3.4', 'm >= "2.7" and m < "3.4"'),
+ ('>=2.7 || >=3.4', 'm >= "2.7" or m >= "3.4"'),
+])
+def test_to_marker(spec, marker):
+ assert RangeSpecifier(spec).to_marker('m') == marker
+
+
[email protected]('left, right, expected', [
+ ('>=2.7', '<=3.4', '>=2.7,<=3.4'),
+ ('>=2.7', '>=3.4,<=3.7', '>=2.7,>=3.4,<=3.7'),
+ ('==2.7 || >=3.4', '<=3.7', '==2.7,<=3.7 || >=3.4,<=3.7'),
+ ('==2.7 || >=3.4', '!=3.6,<=3.7', '==2.7,!=3.6,,<=3.7 ||
>=3.4,!=3.6,,<=3.7'),
+ ('<=3.7', '==2.7 || >=3.4', '==2.7,<=3.7 || >=3.4,<=3.7'),
+ ('<=3.7 || !=3.6', '==2.7 || >=3.4', '<=3.7,==2.7 || <=3.7,>=3.4 ||
!=3.6,==2.7 || !=3.6,>=3.4'),
+])
+def test_merging(left, right, expected):
+ spec = RangeSpecifier(left) + RangeSpecifier(right)
+ assert spec == RangeSpecifier(expected)
+
+
[email protected]('spec, expected', [
+ ('>=2.7', '>=2.7'),
+ ('>=2.7,<3.4', '>=2.7,<3.4'),
+ ('==2.7.* || >=3.4', '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*'),
+ ('==2.7.* || >=3.4,<3.8', '>=2.7,<3.8,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*'),
+])
+def test_peppify_python(spec, expected):
+ new = RangeSpecifier(spec).peppify()
+ assert str(new) == str(RangeSpecifier(expected))
+
+
[email protected]('spec, expected', [
+ ('[1.0]', '==1.0'),
+
+ # closed intervals
+ ('[1.2,1.3]', '>=1.2,<=1.3'),
+ ('[1.0,2.0)', '>=1.0,<2.0'),
+ ('(1.0,2.0]', '>1.0,<=2.0'),
+ ('(1.0,2.0)', '>1.0,<2.0'),
+
+ # open intervals
+ ('[1.5,)', '>=1.5'),
+ ('(,1.5]', '<=1.5'),
+ ('(1.5,)', '>1.5'),
+ ('(,1.5)', '<1.5'),
+
+ # or-chaining of intervals
+ ('(,1.0],[1.2,)', '<=1.0 || >=1.2'),
+ ('(,1.0),[1.2,)', '<1.0 || >=1.2'),
+ ('(,1.0],(1.2,)', '<=1.0 || >1.2'),
+ ('(,1.0),(1.2,)', '<1.0 || >1.2'),
+])
+def test_intervals(spec, expected):
+ assert str(RangeSpecifier(spec)) == str(RangeSpecifier(expected))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dephell_specifier-0.1.5/tests/test_specifier.py
new/dephell_specifier-0.2.1/tests/test_specifier.py
--- old/dephell_specifier-0.1.5/tests/test_specifier.py 1970-01-01
01:00:00.000000000 +0100
+++ new/dephell_specifier-0.2.1/tests/test_specifier.py 2019-03-20
14:12:54.000000000 +0100
@@ -0,0 +1,59 @@
+import pytest
+from dephell_specifier import Specifier
+
+
[email protected]('left, right, result', [
+ # left
+ ('<1.2', '<1.4', '<1.2'),
+ ('<1.2', '<=1.4', '<1.2'),
+ ('<=1.2', '<1.4', '<=1.2'),
+ ('<=1.2', '<=1.4', '<=1.2'),
+
+ # swap is not important
+ ('<1.4', '<1.2', '<1.2'),
+ ('<=1.4', '<1.2', '<1.2'),
+ ('<1.4', '<=1.2', '<=1.2'),
+ ('<=1.4', '<=1.2', '<=1.2'),
+
+ # right
+ ('>1.2', '>1.4', '>1.4'),
+ ('>=1.2', '>1.4', '>1.4'),
+ ('>1.2', '>=1.4', '>=1.4'),
+ ('>=1.2', '>=1.4', '>=1.4'),
+
+ # equal
+ ('==1.2', '<1.4', '==1.2'),
+ ('==1.2', '<=1.4', '==1.2'),
+ ('>=1.2', '==1.4', '==1.4'),
+ ('>1.2', '==1.4', '==1.4'),
+
+ # common version
+ ('==1.2', '==1.2', '==1.2'),
+ ('<=1.2', '==1.2', '==1.2'),
+ ('>=1.2', '==1.2', '==1.2'),
+ ('<=1.2', '>=1.2', '==1.2'),
+
+ # empty interval
+ ('<=1.2', '>=1.4', None),
+ ('<=1.2', '>1.4', None),
+ ('<1.2', '>=1.4', None),
+ ('==1.2', '>=1.4', None),
+ ('==1.2', '>1.4', None),
+ ('<=1.2', '==1.4', None),
+ ('<1.2', '==1.4', None),
+
+ # closed interval
+ ('>=1.2', '<=1.4', None),
+ ('>1.2', '<1.4', None),
+ ('>=1.2', '<1.4', None),
+ ('>1.2', '<=1.4', None),
+])
+def test_merge(left, right, result):
+ ls = Specifier(left)
+ rs = Specifier(right)
+ if result is None:
+ with pytest.raises(TypeError):
+ ls + rs
+ else:
+ merged = ls + rs
+ assert str(merged) == result