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

Fall back to isolated mode for metadata build & simplify codepath #92

Merged
merged 9 commits into from
Feb 13, 2023
14 changes: 12 additions & 2 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -27,7 +38,6 @@ Changelog
- Check if author_email field contains author name [bessman]



4.0 (2022-04-14)
----------------

Expand Down
43 changes: 28 additions & 15 deletions pyroma/projectdata.py
Original file line number Diff line number Diff line change
@@ -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",
Expand All @@ -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)
Expand All @@ -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

Expand Down Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion pyroma/testdata/custom_test/setup.py
Original file line number Diff line number Diff line change
@@ -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):
Expand Down
2 changes: 1 addition & 1 deletion pyroma/testdata/minimal/setup.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from setuptools import setup, find_packages

version = "0.0foo"
version = "0.0.1"

setup(
name="minimal",
Expand Down
2 changes: 0 additions & 2 deletions pyroma/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,6 @@ def test_minimal(self):
(
2,
[
"The package's version number does not comply with PEP-386 or PEP-440.",
regebro marked this conversation as resolved.
Show resolved Hide resolved
"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.",
Expand Down Expand Up @@ -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.",
Expand Down
14 changes: 5 additions & 9 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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]
Expand All @@ -70,7 +67,6 @@ testpaths =
[check-manifest]
ignore =
.pre-commit-hooks.yaml
fetch_classifiers.py

[zest.releaser]
create-wheel = yes