Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace the PEP-386 parser for the more general PEP-440 #860

Merged
merged 4 commits into from
Jun 29, 2018
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,3 @@ comment:
layout: "header, diff"
behavior: default
require_changes: no

ignore:
- "src/tox/_verlib.py" # vendored in and not internally tested
1 change: 1 addition & 0 deletions changelog/860.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Replace the internal version parsing logic from the not well tested `PEP-386 <https://www.python.org/dev/peps/pep-0386/>`_ parser for the more general `PEP-440 <https://www.python.org/dev/peps/pep-0440/>`_. `packaging >= 17.1 <https://pypi.org/project/packaging/>`_ is now an install dependency by :user:`gaborbernat`.
8 changes: 7 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,13 @@ def main():
},
python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*",
setup_requires=["setuptools_scm"],
install_requires=["py>=1.4.17", "pluggy>=0.3.0,<1.0", "six", "virtualenv>=1.11.2"],
install_requires=[
"packaging >= 17.1",
"pluggy >= 0.3.0, <1",
"py >= 1.4.17, <2",
"six >= 1.0.0, <2",
"virtualenv >= 1.11.2",
],
extras_require={
"testing": [
"pytest >= 3.0.0",
Expand Down
230 changes: 0 additions & 230 deletions src/tox/_verlib.py

This file was deleted.

12 changes: 7 additions & 5 deletions src/tox/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
import pkg_resources
import pluggy
import py
from packaging.version import parse

import tox
from tox._verlib import NormalizedVersion
from tox.interpreters import Interpreters

hookimpl = tox.hookimpl
Expand Down Expand Up @@ -898,11 +898,13 @@ def __init__(self, config, inipath):
# prevent parsing of tox.ini this must be the first thing checked.
config.minversion = reader.getstring("minversion", None)
if config.minversion:
minversion = NormalizedVersion(self.config.minversion)
toxversion = NormalizedVersion(tox.__version__)
if toxversion < minversion:
tox_version = parse(tox.__version__)
config_min_version = parse(self.config.minversion)
if config_min_version > tox_version:
raise tox.exception.MinVersionError(
"tox version is {}, required is at least {}".format(toxversion, minversion)
"tox version is {}, required is at least {}".format(
tox.__version__, self.config.minversion
)
)
if config.option.workdir is None:
config.toxworkdir = reader.getpath("toxworkdir", "{toxinidir}/.tox")
Expand Down
51 changes: 26 additions & 25 deletions src/tox/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
import time

import py
from packaging.version import InvalidVersion, Version

import tox
from tox._verlib import IrrationalVersionError, NormalizedVersion
from tox.config import parseconfig
from tox.result import ResultLog
from tox.venv import VirtualEnv
Expand Down Expand Up @@ -575,7 +575,7 @@ def get_installpkg_path(self):
path = self.config.option.installpkg
if not path:
path = self.config.sdistsrc
path = self._resolve_pkg(path)
path = self._resolve_package(path)
self.report.info("using package {!r}, skipping 'sdist' activity ".format(str(path)))
else:
try:
Expand Down Expand Up @@ -730,50 +730,51 @@ def info_versions(self):
versions.append("virtualenv-{}".format(out.decode("UTF-8").strip()))
self.report.keyvalue("tool-versions:", " ".join(versions))

def _resolve_pkg(self, pkgspec):
def _resolve_package(self, package_spec):
try:
return self._spec2pkg[pkgspec]
return self._spec2pkg[package_spec]
except KeyError:
self._spec2pkg[pkgspec] = x = self._resolvepkg(pkgspec)
self._spec2pkg[package_spec] = x = self._get_latest_version_of_package(package_spec)
return x

def _resolvepkg(self, pkgspec):
if not os.path.isabs(str(pkgspec)):
return pkgspec
p = py.path.local(pkgspec)
def _get_latest_version_of_package(self, package_spec):
if not os.path.isabs(str(package_spec)):
return package_spec
p = py.path.local(package_spec)
if p.check():
return p
if not p.dirpath().check(dir=1):
raise tox.exception.MissingDirectory(p.dirpath())
self.report.info("determining {}".format(p))
candidates = p.dirpath().listdir(p.basename)
if len(candidates) == 0:
raise tox.exception.MissingDependency(pkgspec)
raise tox.exception.MissingDependency(package_spec)
if len(candidates) > 1:
items = []
for x in candidates:
ver = getversion(x.basename)
if ver is not None:
items.append((ver, x))
version_package = []
for filename in candidates:
version = get_version_from_filename(filename.basename)
if version is not None:
version_package.append((version, filename))
else:
self.report.warning("could not determine version of: {}".format(str(x)))
items.sort()
if not items:
raise tox.exception.MissingDependency(pkgspec)
return items[-1][1]
self.report.warning("could not determine version of: {}".format(str(filename)))
if not version_package:
raise tox.exception.MissingDependency(package_spec)
version_package.sort()
_, package_with_largest_version = version_package[-1]
return package_with_largest_version
else:
return candidates[0]


_rex_getversion = re.compile(r"[\w_\-\+\.]+-(.*)\.(zip|tar\.gz)")
_REGEX_FILE_NAME_WITH_VERSION = re.compile(r"[\w_\-\+\.]+-(.*)\.(zip|tar\.gz)")


def getversion(basename):
m = _rex_getversion.match(basename)
def get_version_from_filename(basename):
m = _REGEX_FILE_NAME_WITH_VERSION.match(basename)
if m is None:
return None
version = m.group(1)
try:
return NormalizedVersion(version)
except IrrationalVersionError:
return Version(version)
except InvalidVersion:
return None
Loading