diff --git a/CHANGES.txt b/CHANGES.txt index ca1b74d..9bfe817 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -4,7 +4,18 @@ Changelog 4.2 (unreleased) ---------------- -- Nothing changed yet. +- Fall back to installing project's build backend in an isolated environment + if a compatible version isn't installed in the current env [CAM-Gerlach] + +- Fix metadata extraction failure when project ``long_description`` is included + as a header rather than a payload in the ``METADTA`` file [CAM-Gerlach] + +- Add a fallback to restore compatibility with Setuptools <61 [CAM-Gerlach] + +- Fix tests failing due to invalid versions on Setuptools >=66 [CAM-Gerlach] + +- Add ``python_requires``, update classifiers, add implicit dependencies + and remove unused deps in Pyroma's own packaging metadata [CAM-Gerlach] 4.1 (2022-11-24) @@ -27,7 +38,6 @@ Changelog - Check if author_email field contains author name [bessman] - 4.0 (2022-04-14) ---------------- diff --git a/pyroma/projectdata.py b/pyroma/projectdata.py index da27db0..4039683 100644 --- a/pyroma/projectdata.py +++ b/pyroma/projectdata.py @@ -1,17 +1,18 @@ # Extracts information from a project that has a distutils setup.py file. import build -import email -import email.policy +import build.util import logging import os import pathlib -import pep517 import sys -import tempfile import tokenize from copy import copy from distutils import core -from setuptools import config + +try: # config renamed to config.setupcfg on Setuptools >=61 adding pyproject.toml support + from setuptools.config.setupcfg import read_configuration +except ModuleNotFoundError: + from setuptools.config import read_configuration METADATA_MAP = { "summary": "description", @@ -24,16 +25,25 @@ } -def get_build_data(path): - with tempfile.TemporaryDirectory() as tempdir: - metadata_dir = build.ProjectBuilder(str(path), runner=pep517.quiet_subprocess_runner).prepare("wheel", tempdir) - with open(pathlib.Path(metadata_dir) / "METADATA", "rb") as metadata_file: - metadata = email.message_from_binary_file(metadata_file, policy=email.policy.compat32) +def build_metadata(path, isolated=None): + # If explictly specified whether to use isolation, pass it directly + if isolated is not None: + return build.util.project_wheel_metadata(path, isolated=isolated) + + # Otherwise, try without build isolation first for efficiency + try: + return build.util.project_wheel_metadata(path, isolated=False) + # If building with build isolation fails, e.g. missing build deps, try with it + except build.BuildBackendException: + return build.util.project_wheel_metadata(path, isolated=True) + +def map_metadata_keys(metadata): + data = {} if "Description" not in metadata.keys(): # Having the description as a payload tends to add two newlines, we clean that up here: long_description = metadata.get_payload().strip() + "\n" - data = {"long_description": long_description} + data["long_description"] = long_description for key in set(metadata.keys()): value = metadata.get_all(key) @@ -48,9 +58,14 @@ def get_build_data(path): return data +def get_build_data(path, isolated=None): + metadata = build_metadata(path, isolated=isolated) + return map_metadata_keys(metadata) + + def get_setupcfg_data(path): # Note: By default, setup.cfg will read the pyroma.git/setup.cfg - forcing explicit setup.cfg under test's file path - data = config.setupcfg.read_configuration(str(pathlib.Path(path) / "setup.cfg")) + data = read_configuration(str(pathlib.Path(path) / "setup.cfg")) metadata = data["metadata"] return metadata @@ -245,9 +260,7 @@ def get_setuppy_data(path): elif os.path.isfile("setup.cfg"): try: - from setuptools import config - - data = config.read_configuration("setup.cfg") + data = read_configuration("setup.cfg") metadata = data["metadata"] metadata["_setuptools"] = True except Exception as e: diff --git a/pyroma/testdata/custom_test/setup.py b/pyroma/testdata/custom_test/setup.py index 532092d..5b7d60e 100644 --- a/pyroma/testdata/custom_test/setup.py +++ b/pyroma/testdata/custom_test/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, find_packages from setuptools.command.test import test -version = "0.0foo" +version = "0.0.1" class CustomTest(test): diff --git a/pyroma/testdata/minimal/setup.py b/pyroma/testdata/minimal/setup.py index 3e336a9..ba098ae 100644 --- a/pyroma/testdata/minimal/setup.py +++ b/pyroma/testdata/minimal/setup.py @@ -1,6 +1,6 @@ from setuptools import setup, find_packages -version = "0.0foo" +version = "0.0.1" setup( name="minimal", diff --git a/pyroma/tests.py b/pyroma/tests.py index d54ec3f..6c13329 100644 --- a/pyroma/tests.py +++ b/pyroma/tests.py @@ -169,7 +169,6 @@ def test_minimal(self): ( 2, [ - "The package's version number does not comply with PEP-386 or PEP-440.", "The package's description should be longer than 10 characters.", "The package's long_description is quite short.", "Your package does not have classifiers data.", @@ -228,7 +227,6 @@ def test_custom_test(self): ( 2, [ - "The package's version number does not comply with PEP-386 or PEP-440.", "The package's description should be longer than 10 characters.", "The package's long_description is quite short.", "Your package does not have classifiers data.", diff --git a/setup.cfg b/setup.cfg index ca446a5..eb840b3 100644 --- a/setup.cfg +++ b/setup.cfg @@ -10,13 +10,13 @@ classifiers = Operating System :: OS Independent Programming Language :: Python Programming Language :: Python :: 3 - Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.11 Programming Language :: Python :: 3 :: Only + Programming Language :: Python :: Implementation :: CPython Programming Language :: Python :: Implementation :: PyPy keywords = pypi, quality, testing author = Lennart Regebro @@ -32,25 +32,22 @@ include_package_data = True packages = find: package_dir = = . +python_requires = >=3.7 install_requires = - build + build>=0.7.0 docutils - pep517 + packaging pygments requests - setuptools>=61.0.0 + setuptools>=42 trove-classifiers>=2022.6.26 - wheel [options.packages.find] where = . [options.extras_require] test = - pytest - pytest-cov setuptools>=60 - flit >=3.4,<4 zest.releaser[recommended] [options.entry_points] @@ -70,7 +67,6 @@ testpaths = [check-manifest] ignore = .pre-commit-hooks.yaml - fetch_classifiers.py [zest.releaser] create-wheel = yes