From 0a12aa5a2f1cb1a1003e5098108a6c5aa2040ce7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Mon, 15 Mar 2021 18:59:40 +0100 Subject: [PATCH] Do not generate setuptools requirement for console_scripts on Python 3.10+ See https://fedoraproject.org/wiki/Changes/Reduce_dependencies_on_python3-setuptools --- python-rpm-generators.spec | 6 +++- pythondist.attr | 2 +- pythondistdeps.py | 35 +++++++++++++----- tests/console_script.sh | 17 +++++++++ .../scripts_pythondistdeps/test-data.yaml | 24 +++++++++---- .../scripts_pythondistdeps/test-requires.yaml | 2 +- tests/isort.spec | 36 +++++++++++++++++++ tests/tests.yml | 3 ++ 8 files changed, 107 insertions(+), 18 deletions(-) create mode 100755 tests/console_script.sh create mode 100644 tests/isort.spec diff --git a/python-rpm-generators.spec b/python-rpm-generators.spec index 24994bf..16a48b8 100644 --- a/python-rpm-generators.spec +++ b/python-rpm-generators.spec @@ -1,7 +1,7 @@ Name: python-rpm-generators Summary: Dependency generators for Python RPMs Version: 12 -Release: 4%{?dist} +Release: 5%{?dist} # Originally all those files were part of RPM, so license is kept here License: GPLv2+ @@ -47,6 +47,10 @@ install -Dpm0755 -t %{buildroot}%{_rpmconfigdir} *.py %{_rpmconfigdir}/pythonbundles.py %changelog +* Wed Mar 31 2021 Miro HronĨok - 12-5 +- Do not generate setuptools requirement for console_scripts on Python 3.10+ +- See https://fedoraproject.org/wiki/Changes/Reduce_dependencies_on_python3-setuptools + * Thu Mar 11 2021 Tomas Orsava - 12-4 - scripts/pythondistdeps: Treat extras names case-insensitively and always output them in lower case (#1936875) diff --git a/pythondist.attr b/pythondist.attr index f849ba1..747cc32 100644 --- a/pythondist.attr +++ b/pythondist.attr @@ -1,3 +1,3 @@ %__pythondist_provides %{_rpmconfigdir}/pythondistdeps.py --provides --normalized-names-format pep503 --package-name %{name} --normalized-names-provide-both --majorver-provides-versions %{__default_python3_version} -%__pythondist_requires %{_rpmconfigdir}/pythondistdeps.py --requires --normalized-names-format pep503 --package-name %{name} %{?!_python_no_extras_requires:--require-extras-subpackages} +%__pythondist_requires %{_rpmconfigdir}/pythondistdeps.py --requires --normalized-names-format pep503 --package-name %{name} %{?!_python_no_extras_requires:--require-extras-subpackages} --console-scripts-nodep-setuptools-since 3.10 %__pythondist_path ^/usr/lib(64)?/python[3-9]\\.[[:digit:]]+/site-packages/[^/]+\\.(dist-info|egg-info|egg-link)$ diff --git a/pythondistdeps.py b/pythondistdeps.py index f38f726..17f49f3 100755 --- a/pythondistdeps.py +++ b/pythondistdeps.py @@ -276,6 +276,12 @@ if __name__ == "__main__": help='Provide both `pep503` and `legacy-dots` format of normalized names (useful for a transition period)') parser.add_argument('-L', '--legacy-provides', action='store_true', help='Print extra legacy pythonegg Provides') parser.add_argument('-l', '--legacy', action='store_true', help='Print legacy pythonegg Provides/Requires instead') + parser.add_argument('--console-scripts-nodep-setuptools-since', action='store', + help='An optional Python version (X.Y), at least 3.8. ' + 'For that version and any newer version, ' + 'a dependency on "setuptools" WILL NOT be generated for packages with console_scripts/gui_scripts entry points. ' + 'By setting this flag, you guarantee that setuptools >= 47.2.0 is used ' + 'during the build of packages for this and any newer Python version.') parser.add_argument('--require-extras-subpackages', action='store_true', help="If there is a dependency on a package with extras functionality, require the extras subpackage") parser.add_argument('--package-name', action='store', help="Name of the RPM package that's being inspected. Required for extras requires/provides to work.") @@ -305,6 +311,15 @@ if __name__ == "__main__": # At least one type of normalization must be provided assert normalized_names_provide_pep503 or normalized_names_provide_legacy + if args.console_scripts_nodep_setuptools_since: + nodep_setuptools_pyversion = parse(args.console_scripts_nodep_setuptools_since) + if nodep_setuptools_pyversion < parse("3.8"): + print("Only version 3.8+ is supported in --console-scripts-nodep-setuptools-since", file=stderr) + print("*** PYTHON_EXTRAS_ARGUMENT_ERROR___SEE_STDERR ***") + exit(65) # os.EX_DATAERR + else: + nodep_setuptools_pyversion = None + # Is this script being run for an extras subpackage? extras_subpackage = None if args.package_name and '+' in args.package_name: @@ -438,15 +453,17 @@ if __name__ == "__main__": else: deps = dist.requirements - # console_scripts/gui_scripts entry points need pkg_resources from setuptools - if (dist.entry_points and - (lower.endswith('.egg') or - lower.endswith('.egg-info'))): - groups = {ep.group for ep in dist.entry_points} - if {"console_scripts", "gui_scripts"} & groups: - # stick them first so any more specific requirement - # overrides it - deps.insert(0, Requirement('setuptools')) + # console_scripts/gui_scripts entry points needed pkg_resources from setuptools + # on new Python/setuptools versions, this is no longer required + if nodep_setuptools_pyversion is None or parse(dist.py_version) < nodep_setuptools_pyversion: + if (dist.entry_points and + (lower.endswith('.egg') or + lower.endswith('.egg-info'))): + groups = {ep.group for ep in dist.entry_points} + if {"console_scripts", "gui_scripts"} & groups: + # stick them first so any more specific requirement + # overrides it + deps.insert(0, Requirement('setuptools')) # add requires/recommends based on egg/dist metadata for dep in deps: # Even if we're requiring `foo[bar]`, also require `foo` diff --git a/tests/console_script.sh b/tests/console_script.sh new file mode 100755 index 0000000..892fd4b --- /dev/null +++ b/tests/console_script.sh @@ -0,0 +1,17 @@ +#!/usr/bin/bash -eux +RPMDIR=$(rpm --eval '%_topdir')/RPMS/noarch +RPMPKG="${RPMDIR}/isort-5.7.0-0.noarch.rpm" + +mkdir -p $(rpm --eval '%_topdir')/SOURCES/ + +spectool -g -R isort.spec + +for py_version in 3.6 3.7 3.8 3.9; do + rpmbuild -ba --define "python3_test_version ${py_version}" isort.spec + rpm -qp --requires ${RPMPKG} | grep "python${py_version}dist(setuptools)" +done + +for py_version in 3.10 3.11; do + rpmbuild -ba --define "python3_test_version ${py_version}" isort.spec + rpm -qp --requires ${RPMPKG} | grep "python${py_version}dist(setuptools)" && exit 1 || true +done diff --git a/tests/data/scripts_pythondistdeps/test-data.yaml b/tests/data/scripts_pythondistdeps/test-data.yaml index 35c72a8..0a81eaa 100644 --- a/tests/data/scripts_pythondistdeps/test-data.yaml +++ b/tests/data/scripts_pythondistdeps/test-data.yaml @@ -762,7 +762,16 @@ python3.9dist(simplejson) = 3.16 python3dist(simplejson) = 3.16 requires: python(abi) = 3.9 ---requires --normalized-names-format legacy-dots: +--requires --console-scripts-nodep-setuptools-since 3.7: + --provides --console-scripts-nodep-setuptools-since 3.6: + usr/lib/python3.9/site-packages/zope.component-4.3.0-py3.9.egg-info: + stderr: + provides: Only version 3.8+ is supported in --console-scripts-nodep-setuptools-since + requires: Only version 3.8+ is supported in --console-scripts-nodep-setuptools-since + stdout: + provides: '*** PYTHON_EXTRAS_ARGUMENT_ERROR___SEE_STDERR ***' + requires: '*** PYTHON_EXTRAS_ARGUMENT_ERROR___SEE_STDERR ***' +--requires --normalized-names-format legacy-dots --console-scripts-nodep-setuptools-since 3.10: --provides --majorver-provides --normalized-names-format legacy-dots: usr/lib/python2.7/site-packages/zope.component-4.3.0-py2.7.egg-info: provides: |- @@ -800,16 +809,19 @@ provides: |- python3.10dist(setuptools) = 41.6 python3dist(setuptools) = 41.6 - requires: |- - python(abi) = 3.10 - python3.10dist(setuptools) + requires: python(abi) = 3.10 usr/lib/python3.11/site-packages/pip-20.0.2-py3.11.egg-info: provides: |- python3.11dist(pip) = 20.0.2 python3dist(pip) = 20.0.2 + requires: python(abi) = 3.11 + usr/lib/python3.8/site-packages/pip-20.0.2-py3.8.egg-info: + provides: |- + python3.8dist(pip) = 20.0.2 + python3dist(pip) = 20.0.2 requires: |- - python(abi) = 3.11 - python3.11dist(setuptools) + python(abi) = 3.8 + python3.8dist(setuptools) usr/lib/python3.9/site-packages/zope.component-4.3.0-py3.9.egg-info: provides: |- python3.9dist(zope.component) = 4.3 diff --git a/tests/data/scripts_pythondistdeps/test-requires.yaml b/tests/data/scripts_pythondistdeps/test-requires.yaml index 32d70f2..d876674 100644 --- a/tests/data/scripts_pythondistdeps/test-requires.yaml +++ b/tests/data/scripts_pythondistdeps/test-requires.yaml @@ -8,7 +8,7 @@ pip: '19.1.1': ['2.7', '3.7'] '20.0.2': ['3.9'] sdist: - '20.0.2': ['3.11'] + '20.0.2': ['3.8', '3.11'] packaging: wheel: '19.0': ['2.7', '3.7'] diff --git a/tests/isort.spec b/tests/isort.spec new file mode 100644 index 0000000..74514d4 --- /dev/null +++ b/tests/isort.spec @@ -0,0 +1,36 @@ +Name: isort +Version: 5.7.0 +Release: 0 +Summary: A Python package with a console_scripts entrypoint +License: MIT +Source0: %{pypi_source} +BuildArch: noarch +BuildRequires: python3-devel +BuildRequires: python3-setuptools + +# Turn off Python bytecode compilation because the build would fail without Python %%{python3_test_version} +%define __brp_python_bytecompile %{nil} + +%description +... + +%prep +%autosetup + +%build +%py3_build + +%install +%py3_install + +# A fake installation by a different Python version: +%if "%{python3_version}" != "%{python3_test_version}" +mv %{buildroot}%{_prefix}/lib/python%{python3_version} \ + %{buildroot}%{_prefix}/lib/python%{python3_test_version} +mv %{buildroot}%{_prefix}/lib/python%{python3_test_version}/site-packages/%{name}-%{version}-py%{python3_version}.egg-info \ + %{buildroot}%{_prefix}/lib/python%{python3_test_version}/site-packages/%{name}-%{version}-py%{python3_test_version}.egg-info +%endif + +%files +%{_bindir}/%{name}* +%{_prefix}/lib/python%{python3_test_version}/site-packages/%{name}* diff --git a/tests/tests.yml b/tests/tests.yml index a79a5f1..668ff36 100644 --- a/tests/tests.yml +++ b/tests/tests.yml @@ -27,6 +27,9 @@ - pythondist: dir: . run: ./pythondist.sh + - console_script: + dir: . + run: ./console_script.sh - prepare-test-data: dir: . run: tar -xvf test-sources-*.tar.gz -C ./tests/data/scripts_pythondistdeps/