From 6a503262290d571a489202f6e772370b9ee95801 Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Fri, 26 Mar 2021 14:36:24 +0200 Subject: [PATCH] Remove remaining Python helpers and scripts from the repo These are far better maintained by the Python community, in a repository of their own: https://github.com/rpm-software-management/python-rpm-packaging/ --- fileattrs/Makefile.am | 2 +- fileattrs/python.attr | 27 -- fileattrs/pythondist.attr | 3 - platform.in | 3 - scripts/Makefile.am | 12 +- scripts/brp-python-bytecompile | 116 --------- scripts/brp-python-hardlink | 25 -- scripts/pythondistdeps.py | 455 --------------------------------- 8 files changed, 7 insertions(+), 636 deletions(-) delete mode 100644 fileattrs/python.attr delete mode 100644 fileattrs/pythondist.attr delete mode 100644 scripts/brp-python-bytecompile delete mode 100755 scripts/brp-python-hardlink delete mode 100755 scripts/pythondistdeps.py diff --git a/fileattrs/Makefile.am b/fileattrs/Makefile.am index e0ca5b6bc8..f13bdd81aa 100644 --- a/fileattrs/Makefile.am +++ b/fileattrs/Makefile.am @@ -7,7 +7,7 @@ fattrsdir = $(rpmconfigdir)/fileattrs fattrs_DATA = \ debuginfo.attr desktop.attr elf.attr font.attr libtool.attr metainfo.attr \ - perl.attr perllib.attr pkgconfig.attr python.attr pythondist.attr ocaml.attr \ + perl.attr perllib.attr pkgconfig.attr ocaml.attr \ script.attr EXTRA_DIST = $(fattrs_DATA) diff --git a/fileattrs/python.attr b/fileattrs/python.attr deleted file mode 100644 index 1793d3cfb1..0000000000 --- a/fileattrs/python.attr +++ /dev/null @@ -1,27 +0,0 @@ -%__python_provides() %{lua: - -- Match buildroot/payload paths of the form - -- /PATH/OF/BUILDROOT/usr/bin/pythonMAJOR.MINOR - -- generating a line of the form - -- python(abi) = MAJOR.MINOR - -- (Don't match against -config tools e.g. /usr/bin/python2.6-config) - local path = rpm.expand('%1') - if path:match('/usr/bin/python%d+%.%d+$') then - local provides = path:gsub('.*/usr/bin/python(%d+%.%d+)', 'python(abi) = %1') - print(provides) - end -} - -%__python_requires() %{lua: - -- Match buildroot paths of the form - -- /PATH/OF/BUILDROOT/usr/lib/pythonMAJOR.MINOR/ and - -- /PATH/OF/BUILDROOT/usr/lib64/pythonMAJOR.MINOR/ - -- generating a line of the form: - -- python(abi) = MAJOR.MINOR - local path = rpm.expand('%1') - if path:match('/usr/lib%d*/python%d+%.%d+/.*') then - local requires = path:gsub('.*/usr/lib%d*/python(%d+%.%d+)/.*', 'python(abi) = %1') - print(requires) - end -} - -%__python_path ^((%{_prefix}/lib(64)?/python[[:digit:]]+\\.[[:digit:]]+/.*\\.(py[oc]?|so))|(%{_bindir}/python[[:digit:]]+\\.[[:digit:]]+))$ diff --git a/fileattrs/pythondist.attr b/fileattrs/pythondist.attr deleted file mode 100644 index 113ad9eae0..0000000000 --- a/fileattrs/pythondist.attr +++ /dev/null @@ -1,3 +0,0 @@ -%__pythondist_provides %{_rpmconfigdir}/pythondistdeps.py --provides --majorver-provides -%__pythondist_requires %{_rpmconfigdir}/pythondistdeps.py --requires -%__pythondist_path /lib(64)?/python[[:digit:]]\\.[[:digit:]]+/site-packages/[^/]+\\.(dist-info|egg-info|egg-link)$ diff --git a/platform.in b/platform.in index ac6999bbb9..a17468e06b 100644 --- a/platform.in +++ b/platform.in @@ -82,14 +82,11 @@ # %__arch_install_post @ARCH_INSTALL_POST@ -%_python_bytecompile_errors_terminate_build 0 -%_python_bytecompile_extra 1 # Standard brp-macro naming: # convert all '-' in basename to '_', add two leading underscores. %__brp_compress %{_rpmconfigdir}/brp-compress %{?_prefix} %__brp_java_gcjcompile %{_rpmconfigdir}/brp-java-bytecompile -%__brp_python_bytecompile %{_rpmconfigdir}/brp-python-bytecompile "" "%{?_python_bytecompile_errors_terminate_build}" "%{?_python_bytecompile_extra}" %__brp_strip %{_rpmconfigdir}/brp-strip %{__strip} %__brp_strip_comment_note %{_rpmconfigdir}/brp-strip-comment-note %{__strip} %{__objdump} %__brp_strip_static_archive %{_rpmconfigdir}/brp-strip-static-archive %{__strip} diff --git a/scripts/Makefile.am b/scripts/Makefile.am index efaf73c7d8..2393270b03 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -6,13 +6,13 @@ AM_CFLAGS = @RPMCFLAGS@ CLEANFILES = EXTRA_DIST = \ - brp-compress brp-python-bytecompile brp-java-gcjcompile \ - brp-strip brp-strip-comment-note brp-python-hardlink \ + brp-compress brp-java-gcjcompile \ + brp-strip brp-strip-comment-note \ brp-strip-static-archive brp-elfperms \ check-files check-prereqs \ check-buildroot check-rpaths check-rpaths-worker \ find-debuginfo.sh find-lang.sh \ - perl.prov perl.req pythondistdeps.py \ + perl.prov perl.req \ rpmdb_dump rpmdb_load \ rpm.daily rpm.log rpm.supp rpm2cpio.sh \ tgpg vpkg-provides.sh \ @@ -23,13 +23,13 @@ EXTRA_DIST = \ fontconfig.prov script.req rpmconfig_SCRIPTS = \ - brp-compress brp-python-bytecompile brp-java-gcjcompile \ - brp-strip brp-strip-comment-note brp-python-hardlink \ + brp-compress brp-java-gcjcompile \ + brp-strip brp-strip-comment-note \ brp-strip-static-archive brp-elfperms \ check-files check-prereqs \ check-buildroot check-rpaths check-rpaths-worker \ find-lang.sh find-requires find-provides \ - perl.prov perl.req pythondistdeps.py \ + perl.prov perl.req \ pkgconfigdeps.sh libtooldeps.sh \ ocamldeps.sh \ fontconfig.prov script.req \ diff --git a/scripts/brp-python-bytecompile b/scripts/brp-python-bytecompile deleted file mode 100644 index 97691935d2..0000000000 --- a/scripts/brp-python-bytecompile +++ /dev/null @@ -1,116 +0,0 @@ -#!/bin/bash -errors_terminate=$2 -extra=$3 - -# If using normal root, avoid changing anything. -if [ -z "$RPM_BUILD_ROOT" ] || [ "$RPM_BUILD_ROOT" = "/" ]; then - exit 0 -fi - -# Figure out how deep we need to descend. We could pick an insanely high -# number and hope it's enough, but somewhere, somebody's sure to run into it. -depth=`(find "$RPM_BUILD_ROOT" -type f -name "*.py" -print0 ; echo /) | \ - xargs -0 -n 1 dirname | sed 's,[^/],,g' | sort -u | tail -n 1 | wc -c` -if [ -z "$depth" ] || [ "$depth" -le "1" ]; then - exit 0 -fi - -function python_bytecompile() -{ - local options=$1 - local python_binary=$2 - local exclude=$3 - local python_libdir=$4 - local depth=$5 - local real_libdir=$6 - -cat << EOF | $python_binary $options -import compileall, sys, os, re - -python_libdir = "$python_libdir" -depth = $depth -real_libdir = "$real_libdir" -build_root = "$RPM_BUILD_ROOT" -exclude = r"$exclude" - -class Filter: - def search(self, path): - ret = not os.path.realpath(path).startswith(build_root) - if exclude: - ret = ret or re.search(exclude, path) - return ret - -sys.exit(not compileall.compile_dir(python_libdir, depth, real_libdir, force=1, rx=Filter(), quiet=1)) -EOF -} - -# .pyc/.pyo files embed a "magic" value, identifying the ABI version of Python -# bytecode that they are for. -# -# The files below RPM_BUILD_ROOT could be targeting multiple versions of -# python (e.g. a single build that emits several subpackages e.g. a -# python26-foo subpackage, a python31-foo subpackage etc) -# -# Support this by assuming that below each /usr/lib/python$VERSION/, all -# .pyc/.pyo files are to be compiled for /usr/bin/python$VERSION. -# -# For example, below /usr/lib/python2.6/, we're targeting /usr/bin/python2.6 -# and below /usr/lib/python3.1/, we're targeting /usr/bin/python3.1 - -# Disable Python hash seed randomization -# This helps to make byte-compilation more reproducible -export PYTHONHASHSEED=0 - -shopt -s nullglob -for python_libdir in `find "$RPM_BUILD_ROOT" -type d|grep -E "/usr/lib(64)?/python[0-9]\.[0-9]$"`; -do - python_binary=/usr/bin/$(basename $python_libdir) - real_libdir=${python_libdir/$RPM_BUILD_ROOT/} - echo "Bytecompiling .py files below $python_libdir using $python_binary" - - # Generate normal (.pyc) byte-compiled files. - python_bytecompile "" "$python_binary" "" "$python_libdir" "$depth" "$real_libdir" - if [ $? -ne 0 ] && [ 0$errors_terminate -ne 0 ]; then - # One or more of the files had a syntax error - exit 1 - fi - - # Generate optimized (.pyo) byte-compiled files. - python_bytecompile "-O" "$python_binary" "" "$python_libdir" "$depth" "$real_libdir" - if [ $? -ne 0 ] && [ 0$errors_terminate -ne 0 ]; then - # One or more of the files had a syntax error - exit 1 - fi -done - - -# Handle other locations in the filesystem using the default python implementation -# if extra is set to 0, don't do this -if [ 0$extra -eq 0 ]; then - exit 0 -fi - -# If we don't have a default python interpreter, we cannot proceed -default_python=${1:-/usr/bin/python} -if [ ! -x "$default_python" ]; then - exit 0 -fi - -# Figure out if there are files to be bytecompiled with the default_python at all -# this prevents unnecessary default_python invocation -find "$RPM_BUILD_ROOT" -type f -name "*.py" | grep -Ev "/bin/|/sbin/|/usr/lib(64)?/python[0-9]\.[0-9]|/usr/share/doc" || exit 0 - -# Generate normal (.pyc) byte-compiled files. -python_bytecompile "" $default_python "/bin/|/sbin/|/usr/lib(64)?/python[0-9]\.[0-9]|/usr/share/doc" "$RPM_BUILD_ROOT" "$depth" "/" -if [ $? -ne 0 ] && [ 0$errors_terminate -ne 0 ]; then - # One or more of the files had a syntax error - exit 1 -fi - -# Generate optimized (.pyo) byte-compiled files. -python_bytecompile "-O" $default_python "/bin/|/sbin/|/usr/lib(64)?/python[0-9]\.[0-9]|/usr/share/doc" "$RPM_BUILD_ROOT" "$depth" "/" -if [ $? -ne 0 ] && [ 0$errors_terminate -ne 0 ]; then - # One or more of the files had a syntax error - exit 1 -fi -exit 0 diff --git a/scripts/brp-python-hardlink b/scripts/brp-python-hardlink deleted file mode 100755 index 5fd1b43bb8..0000000000 --- a/scripts/brp-python-hardlink +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh - -# If using normal root, avoid changing anything. -if [ -z "$RPM_BUILD_ROOT" ] || [ "$RPM_BUILD_ROOT" = "/" ]; then - exit 0 -fi - -hardlink_if_same() { - if cmp -s "$1" "$2" ; then - ln -f "$1" "$2" - return 0 - fi - return 1 -} - -# Hardlink identical *.pyc, *.pyo, and *.opt-[12].pyc. -# Originally from PLD's rpm-build-macros -find "$RPM_BUILD_ROOT" -type f -name "*.pyc" -not -name "*.opt-[12].pyc" | while read pyc ; do - hardlink_if_same "$pyc" "${pyc%c}o" - o1pyc="${pyc%pyc}opt-1.pyc" - hardlink_if_same "$pyc" "$o1pyc" - o2pyc="${pyc%pyc}opt-2.pyc" - hardlink_if_same "$pyc" "$o2pyc" || hardlink_if_same "$o1pyc" "$o2pyc" -done -exit 0 diff --git a/scripts/pythondistdeps.py b/scripts/pythondistdeps.py deleted file mode 100755 index 4e178c0031..0000000000 --- a/scripts/pythondistdeps.py +++ /dev/null @@ -1,455 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# -# Copyright 2010 Per Øyvind Karlsen -# Copyright 2015 Neal Gompa -# Copyright 2020 SUSE LLC -# -# This program is free software. It may be redistributed and/or modified under -# the terms of the LGPL version 2.1 (or later). -# -# RPM python dependency generator, using .egg-info/.egg-link/.dist-info data -# - -from __future__ import print_function -import argparse -from distutils.sysconfig import get_python_lib -from os.path import dirname, sep -import re -from sys import argv, stdin -from warnings import warn - -from packaging.requirements import Requirement as Requirement_ -from packaging.version import parse - -try: - from importlib.metadata import PathDistribution -except ImportError: - from importlib_metadata import PathDistribution - -try: - from pathlib import Path -except ImportError: - from pathlib2 import Path - - -def normalize_name(name): - """https://www.python.org/dev/peps/pep-0503/#normalized-names""" - return re.sub(r'[-_.]+', '-', name).lower() - - -def legacy_normalize_name(name): - """Like pkg_resources Distribution.key property""" - return re.sub(r'[-_]+', '-', name).lower() - - -class Requirement(Requirement_): - def __init__(self, requirement_string): - super(Requirement, self).__init__(requirement_string) - self.normalized_name = normalize_name(self.name) - self.legacy_normalized_name = legacy_normalize_name(self.name) - - -class Distribution(PathDistribution): - def __init__(self, path): - super(Distribution, self).__init__(Path(path)) - self.normalized_name = normalize_name(self.name) - self.legacy_normalized_name = legacy_normalize_name(self.name) - self.requirements = [Requirement(r) for r in self.requires or []] - self.extras = [ - v for k, v in self.metadata.items() if k == 'Provides-Extra'] - self.py_version = self._parse_py_version(path) - - # `name` is defined as a property exactly like this in Python 3.10 in the - # PathDistribution class. Due to that we can't redefine `name` as a normal - # attribute. So we copied the Python 3.10 definition here into the code so - # that it works also on previous Python/importlib_metadata versions. - @property - def name(self): - """Return the 'Name' metadata for the distribution package.""" - return self.metadata['Name'] - - def _parse_py_version(self, path): - # Try to parse the Python version from the path the metadata - # resides at (e.g. /usr/lib/pythonX.Y/site-packages/...) - res = re.search(r"/python(?P\d+\.\d+)/", path) - if res: - return res.group('pyver') - # If that hasn't worked, attempt to parse it from the metadata - # directory name - res = re.search(r"-py(?P\d+.\d+)[.-]egg-info$", path) - if res: - return res.group('pyver') - return None - - def requirements_for_extra(self, extra): - extra_deps = [] - for req in self.requirements: - if not req.marker: - continue - if req.marker.evaluate(get_marker_env(self, extra)): - extra_deps.append(req) - return extra_deps - - def __repr__(self): - return '{} from {}'.format(self.name, self._path) - - -class RpmVersion(): - def __init__(self, version_id): - version = parse(version_id) - if isinstance(version._version, str): - self.version = version._version - else: - self.epoch = version._version.epoch - self.version = list(version._version.release) - self.pre = version._version.pre - self.dev = version._version.dev - self.post = version._version.post - - def increment(self): - self.version[-1] += 1 - self.pre = None - self.dev = None - self.post = None - return self - - def __str__(self): - if isinstance(self.version, str): - return self.version - if self.epoch: - rpm_epoch = str(self.epoch) + ':' - else: - rpm_epoch = '' - while len(self.version) > 1 and self.version[-1] == 0: - self.version.pop() - rpm_version = '.'.join(str(x) for x in self.version) - if self.pre: - rpm_suffix = '~{}'.format(''.join(str(x) for x in self.pre)) - elif self.dev: - rpm_suffix = '~~{}'.format(''.join(str(x) for x in self.dev)) - elif self.post: - rpm_suffix = '^post{}'.format(self.post[1]) - else: - rpm_suffix = '' - return '{}{}{}'.format(rpm_epoch, rpm_version, rpm_suffix) - - -def convert_compatible(name, operator, version_id): - if version_id.endswith('.*'): - print('Invalid requirement: {} {} {}'.format(name, operator, version_id)) - exit(65) # os.EX_DATAERR - version = RpmVersion(version_id) - if len(version.version) == 1: - print('Invalid requirement: {} {} {}'.format(name, operator, version_id)) - exit(65) # os.EX_DATAERR - upper_version = RpmVersion(version_id) - upper_version.version.pop() - upper_version.increment() - return '({} >= {} with {} < {})'.format( - name, version, name, upper_version) - - -def convert_equal(name, operator, version_id): - if version_id.endswith('.*'): - version_id = version_id[:-2] + '.0' - return convert_compatible(name, '~=', version_id) - version = RpmVersion(version_id) - return '{} = {}'.format(name, version) - - -def convert_arbitrary_equal(name, operator, version_id): - if version_id.endswith('.*'): - print('Invalid requirement: {} {} {}'.format(name, operator, version_id)) - exit(65) # os.EX_DATAERR - version = RpmVersion(version_id) - return '{} = {}'.format(name, version) - - -def convert_not_equal(name, operator, version_id): - if version_id.endswith('.*'): - version_id = version_id[:-2] - version = RpmVersion(version_id) - lower_version = RpmVersion(version_id).increment() - else: - version = RpmVersion(version_id) - lower_version = version - return '({} < {} or {} > {})'.format( - name, version, name, lower_version) - - -def convert_ordered(name, operator, version_id): - if version_id.endswith('.*'): - # PEP 440 does not define semantics for prefix matching - # with ordered comparisons - version_id = version_id[:-2] - version = RpmVersion(version_id) - if operator == '>': - # distutils will allow a prefix match with '>' - operator = '>=' - if operator == '<=': - # distutils will not allow a prefix match with '<=' - operator = '<' - else: - version = RpmVersion(version_id) - return '{} {} {}'.format(name, operator, version) - - -OPERATORS = {'~=': convert_compatible, - '==': convert_equal, - '===': convert_arbitrary_equal, - '!=': convert_not_equal, - '<=': convert_ordered, - '<': convert_ordered, - '>=': convert_ordered, - '>': convert_ordered} - - -def convert(name, operator, version_id): - try: - return OPERATORS[operator](name, operator, version_id) - except Exception as exc: - raise RuntimeError("Cannot process Python package version `{}` for name `{}`". - format(version_id, name)) from exc - - -def get_marker_env(dist, extra): - # packaging uses a default environment using - # platform.python_version to evaluate if a dependency is relevant - # based on environment markers [1], - # e.g. requirement `argparse;python_version<"2.7"` - # - # Since we're running this script on one Python version while - # possibly evaluating packages for different versions, we - # set up an environment with the version we want to evaluate. - # - # [1] https://www.python.org/dev/peps/pep-0508/#environment-markers - return {"python_full_version": dist.py_version, - "python_version": dist.py_version, - "extra": extra} - - -if __name__ == "__main__": - """To allow this script to be importable (and its classes/functions - reused), actions are performed only when run as a main script.""" - - parser = argparse.ArgumentParser(prog=argv[0]) - group = parser.add_mutually_exclusive_group(required=True) - group.add_argument('-P', '--provides', action='store_true', help='Print Provides') - group.add_argument('-R', '--requires', action='store_true', help='Print Requires') - group.add_argument('-r', '--recommends', action='store_true', help='Print Recommends') - group.add_argument('-C', '--conflicts', action='store_true', help='Print Conflicts') - group.add_argument('-E', '--extras', action='store_true', help='Print Extras') - group_majorver = parser.add_mutually_exclusive_group() - group_majorver.add_argument('-M', '--majorver-provides', action='store_true', help='Print extra Provides with Python major version only') - group_majorver.add_argument('--majorver-provides-versions', action='append', - help='Print extra Provides with Python major version only for listed ' - 'Python VERSIONS (appended or comma separated without spaces, e.g. 2.7,3.9)') - parser.add_argument('-m', '--majorver-only', action='store_true', help='Print Provides/Requires with Python major version only') - parser.add_argument('-n', '--normalized-names-format', action='store', - default="legacy-dots", choices=["pep503", "legacy-dots"], - help='Format of normalized names according to pep503 or legacy format that allows dots [default]') - parser.add_argument('--normalized-names-provide-both', action='store_true', - 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('files', nargs=argparse.REMAINDER) - args = parser.parse_args() - - py_abi = args.requires - py_deps = {} - - if args.majorver_provides_versions: - # Go through the arguments (can be specified multiple times), - # and parse individual versions (can be comma-separated) - args.majorver_provides_versions = [v for vstring in args.majorver_provides_versions - for v in vstring.split(",")] - - # If normalized_names_require_pep503 is True we require the pep503 - # normalized name, if it is False we provide the legacy normalized name - normalized_names_require_pep503 = args.normalized_names_format == "pep503" - - # If normalized_names_provide_pep503/legacy is True we provide the - # pep503/legacy normalized name, if it is False we don't - normalized_names_provide_pep503 = \ - args.normalized_names_format == "pep503" or args.normalized_names_provide_both - normalized_names_provide_legacy = \ - args.normalized_names_format == "legacy-dots" or args.normalized_names_provide_both - - # At least one type of normalization must be provided - assert normalized_names_provide_pep503 or normalized_names_provide_legacy - - for f in (args.files or stdin.readlines()): - f = f.strip() - lower = f.lower() - name = 'python(abi)' - # add dependency based on path, versioned if within versioned python directory - if py_abi and (lower.endswith('.py') or lower.endswith('.pyc') or lower.endswith('.pyo')): - if name not in py_deps: - py_deps[name] = [] - purelib = get_python_lib(standard_lib=0, plat_specific=0).split(version[:3])[0] - platlib = get_python_lib(standard_lib=0, plat_specific=1).split(version[:3])[0] - for lib in (purelib, platlib): - if lib in f: - spec = ('==', f.split(lib)[1].split(sep)[0]) - if spec not in py_deps[name]: - py_deps[name].append(spec) - - # XXX: hack to workaround RPM internal dependency generator not passing directories - lower_dir = dirname(lower) - if lower_dir.endswith('.egg') or \ - lower_dir.endswith('.egg-info') or \ - lower_dir.endswith('.dist-info'): - lower = lower_dir - f = dirname(f) - # Determine provide, requires, conflicts & recommends based on egg/dist metadata - if lower.endswith('.egg') or \ - lower.endswith('.egg-info') or \ - lower.endswith('.dist-info'): - dist = Distribution(f) - if not dist.py_version: - warn("Version for {!r} has not been found".format(dist), RuntimeWarning) - continue - - if args.majorver_provides or args.majorver_provides_versions or \ - args.majorver_only or args.legacy_provides or args.legacy: - # Get the Python major version - pyver_major = dist.py_version.split('.')[0] - if args.provides: - # If egg/dist metadata says package name is python, we provide python(abi) - if dist.normalized_name == 'python': - name = 'python(abi)' - if name not in py_deps: - py_deps[name] = [] - py_deps[name].append(('==', dist.py_version)) - if not args.legacy or not args.majorver_only: - if normalized_names_provide_legacy: - name = 'python{}dist({})'.format(dist.py_version, dist.legacy_normalized_name) - if name not in py_deps: - py_deps[name] = [] - if normalized_names_provide_pep503: - name_ = 'python{}dist({})'.format(dist.py_version, dist.normalized_name) - if name_ not in py_deps: - py_deps[name_] = [] - if args.majorver_provides or args.majorver_only or \ - (args.majorver_provides_versions and dist.py_version in args.majorver_provides_versions): - if normalized_names_provide_legacy: - pymajor_name = 'python{}dist({})'.format(pyver_major, dist.legacy_normalized_name) - if pymajor_name not in py_deps: - py_deps[pymajor_name] = [] - if normalized_names_provide_pep503: - pymajor_name_ = 'python{}dist({})'.format(pyver_major, dist.normalized_name) - if pymajor_name_ not in py_deps: - py_deps[pymajor_name_] = [] - if args.legacy or args.legacy_provides: - legacy_name = 'pythonegg({})({})'.format(pyver_major, dist.legacy_normalized_name) - if legacy_name not in py_deps: - py_deps[legacy_name] = [] - if dist.version: - version = dist.version - spec = ('==', version) - - if normalized_names_provide_legacy: - if spec not in py_deps[name]: - py_deps[name].append(spec) - if args.majorver_provides or \ - (args.majorver_provides_versions and dist.py_version in args.majorver_provides_versions): - py_deps[pymajor_name].append(spec) - if normalized_names_provide_pep503: - if spec not in py_deps[name_]: - py_deps[name_].append(spec) - if args.majorver_provides or \ - (args.majorver_provides_versions and dist.py_version in args.majorver_provides_versions): - py_deps[pymajor_name_].append(spec) - if args.legacy or args.legacy_provides: - if spec not in py_deps[legacy_name]: - py_deps[legacy_name].append(spec) - if args.requires or (args.recommends and dist.extras): - name = 'python(abi)' - # If egg/dist metadata says package name is python, we don't add dependency on python(abi) - if dist.normalized_name == 'python': - py_abi = False - if name in py_deps: - py_deps.pop(name) - elif py_abi and dist.py_version: - if name not in py_deps: - py_deps[name] = [] - spec = ('==', dist.py_version) - if spec not in py_deps[name]: - py_deps[name].append(spec) - 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')) - # add requires/recommends based on egg/dist metadata - for dep in deps: - if normalized_names_require_pep503: - dep_normalized_name = dep.normalized_name - else: - dep_normalized_name = dep.legacy_normalized_name - - if args.legacy: - name = 'pythonegg({})({})'.format(pyver_major, dep.legacy_normalized_name) - else: - if args.majorver_only: - name = 'python{}dist({})'.format(pyver_major, dep_normalized_name) - else: - name = 'python{}dist({})'.format(dist.py_version, dep_normalized_name) - if dep.marker and not args.recommends: - if not dep.marker.evaluate(get_marker_env(dist, '')): - continue - if name not in py_deps: - py_deps[name] = [] - for spec in dep.specifier: - if (spec.operator, spec.version) not in py_deps[name]: - py_deps[name].append((spec.operator, spec.version)) - # Unused, for automatic sub-package generation based on 'extras' from egg/dist metadata - # TODO: implement in rpm later, or...? - if args.extras: - print(dist.extras) - for extra in dist.extras: - print('%%package\textras-{}'.format(extra)) - print('Summary:\t{} extra for {} python package'.format(extra, dist.legacy_normalized_name)) - print('Group:\t\tDevelopment/Python') - for dep in dist.requirements_for_extra(extra): - for spec in dep.specifier: - if spec.operator == '!=': - print('Conflicts:\t{} {} {}'.format(dep.legacy_normalized_name, '==', spec.version)) - else: - print('Requires:\t{} {} {}'.format(dep.legacy_normalized_name, spec.operator, spec.version)) - print('%%description\t{}'.format(extra)) - print('{} extra for {} python package'.format(extra, dist.legacy_normalized_name)) - print('%%files\t\textras-{}\n'.format(extra)) - if args.conflicts: - # Should we really add conflicts for extras? - # Creating a meta package per extra with recommends on, which has - # the requires/conflicts in stead might be a better solution... - for dep in dist.requirements: - for spec in dep.specifier: - if spec.operator == '!=': - if dep.legacy_normalized_name not in py_deps: - py_deps[dep.legacy_normalized_name] = [] - spec = ('==', spec.version) - if spec not in py_deps[dep.legacy_normalized_name]: - py_deps[dep.legacy_normalized_name].append(spec) - - for name in sorted(py_deps): - if py_deps[name]: - # Print out versioned provides, requires, recommends, conflicts - spec_list = [] - for spec in py_deps[name]: - spec_list.append(convert(name, spec[0], spec[1])) - if len(spec_list) == 1: - print(spec_list[0]) - else: - # Sort spec_list so that the results can be tested easily - print('({})'.format(' with '.join(sorted(spec_list)))) - else: - # Print out unversioned provides, requires, recommends, conflicts - print(name)