Use importlib_metadata rather than pip freeze
This commit is contained in:
parent
23901d999a
commit
d262d909f5
@ -24,7 +24,6 @@ fi
|
||||
%{-e:%{expand:%global toxenv %{-e*}}}
|
||||
echo 'python3-devel'
|
||||
echo 'python3dist(packaging)'
|
||||
echo 'python3dist(pip) >= 19'
|
||||
echo 'python3dist(pytoml)'
|
||||
# setuptools assumes no pre-existing dist-info
|
||||
rm -rfv *.dist-info/
|
||||
|
@ -21,17 +21,28 @@ URL: https://src.fedoraproject.org/rpms/pyproject-rpm-macros
|
||||
|
||||
BuildArch: noarch
|
||||
|
||||
# We keep them here for now to avoid one loop of %%generate_buildrequires
|
||||
# And to allow the other macros without %%pyproject_buildrequires (e.g. on Fedora 30)
|
||||
# But those are also always in the output of %%generate_buildrequires
|
||||
# in order to be removable in the future
|
||||
Requires: python3-pip >= 19
|
||||
Requires: python3-devel
|
||||
|
||||
# We keep these here for now to avoid one loop of %%generate_buildrequires
|
||||
# But those are also always in the output of %%generate_buildrequires
|
||||
# in order to be removable in the future
|
||||
Requires: python3dist(packaging)
|
||||
Requires: python3dist(pytoml)
|
||||
|
||||
# This is not output from %%generate_buildrequires to work around:
|
||||
# https://github.com/rpm-software-management/mock/issues/336
|
||||
Requires: (python3dist(importlib-metadata) if python3 < 3.8)
|
||||
|
||||
%if %{with tests}
|
||||
BuildRequires: python3dist(pytest)
|
||||
BuildRequires: python3dist(pyyaml)
|
||||
BuildRequires: python3dist(packaging)
|
||||
%if 0%{fedora} < 32
|
||||
# The %%if should not be needed, it works around:
|
||||
# https://github.com/rpm-software-management/mock/issues/336
|
||||
BuildRequires: (python3dist(importlib-metadata) if python3 < 3.8)
|
||||
%endif
|
||||
BuildRequires: python3dist(pytoml)
|
||||
BuildRequires: python3dist(pip)
|
||||
BuildRequires: python3dist(setuptools)
|
||||
|
@ -26,7 +26,10 @@ try:
|
||||
from packaging.requirements import Requirement, InvalidRequirement
|
||||
from packaging.version import Version
|
||||
from packaging.utils import canonicalize_name, canonicalize_version
|
||||
import pip
|
||||
try:
|
||||
import importlib.metadata as importlib_metadata
|
||||
except ImportError:
|
||||
import importlib_metadata
|
||||
except ImportError as e:
|
||||
print_err('Import error:', e)
|
||||
# already echoed by the %pyproject_buildrequires macro
|
||||
@ -44,14 +47,8 @@ def hook_call():
|
||||
|
||||
class Requirements:
|
||||
"""Requirement printer"""
|
||||
def __init__(self, freeze_output, extras=''):
|
||||
self.installed_packages = {}
|
||||
for line in freeze_output.splitlines():
|
||||
line = line.strip()
|
||||
if line.startswith('#'):
|
||||
continue
|
||||
name, version = line.split('==')
|
||||
self.installed_packages[name.strip()] = Version(version)
|
||||
def __init__(self, get_installed_version, extras=''):
|
||||
self.get_installed_version = get_installed_version
|
||||
|
||||
self.marker_env = {'extra': extras}
|
||||
|
||||
@ -77,7 +74,11 @@ class Requirements:
|
||||
print_err(f'Ignoring alien requirement:', requirement_str)
|
||||
return
|
||||
|
||||
installed = self.installed_packages.get(requirement.name)
|
||||
try:
|
||||
installed = self.get_installed_version(requirement.name)
|
||||
except importlib_metadata.PackageNotFoundError:
|
||||
print_err(f'Requirement not satisfied: {requirement_str}')
|
||||
installed = None
|
||||
if installed and installed in requirement.specifier:
|
||||
print_err(f'Requirement satisfied: {requirement_str}')
|
||||
print_err(f' (installed: {requirement.name} {installed})')
|
||||
@ -203,9 +204,14 @@ def python3dist(name, op=None, version=None):
|
||||
|
||||
|
||||
def generate_requires(
|
||||
freeze_output, *, include_runtime=False, toxenv=None, extras='',
|
||||
*, include_runtime=False, toxenv=None, extras='',
|
||||
get_installed_version=importlib_metadata.version, # for dep injection
|
||||
):
|
||||
requirements = Requirements(freeze_output, extras=extras)
|
||||
"""Generate the BuildRequires for the project in the current directory
|
||||
|
||||
This is the main Python entry point.
|
||||
"""
|
||||
requirements = Requirements(get_installed_version, extras=extras)
|
||||
|
||||
try:
|
||||
backend = get_backend(requirements)
|
||||
@ -259,16 +265,8 @@ def main(argv):
|
||||
print_err('-x (--extras) are only useful with -r (--runtime)')
|
||||
exit(1)
|
||||
|
||||
freeze_output = subprocess.run(
|
||||
[sys.executable, '-I', '-m', 'pip', 'freeze', '--all'],
|
||||
encoding='utf-8',
|
||||
stdout=subprocess.PIPE,
|
||||
check=True,
|
||||
).stdout
|
||||
|
||||
try:
|
||||
generate_requires(
|
||||
freeze_output,
|
||||
include_runtime=args.runtime,
|
||||
toxenv=args.toxenv,
|
||||
extras=args.extras,
|
||||
|
@ -6,6 +6,11 @@ import yaml
|
||||
|
||||
from pyproject_buildrequires import generate_requires
|
||||
|
||||
try:
|
||||
import importlib.metadata as importlib_metadata
|
||||
except ImportError:
|
||||
import importlib_metadata
|
||||
|
||||
testcases = {}
|
||||
with Path(__file__).parent.joinpath('testcases.yaml').open() as f:
|
||||
testcases = yaml.safe_load(f)
|
||||
@ -26,9 +31,17 @@ def test_data(case_name, capsys, tmp_path, monkeypatch):
|
||||
if filename in case:
|
||||
cwd.joinpath(filename).write_text(case[filename])
|
||||
|
||||
def get_installed_version(dist_name):
|
||||
try:
|
||||
return str(case['installed'][dist_name])
|
||||
except (KeyError, TypeError):
|
||||
raise importlib_metadata.PackageNotFoundError(
|
||||
f'info not found for {dist_name}'
|
||||
)
|
||||
|
||||
try:
|
||||
generate_requires(
|
||||
case['freeze_output'],
|
||||
get_installed_version=get_installed_version,
|
||||
include_runtime=case.get('include_runtime', False),
|
||||
extras=case.get('extras', ''),
|
||||
toxenv=case.get('toxenv', None),
|
||||
|
@ -1,5 +1,5 @@
|
||||
No pyproject.toml, nothing installed:
|
||||
freeze_output: |
|
||||
installed:
|
||||
# empty
|
||||
expected: |
|
||||
python3dist(setuptools) >= 40.8
|
||||
@ -7,7 +7,7 @@ No pyproject.toml, nothing installed:
|
||||
result: 0
|
||||
|
||||
Nothing installed yet:
|
||||
freeze_output: |
|
||||
installed:
|
||||
# empty
|
||||
pyproject.toml: |
|
||||
# empty
|
||||
@ -17,9 +17,9 @@ Nothing installed yet:
|
||||
result: 0
|
||||
|
||||
Insufficient version of setuptools:
|
||||
freeze_output: |
|
||||
setuptools==5
|
||||
wheel==1
|
||||
installed:
|
||||
setuptools: 5
|
||||
wheel: 1
|
||||
pyproject.toml: |
|
||||
# empty
|
||||
expected: |
|
||||
@ -28,9 +28,9 @@ Insufficient version of setuptools:
|
||||
result: 0
|
||||
|
||||
Empty pyproject.toml, empty setup.py:
|
||||
freeze_output: |
|
||||
setuptools==50
|
||||
wheel==1
|
||||
installed:
|
||||
setuptools: 50
|
||||
wheel: 1
|
||||
setup.py: |
|
||||
expected: |
|
||||
python3dist(setuptools) >= 40.8
|
||||
@ -39,9 +39,9 @@ Empty pyproject.toml, empty setup.py:
|
||||
result: 0
|
||||
|
||||
Default build system, empty setup.py:
|
||||
freeze_output: |
|
||||
setuptools==50
|
||||
wheel==1
|
||||
installed:
|
||||
setuptools: 50
|
||||
wheel: 1
|
||||
pyproject.toml: |
|
||||
# empty
|
||||
setup.py: |
|
||||
@ -52,24 +52,24 @@ Default build system, empty setup.py:
|
||||
result: 0
|
||||
|
||||
Erroring setup.py:
|
||||
freeze_output: |
|
||||
setuptools==50
|
||||
wheel==1
|
||||
installed:
|
||||
setuptools: 50
|
||||
wheel: 1
|
||||
setup.py: |
|
||||
exit(77)
|
||||
result: 77
|
||||
|
||||
Bad character in version:
|
||||
freeze_output: |
|
||||
installed: {}
|
||||
pyproject.toml: |
|
||||
[build-system]
|
||||
requires = ["pkg == 0.$.^.*"]
|
||||
except: ValueError
|
||||
|
||||
Build system dependencies in pyproject.toml:
|
||||
freeze_output: |
|
||||
setuptools==50
|
||||
wheel==1
|
||||
installed:
|
||||
setuptools: 50
|
||||
wheel: 1
|
||||
pyproject.toml: |
|
||||
[build-system]
|
||||
requires = [
|
||||
@ -100,9 +100,9 @@ Build system dependencies in pyproject.toml:
|
||||
result: 0
|
||||
|
||||
Default build system, build dependencies in setup.py:
|
||||
freeze_output: |
|
||||
setuptools==50
|
||||
wheel==1
|
||||
installed:
|
||||
setuptools: 50
|
||||
wheel: 1
|
||||
setup.py: |
|
||||
from setuptools import setup
|
||||
setup(
|
||||
@ -120,10 +120,10 @@ Default build system, build dependencies in setup.py:
|
||||
result: 0
|
||||
|
||||
Default build system, run dependencies in setup.py:
|
||||
freeze_output: |
|
||||
setuptools==50
|
||||
wheel==1
|
||||
pyyaml==1
|
||||
installed:
|
||||
setuptools: 50
|
||||
wheel: 1
|
||||
pyyaml: 1
|
||||
include_runtime: true
|
||||
setup.py: |
|
||||
from setuptools import setup
|
||||
@ -143,10 +143,10 @@ Default build system, run dependencies in setup.py:
|
||||
result: 0
|
||||
|
||||
Run dependencies with extras (not selected):
|
||||
freeze_output: |
|
||||
setuptools==50
|
||||
wheel==1
|
||||
pyyaml==1
|
||||
installed:
|
||||
setuptools: 50
|
||||
wheel: 1
|
||||
pyyaml: 1
|
||||
include_runtime: true
|
||||
setup.py: &pytest_setup_py |
|
||||
# slightly abriged copy of pytest's setup.py
|
||||
@ -200,10 +200,10 @@ Run dependencies with extras (not selected):
|
||||
result: 0
|
||||
|
||||
Run dependencies with extras (selected):
|
||||
freeze_output: |
|
||||
setuptools==50
|
||||
wheel==1
|
||||
pyyaml==1
|
||||
installed:
|
||||
setuptools: 50
|
||||
wheel: 1
|
||||
pyyaml: 1
|
||||
include_runtime: true
|
||||
extras: testing
|
||||
setup.py: *pytest_setup_py
|
||||
@ -227,10 +227,10 @@ Run dependencies with extras (selected):
|
||||
|
||||
Run dependencies with multiple extras:
|
||||
xfail: requirement.marker.evaluate seems to not support multiple extras
|
||||
freeze_output: |
|
||||
setuptools==50
|
||||
wheel==1
|
||||
pyyaml==1
|
||||
installed:
|
||||
setuptools: 50
|
||||
wheel: 1
|
||||
pyyaml: 1
|
||||
include_runtime: true
|
||||
extras: testing,more-testing, even-more-testing , cool-feature
|
||||
setup.py: |
|
||||
@ -246,19 +246,18 @@ Run dependencies with multiple extras:
|
||||
expected: |
|
||||
python3dist(setuptools) >= 40.8
|
||||
python3dist(wheel)
|
||||
python3dist(wheel)
|
||||
python3dist(dep1)
|
||||
python3dist(dep2)
|
||||
python3dist(dep3)
|
||||
python3dist(dep4)
|
||||
result: 0
|
||||
|
||||
Tox depndencies:
|
||||
freeze_output: |
|
||||
setuptools==50
|
||||
wheel==1
|
||||
tox==3.5.3
|
||||
tox-current-env==0.0.2
|
||||
Tox dependencies:
|
||||
installed:
|
||||
setuptools: 50
|
||||
wheel: 1
|
||||
tox: 3.5.3
|
||||
tox-current-env: 0.0.2
|
||||
toxenv: py3
|
||||
setup.py: |
|
||||
from setuptools import setup
|
||||
|
Loading…
Reference in New Issue
Block a user