-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Test pyproject.toml config has the same effect as setup.cfg
- Loading branch information
1 parent
43e3436
commit c6907cb
Showing
4 changed files
with
142 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,3 +20,4 @@ setuptools.egg-info | |
.idea/ | ||
.pytest_cache/ | ||
.mypy_cache/ | ||
/setuptools/tests/config/downloads |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# ==================================================================== | ||
# Some popular packages that use setup.cfg (and others not so popular) | ||
# Reference: https://hugovk.github.io/top-pypi-packages/ | ||
# ==================================================================== | ||
https://github.com/pypa/setuptools/raw/52c990172fec37766b3566679724aa8bf70ae06d/setup.cfg | ||
https://github.com/pypa/wheel/raw/0acd203cd896afec7f715aa2ff5980a403459a3b/setup.cfg | ||
https://github.com/python/importlib_metadata/raw/2f05392ca980952a6960d82b2f2d2ea10aa53239/setup.cfg | ||
https://github.com/jaraco/skeleton/raw/d9008b5c510cd6969127a6a2ab6f832edddef296/setup.cfg | ||
https://github.com/jaraco/zipp/raw/700d3a96390e970b6b962823bfea78b4f7e1c537/setup.cfg | ||
https://github.com/pallets/jinja/raw/7d72eb7fefb7dce065193967f31f805180508448/setup.cfg | ||
https://github.com/tkem/cachetools/raw/2fd87a94b8d3861d80e9e4236cd480bfdd21c90d/setup.cfg | ||
https://github.com/aio-libs/aiohttp/raw/5e0e6b7080f2408d5f1dd544c0e1cf88378b7b10/setup.cfg | ||
https://github.com/pallets/flask/raw/9486b6cf57bd6a8a261f67091aca8ca78eeec1e3/setup.cfg | ||
https://github.com/pallets/click/raw/6411f425fae545f42795665af4162006b36c5e4a/setup.cfg | ||
https://github.com/sqlalchemy/sqlalchemy/raw/533f5718904b620be8d63f2474229945d6f8ba5d/setup.cfg | ||
https://github.com/pytest-dev/pluggy/raw/461ef63291d13589c4e21aa182cd1529257e9a0a/setup.cfg | ||
https://github.com/pytest-dev/pytest/raw/c7be96dae487edbd2f55b561b31b68afac1dabe6/setup.cfg | ||
https://github.com/tqdm/tqdm/raw/fc69d5dcf578f7c7986fa76841a6b793f813df35/setup.cfg | ||
https://github.com/platformdirs/platformdirs/raw/7b7852128dd6f07511b618d6edea35046bd0c6ff/setup.cfg | ||
https://github.com/pandas-dev/pandas/raw/bc17343f934a33dc231c8c74be95d8365537c376/setup.cfg | ||
https://github.com/django/django/raw/4e249d11a6e56ca8feb4b055b681cec457ef3a3d/setup.cfg | ||
https://github.com/pyscaffold/pyscaffold/raw/de7aa5dc059fbd04307419c667cc4961bc9df4b8/setup.cfg | ||
https://github.com/pypa/virtualenv/raw/f92eda6e3da26a4d28c2663ffb85c4960bdb990c/setup.cfg |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
"""Make sure that applying the configuration from pyproject.toml is equivalent to | ||
applying a similar configuration from setup.cfg | ||
""" | ||
import io | ||
import re | ||
from pathlib import Path | ||
from urllib.request import urlopen | ||
from unittest.mock import Mock | ||
|
||
import pytest | ||
from ini2toml.api import Translator | ||
|
||
import setuptools # noqa ensure monkey patch to metadata | ||
from setuptools.dist import Distribution | ||
from setuptools.config import setupcfg, pyprojecttoml | ||
from setuptools.config import expand | ||
|
||
|
||
EXAMPLES = (Path(__file__).parent / "setupcfg_examples.txt").read_text() | ||
EXAMPLE_URLS = [x for x in EXAMPLES.splitlines() if not x.startswith("#")] | ||
DOWNLOAD_DIR = Path(__file__).parent / "downloads" | ||
|
||
|
||
@pytest.mark.parametrize("url", EXAMPLE_URLS) | ||
@pytest.mark.filterwarnings("ignore") | ||
def test_apply_pyproject_equivalent_to_setupcfg(url, monkeypatch, tmp_path): | ||
monkeypatch.setattr(expand, "read_attr", Mock(return_value="0.0.1")) | ||
setupcfg_example = retrieve_file(url, DOWNLOAD_DIR) | ||
pyproject_example = Path(tmp_path, "pyproject.toml") | ||
toml_config = Translator().translate(setupcfg_example.read_text(), "setup.cfg") | ||
pyproject_example.write_text(toml_config) | ||
|
||
dist_toml = pyprojecttoml.apply_configuration(Distribution(), pyproject_example) | ||
dist_cfg = setupcfg.apply_configuration(Distribution(), setupcfg_example) | ||
|
||
pkg_info_toml = core_metadata(dist_toml) | ||
pkg_info_cfg = core_metadata(dist_cfg) | ||
assert pkg_info_toml == pkg_info_cfg | ||
|
||
if any(getattr(d, "license_files", None) for d in (dist_toml, dist_cfg)): | ||
assert set(dist_toml.license_files) == set(dist_cfg.license_files) | ||
|
||
if any(getattr(d, "entry_points", None) for d in (dist_toml, dist_cfg)): | ||
print(dist_cfg.entry_points) | ||
ep_toml = {(k, *sorted(i.replace(" ", "") for i in v)) | ||
for k, v in dist_toml.entry_points.items()} | ||
ep_cfg = {(k, *sorted(i.replace(" ", "") for i in v)) | ||
for k, v in dist_cfg.entry_points.items()} | ||
assert ep_toml == ep_cfg | ||
|
||
if any(getattr(d, "package_data", None) for d in (dist_toml, dist_cfg)): | ||
pkg_data_toml = {(k, *sorted(v)) for k, v in dist_toml.package_data.items()} | ||
pkg_data_cfg = {(k, *sorted(v)) for k, v in dist_cfg.package_data.items()} | ||
assert pkg_data_toml == pkg_data_cfg | ||
|
||
if any(getattr(d, "data_files", None) for d in (dist_toml, dist_cfg)): | ||
data_files_toml = {(k, *sorted(v)) for k, v in dist_toml.data_files} | ||
data_files_cfg = {(k, *sorted(v)) for k, v in dist_cfg.data_files} | ||
assert data_files_toml == data_files_cfg | ||
|
||
assert set(dist_toml.install_requires) == set(dist_cfg.install_requires) | ||
if any(getattr(d, "extras_require", None) for d in (dist_toml, dist_cfg)): | ||
if ( | ||
"testing" in dist_toml.extras_require | ||
and "testing" not in dist_cfg.extras_require | ||
): | ||
# ini2toml can automatically convert `tests_require` to `testing` extra | ||
dist_toml.extras_require.pop("testing") | ||
extra_req_toml = {(k, *sorted(v)) for k, v in dist_toml.extras_require.items()} | ||
extra_req_cfg = {(k, *sorted(v)) for k, v in dist_cfg.extras_require.items()} | ||
assert extra_req_toml == extra_req_cfg | ||
|
||
|
||
NAME_REMOVE = ("http://", "https://", "github.com/", "/raw/") | ||
|
||
|
||
def retrieve_file(url, download_dir): | ||
file_name = url.strip() | ||
for part in NAME_REMOVE: | ||
file_name = file_name.replace(part, '').strip().strip('/:').strip() | ||
file_name = re.sub(r"[^\-_\.\w\d]+", "_", file_name) | ||
path = Path(download_dir, file_name) | ||
if not path.exists(): | ||
download_dir.mkdir(exist_ok=True, parents=True) | ||
download(url, path) | ||
return path | ||
|
||
|
||
def download(url, dest): | ||
with urlopen(url) as f: | ||
data = f.read() | ||
|
||
with open(dest, "wb") as f: | ||
f.write(data) | ||
|
||
assert Path(dest).exists() | ||
|
||
|
||
def core_metadata(dist) -> str: | ||
buffer = io.StringIO() | ||
dist.metadata.write_pkg_file(buffer) | ||
value = "\n".join(buffer.getvalue().strip().splitlines()) | ||
|
||
# ---- DIFF NORMALISATION ---- | ||
# PEP 621 is very particular about author/maintainer metadata conversion, so skip | ||
value = re.sub(r"^(Author|Maintainer)(-email)?:.*$", "", value, flags=re.M) | ||
# May be redundant with Home-page | ||
value = re.sub(r"^Project-URL: Homepage,.*$", "", value, flags=re.M) | ||
# May be missing in original (relying on default) but backfilled in the TOML | ||
value = re.sub(r"^Description-Content-Type:.*$", "", value, flags=re.M) | ||
# ini2toml can automatically convert `tests_require` to `testing` extra | ||
value = value.replace("Provides-Extra: testing\n", "") | ||
# Remove empty lines | ||
value = re.sub(r"^\s*$", "", value, flags=re.M) | ||
value = re.sub(r"^\n", "", value, flags=re.M) | ||
|
||
return value |