Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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: 3 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
# devpi-plumber runs devpi-init, which still uses pkg_resources; use setuptools <82 in CI only
# so integration tests pass
python -m pip install 'setuptools<82'
python -m pip install -r requirements.txt
Comment on lines +25 to 28
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've done manual testing on this PR, but unfortunately I can't get coverage of version 82 in these tests due to this issue.

python -m pip install --no-deps -e .
if [ "${{ matrix.python-version }}" != "3.13" ]; then # workaround for TheKevJames/coveralls-python#523
Expand Down
8 changes: 4 additions & 4 deletions devpi_builder/requirements.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"""

import pip_requirements_parser
import pkg_resources
from packaging.utils import canonicalize_name, canonicalize_version


def _extract_project_version(requirement):
Expand Down Expand Up @@ -61,10 +61,10 @@ def matched_by_list(package, version, requirements):
:param requirements: A list of requirements as read by read_raw()
:return: True if the package can be used to fulfil on of the requirements in the file, False otherwise
"""
version = pkg_resources.safe_version('{}'.format(version))
package = pkg_resources.safe_name(package)
version = canonicalize_version('{}'.format(version))
package = canonicalize_name(package)
matches = (
package.lower() == pkg_resources.safe_name(requirement.name) and (requirement.specifier.contains(version) if requirement.specifier else 1)
package == canonicalize_name(requirement.name) and (requirement.specifier.contains(version) if requirement.specifier else True)
for requirement in requirements
)
return any(matches)
26 changes: 19 additions & 7 deletions devpi_builder/wheeler.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,20 @@
import tempfile

from packaging import tags
from pkg_resources import Distribution, Requirement
from packaging.requirements import Requirement
from packaging.utils import canonicalize_name

# Support both wheel-filename 1.x (Python 3.9 + wheel-inspect 1.7) and 2.x (Python 3.10+ + wheel-inspect 1.8)
try:
from wheel_filename import ParseError as _WheelParseError
from wheel_filename import WheelFilename

def _parse_wheel_filename(filename):
return WheelFilename.parse(filename)
except ImportError:
from wheel_filename import InvalidFilenameError as _WheelParseError
from wheel_filename import parse_wheel_filename as _parse_wheel_filename

from wheel_filename import InvalidFilenameError, parse_wheel_filename
from wheel_inspect import inspect_wheel
from wheel_inspect.classes import WheelFile

Expand Down Expand Up @@ -52,13 +63,14 @@ def _matches_requirement(self, requirement, wheels):
:param requirement:str : The requirement to satisfy
:param wheels: List of wheels to search.
"""
req = Requirement.parse(requirement)
req = Requirement(requirement)
req_name = canonicalize_name(req.name)

matching = []
for wheel in wheels:
w = wheel.parsed_filename
dist = Distribution(project_name=self._standardize_package_name(w.project), version=w.version)
if dist in req:
name = canonicalize_name(self._standardize_package_name(w.project))
if name == req_name and req.specifier.contains(str(w.version)):
matching.append(wheel.path)
return matching

Expand Down Expand Up @@ -120,12 +132,12 @@ def is_compatible(package):
Compatibility is based on https://www.python.org/dev/peps/pep-0425/
"""
try:
w = parse_wheel_filename(package)
w = _parse_wheel_filename(package)
for systag in tags.sys_tags():
for tag in w.tag_triples():
if systag in tags.parse_tag(tag):
return True
except InvalidFilenameError:
except _WheelParseError:
return False


Expand Down