|
15 | 15 | from subprocess import list2cmdline
|
16 | 16 | from threading import Thread
|
17 | 17 |
|
18 |
| -import pkg_resources |
| 18 | +import importlib_metadata |
19 | 19 | import pluggy
|
20 | 20 | import py
|
21 | 21 | import toml
|
| 22 | +from packaging import requirements |
| 23 | +from packaging.utils import canonicalize_name |
22 | 24 |
|
23 | 25 | import tox
|
24 | 26 | from tox.constants import INFO
|
| 27 | +from tox.exception import MissingDependency |
25 | 28 | from tox.interpreters import Interpreters, NoInterpreterInfo
|
26 | 29 | from tox.reporter import (
|
27 | 30 | REPORTER_TIMESTAMP_ON_ENV,
|
@@ -192,10 +195,10 @@ def _cut_off_dep_comment(name):
|
192 | 195 | @classmethod
|
193 | 196 | def _is_same_dep(cls, dep1, dep2):
|
194 | 197 | """Definitions are the same if they refer to the same package, even if versions differ."""
|
195 |
| - dep1_name = pkg_resources.Requirement.parse(dep1).project_name |
| 198 | + dep1_name = canonicalize_name(requirements.Requirement(dep1).name) |
196 | 199 | try:
|
197 |
| - dep2_name = pkg_resources.Requirement.parse(dep2).project_name |
198 |
| - except pkg_resources.RequirementParseError: |
| 200 | + dep2_name = canonicalize_name(requirements.Requirement(dep2).name) |
| 201 | + except requirements.InvalidRequirement: |
199 | 202 | # we couldn't parse a version, probably a URL
|
200 | 203 | return False
|
201 | 204 | return dep1_name == dep2_name
|
@@ -1133,17 +1136,20 @@ def ensure_requires_satisfied(config, requires, min_version):
|
1133 | 1136 | for require in requires + [min_version]:
|
1134 | 1137 | # noinspection PyBroadException
|
1135 | 1138 | try:
|
1136 |
| - package = pkg_resources.Requirement.parse(require) |
1137 |
| - if package.project_name not in exists: |
| 1139 | + package = requirements.Requirement(require) |
| 1140 | + package_name = canonicalize_name(package.name) |
| 1141 | + if package_name not in exists: |
1138 | 1142 | deps.append(DepConfig(require, None))
|
1139 |
| - exists.add(package.project_name) |
1140 |
| - pkg_resources.get_distribution(package) |
1141 |
| - except pkg_resources.RequirementParseError as exception: |
| 1143 | + exists.add(package_name) |
| 1144 | + dist = importlib_metadata.distribution(package_name) |
| 1145 | + if not package.specifier.contains(dist.version, prereleases=True): |
| 1146 | + raise MissingDependency(package) |
| 1147 | + except requirements.InvalidRequirement as exception: |
1142 | 1148 | failed_to_parse = True
|
1143 | 1149 | error("failed to parse {!r}".format(exception))
|
1144 | 1150 | except Exception as exception:
|
1145 | 1151 | verbosity1("could not satisfy requires {!r}".format(exception))
|
1146 |
| - missing_requirements.append(str(pkg_resources.Requirement(require))) |
| 1152 | + missing_requirements.append(str(requirements.Requirement(require))) |
1147 | 1153 | if failed_to_parse:
|
1148 | 1154 | raise tox.exception.BadRequirement()
|
1149 | 1155 | config.run_provision = bool(len(missing_requirements))
|
|
0 commit comments