Compare commits

...

No commits in common. 'i8c' and 'c9' have entirely different histories.
i8c ... c9

2
.gitignore vendored

@ -1 +1 @@
SOURCES/setuptools-39.2.0.zip SOURCES/setuptools-53.0.0.tar.gz

@ -1 +1 @@
83e75ec6b04423735e0a9a384b465c68f5206bcf SOURCES/setuptools-39.2.0.zip 878b8c351cac940e0b9fd1ba3ad49665dfc2889c SOURCES/setuptools-53.0.0.tar.gz

@ -0,0 +1,170 @@
From 21b122e06969a9d85c65ce8276519d34da7dc747 Mon Sep 17 00:00:00 2001
From: Melissa Li <li.melissa.kun@gmail.com>
Date: Tue, 23 Feb 2021 21:23:35 -0500
Subject: [PATCH 1/6] Preserve case-sensitive keys in setup.cfg
---
setuptools/dist.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/setuptools/dist.py b/setuptools/dist.py
index 050388de16..c31020f0c4 100644
--- a/setuptools/dist.py
+++ b/setuptools/dist.py
@@ -583,6 +583,7 @@ def _parse_config_files(self, filenames=None): # noqa: C901
self.announce("Distribution.parse_config_files():")
parser = ConfigParser()
+ parser.optionxform = str
for filename in filenames:
with io.open(filename, encoding='utf-8') as reader:
if DEBUG:
From 90d8740c353ddf20c1c76d8c06cd923c19b8cc84 Mon Sep 17 00:00:00 2001
From: Melissa Li <li.melissa.kun@gmail.com>
Date: Tue, 23 Feb 2021 21:06:55 -0500
Subject: [PATCH 2/6] Add case-sensitive entry point name test
---
setuptools/tests/test_config.py | 34 +++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/setuptools/tests/test_config.py b/setuptools/tests/test_config.py
index 1dee12718f..6cc1d0a46b 100644
--- a/setuptools/tests/test_config.py
+++ b/setuptools/tests/test_config.py
@@ -802,6 +802,40 @@ def test_entry_points(self, tmpdir):
with get_dist(tmpdir) as dist:
assert dist.entry_points == expected
+ def test_case_sensitive_entry_points(self, tmpdir):
+ _, config = fake_env(
+ tmpdir,
+ '[options.entry_points]\n'
+ 'GROUP1 = point1 = pack.module:func, '
+ '.point2 = pack.module2:func_rest [rest]\n'
+ 'group2 = point3 = pack.module:func2\n'
+ )
+
+ with get_dist(tmpdir) as dist:
+ assert dist.entry_points == {
+ 'GROUP1': [
+ 'point1 = pack.module:func',
+ '.point2 = pack.module2:func_rest [rest]',
+ ],
+ 'group2': ['point3 = pack.module:func2']
+ }
+
+ expected = (
+ '[blogtool.parsers]\n'
+ '.rst = some.nested.module:SomeClass.some_classmethod[reST]\n'
+ )
+
+ tmpdir.join('entry_points').write(expected)
+
+ # From file.
+ config.write(
+ '[options]\n'
+ 'entry_points = file: entry_points\n'
+ )
+
+ with get_dist(tmpdir) as dist:
+ assert dist.entry_points == expected
+
def test_data_files(self, tmpdir):
fake_env(
tmpdir,
From 39659040bda0664ee08588ecd2faa41b4ea406a1 Mon Sep 17 00:00:00 2001
From: Melissa Li <li.melissa.kun@gmail.com>
Date: Wed, 24 Feb 2021 00:31:16 -0500
Subject: [PATCH 3/6] Add change note
---
changelog.d/1937.breaking.rst | 1 +
1 file changed, 1 insertion(+)
create mode 100644 changelog.d/1937.breaking.rst
diff --git a/changelog.d/1937.breaking.rst b/changelog.d/1937.breaking.rst
new file mode 100644
index 0000000000..94dc739ab6
--- /dev/null
+++ b/changelog.d/1937.breaking.rst
@@ -0,0 +1 @@
+Preserved case-sensitivity of keys in setup.cfg so that entry point names are case-sensitive. Changed sensitivity of configparser -- by :user:`melissa-kun-li`
\ No newline at end of file
From 7f3e6d688e5ff080ee6bd7ccc6bd81a87c05cfd7 Mon Sep 17 00:00:00 2001
From: Melissa Li <li.melissa.kun@gmail.com>
Date: Wed, 24 Feb 2021 23:57:59 -0500
Subject: [PATCH 4/6] Update test for case-sensitive entry point names
---
setuptools/tests/test_config.py | 16 ----------------
1 file changed, 16 deletions(-)
diff --git a/setuptools/tests/test_config.py b/setuptools/tests/test_config.py
index 6cc1d0a46b..649075609a 100644
--- a/setuptools/tests/test_config.py
+++ b/setuptools/tests/test_config.py
@@ -820,22 +820,6 @@ def test_case_sensitive_entry_points(self, tmpdir):
'group2': ['point3 = pack.module:func2']
}
- expected = (
- '[blogtool.parsers]\n'
- '.rst = some.nested.module:SomeClass.some_classmethod[reST]\n'
- )
-
- tmpdir.join('entry_points').write(expected)
-
- # From file.
- config.write(
- '[options]\n'
- 'entry_points = file: entry_points\n'
- )
-
- with get_dist(tmpdir) as dist:
- assert dist.entry_points == expected
-
def test_data_files(self, tmpdir):
fake_env(
tmpdir,
From 11529db0de4081404b37fab17711660faa85abb8 Mon Sep 17 00:00:00 2001
From: Melissa Li <li.melissa.kun@gmail.com>
Date: Thu, 25 Feb 2021 00:00:23 -0500
Subject: [PATCH 5/6] Update change log
---
changelog.d/1937.change.rst | 1 +
1 file changed, 1 insertion(+)
create mode 100644 changelog.d/1937.change.rst
diff --git a/changelog.d/1937.change.rst b/changelog.d/1937.change.rst
new file mode 100644
index 0000000000..acd4305968
--- /dev/null
+++ b/changelog.d/1937.change.rst
@@ -0,0 +1 @@
+Preserved case-sensitivity of keys in setup.cfg so that entry point names are case-sensitive. Changed sensitivity of configparser. NOTE: Any projects relying on case-insensitivity will need to adapt to accept the original case as published. -- by :user:`melissa-kun-li`
\ No newline at end of file
From 898a0b59427f143efe0bcc0cabf69007fb3ee439 Mon Sep 17 00:00:00 2001
From: "Jason R. Coombs" <jaraco@jaraco.com>
Date: Thu, 25 Feb 2021 08:57:04 -0500
Subject: [PATCH 6/6] Remove 'breaking' changelog, superseded by 'change'.
---
changelog.d/1937.breaking.rst | 1 -
1 file changed, 1 deletion(-)
delete mode 100644 changelog.d/1937.breaking.rst
diff --git a/changelog.d/1937.breaking.rst b/changelog.d/1937.breaking.rst
deleted file mode 100644
index 94dc739ab6..0000000000
--- a/changelog.d/1937.breaking.rst
+++ /dev/null
@@ -1 +0,0 @@
-Preserved case-sensitivity of keys in setup.cfg so that entry point names are case-sensitive. Changed sensitivity of configparser -- by :user:`melissa-kun-li`
\ No newline at end of file

@ -1,8 +1,8 @@
diff --git a/setuptools/package_index.py b/setuptools/package_index.py diff --git a/setuptools/package_index.py b/setuptools/package_index.py
index b6407be..bdcf4a6 100755 index 123e958..a90b810 100644
--- a/setuptools/package_index.py --- a/setuptools/package_index.py
+++ b/setuptools/package_index.py +++ b/setuptools/package_index.py
@@ -212,7 +212,7 @@ def unique_values(func): @@ -215,7 +215,7 @@ def unique_values(func):
return wrapper return wrapper
@ -12,19 +12,17 @@ index b6407be..bdcf4a6 100755
diff --git a/setuptools/tests/test_packageindex.py b/setuptools/tests/test_packageindex.py diff --git a/setuptools/tests/test_packageindex.py b/setuptools/tests/test_packageindex.py
index 63b9294..49bd819 100644 index 8e9435e..bc1e373 100644
--- a/setuptools/tests/test_packageindex.py --- a/setuptools/tests/test_packageindex.py
+++ b/setuptools/tests/test_packageindex.py +++ b/setuptools/tests/test_packageindex.py
@@ -223,6 +223,12 @@ class TestPackageIndex: @@ -308,3 +308,10 @@ class TestPyPIConfig:
assert dists[0].version == '' cred = cfg.creds_by_repository['https://pypi.org']
assert dists[1].version == vc assert cred.username == 'jaraco'
assert cred.password == 'pity%'
+ def test_REL_DoS(self):
+ """
+ REL should not hang on a contrived attack string.
+ """
+ setuptools.package_index.REL.search('< rel=' + ' ' * 2**12)
+ +
+@pytest.mark.timeout(1)
class TestContentCheckers: +def test_REL_DoS():
def test_md5(self): + """
+ REL should not hang on a contrived attack string.
+ """
+ setuptools.package_index.REL.search('< rel=' + ' ' * 2**12)

@ -1,14 +1,15 @@
From 8af1b3e03edc8a38565558aff3bf1689c1ca3545 Mon Sep 17 00:00:00 2001 From 39a1aa65fb4163d917131b4814d4c2dd2bf19677 Mon Sep 17 00:00:00 2001
From: Lumir Balhar <lbalhar@redhat.com> From: Lumir Balhar <lbalhar@redhat.com>
Date: Fri, 26 Jul 2024 13:49:11 +0200 Date: Wed, 24 Jul 2024 12:43:20 +0200
Subject: [PATCH] CVE-2024-6345 Subject: [PATCH] CVE-2024-6345
--- ---
setuptools/package_index.py | 23 +++++++++-------------- setuptools/package_index.py | 23 +++++++++-------------
1 file changed, 9 insertions(+), 14 deletions(-) setuptools/tests/test_packageindex.py | 28 +++++++++++++--------------
2 files changed, 23 insertions(+), 28 deletions(-)
diff --git a/setuptools/package_index.py b/setuptools/package_index.py diff --git a/setuptools/package_index.py b/setuptools/package_index.py
index bdcf4a6..1d3e5b4 100755 index 123e9582b..07cc8924b 100644
--- a/setuptools/package_index.py --- a/setuptools/package_index.py
+++ b/setuptools/package_index.py +++ b/setuptools/package_index.py
@@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
@ -17,24 +18,24 @@ index bdcf4a6..1d3e5b4 100755
import sys import sys
import os import os
import re import re
@@ -848,7 +849,7 @@ class PackageIndex(Environment): @@ -860,7 +861,7 @@ class PackageIndex(Environment):
def _download_svn(self, url, filename): def _download_svn(self, url, filename):
warnings.warn("SVN download support is deprecated", UserWarning)
url = url.split('#', 1)[0] # remove any fragment for svn's sake url = url.split('#', 1)[0] # remove any fragment for svn's sake
- creds = '' - creds = ''
+ creds = [] + creds = []
if url.lower().startswith('svn:') and '@' in url: if url.lower().startswith('svn:') and '@' in url:
scheme, netloc, path, p, q, f = urllib.parse.urlparse(url) scheme, netloc, path, p, q, f = urllib.parse.urlparse(url)
if not netloc and path.startswith('//') and '/' in path[2:]: if not netloc and path.startswith('//') and '/' in path[2:]:
@@ -857,14 +858,14 @@ class PackageIndex(Environment): @@ -869,14 +870,14 @@ class PackageIndex(Environment):
if auth: if auth:
if ':' in auth: if ':' in auth:
user, pw = auth.split(':', 1) user, pw = auth.split(':', 1)
- creds = " --username=%s --password=%s" % (user, pw) - creds = " --username=%s --password=%s" % (user, pw)
+ creds = ["--username=" + user, "--password=" + pw] + creds = [f"--username={user}", f"--password={pw}"]
else: else:
- creds = " --username=" + auth - creds = " --username=" + auth
+ creds = ["--username=" + auth] + creds = [f"--username={auth}"]
netloc = host netloc = host
parts = scheme, netloc, url, p, q, f parts = scheme, netloc, url, p, q, f
url = urllib.parse.urlunparse(parts) url = urllib.parse.urlunparse(parts)
@ -44,7 +45,7 @@ index bdcf4a6..1d3e5b4 100755
return filename return filename
@staticmethod @staticmethod
@@ -890,14 +891,11 @@ class PackageIndex(Environment): @@ -902,14 +903,11 @@ class PackageIndex(Environment):
url, rev = self._vcs_split_rev_from_url(url, pop_prefix=True) url, rev = self._vcs_split_rev_from_url(url, pop_prefix=True)
self.info("Doing git clone from %s to %s", url, filename) self.info("Doing git clone from %s to %s", url, filename)
@ -53,7 +54,7 @@ index bdcf4a6..1d3e5b4 100755
if rev is not None: if rev is not None:
self.info("Checking out %s", rev) self.info("Checking out %s", rev)
- os.system("(cd %s && git checkout --quiet %s)" % ( - os.system("git -C %s checkout --quiet %s" % (
- filename, - filename,
- rev, - rev,
- )) - ))
@ -61,7 +62,7 @@ index bdcf4a6..1d3e5b4 100755
return filename return filename
@@ -906,14 +904,11 @@ class PackageIndex(Environment): @@ -918,14 +916,11 @@ class PackageIndex(Environment):
url, rev = self._vcs_split_rev_from_url(url, pop_prefix=True) url, rev = self._vcs_split_rev_from_url(url, pop_prefix=True)
self.info("Doing hg clone from %s to %s", url, filename) self.info("Doing hg clone from %s to %s", url, filename)
@ -70,7 +71,7 @@ index bdcf4a6..1d3e5b4 100755
if rev is not None: if rev is not None:
self.info("Updating to %s", rev) self.info("Updating to %s", rev)
- os.system("(cd %s && hg up -C -r %s -q)" % ( - os.system("hg --cwd %s up -C -r %s -q" % (
- filename, - filename,
- rev, - rev,
- )) - ))
@ -78,6 +79,81 @@ index bdcf4a6..1d3e5b4 100755
return filename return filename
diff --git a/setuptools/tests/test_packageindex.py b/setuptools/tests/test_packageindex.py
index 8e9435efe..9289b9032 100644
--- a/setuptools/tests/test_packageindex.py
+++ b/setuptools/tests/test_packageindex.py
@@ -197,56 +197,56 @@ class TestPackageIndex:
url = 'git+https://github.example/group/project@master#egg=foo'
index = setuptools.package_index.PackageIndex()
- with mock.patch("os.system") as os_system_mock:
+ with mock.patch("subprocess.check_call") as subprocess_check_call_mock:
result = index.download(url, str(tmpdir))
- os_system_mock.assert_called()
+ subprocess_check_call_mock.assert_called()
expected_dir = str(tmpdir / 'project@master')
expected = (
'git clone --quiet '
'https://github.example/group/project {expected_dir}'
- ).format(**locals())
- first_call_args = os_system_mock.call_args_list[0][0]
+ ).format(**locals()).split()
+ first_call_args = subprocess_check_call_mock.call_args_list[0][0]
assert first_call_args == (expected,)
tmpl = 'git -C {expected_dir} checkout --quiet master'
- expected = tmpl.format(**locals())
- assert os_system_mock.call_args_list[1][0] == (expected,)
+ expected = tmpl.format(**locals()).split()
+ assert subprocess_check_call_mock.call_args_list[1][0] == (expected,)
assert result == expected_dir
def test_download_git_no_rev(self, tmpdir):
url = 'git+https://github.example/group/project#egg=foo'
index = setuptools.package_index.PackageIndex()
- with mock.patch("os.system") as os_system_mock:
+ with mock.patch("subprocess.check_call") as subprocess_check_call_mock:
result = index.download(url, str(tmpdir))
- os_system_mock.assert_called()
+ subprocess_check_call_mock.assert_called()
expected_dir = str(tmpdir / 'project')
expected = (
'git clone --quiet '
'https://github.example/group/project {expected_dir}'
- ).format(**locals())
- os_system_mock.assert_called_once_with(expected)
+ ).format(**locals()).split()
+ subprocess_check_call_mock.assert_called_once_with(expected)
def test_download_svn(self, tmpdir):
url = 'svn+https://svn.example/project#egg=foo'
index = setuptools.package_index.PackageIndex()
with pytest.warns(UserWarning):
- with mock.patch("os.system") as os_system_mock:
+ with mock.patch("subprocess.check_call") as subprocess_check_call_mock:
result = index.download(url, str(tmpdir))
- os_system_mock.assert_called()
+ subprocess_check_call_mock.assert_called()
expected_dir = str(tmpdir / 'project')
expected = (
'svn checkout -q '
'svn+https://svn.example/project {expected_dir}'
- ).format(**locals())
- os_system_mock.assert_called_once_with(expected)
+ ).format(**locals()).split()
+ subprocess_check_call_mock.assert_called_once_with(expected)
class TestContentCheckers:
-- --
2.45.2 2.45.2

@ -1,17 +0,0 @@
diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py
index 91c48b3..0c9b0f4 100755
--- a/setuptools/command/easy_install.py
+++ b/setuptools/command/easy_install.py
@@ -446,6 +446,12 @@ class easy_install(Command):
instdir = normalize_path(self.install_dir)
pth_file = os.path.join(instdir, 'easy-install.pth')
+ if not os.path.exists(instdir):
+ try:
+ os.makedirs(instdir)
+ except (OSError, IOError):
+ self.cant_write_to_target()
+
# Is it a configured, PYTHONPATH, implicit, or explicit site dir?
is_site_dir = instdir in self.all_site_dirs

@ -0,0 +1,650 @@
From 490a2b28fa2325f9929261aa2ee398fbb4c715dd Mon Sep 17 00:00:00 2001
From: Marc Mueller <30130371+cdce8p@users.noreply.github.com>
Date: Sat, 3 Apr 2021 16:12:19 -0400
Subject: [PATCH 1/2] license_files - Add support for glob patterns + add
default patterns
https://github.com/pypa/setuptools/pull/2620
---
changelog.d/2620.breaking.rst | 4 ++
changelog.d/2620.change.rst | 1 +
changelog.d/2620.deprecation.rst | 2 +
changelog.d/2620.doc.rst | 1 +
docs/references/keywords.rst | 11 +++++
docs/userguide/declarative_config.rst | 2 +-
setuptools/command/sdist.py | 55 +++++++++++++---------
setuptools/tests/test_egg_info.py | 68 +++++++++++++++++++++++++--
setuptools/tests/test_manifest.py | 1 +
9 files changed, 118 insertions(+), 27 deletions(-)
create mode 100644 changelog.d/2620.breaking.rst
create mode 100644 changelog.d/2620.change.rst
create mode 100644 changelog.d/2620.deprecation.rst
create mode 100644 changelog.d/2620.doc.rst
diff --git a/changelog.d/2620.breaking.rst b/changelog.d/2620.breaking.rst
new file mode 100644
index 00000000..431e7105
--- /dev/null
+++ b/changelog.d/2620.breaking.rst
@@ -0,0 +1,4 @@
+If neither ``license_file`` nor ``license_files`` is specified, the ``sdist``
+option will now auto-include files that match the following patterns:
+``LICEN[CS]E*``, ``COPYING*``, ``NOTICE*``, ``AUTHORS*``.
+This matches the behavior of ``bdist_wheel``. -- by :user:`cdce8p`
diff --git a/changelog.d/2620.change.rst b/changelog.d/2620.change.rst
new file mode 100644
index 00000000..5470592d
--- /dev/null
+++ b/changelog.d/2620.change.rst
@@ -0,0 +1 @@
+The ``license_file`` and ``license_files`` options now support glob patterns. -- by :user:`cdce8p`
diff --git a/changelog.d/2620.deprecation.rst b/changelog.d/2620.deprecation.rst
new file mode 100644
index 00000000..1af5f246
--- /dev/null
+++ b/changelog.d/2620.deprecation.rst
@@ -0,0 +1,2 @@
+The ``license_file`` option is now marked as deprecated.
+Use ``license_files`` instead. -- by :user:`cdce8p`
diff --git a/changelog.d/2620.doc.rst b/changelog.d/2620.doc.rst
new file mode 100644
index 00000000..7564adac
--- /dev/null
+++ b/changelog.d/2620.doc.rst
@@ -0,0 +1 @@
+Added documentation for the ``license_files`` option. -- by :user:`cdce8p`
diff --git a/docs/references/keywords.rst b/docs/references/keywords.rst
index 03ce9fa2..619b2d14 100644
--- a/docs/references/keywords.rst
+++ b/docs/references/keywords.rst
@@ -76,6 +76,17 @@ Keywords
``license``
A string specifying the license of the package.
+``license_file``
+
+ .. warning::
+ ``license_file`` is deprecated. Use ``license_files`` instead.
+
+``license_files``
+
+ A list of glob patterns for license related files that should be included.
+ If neither ``license_file`` nor ``license_files`` is specified, this option
+ defaults to ``LICEN[CS]E*``, ``COPYING*``, ``NOTICE*``, and ``AUTHORS*``.
+
``keywords``
A list of strings or a comma-separated string providing descriptive
meta-data. See: `PEP 0314`_.
diff --git a/docs/userguide/declarative_config.rst b/docs/userguide/declarative_config.rst
index bc66869b..1d2d66e2 100644
--- a/docs/userguide/declarative_config.rst
+++ b/docs/userguide/declarative_config.rst
@@ -184,7 +184,7 @@ maintainer_email maintainer-email str
classifiers classifier file:, list-comma
license str
license_file str
-license_files list-comma
+license_files list-comma 42.0.0
description summary file:, str
long_description long-description file:, str
long_description_content_type str 38.6.0
diff --git a/setuptools/command/sdist.py b/setuptools/command/sdist.py
index 887b7efa..a6ea814a 100644
--- a/setuptools/command/sdist.py
+++ b/setuptools/command/sdist.py
@@ -4,6 +4,7 @@ import os
import sys
import io
import contextlib
+from glob import iglob
from setuptools.extern import ordered_set
@@ -194,29 +195,41 @@ class sdist(sdist_add_defaults, orig.sdist):
"""Checks if license_file' or 'license_files' is configured and adds any
valid paths to 'self.filelist'.
"""
-
- files = ordered_set.OrderedSet()
-
opts = self.distribution.get_option_dict('metadata')
- # ignore the source of the value
- _, license_file = opts.get('license_file', (None, None))
-
- if license_file is None:
- log.debug("'license_file' option was not specified")
- else:
- files.add(license_file)
-
+ files = ordered_set.OrderedSet()
try:
- files.update(self.distribution.metadata.license_files)
+ license_files = self.distribution.metadata.license_files
except TypeError:
log.warn("warning: 'license_files' option is malformed")
-
- for f in files:
- if not os.path.exists(f):
- log.warn(
- "warning: Failed to find the configured license file '%s'",
- f)
- files.remove(f)
-
- self.filelist.extend(files)
+ license_files = ordered_set.OrderedSet()
+ patterns = license_files if isinstance(license_files, ordered_set.OrderedSet) \
+ else ordered_set.OrderedSet(license_files)
+
+ if 'license_file' in opts:
+ log.warn(
+ "warning: the 'license_file' option is deprecated, "
+ "use 'license_files' instead")
+ patterns.append(opts['license_file'][1])
+
+ if 'license_file' not in opts and 'license_files' not in opts:
+ # Default patterns match the ones wheel uses
+ # See https://wheel.readthedocs.io/en/stable/user_guide.html
+ # -> 'Including license files in the generated wheel file'
+ patterns = ('LICEN[CS]E*', 'COPYING*', 'NOTICE*', 'AUTHORS*')
+
+ for pattern in patterns:
+ for path in iglob(pattern):
+ if path.endswith('~'):
+ log.debug(
+ "ignoring license file '%s' as it looks like a backup",
+ path)
+ continue
+
+ if path not in files and os.path.isfile(path):
+ log.info(
+ "adding license file '%s' (matched pattern '%s')",
+ path, pattern)
+ files.add(path)
+
+ self.filelist.extend(sorted(files))
diff --git a/setuptools/tests/test_egg_info.py b/setuptools/tests/test_egg_info.py
index 1047468b..c93ed020 100644
--- a/setuptools/tests/test_egg_info.py
+++ b/setuptools/tests/test_egg_info.py
@@ -533,7 +533,7 @@ class TestEggInfo:
'setup.cfg': DALS("""
"""),
'LICENSE': "Test license"
- }, False), # no license_file attribute
+ }, True), # no license_file attribute, LICENSE auto-included
({
'setup.cfg': DALS("""
[metadata]
@@ -541,7 +541,15 @@ class TestEggInfo:
"""),
'MANIFEST.in': "exclude LICENSE",
'LICENSE': "Test license"
- }, False) # license file is manually excluded
+ }, False), # license file is manually excluded
+ pytest.param({
+ 'setup.cfg': DALS("""
+ [metadata]
+ license_file = LICEN[CS]E*
+ """),
+ 'LICENSE': "Test license",
+ }, True,
+ id="glob_pattern"),
])
def test_setup_cfg_license_file(
self, tmpdir_cwd, env, files, license_in_sources):
@@ -621,7 +629,7 @@ class TestEggInfo:
'setup.cfg': DALS("""
"""),
'LICENSE': "Test license"
- }, [], ['LICENSE']), # no license_files attribute
+ }, ['LICENSE'], []), # no license_files attribute, LICENSE auto-included
({
'setup.cfg': DALS("""
[metadata]
@@ -640,7 +648,36 @@ class TestEggInfo:
'MANIFEST.in': "exclude LICENSE-XYZ",
'LICENSE-ABC': "ABC license",
'LICENSE-XYZ': "XYZ license"
- }, ['LICENSE-ABC'], ['LICENSE-XYZ']) # subset is manually excluded
+ }, ['LICENSE-ABC'], ['LICENSE-XYZ']), # subset is manually excluded
+ pytest.param({
+ 'setup.cfg': "",
+ 'LICENSE-ABC': "ABC license",
+ 'COPYING-ABC': "ABC copying",
+ 'NOTICE-ABC': "ABC notice",
+ 'AUTHORS-ABC': "ABC authors",
+ 'LICENCE-XYZ': "XYZ license",
+ 'LICENSE': "License",
+ 'INVALID-LICENSE': "Invalid license",
+ }, [
+ 'LICENSE-ABC',
+ 'COPYING-ABC',
+ 'NOTICE-ABC',
+ 'AUTHORS-ABC',
+ 'LICENCE-XYZ',
+ 'LICENSE',
+ ], ['INVALID-LICENSE'],
+ # ('LICEN[CS]E*', 'COPYING*', 'NOTICE*', 'AUTHORS*')
+ id="default_glob_patterns"),
+ pytest.param({
+ 'setup.cfg': DALS("""
+ [metadata]
+ license_files =
+ LICENSE*
+ """),
+ 'LICENSE-ABC': "ABC license",
+ 'NOTICE-XYZ': "XYZ notice",
+ }, ['LICENSE-ABC'], ['NOTICE-XYZ'],
+ id="no_default_glob_patterns"),
])
def test_setup_cfg_license_files(
self, tmpdir_cwd, env, files, incl_licenses, excl_licenses):
@@ -745,7 +782,28 @@ class TestEggInfo:
'LICENSE-PQR': "PQR license",
'LICENSE-XYZ': "XYZ license"
# manually excluded
- }, ['LICENSE-XYZ'], ['LICENSE-ABC', 'LICENSE-PQR'])
+ }, ['LICENSE-XYZ'], ['LICENSE-ABC', 'LICENSE-PQR']),
+ pytest.param({
+ 'setup.cfg': DALS("""
+ [metadata]
+ license_file = LICENSE*
+ """),
+ 'LICENSE-ABC': "ABC license",
+ 'NOTICE-XYZ': "XYZ notice",
+ }, ['LICENSE-ABC'], ['NOTICE-XYZ'],
+ id="no_default_glob_patterns"),
+ pytest.param({
+ 'setup.cfg': DALS("""
+ [metadata]
+ license_file = LICENSE*
+ license_files =
+ NOTICE*
+ """),
+ 'LICENSE-ABC': "ABC license",
+ 'NOTICE-ABC': "ABC notice",
+ 'AUTHORS-ABC': "ABC authors",
+ }, ['LICENSE-ABC', 'NOTICE-ABC'], ['AUTHORS-ABC'],
+ id="combined_glob_patterrns"),
])
def test_setup_cfg_license_file_license_files(
self, tmpdir_cwd, env, files, incl_licenses, excl_licenses):
diff --git a/setuptools/tests/test_manifest.py b/setuptools/tests/test_manifest.py
index 82bdb9c6..589cefb2 100644
--- a/setuptools/tests/test_manifest.py
+++ b/setuptools/tests/test_manifest.py
@@ -55,6 +55,7 @@ def touch(filename):
default_files = frozenset(map(make_local_path, [
'README.rst',
'MANIFEST.in',
+ 'LICENSE',
'setup.py',
'app.egg-info/PKG-INFO',
'app.egg-info/SOURCES.txt',
From e1aa3949d2b0d610f6d83bc3c85d96c5c4cabd3a Mon Sep 17 00:00:00 2001
From: Marc Mueller <30130371+cdce8p@users.noreply.github.com>
Date: Sat, 22 May 2021 20:00:24 -0400
Subject: [PATCH 2/2] Add License-File field to package metadata
https://github.com/pypa/setuptools/pull/2645
---
changelog.d/2645.breaking.rst | 3 ++
changelog.d/2645.change.rst | 4 +++
setuptools/command/egg_info.py | 9 +++++-
setuptools/command/sdist.py | 46 --------------------------
setuptools/config.py | 5 +++
setuptools/dist.py | 54 ++++++++++++++++++++++++++++++-
setuptools/tests/test_egg_info.py | 54 ++++++++++++++++++++++++++++---
setuptools/tests/test_manifest.py | 1 -
8 files changed, 122 insertions(+), 54 deletions(-)
create mode 100644 changelog.d/2645.breaking.rst
create mode 100644 changelog.d/2645.change.rst
diff --git a/changelog.d/2645.breaking.rst b/changelog.d/2645.breaking.rst
new file mode 100644
index 00000000..b96b492a
--- /dev/null
+++ b/changelog.d/2645.breaking.rst
@@ -0,0 +1,3 @@
+License files excluded via the ``MANIFEST.in`` but matched by either
+the ``license_file`` (deprecated) or ``license_files`` options,
+will be nevertheless included in the source distribution. - by :user:`cdce8p`
diff --git a/changelog.d/2645.change.rst b/changelog.d/2645.change.rst
new file mode 100644
index 00000000..b22385c1
--- /dev/null
+++ b/changelog.d/2645.change.rst
@@ -0,0 +1,4 @@
+Added ``License-File`` (multiple) to the output package metadata.
+The field will contain the path of a license file, matched by the
+``license_file`` (deprecated) and ``license_files`` options,
+relative to ``.dist-info``. - by :user:`cdce8p`
diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py
index 1f120b67..18b81340 100644
--- a/setuptools/command/egg_info.py
+++ b/setuptools/command/egg_info.py
@@ -541,6 +541,7 @@ class manifest_maker(sdist):
self.add_defaults()
if os.path.exists(self.template):
self.read_template()
+ self.add_license_files()
self.prune_file_list()
self.filelist.sort()
self.filelist.remove_duplicates()
@@ -575,7 +576,6 @@ class manifest_maker(sdist):
def add_defaults(self):
sdist.add_defaults(self)
- self.check_license()
self.filelist.append(self.template)
self.filelist.append(self.manifest)
rcfiles = list(walk_revctrl())
@@ -592,6 +592,13 @@ class manifest_maker(sdist):
ei_cmd = self.get_finalized_command('egg_info')
self.filelist.graft(ei_cmd.egg_info)
+ def add_license_files(self):
+ license_files = self.distribution.metadata.license_files or []
+ for lf in license_files:
+ log.info("adding license file '%s'", lf)
+ pass
+ self.filelist.extend(license_files)
+
def prune_file_list(self):
build = self.get_finalized_command('build')
base_dir = self.distribution.get_fullname()
diff --git a/setuptools/command/sdist.py b/setuptools/command/sdist.py
index a6ea814a..4a014283 100644
--- a/setuptools/command/sdist.py
+++ b/setuptools/command/sdist.py
@@ -4,9 +4,6 @@ import os
import sys
import io
import contextlib
-from glob import iglob
-
-from setuptools.extern import ordered_set
from .py36compat import sdist_add_defaults
@@ -190,46 +187,3 @@ class sdist(sdist_add_defaults, orig.sdist):
continue
self.filelist.append(line)
manifest.close()
-
- def check_license(self):
- """Checks if license_file' or 'license_files' is configured and adds any
- valid paths to 'self.filelist'.
- """
- opts = self.distribution.get_option_dict('metadata')
-
- files = ordered_set.OrderedSet()
- try:
- license_files = self.distribution.metadata.license_files
- except TypeError:
- log.warn("warning: 'license_files' option is malformed")
- license_files = ordered_set.OrderedSet()
- patterns = license_files if isinstance(license_files, ordered_set.OrderedSet) \
- else ordered_set.OrderedSet(license_files)
-
- if 'license_file' in opts:
- log.warn(
- "warning: the 'license_file' option is deprecated, "
- "use 'license_files' instead")
- patterns.append(opts['license_file'][1])
-
- if 'license_file' not in opts and 'license_files' not in opts:
- # Default patterns match the ones wheel uses
- # See https://wheel.readthedocs.io/en/stable/user_guide.html
- # -> 'Including license files in the generated wheel file'
- patterns = ('LICEN[CS]E*', 'COPYING*', 'NOTICE*', 'AUTHORS*')
-
- for pattern in patterns:
- for path in iglob(pattern):
- if path.endswith('~'):
- log.debug(
- "ignoring license file '%s' as it looks like a backup",
- path)
- continue
-
- if path not in files and os.path.isfile(path):
- log.info(
- "adding license file '%s' (matched pattern '%s')",
- path, pattern)
- files.add(path)
-
- self.filelist.extend(sorted(files))
diff --git a/setuptools/config.py b/setuptools/config.py
index af3a3bcb..ece325e2 100644
--- a/setuptools/config.py
+++ b/setuptools/config.py
@@ -520,6 +520,11 @@ class ConfigMetadataHandler(ConfigHandler):
'obsoletes': parse_list,
'classifiers': self._get_parser_compound(parse_file, parse_list),
'license': exclude_files_parser('license'),
+ 'license_file': self._deprecated_config_handler(
+ exclude_files_parser('license_file'),
+ "The license_file parameter is deprecated, "
+ "use license_files instead.",
+ DeprecationWarning),
'license_files': parse_list,
'description': parse_file,
'long_description': parse_file,
diff --git a/setuptools/dist.py b/setuptools/dist.py
index 050388de..bc663e63 100644
--- a/setuptools/dist.py
+++ b/setuptools/dist.py
@@ -14,6 +14,7 @@ import distutils.dist
from distutils.util import strtobool
from distutils.debug import DEBUG
from distutils.fancy_getopt import translate_longopt
+from glob import iglob
import itertools
from collections import defaultdict
@@ -117,6 +118,8 @@ def read_pkg_file(self, file):
self.provides = None
self.obsoletes = None
+ self.license_files = _read_list('license-file')
+
def single_line(val):
# quick and dirty validation for description pypa/setuptools#1390
@@ -199,6 +202,7 @@ def write_pkg_file(self, file): # noqa: C901 # is too complex (14) # FIXME
for extra in self.provides_extras:
write_field('Provides-Extra', extra)
+ self._write_list(file, 'License-File', self.license_files or [])
sequence = tuple, list
@@ -398,7 +402,8 @@ class Distribution(_Distribution):
'long_description_content_type': None,
'project_urls': dict,
'provides_extras': ordered_set.OrderedSet,
- 'license_files': ordered_set.OrderedSet,
+ 'license_file': lambda: None,
+ 'license_files': lambda: None,
}
_patched_dist = None
@@ -557,6 +562,34 @@ class Distribution(_Distribution):
req.marker = None
return req
+ def _finalize_license_files(self):
+ """Compute names of all license files which should be included."""
+ license_files: Optional[List[str]] = self.metadata.license_files
+ patterns: List[str] = license_files if license_files else []
+
+ license_file: Optional[str] = self.metadata.license_file
+ if license_file and license_file not in patterns:
+ patterns.append(license_file)
+
+ if license_files is None and license_file is None:
+ # Default patterns match the ones wheel uses
+ # See https://wheel.readthedocs.io/en/stable/user_guide.html
+ # -> 'Including license files in the generated wheel file'
+ patterns = ('LICEN[CS]E*', 'COPYING*', 'NOTICE*', 'AUTHORS*')
+
+ self.metadata.license_files = list(
+ unique_everseen(self._expand_patterns(patterns)))
+
+ @staticmethod
+ def _expand_patterns(patterns):
+ return (
+ path
+ for pattern in patterns
+ for path in iglob(pattern)
+ if not path.endswith('~')
+ and os.path.isfile(path)
+ )
+
# FIXME: 'Distribution._parse_config_files' is too complex (14)
def _parse_config_files(self, filenames=None): # noqa: C901
"""
@@ -680,6 +713,7 @@ class Distribution(_Distribution):
parse_configuration(self, self.command_options,
ignore_option_errors=ignore_option_errors)
self._finalize_requires()
+ self._finalize_license_files()
def fetch_build_eggs(self, requires):
"""Resolve pre-setup requirements"""
@@ -1020,3 +1054,21 @@ class Distribution(_Distribution):
class DistDeprecationWarning(SetuptoolsDeprecationWarning):
"""Class for warning about deprecations in dist in
setuptools. Not ignored by default, unlike DeprecationWarning."""
+
+
+def unique_everseen(iterable, key=None):
+ "List unique elements, preserving order. Remember all elements ever seen."
+ # unique_everseen('AAAABBBCCDAABBB') --> A B C D
+ # unique_everseen('ABBCcAD', str.lower) --> A B C D
+ seen = set()
+ seen_add = seen.add
+ if key is None:
+ for element in itertools.filterfalse(seen.__contains__, iterable):
+ seen_add(element)
+ yield element
+ else:
+ for element in iterable:
+ k = key(element)
+ if k not in seen:
+ seen_add(k)
+ yield element
diff --git a/setuptools/tests/test_egg_info.py b/setuptools/tests/test_egg_info.py
index c93ed020..e8b49732 100644
--- a/setuptools/tests/test_egg_info.py
+++ b/setuptools/tests/test_egg_info.py
@@ -541,7 +541,7 @@ class TestEggInfo:
"""),
'MANIFEST.in': "exclude LICENSE",
'LICENSE': "Test license"
- }, False), # license file is manually excluded
+ }, True), # manifest is overwritten by license_file
pytest.param({
'setup.cfg': DALS("""
[metadata]
@@ -637,7 +637,7 @@ class TestEggInfo:
"""),
'MANIFEST.in': "exclude LICENSE",
'LICENSE': "Test license"
- }, [], ['LICENSE']), # license file is manually excluded
+ }, ['LICENSE'], []), # manifest is overwritten by license_files
({
'setup.cfg': DALS("""
[metadata]
@@ -648,7 +648,8 @@ class TestEggInfo:
'MANIFEST.in': "exclude LICENSE-XYZ",
'LICENSE-ABC': "ABC license",
'LICENSE-XYZ': "XYZ license"
- }, ['LICENSE-ABC'], ['LICENSE-XYZ']), # subset is manually excluded
+ # manifest is overwritten by license_files
+ }, ['LICENSE-ABC', 'LICENSE-XYZ'], []),
pytest.param({
'setup.cfg': "",
'LICENSE-ABC': "ABC license",
@@ -678,6 +679,17 @@ class TestEggInfo:
'NOTICE-XYZ': "XYZ notice",
}, ['LICENSE-ABC'], ['NOTICE-XYZ'],
id="no_default_glob_patterns"),
+ pytest.param({
+ 'setup.cfg': DALS("""
+ [metadata]
+ license_files =
+ LICENSE-ABC
+ LICENSE*
+ """),
+ 'LICENSE-ABC': "ABC license",
+ }, ['LICENSE-ABC'], [],
+ id="files_only_added_once",
+ ),
])
def test_setup_cfg_license_files(
self, tmpdir_cwd, env, files, incl_licenses, excl_licenses):
@@ -781,8 +793,8 @@ class TestEggInfo:
'LICENSE-ABC': "ABC license",
'LICENSE-PQR': "PQR license",
'LICENSE-XYZ': "XYZ license"
- # manually excluded
- }, ['LICENSE-XYZ'], ['LICENSE-ABC', 'LICENSE-PQR']),
+ # manifest is overwritten
+ }, ['LICENSE-ABC', 'LICENSE-PQR', 'LICENSE-XYZ'], []),
pytest.param({
'setup.cfg': DALS("""
[metadata]
@@ -825,6 +837,38 @@ class TestEggInfo:
for lf in excl_licenses:
assert sources_lines.count(lf) == 0
+ def test_license_file_attr_pkg_info(self, tmpdir_cwd, env):
+ """All matched license files should have a corresponding License-File."""
+ self._create_project()
+ build_files({
+ "setup.cfg": DALS("""
+ [metadata]
+ license_files =
+ NOTICE*
+ LICENSE*
+ """),
+ "LICENSE-ABC": "ABC license",
+ "LICENSE-XYZ": "XYZ license",
+ "NOTICE": "included",
+ "IGNORE": "not include",
+ })
+
+ environment.run_setup_py(
+ cmd=['egg_info'],
+ pypath=os.pathsep.join([env.paths['lib'], str(tmpdir_cwd)])
+ )
+ egg_info_dir = os.path.join('.', 'foo.egg-info')
+ with open(os.path.join(egg_info_dir, 'PKG-INFO')) as pkginfo_file:
+ pkg_info_lines = pkginfo_file.read().split('\n')
+ license_file_lines = [
+ line for line in pkg_info_lines if line.startswith('License-File:')]
+
+ # Only 'NOTICE', LICENSE-ABC', and 'LICENSE-XYZ' should have been matched
+ # Also assert that order from license_files is keeped
+ assert "License-File: NOTICE" == license_file_lines[0]
+ assert "License-File: LICENSE-ABC" in license_file_lines[1:]
+ assert "License-File: LICENSE-XYZ" in license_file_lines[1:]
+
def test_long_description_content_type(self, tmpdir_cwd, env):
# Test that specifying a `long_description_content_type` keyword arg to
# the `setup` function results in writing a `Description-Content-Type`
diff --git a/setuptools/tests/test_manifest.py b/setuptools/tests/test_manifest.py
index 589cefb2..82bdb9c6 100644
--- a/setuptools/tests/test_manifest.py
+++ b/setuptools/tests/test_manifest.py
@@ -55,7 +55,6 @@ def touch(filename):
default_files = frozenset(map(make_local_path, [
'README.rst',
'MANIFEST.in',
- 'LICENSE',
'setup.py',
'app.egg-info/PKG-INFO',
'app.egg-info/SOURCES.txt',

@ -1,359 +1,470 @@
%global srcname setuptools %global srcname setuptools
# WARNING When bootstrapping, disable tests as well, # The original RHEL 9 content set is defined by (build)dependencies
# because tests need pip. # of the packages in Fedora ELN. Hence we disable tests here
%bcond_with bootstrap # to prevent pulling many unwanted packages in.
# Once the RHEL 9 content set is defined and/or RHEL 9 forks from ELN,
# the conditional can be removed from the Fedora spec file.
# We intentionally keep this enabled on EPEL.
%if 0%{?rhel} >= 9 && !0%{?epel}
%bcond_with tests
%else
%bcond_without tests %bcond_without tests
%bcond_with py2_wheel
%if 0%{?rhel} && 0%{?rhel} <= 7
%global _without_python3 1
# define some macros for RHEL 6
%global __python2 %__python
%global python2_sitelib %python_sitelib
%endif %endif
# Note(hguemar): overrides must be placed *before* those # WARNING When bootstrapping, disable tests as well,
# Otherwise it doesn't work # because tests need pip.
%bcond_without python2 %bcond_with bootstrap
%bcond_without python3 # Similar to what we have in pythonX.Y.spec files.
# If enabled, provides unversioned executables and other stuff.
# Disable it if you build this package in an alternative stack.
%bcond_without main_python
%if %{without bootstrap} %if %{without bootstrap}
%global python_wheelname %{srcname}-%{version}-py2.py3-none-any.whl %global python_wheel_name %{srcname}-%{version}-py3-none-any.whl
%if %{with python2}
%global python2_wheelname %python_wheelname
%global python2_record %{python2_sitelib}/%{srcname}-%{version}.dist-info/RECORD
%global python2_wheeldir %{_datadir}/python2-wheels
%endif # with python2
%if %{with python3}
%global python3_wheelname %python_wheelname
%global python3_record %{python3_sitelib}/%{srcname}-%{version}.dist-info/RECORD %global python3_record %{python3_sitelib}/%{srcname}-%{version}.dist-info/RECORD
%global python3_wheeldir %{_datadir}/python3-wheels %endif
%endif # with python3
%endif # without bootstrap
Name: python-setuptools Name: python-setuptools
Version: 39.2.0 # When updating, update the bundled libraries versions bellow!
Release: 8%{?dist} Version: 53.0.0
Release: 12%{?dist}.1
Summary: Easily build and distribute Python packages Summary: Easily build and distribute Python packages
# setuptools is MIT
Group: Applications/System # appdirs is MIT
License: MIT # ordered-set is MIT
# packaging is BSD or ASL 2.0
# pyparsing is MIT
# the setuptools logo has unknown license and possible TM problems,
# but the sdist **does not** contain it,
# see https://github.com/pypa/setuptools/issues/2227
License: MIT and (BSD or ASL 2.0)
URL: https://pypi.python.org/pypi/%{srcname} URL: https://pypi.python.org/pypi/%{srcname}
Source0: https://files.pythonhosted.org/packages/source/s/%{srcname}/%{srcname}-%{version}.zip Source0: %{pypi_source %{srcname} %{version}}
# In Fedora, sudo setup.py install installs to /usr/local/lib/pythonX.Y/site-packages # Two backports related to the License-File metadata field
# But pythonX doesn't own that dir, that would be against FHS # Fixes https://bugzilla.redhat.com/2033994
# We need to create it if it doesn't exist #
# https://bugzilla.redhat.com/show_bug.cgi?id=1576924 # license_files - Add support for glob patterns + add default patterns
Patch0: create-site-packages.patch # https://github.com/pypa/setuptools/pull/2620
# included in setuptools 56+
#
# Add License-File field to package metadata
# https://github.com/pypa/setuptools/pull/2645
# included in setuptools 57+
# depends on the previous one
Patch1: license-file-metadata.patch
# Fix case sensitivity of entry point names and keys in setup.cfg
# Fixes https://bugzilla.redhat.com/2124281
Patch2: https://github.com/pypa/setuptools/pull/2580.patch
# Security fix for CVE-2022-40897 # Security fix for CVE-2022-40897
# Regular Expression Denial of Service (ReDoS) in package_index.py # Regular Expression Denial of Service (ReDoS) in package_index.py
# Resolved upstream: https://github.com/pypa/setuptools/commit/43a9c9bfa6aa626ec2a22540bea28d2ca77964be # Resolved upstream: https://github.com/pypa/setuptools/commit/43a9c9bfa6aa626ec2a22540bea28d2ca77964be
Patch1: CVE-2022-40897.patch Patch3: CVE-2022-40897.patch
# Security fix for CVE-2024-6345 # Security fix for CVE-2024-6345
# Remote code execution via download functions in the package_index module # Remote code execution via download functions in the package_index module
# Tracking bug: https://bugzilla.redhat.com/show_bug.cgi?id=2297771 # Tracking bug: https://bugzilla.redhat.com/show_bug.cgi?id=2297771
# Upstream solution: https://github.com/pypa/setuptools/pull/4332 # Upstream solution: https://github.com/pypa/setuptools/pull/4332
# Patch simplified because upstream doesn't support SVN anymore. # Patch simplified because upstream doesn't support SVN anymore.
Patch2: CVE-2024-6345.patch Patch4: CVE-2024-6345.patch
BuildArch: noarch BuildArch: noarch
BuildRequires: gcc BuildRequires: python%{python3_pkgversion}-devel
%if %{with python2}
BuildRequires: python2-devel
%if %{with py2_wheel}
BuildRequires: python2-pip
BuildRequires: python2-wheel
%endif # with py2_wheel
%endif # with python2
%if %{with python3}
BuildRequires: python3-devel
%if %{with tests} %if %{with tests}
BuildRequires: python3-pip BuildRequires: gcc
BuildRequires: python3-pytest BuildRequires: python%{python3_pkgversion}-pip
BuildRequires: python3-mock BuildRequires: python%{python3_pkgversion}-pytest
BuildRequires: python%{python3_pkgversion}-mock
BuildRequires: python%{python3_pkgversion}-pytest-fixture-config
BuildRequires: python%{python3_pkgversion}-pytest-virtualenv
BuildRequires: python%{python3_pkgversion}-jaraco-envs
%endif # with tests %endif # with tests
%if %{without bootstrap} %if %{without bootstrap}
BuildRequires: python3-pip BuildRequires: python%{python3_pkgversion}-pip
BuildRequires: python3-wheel BuildRequires: python%{python3_pkgversion}-wheel
BuildRequires: python%{python3_pkgversion}-setuptools
# python3 bootstrap: this is built before the final build of python3, which
# adds the dependency on python3-rpm-generators, so we require it manually
# The minimal version is for bundled provides verification script
BuildRequires: python3-rpm-generators >= 11-8
%endif # without bootstrap %endif # without bootstrap
%endif # with python3
# We're now back to setuptools as the package.
# Keep the python-distribute name active for a few releases. Eventually we'll
# want to get rid of the Provides and just keep the Obsoletes
Provides: python-distribute = %{version}-%{release}
Obsoletes: python-distribute < 0.6.36-2
%global _description \
Setuptools is a collection of enhancements to the Python distutils that allow \
you to more easily build and distribute Python packages, especially ones that \
have dependencies on other packages. \
\
This package also contains the runtime components of setuptools, necessary to \
execute the software that requires pkg_resources.py.
%description %_description
%if %{with python3}
%package -n platform-python-setuptools
Summary: Easily build and distribute Python 3 packages
Group: Applications/System
Conflicts: python3-setuptools < 39.2.0-4%{?dist}
%description -n platform-python-setuptools %_description
%endif # with python3
%if %{with python2}
%package -n python2-setuptools
Summary: Easily build and distribute Python packages
%{?python_provide:%python_provide python2-setuptools}
%description -n python2-setuptools %_description %description
Setuptools is a collection of enhancements to the Python distutils that allow
you to more easily build and distribute Python packages, especially ones that
have dependencies on other packages.
This package also contains the runtime components of setuptools, necessary to
execute the software that requires pkg_resources.
# Virtual provides for the packages bundled by setuptools.
# Bundled packages are defined in two files:
# - pkg_resources/_vendor/vendored.txt, and
# - setuptools/_vendor/vendored.txt
# Merge them to one and then generate the list with:
# %%{_rpmconfigdir}/pythonbundles.py --namespace 'python%%{python3_pkgversion}dist' allvendor.txt
%global bundled %{expand:
Provides: bundled(python%{python3_pkgversion}dist(appdirs)) = 1.4.3
Provides: bundled(python%{python3_pkgversion}dist(ordered-set)) = 3.1.1
Provides: bundled(python%{python3_pkgversion}dist(packaging)) = 20.4
Provides: bundled(python%{python3_pkgversion}dist(pyparsing)) = 2.2.1
}
%package -n python%{python3_pkgversion}-setuptools
Summary: Easily build and distribute Python 3 packages
%{bundled}
%endif # with python2 %if %{with bootstrap}
Provides: python%{python3_pkgversion}dist(setuptools) = %{version}
Provides: python%{python3_version}dist(setuptools) = %{version}
%endif
# For users who might see ModuleNotFoundError: No module named 'pkg_resoureces'
%py_provides python%{python3_pkgversion}-pkg_resources
%py_provides python%{python3_pkgversion}-pkg-resources
%if %{with python3} # Provide platform-python-setuptools for backwards compatibility with RHEL 8
%package -n python3-setuptools Provides: platform-python-setuptools = %{version}-%{release}
Summary: Easily build and distribute Python 3 packages
Group: Applications/System
Requires: platform-python-setuptools = %{version}-%{release}
%{?python_provide:%python_provide python3-setuptools}
%description -n python3-setuptools %_description %description -n python%{python3_pkgversion}-setuptools
Setuptools is a collection of enhancements to the Python 3 distutils that allow
you to more easily build and distribute Python 3 packages, especially ones that
have dependencies on other packages.
%endif # with python3 This package also contains the runtime components of setuptools, necessary to
execute the software that requires pkg_resources.
%if %{without bootstrap} %if %{without bootstrap}
%if %{with py2_wheel} %package -n %{python_wheel_pkg_prefix}-%{srcname}-wheel
%if %{with python2}
%package -n python2-setuptools-wheel
Summary: The setuptools wheel Summary: The setuptools wheel
%{bundled}
Provides: %{name}-wheel = %{version}-%{release}
Obsoletes: %{name}-wheel < %{version}-%{release}
%description -n python2-setuptools-wheel # Older versions of python3-libs expect Python wheels at the old unversioned
A Python wheel of setuptools to use with venv. # location, so we conflict with the old Python versions that wouldn't work with
%endif #with python2 # the new wheel location.
%endif #with py2_wheel Conflicts: python3-libs < 3.9.9-2
%if %{with python3} %description -n %{python_wheel_pkg_prefix}-%{srcname}-wheel
%package -n python3-setuptools-wheel
Summary: The setuptools wheel
%description -n python3-setuptools-wheel
A Python wheel of setuptools to use with venv. A Python wheel of setuptools to use with venv.
%endif #with python3 %endif
%endif #with bootstrap
%prep %prep
%autosetup -p1 -n %{srcname}-%{version} %autosetup -p1 -n %{srcname}-%{version}
%if %{without bootstrap}
# We can't remove .egg-info (but it doesn't matter, since it'll be rebuilt): # If we don't have setuptools installed yet, we use the pre-generated .egg-info
# The problem is that to properly execute setuptools' setup.py, # See https://github.com/pypa/setuptools/pull/2543
# it is needed for setuptools to be loaded as a Distribution # And https://github.com/pypa/setuptools/issues/2550
# (with egg-info or .dist-info dir), it's not sufficient rm -r %{srcname}.egg-info
# to just have them on PYTHONPATH %endif
# Running "setup.py install" without having setuptools installed
# as a distribution gives warnings such as
# ... distutils/dist.py:267: UserWarning: Unknown distribution option: 'entry_points'
# and doesn't create "easy_install" and .egg-info directory
# Note: this is only a problem if bootstrapping wheel or building on RHEL,
# otherwise setuptools are installed as dependency into buildroot
# Strip shbang # Strip shbang
find setuptools -name \*.py | xargs sed -i -e '1 {/^#!\//d}' find setuptools pkg_resources -name \*.py | xargs sed -i -e '1 {/^#!\//d}'
# Remove bundled exes # Remove bundled exes
rm -f setuptools/*.exe rm -f setuptools/*.exe
# These tests require internet connection # These tests require internet connection
rm setuptools/tests/test_integration.py rm setuptools/tests/test_integration.py
# We don't do linting or coverage here
sed -i pytest.ini -e 's/ --flake8//' \
-e 's/ --cov//'
%build %build
%if %{with python2}
%if %{with py2_wheel} && %{without bootstrap}
export RHEL_ALLOW_PYTHON2_FOR_BUILD=1
%py2_build_wheel
%else
export RHEL_ALLOW_PYTHON2_FOR_BUILD=1
%py2_build
%endif # without bootstrap + py2_wheel
%endif # with python2
%if %{with python3}
%if %{without bootstrap} %if %{without bootstrap}
%py3_build_wheel %py3_build_wheel
%else %else
%py3_build %py3_build
%endif # without bootstrap %endif
%endif # with python3
%install %install
# Must do the python3 install first because the scripts in /usr/bin are
# overwritten with every setup.py install (and we want the python2 version to
# be the default for now).
%if %{with python3}
%if %{without bootstrap} %if %{without bootstrap}
%py3_install_wheel %{python3_wheelname} %py3_install_wheel %{python_wheel_name}
# Remove /usr/bin/easy_install from the record as later on we delete the file
sed -i '/\/usr\/bin\/easy_install,/d' %{buildroot}%{python3_record}
%else %else
%py3_install %py3_install
%endif %endif
# TODO: we have to remove this by hand now, but it'd be nice if we wouldn't have to # This is not installed (in 45.2.0 anyway), but better be safe than sorry
# (pip install wheel doesn't overwrite) rm -rf %{buildroot}%{python3_sitelib}/{setuptools,pkg_resources}/tests
rm %{buildroot}%{_bindir}/easy_install
rm -rf %{buildroot}%{python3_sitelib}/setuptools/tests
%if %{without bootstrap} %if %{without bootstrap}
sed -i '/^setuptools\/tests\//d' %{buildroot}%{python3_record} sed -i '/^setuptools\/tests\//d' %{buildroot}%{python3_record}
%endif %endif
find %{buildroot}%{python3_sitelib} -name '*.exe' | xargs rm -f find %{buildroot}%{python3_sitelib} -name '*.exe' | xargs rm -f
%endif # with python3
%if %{with python2}
export RHEL_ALLOW_PYTHON2_FOR_BUILD=1
%if %{with py2_wheel}
%py2_install_wheel %{python2_wheelname}
%else
%py2_install
%endif #with py2_wheel
rm -rf %{buildroot}%{python2_sitelib}/setuptools/tests
%if %{with py2_wheel}
sed -i '/^setuptools\/tests\//d' %{buildroot}%{python2_record}
%endif # with py2_wheel
find %{buildroot}%{python2_sitelib} -name '*.exe' | xargs rm -f
%endif # with python2
# Don't ship these # Don't ship these
rm -r docs/{Makefile,conf.py,_*} rm -r docs/{conf.py,_*}
%if %{without bootstrap} %if %{without bootstrap}
%if %{with py2_wheel} mkdir -p %{buildroot}%{python_wheel_dir}
%if %{with python2} install -p dist/%{python_wheel_name} -t %{buildroot}%{python_wheel_dir}
mkdir -p %{buildroot}%{python2_wheeldir} %endif
install -p dist/%{python2_wheelname} -t %{buildroot}%{python2_wheeldir}
%endif #with python2
%endif #with py2_wheel
%if %{with python3}
mkdir -p %{buildroot}%{python3_wheeldir}
install -p dist/%{python3_wheelname} -t %{buildroot}%{python3_wheeldir}
%endif #with python3
%endif #with bootstrap
%if %{with tests} %if %{with tests}
%check %check
%if %{with python3} # Verify bundled provides are up to date
# --ignore=setuptools/tests/test_virtualenv.py: because virtualenv executable cat pkg_resources/_vendor/vendored.txt setuptools/_vendor/vendored.txt > allvendor.txt
# is configured only for Python 2 version of virtualenv—this needs to be fixed %{_rpmconfigdir}/pythonbundles.py allvendor.txt --namespace 'python%{python3_pkgversion}dist' --compare-with '%{bundled}'
# in the `python-pytest-virtualenv` package
PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=$(pwd) py.test-%{python3_version} --ignore=setuptools/tests/test_virtualenv.py # Regression test, the wheel should not be larger than 600 KiB
%endif # with python3 # https://bugzilla.redhat.com/show_bug.cgi?id=1914481#c3
test $(du dist/%{python_wheel_name} | cut -f1) -lt 600
# Upstream tests
# --ignore=pavement.py:
# pavement.py is only used by upstream to do releases and vendoring, we don't ship it
PYTHONPATH=$(pwd) %pytest --ignore=pavement.py
%endif # with tests %endif # with tests
%if %{with python2} %files -n python%{python3_pkgversion}-setuptools
%files -n python2-setuptools
%license LICENSE
%doc docs/* CHANGES.rst README.rst
%{python2_sitelib}/*
%{_bindir}/easy_install
%{_bindir}/easy_install-2.*
%endif # with python2
%if %{with python3}
%files -n python3-setuptools
%license LICENSE %license LICENSE
%doc docs/* CHANGES.rst README.rst %doc docs/* CHANGES.rst README.rst
# The easy_install-3 binary is created using alternatives
# defined in the python36 package
%{_bindir}/easy_install-3.*
%files -n platform-python-setuptools
%license LICENSE
%doc docs/* CHANGES.rst README.rst
%{python3_sitelib}/easy_install.py
%{python3_sitelib}/pkg_resources/ %{python3_sitelib}/pkg_resources/
%{python3_sitelib}/setuptools*/ %{python3_sitelib}/setuptools*/
%{python3_sitelib}/__pycache__/* %{python3_sitelib}/_distutils_hack/
%endif # with python3 %{python3_sitelib}/distutils-precedence.pth
%if %{without bootstrap} %if %{without bootstrap}
%if %{with py2_wheel} %files -n %{python_wheel_pkg_prefix}-%{srcname}-wheel
%if %{with python2}
%files -n python2-setuptools-wheel
%license LICENSE
# we own the dir for simplicity
%dir %{python2_wheeldir}/
%{python2_wheeldir}/%{python2_wheelname}
%endif #with python2
%endif #with py2_wheel
%if %{with python3}
%files -n python3-setuptools-wheel
%license LICENSE %license LICENSE
# we own the dir for simplicity # we own the dir for simplicity
%dir %{python3_wheeldir}/ %dir %{python_wheel_dir}/
%{python3_wheeldir}/%{python3_wheelname} %{python_wheel_dir}/%{python_wheel_name}
%endif #with python3 %endif
%endif #with bootstrap
%changelog %changelog
* Wed Jul 24 2024 Lumír Balhar <lbalhar@redhat.com> - 39.2.0-8 * Wed Jul 24 2024 Lumír Balhar <lbalhar@redhat.com> - 53.0.0-12.1
- Security fix for CVE-2024-6345 - Security fix for CVE-2024-6345
Resolves: RHEL-50470 Resolves: RHEL-50466
* Wed Jul 26 2023 MSVSphere Packaging Team <packager@msvsphere.ru> - 39.2.0-7
- Rebuilt for MSVSphere 8.8
* Wed Jan 11 2023 Charalampos Stratakis <cstratak@redhat.com> - 39.2.0-7 * Wed Jan 11 2023 Charalampos Stratakis <cstratak@redhat.com> - 53.0.0-12
- Security fix for CVE-2022-40897 - Security fix for CVE-2022-40897
Resolves: rhbz#2158559 Resolves: rhbz#2158559
* Wed Mar 25 2020 Charalampos Stratakis <cstratak@redhat.com> - 39.2.0-6 * Wed Sep 07 2022 Miro Hrončok <mhroncok@redhat.com> - 53.0.0-11
- Create /usr/local/lib/pythonX.Y when needed - Fix case sensitivity of entry point names and keys in setup.cfg
Resolves: rhbz#1808301 - Resolves: rhbz#2124281
* Wed Apr 17 2019 Petr Viktorin <pviktori@redhat.com> - 39.2.0-5 * Tue Feb 08 2022 Tomas Orsava <torsava@redhat.com> - 53.0.0-10
- Add subpackages with wheels - Add automatically generated Obsoletes tag with the python39- prefix
Resolves: rhbz#1718032 for smoother upgrade from RHEL8
- Related: rhbz#1990421
* Mon Oct 22 2018 Lumír Balhar <lbalhar@redhat.com> - 39.2.0-4 * Wed Jan 12 2022 Miro Hrončok <mhroncok@redhat.com> - 53.0.0-9
- New subpackage platform-python-setuptools without files from /usr/bin/* - Add License-File field to package metadata
- python3-setuptools contains only files from /usr/bin/* and depends - Resolves: rhbz#2033994
on platform-python-setuptools
- Resolves: rhbz#1641973
* Mon Jun 25 2018 Petr Viktorin <pviktori@redhat.com> - 39.2.0-3 * Wed Nov 24 2021 Tomas Orsava <torsava@redhat.com> - 53.0.0-8
- Allow Python 2 for build - Conflict with old Python versions that use the old unversioned wheel location
see https://hurl.corp.redhat.com/rhel8-py2 - Resolves: rhbz#1982668
* Fri Jun 22 2018 Petr Viktorin <pviktori@redhat.com> - 39.2.0-2 * Wed Sep 22 2021 Tomas Orsava <torsava@redhat.com> - 53.0.0-7
- Do not use wheel on Python 2 - Make the python-setuptools-wheel subpackage versioned (python3-setuptools-wheel),
and move its contents to a versioned directory /usr/share/python3-wheels
- Resolves: rhbz#1982668
* Tue Jun 19 2018 Charalampos Stratakis <cstratak@redhat.com> - 39.2.0-1 * Tue Aug 10 2021 Mohan Boddu <mboddu@redhat.com>
- update to 39.2.0 Fixes bug #1572889 - Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688
* Wed Jul 28 2021 Tomas Orsava <torsava@redhat.com> - 53.0.0-5
- Provide the platform-python-setuptools name for backwards compatibility
with RHEL 8
- Related: rhbz#1891487
* Mon Jun 21 2021 Lumír Balhar <lbalhar@redhat.com> - 53.0.0-4
- Add missing bundled provide - ordered-set
Related: rhbz#1950291
* Thu Apr 22 2021 Miro Hrončok <mhroncok@redhat.com> - 53.0.0-3
- Provide python3-pkg_resources
- Provide python3-pkg-resources
Resolves: rhbz#1947857
* Fri Apr 16 2021 Mohan Boddu <mboddu@redhat.com> - 53.0.0-2
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
* Tue Feb 02 2021 Miro Hrončok <mhroncok@redhat.com> - 53.0.0-1
- Update to 53.0.0
- https://setuptools.readthedocs.io/en/latest/history.html#v53-0-0
- Fixes: rhbz#1923249
* Tue Jan 26 2021 Lumír Balhar <lbalhar@redhat.com> - 52.0.0-1
- Update to 52.0.0 (#1917060)
- Removes easy_install module and executable
* Mon Jan 11 2021 Miro Hrončok <mhroncok@redhat.com> - 51.1.2-1
- Update to 51.1.2
- Removes tests from the wheel
- https://setuptools.readthedocs.io/en/latest/history.html#v51-1-2
- Fixes: rhbz#1914481
* Tue Dec 29 2020 Miro Hrončok <mhroncok@redhat.com> - 51.1.1-1
- Update to 51.1.1
- Fixes test failures with pip 20.3 as well as with pytest 6.2+
- Fixes: rhbz#1909575
* Fri Dec 4 2020 Miro Hrončok <mhroncok@redhat.com> - 50.3.2-2
- Disable tests in Fedora ELN (and RHEL)
* Tue Oct 20 2020 Tomas Hrnciar <thrnciar@redhat.com> - 50.3.2-1
- Update to 50.3.2 (#1889093)
* Fri Sep 04 2020 Tomas Hrnciar <thrnciar@redhat.com> - 50.1.0-1
- Update to 50.1.0 (#1873889)
* Fri Aug 21 2020 Petr Viktorin <pviktori@redhat.com> - 49.6.0-1
- Update to 49.6.0 (#1862791)
* Wed Jul 29 2020 Miro Hrončok <mhroncok@redhat.com> - 49.1.3-1
- Update to 49.1.3 (#1853597)
- https://setuptools.readthedocs.io/en/latest/history.html#v49-1-3
* Wed Jul 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 47.3.1-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Fri Jun 26 2020 Miro Hrončok <mhroncok@redhat.com> - 47.3.1-1
- Update to 47.3.1 (#1847049)
- https://setuptools.readthedocs.io/en/latest/history.html#v47-3-1
* Mon Jun 01 2020 Charalampos Stratakis <cstratak@redhat.com> - 47.1.1-1
- Update to 47.1.1 (#1841123)
- https://setuptools.readthedocs.io/en/latest/history.html#v47-1-1
* Sun May 24 2020 Miro Hrončok <mhroncok@redhat.com> - 46.4.0-4
- Rebuilt for Python 3.9
* Thu May 21 2020 Miro Hrončok <mhroncok@redhat.com> - 46.4.0-3
- Bootstrap for Python 3.9
* Thu May 21 2020 Miro Hrončok <mhroncok@redhat.com> - 46.4.0-2
- Bootstrap for Python 3.9
* Mon May 18 2020 Tomas Hrnciar <thrnciar@redhat.com> - 46.4.0-1
- Update to 46.4.0 (#1835411)
- https://setuptools.readthedocs.io/en/latest/history.html#v46-4-0
* Tue May 12 2020 Tomas Hrnciar <thrnciar@redhat.com> - 46.2.0-1
- Update to 46.2.0 (#1833826)
- https://setuptools.readthedocs.io/en/latest/history.html#v46-2-0
* Thu Mar 26 2020 Miro Hrončok <mhroncok@redhat.com> - 46.1.3-1
- Upgrade to 46.1.3 (#1817189)
- https://setuptools.readthedocs.io/en/latest/history.html#v46-1-3
* Tue Mar 10 2020 Miro Hrončok <mhroncok@redhat.com> - 46.0.0-1
- Upgrade to 46.0.0 (#1811340)
- https://setuptools.readthedocs.io/en/latest/history.html#v46-0-0
* Tue Feb 11 2020 Miro Hrončok <mhroncok@redhat.com> - 45.2.0-1
- Upgrade to 45.2.0 (#1775943)
- https://setuptools.readthedocs.io/en/latest/history.html#v45-2-0
- No longer supports Python 2
* Thu Jun 07 2018 Petr Viktorin <pviktori@redhat.com> - 39.0.1-2 * Thu Jan 30 2020 Fedora Release Engineering <releng@fedoraproject.org> - 41.6.0-2
- Remove test requirements on python2 packages and some exotic packages - Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
- Skip tests on Python 2
* Mon Nov 04 2019 Tomas Orsava <torsava@redhat.com> - 41.6.0-1
- Upgrade to 41.6.0 (#1758945).
- https://setuptools.readthedocs.io/en/latest/history.html#v41-6-0
- Disabled a failing upstream test: https://github.com/pypa/setuptools/issues/1896
* Tue Sep 03 2019 Randy Barlow <bowlofeggs@fedoraproject.org> - 41.2.0-1
- Upgrade to 41.2.0 (#1742718).
- https://setuptools.readthedocs.io/en/latest/history.html#v41-2-0
* Mon Aug 26 2019 Miro Hrončok <mhroncok@redhat.com> - 41.0.1-9
- Move python2-setuptools to a separate package
* Sun Aug 18 2019 Miro Hrončok <mhroncok@redhat.com> - 41.0.1-8
- Rebuilt for Python 3.8
* Wed Aug 14 2019 Miro Hrončok <mhroncok@redhat.com> - 41.0.1-7
- Bootstrap for Python 3.8
* Wed Aug 14 2019 Miro Hrončok <mhroncok@redhat.com> - 41.0.1-6
- Provide pythonXdist(setuptools) when bootstrapping
* Wed Aug 14 2019 Miro Hrončok <mhroncok@redhat.com> - 41.0.1-5
- Bootstrap for Python 3.8
* Fri Jul 26 2019 Fedora Release Engineering <releng@fedoraproject.org> - 41.0.1-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Tue Jul 16 2019 Miro Hrončok <mhroncok@redhat.com> - 41.0.1-3
- Make /usr/bin/easy_install Python 3
- Drop obsoleted Obsoletes
* Fri Jun 21 2019 Petr Viktorin <pviktori@redhat.com> - 41.0.1-2
- Remove optional test dependencies for Python 2
- Skip test_virtualenv on Python 2
* Thu Apr 25 2019 Miro Hrončok <mhroncok@redhat.com> - 41.0.1-1
- Update to 41.0.1 (#1695846)
- https://github.com/pypa/setuptools/blob/v41.0.1/CHANGES.rst
* Tue Feb 05 2019 Miro Hrončok <mhroncok@redhat.com> - 40.8.0-1
- Update to 40.8.0 (#1672756)
- https://github.com/pypa/setuptools/blob/v40.8.0/CHANGES.rst
* Sun Feb 03 2019 Miro Hrončok <mhroncok@redhat.com> - 40.7.3-1
- Hotfix update to 40.7.3 (#1672084)
- https://github.com/pypa/setuptools/blob/v40.7.3/CHANGES.rst
* Sat Feb 02 2019 Miro Hrončok <mhroncok@redhat.com> - 40.7.2-1
- Hotfix update to 40.7.2 (#1671608)
- https://github.com/pypa/setuptools/blob/v40.7.2/CHANGES.rst
* Sat Feb 02 2019 Fedora Release Engineering <releng@fedoraproject.org> - 40.7.1-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Tue Jan 29 2019 Miro Hrončok <mhroncok@redhat.com> - 40.7.1-1
- Hotfix update to 40.7.1 (#1670243)
- https://github.com/pypa/setuptools/blob/v40.7.1/CHANGES.rst
* Mon Jan 28 2019 Miro Hrončok <mhroncok@redhat.com> - 40.7.0-1
- Update to 40.7.0 (#1669876)
- https://github.com/pypa/setuptools/blob/v40.7.0/CHANGES.rst
* Mon Sep 24 2018 Miro Hrončok <mhroncok@redhat.com> - 40.4.3-1
- Update to 40.4.3 to fix dire DeprecationWarnings (#1627071)
- List vendored libraries
- https://github.com/pypa/setuptools/blob/v40.4.3/CHANGES.rst
* Wed Sep 19 2018 Randy Barlow <bowlofeggs@fedoraproject.org> - 40.4.1-1
- Update to 40.4.1 (#1599307).
- https://github.com/pypa/setuptools/blob/v40.4.1/CHANGES.rst
* Wed Aug 15 2018 Petr Viktorin <pviktori@redhat.com> - 39.2.0-7
- Add a subpackage with wheels
- Remove the python3 bcond
- Remove macros for RHEL 6
* Thu Jul 19 2018 Miro Hrončok <mhroncok@redhat.com> - 39.2.0-6
- Create /usr/local/lib/pythonX.Y when needed (#1576924)
* Sat Jul 14 2018 Fedora Release Engineering <releng@fedoraproject.org> - 39.2.0-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Mon Jun 18 2018 Miro Hrončok <mhroncok@redhat.com> - 39.2.0-4
- Rebuilt for Python 3.7
* Wed Jun 13 2018 Miro Hrončok <mhroncok@redhat.com> - 39.2.0-3
- Bootstrap for Python 3.7
* Wed Jun 13 2018 Miro Hrončok <mhroncok@redhat.com> - 39.2.0-2
- Bootstrap for Python 3.7
* Wed May 23 2018 Charalampos Stratakis <cstratak@redhat.com> - 39.2.0-1
- update to 39.2.0 Fixes bug #1572889
* Tue Mar 20 2018 Charalampos Stratakis <cstratak@redhat.com> - 39.0.1-1 * Tue Mar 20 2018 Charalampos Stratakis <cstratak@redhat.com> - 39.0.1-1
- update to 39.0.1 Fixes bug #1531527 - update to 39.0.1 Fixes bug #1531527

Loading…
Cancel
Save