Compare commits

...

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

2
.gitignore vendored

@ -1 +1 @@
SOURCES/setuptools-53.0.0.tar.gz SOURCES/setuptools-67.7.2.tar.gz

@ -1 +1 @@
878b8c351cac940e0b9fd1ba3ad49665dfc2889c SOURCES/setuptools-53.0.0.tar.gz caa89a603674611c904288ac13ef7f9592969881 SOURCES/setuptools-67.7.2.tar.gz

@ -1,170 +0,0 @@
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

@ -0,0 +1,41 @@
From 797316bb195387962758faaf85d6c453832ae61d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= <miro@hroncok.cz>
Date: Fri, 5 May 2023 17:53:11 +0200
Subject: [PATCH] Adjust the setup.py install deprecation message and URL
But only when building RPM packages.
---
setuptools/command/install.py | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/setuptools/command/install.py b/setuptools/command/install.py
index dec4e32..704a317 100644
--- a/setuptools/command/install.py
+++ b/setuptools/command/install.py
@@ -1,6 +1,7 @@
from distutils.errors import DistutilsArgError
import inspect
import glob
+import os
import platform
import distutils.command.install as orig
@@ -36,8 +37,13 @@ class install(orig.install):
Please avoid running ``setup.py`` directly.
Instead, use pypa/build, pypa/installer, pypa/build or
other standards-based tools.
- """,
- see_url="https://blog.ganssle.io/articles/2021/10/setup-py-deprecated.html",
+ """
+ + ("""
+ Follow the current Python packaging guidelines when building
+ Python RPM packages.
+ """ if "RPM_BUILD_ROOT" in os.environ else ""),
+ see_url=("https://blog.ganssle.io/articles/2021/10/setup-py-deprecated.html" +
+ ("\nand https://docs.fedoraproject.org/en-US/packaging-guidelines/Python/" if "RPM_BUILD_ROOT" in os.environ else "")),
# TODO: Document how to bootstrap setuptools without install
# (e.g. by unziping the wheel file)
# and then add a due_date to this warning.
--
2.40.0

@ -1,28 +0,0 @@
diff --git a/setuptools/package_index.py b/setuptools/package_index.py
index 123e958..a90b810 100644
--- a/setuptools/package_index.py
+++ b/setuptools/package_index.py
@@ -215,7 +215,7 @@ def unique_values(func):
return wrapper
-REL = re.compile(r"""<([^>]*\srel\s*=\s*['"]?([^'">]+)[^>]*)>""", re.I)
+REL = re.compile(r"""<([^>]*\srel\s{0,10}=\s{0,10}['"]?([^'" >]+)[^>]*)>""", re.I)
# this line is here to fix emacs' cruddy broken syntax highlighting
diff --git a/setuptools/tests/test_packageindex.py b/setuptools/tests/test_packageindex.py
index 8e9435e..bc1e373 100644
--- a/setuptools/tests/test_packageindex.py
+++ b/setuptools/tests/test_packageindex.py
@@ -308,3 +308,10 @@ class TestPyPIConfig:
cred = cfg.creds_by_repository['https://pypi.org']
assert cred.username == 'jaraco'
assert cred.password == 'pity%'
+
+@pytest.mark.timeout(1)
+def test_REL_DoS():
+ """
+ REL should not hang on a contrived attack string.
+ """
+ setuptools.package_index.REL.search('< rel=' + ' ' * 2**12)

@ -1,159 +0,0 @@
From 39a1aa65fb4163d917131b4814d4c2dd2bf19677 Mon Sep 17 00:00:00 2001
From: Lumir Balhar <lbalhar@redhat.com>
Date: Wed, 24 Jul 2024 12:43:20 +0200
Subject: [PATCH] CVE-2024-6345
---
setuptools/package_index.py | 23 +++++++++-------------
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
index 123e9582b..07cc8924b 100644
--- a/setuptools/package_index.py
+++ b/setuptools/package_index.py
@@ -1,4 +1,5 @@
"""PyPI and direct package downloading"""
+import subprocess
import sys
import os
import re
@@ -860,7 +861,7 @@ class PackageIndex(Environment):
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
- creds = ''
+ creds = []
if url.lower().startswith('svn:') and '@' in url:
scheme, netloc, path, p, q, f = urllib.parse.urlparse(url)
if not netloc and path.startswith('//') and '/' in path[2:]:
@@ -869,14 +870,14 @@ class PackageIndex(Environment):
if auth:
if ':' in auth:
user, pw = auth.split(':', 1)
- creds = " --username=%s --password=%s" % (user, pw)
+ creds = [f"--username={user}", f"--password={pw}"]
else:
- creds = " --username=" + auth
+ creds = [f"--username={auth}"]
netloc = host
parts = scheme, netloc, url, p, q, f
url = urllib.parse.urlunparse(parts)
self.info("Doing subversion checkout from %s to %s", url, filename)
- os.system("svn checkout%s -q %s %s" % (creds, url, filename))
+ subprocess.check_call(["svn", "checkout"] + creds + ["-q", url, filename])
return filename
@staticmethod
@@ -902,14 +903,11 @@ class PackageIndex(Environment):
url, rev = self._vcs_split_rev_from_url(url, pop_prefix=True)
self.info("Doing git clone from %s to %s", url, filename)
- os.system("git clone --quiet %s %s" % (url, filename))
+ subprocess.check_call(["git", "clone", "--quiet", url, filename])
if rev is not None:
self.info("Checking out %s", rev)
- os.system("git -C %s checkout --quiet %s" % (
- filename,
- rev,
- ))
+ subprocess.check_call(["git", "-C", filename, "checkout", "--quiet", rev])
return filename
@@ -918,14 +916,11 @@ class PackageIndex(Environment):
url, rev = self._vcs_split_rev_from_url(url, pop_prefix=True)
self.info("Doing hg clone from %s to %s", url, filename)
- os.system("hg clone --quiet %s %s" % (url, filename))
+ subprocess.check_call(["hg", "clone", "--quiet", url, filename])
if rev is not None:
self.info("Updating to %s", rev)
- os.system("hg --cwd %s up -C -r %s -q" % (
- filename,
- rev,
- ))
+ subprocess.check_call(["hg", "--cwd", filename, "up", "-C", "-r", rev, "-q"])
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

@ -0,0 +1,46 @@
From a03fa24ad65286ad9f2dc8bf1934bc84525ed06f Mon Sep 17 00:00:00 2001
From: Charalampos Stratakis <cstratak@redhat.com>
Date: Wed, 8 Mar 2023 02:48:31 +0100
Subject: [PATCH] Remove optional or unpackaged test deps
---
setup.cfg | 16 ----------------
1 file changed, 16 deletions(-)
diff --git a/setup.cfg b/setup.cfg
index 4791ed6..2776b31 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -39,20 +39,6 @@ exclude =
[options.extras_require]
testing =
pytest >= 6
- pytest-checkdocs >= 2.4
- pytest-flake8; \
- python_version < "3.12"
- flake8 < 5
- pytest-black >= 0.3.7; \
- python_implementation != "PyPy"
- pytest-cov; \
- python_implementation != "PyPy"
- pytest-mypy >= 0.9.1; \
- python_implementation != "PyPy"
- pytest-enabler >= 1.3
- pytest-perf
-
- flake8-2020
virtualenv>=13.0.0
wheel
pip>=19.1 # For proper file:// URLs support.
@@ -60,8 +46,6 @@ testing =
pytest-xdist
jaraco.path>=3.2.0
build[virtualenv]
- filelock>=3.4.0
- pip_run>=8.8
ini2toml[lite]>=0.9
tomli-w>=1.0.0
pytest-timeout
--
2.39.2

@ -0,0 +1,133 @@
# This patch combines two upstream fixes (mainly for tests), adapting to
# changes in Python 3.12:
# - Python 3.12 raises a warning if tarfile filter is not set for extractall.
# Tests do this, and fail on this warning.
# Set a "fully trusted" filter. (The tests create the archive, so it is
# trusted.)
# - https://github.com/pypa/setuptools/pull/3917
# - Python 3.12 venv no longer installs setuptools and wheel into new virtual
# environments. Adjust tests that assumed the old behaviour.
# Also, setting setuptools.__version__ assumed setuptools is installed.
# Set a valid dummy value if that's not the case.
# - https://github.com/pypa/setuptools/pull/3915
From 13887c8defa8f2042a5824da4fa049461e3718ac Mon Sep 17 00:00:00 2001
From: Steve Kowalik <steven@wedontsleep.org>
Date: Wed, 3 May 2023 12:02:19 +1000
Subject: [PATCH] tests: Add extraction_filter for tarfile
Python 3.12, and earlier via security backports now issue an
DeprecationWarning when calling tarfile.extractall without an extraction
filter set. Since the only place we've called extractall is literally
right after we've created the archive, use a fully trusted filter. This
can be replaced with a filter argument to extractall in future.
---
setuptools/tests/test_easy_install.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py
index 0ee9bea909..709964b3ac 100644
--- a/setuptools/tests/test_easy_install.py
+++ b/setuptools/tests/test_easy_install.py
@@ -697,6 +697,7 @@ def test_setup_requires_override_nspkg(self, use_setup_cfg):
foobar_1_dir = os.path.join(temp_dir, 'foo.bar-0.1')
os.mkdir(foobar_1_dir)
with tarfile.open(foobar_1_archive) as tf:
+ tf.extraction_filter = (lambda member, path: member)
tf.extractall(foobar_1_dir)
sys.path.insert(1, foobar_1_dir)
From 1bef1e2e793ca59828d7911f702ce05c098c0a74 Mon Sep 17 00:00:00 2001
From: Anderson Bravalheri <andersonbravalheri@gmail.com>
Date: Fri, 28 Apr 2023 12:20:33 +0100
Subject: [PATCH 1/3] Adequate venv fixtures to the latest change in virtualenv
Since version v20.23.0, `virtualenv` will no longer include `wheel` and
`setuptools` in the created folders.
Some tests in the setuptools test suite assume that these packages are
always present. So we need to adequate these tests.
---
setuptools/tests/fixtures.py | 4 +++-
setuptools/tests/test_virtualenv.py | 4 ++--
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/setuptools/tests/fixtures.py b/setuptools/tests/fixtures.py
index 25ab49fd22..f1cfc66c81 100644
--- a/setuptools/tests/fixtures.py
+++ b/setuptools/tests/fixtures.py
@@ -105,6 +105,8 @@ def venv(tmp_path, setuptools_wheel):
"""Virtual env with the version of setuptools under test installed"""
env = environment.VirtualEnv()
env.root = path.Path(tmp_path / 'venv')
+ env.create_opts = ['--no-setuptools', '--wheel=bundle']
+ # TODO: Use `--no-wheel` when setuptools implements its own bdist_wheel
env.req = str(setuptools_wheel)
# In some environments (eg. downstream distro packaging),
# where tox isn't used to run tests and PYTHONPATH is set to point to
@@ -125,7 +127,7 @@ def venv_without_setuptools(tmp_path):
"""Virtual env without any version of setuptools installed"""
env = environment.VirtualEnv()
env.root = path.Path(tmp_path / 'venv_without_setuptools')
- env.create_opts = ['--no-setuptools']
+ env.create_opts = ['--no-setuptools', '--no-wheel']
env.ensure_env()
return env
diff --git a/setuptools/tests/test_virtualenv.py b/setuptools/tests/test_virtualenv.py
index acfe04e9dd..b17be9ef2b 100644
--- a/setuptools/tests/test_virtualenv.py
+++ b/setuptools/tests/test_virtualenv.py
@@ -174,8 +174,8 @@ def sdist(distname, version):
def test_test_command_install_requirements(venv, tmpdir, tmpdir_cwd):
- # Ensure pip/wheel packages are installed.
- venv.run(["python", "-c", "__import__('pkg_resources').require(['pip', 'wheel'])"])
+ # Ensure pip is installed.
+ venv.run(["python", "-c", "import pip"])
# disable index URL so bits and bobs aren't requested from PyPI
with contexts.environment(PYTHONPATH=None, PIP_NO_INDEX="1"):
_check_test_command_install_requirements(venv, tmpdir)
From 70ed7894801a308d93b1d155b30ac58d8ef0accd Mon Sep 17 00:00:00 2001
From: Anderson Bravalheri <andersonbravalheri@gmail.com>
Date: Tue, 2 May 2023 17:16:33 +0100
Subject: [PATCH 2/3] Add news fragment
---
changelog.d/3915.misc.rst | 1 +
1 file changed, 1 insertion(+)
create mode 100644 changelog.d/3915.misc.rst
diff --git a/changelog.d/3915.misc.rst b/changelog.d/3915.misc.rst
new file mode 100644
index 0000000000..cd962b2c6e
--- /dev/null
+++ b/changelog.d/3915.misc.rst
@@ -0,0 +1 @@
+Adequate tests to the latest changes in ``virtualenv`` for Python 3.12.
From 3f172826492e99470db75a74cdaa5494ec3e932c Mon Sep 17 00:00:00 2001
From: Anderson Bravalheri <andersonbravalheri@gmail.com>
Date: Thu, 27 Apr 2023 16:30:41 +0100
Subject: [PATCH 3/3] Attempt to use a valid PEP 440 version fallback
---
setuptools/version.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/setuptools/version.py b/setuptools/version.py
index 75b2a14959..ec253c4144 100644
--- a/setuptools/version.py
+++ b/setuptools/version.py
@@ -1,6 +1,6 @@
from ._importlib import metadata
try:
- __version__ = metadata.version('setuptools')
+ __version__ = metadata.version('setuptools') or '0.dev0+unknown'
except Exception:
- __version__ = 'unknown'
+ __version__ = '0.dev0+unknown'

@ -1,650 +0,0 @@
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',

@ -0,0 +1,14 @@
# let's not report duplicate __init__s
addFilter(r'W: files-duplicate .+__init__\.py ')
# setuptools and pkg_resources have duplicated vendored libraries
# we might want to de-duplicate this somehow in the future, but not yet
# regex a bit complex to allow arbitrary order
addFilter(r'W: files-duplicate .+/(setuptools/_vendor/.+ .+/pkg_resources|pkg_resources/_vendor/.+ .+/setuptools)/_vendor/')
# When duplicate files are found, this errors is produced
# as long as we filter out the warnings, we need to filter the error as well
addFilter(r'E: files-duplicated-waste')
# no %doc in the wheel packages
addFilter(r'python-setuptools-wheel.noarch: (E|W): no-documentation')

@ -1,97 +1,82 @@
%global srcname setuptools %global srcname setuptools
# The original RHEL 9 content set is defined by (build)dependencies # used when bootstrapping new Python versions
# of the packages in Fedora ELN. Hence we disable tests here %bcond bootstrap 0
# 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
%endif
# WARNING When bootstrapping, disable tests as well,
# because tests need pip.
%bcond_with bootstrap
# Similar to what we have in pythonX.Y.spec files. # Similar to what we have in pythonX.Y.spec files.
# If enabled, provides unversioned executables and other stuff. # If enabled, provides unversioned executables and other stuff.
# Disable it if you build this package in an alternative stack. # Disable it if you build this package in an alternative stack.
%bcond_without main_python %bcond main_python 1
# The original RHEL N+1 content set is defined by (build)dependencies
# of the packages in Fedora ELN. Hence we disable tests and documentation here
# to prevent pulling many unwanted packages in.
# We intentionally keep this enabled on EPEL.
%bcond tests %[%{without bootstrap} && (%{defined fedora} || %{defined epel})]
%if %{without bootstrap}
%global python_wheel_name %{srcname}-%{version}-py3-none-any.whl %global python_wheel_name %{srcname}-%{version}-py3-none-any.whl
%global python3_record %{python3_sitelib}/%{srcname}-%{version}.dist-info/RECORD
%endif
Name: python-setuptools Name: python-setuptools
# When updating, update the bundled libraries versions bellow! # When updating, update the bundled libraries versions bellow!
Version: 53.0.0 Version: 67.7.2
Release: 12%{?dist}.1 Release: 7%{?dist}
Summary: Easily build and distribute Python packages Summary: Easily build and distribute Python packages
# setuptools is MIT # setuptools is MIT
# appdirs is MIT # platformdirs is MIT
# more-itertools is MIT
# ordered-set is MIT # ordered-set is MIT
# packaging is BSD or ASL 2.0 # packaging is BSD-2-Clause OR Apache-2.0
# pyparsing is MIT # importlib-metadata is Apache-2.0
# the setuptools logo has unknown license and possible TM problems, # importlib-resources is Apache-2.0
# but the sdist **does not** contain it, # jaraco.text is MIT
# see https://github.com/pypa/setuptools/issues/2227 # typing-extensions is Python-2.0.1
License: MIT and (BSD or ASL 2.0) # zipp is MIT
# nspektr is MIT
# tomli is MIT
# the setuptools logo is MIT
License: MIT AND Apache-2.0 AND (BSD-2-Clause OR Apache-2.0) AND Python-2.0.1
URL: https://pypi.python.org/pypi/%{srcname} URL: https://pypi.python.org/pypi/%{srcname}
Source0: %{pypi_source %{srcname} %{version}} Source0: %{pypi_source %{srcname} %{version}}
# Two backports related to the License-File metadata field # Some test deps are optional and either not desired or not available in Fedora, thus this patch removes them.
# Fixes https://bugzilla.redhat.com/2033994 Patch: Remove-optional-or-unpackaged-test-deps.patch
#
# license_files - Add support for glob patterns + add default patterns # The `setup.py install` deprecation notice might be confusing for RPM packagers
# https://github.com/pypa/setuptools/pull/2620 # adjust it, but only when $RPM_BUILD_ROOT is set
# included in setuptools 56+ Patch: Adjust-the-setup.py-install-deprecation-message.patch
#
# Add License-File field to package metadata # This patch combines two upstream fixes (mainly for tests), adapting to
# https://github.com/pypa/setuptools/pull/2645 # changes in Python 3.12:
# included in setuptools 57+ # - Python 3.12 raises a warning if tarfile filter is not set for extractall.
# depends on the previous one # Tests do this, and fail on this warning.
Patch1: license-file-metadata.patch # Set a "fully trusted" filter. (The tests create the archive, so it is
# trusted.)
# Fix case sensitivity of entry point names and keys in setup.cfg # - https://github.com/pypa/setuptools/pull/3917
# Fixes https://bugzilla.redhat.com/2124281 # - Python 3.12 venv no longer installs setuptools and wheel into new virtual
Patch2: https://github.com/pypa/setuptools/pull/2580.patch # environments. Adjust tests that assumed the old behaviour.
# Also, setting setuptools.__version__ assumed setuptools is installed.
# Security fix for CVE-2022-40897 # Set a valid dummy value if that's not the case.
# Regular Expression Denial of Service (ReDoS) in package_index.py # - https://github.com/pypa/setuptools/pull/3915
# Resolved upstream: https://github.com/pypa/setuptools/commit/43a9c9bfa6aa626ec2a22540bea28d2ca77964be Patch: adjust-for-py3.12.patch
Patch3: CVE-2022-40897.patch
# Security fix for CVE-2024-6345
# Remote code execution via download functions in the package_index module
# Tracking bug: https://bugzilla.redhat.com/show_bug.cgi?id=2297771
# Upstream solution: https://github.com/pypa/setuptools/pull/4332
# Patch simplified because upstream doesn't support SVN anymore.
Patch4: CVE-2024-6345.patch
BuildArch: noarch BuildArch: noarch
BuildRequires: python%{python3_pkgversion}-devel BuildRequires: python%{python3_pkgversion}-devel
%if %{with tests} %if %{with tests}
BuildRequires: gcc BuildRequires: gcc
BuildRequires: python%{python3_pkgversion}-pip %endif
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
%if %{without bootstrap}
BuildRequires: python%{python3_pkgversion}-pip
BuildRequires: python%{python3_pkgversion}-wheel
BuildRequires: python%{python3_pkgversion}-setuptools
# python3 bootstrap: this is built before the final build of python3, which # python3 bootstrap: this is built before the final build of python3, which
# adds the dependency on python3-rpm-generators, so we require it manually # adds the dependency on python3-rpm-generators, so we require it manually
# The minimal version is for bundled provides verification script # The minimal version is for bundled provides verification script to accept multiple files as input
BuildRequires: python3-rpm-generators >= 11-8 BuildRequires: python3-rpm-generators >= 12-8
%endif # without bootstrap
%if %{without bootstrap}
BuildRequires: pyproject-rpm-macros >= 0-44
# Not to use the pre-generated egg-info, we use setuptools from previous build to generate it
BuildRequires: python%{python3_pkgversion}-setuptools
%endif
%description %description
Setuptools is a collection of enhancements to the Python distutils that allow Setuptools is a collection of enhancements to the Python distutils that allow
@ -102,34 +87,31 @@ This package also contains the runtime components of setuptools, necessary to
execute the software that requires pkg_resources. execute the software that requires pkg_resources.
# Virtual provides for the packages bundled by setuptools. # Virtual provides for the packages bundled by setuptools.
# Bundled packages are defined in two files: # Bundled packages are defined in multiple files. Generate the list with:
# - pkg_resources/_vendor/vendored.txt, and # %%{_rpmconfigdir}/pythonbundles.py --namespace 'python%%{python3_pkgversion}dist' */_vendor/vendored.txt
# - 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: %global bundled %{expand:
Provides: bundled(python%{python3_pkgversion}dist(appdirs)) = 1.4.3 Provides: bundled(python%{python3_pkgversion}dist(platformdirs)) = 2.6.2
Provides: bundled(python%{python3_pkgversion}dist(importlib-metadata)) = 6
Provides: bundled(python%{python3_pkgversion}dist(importlib-resources)) = 5.10.2
Provides: bundled(python%{python3_pkgversion}dist(jaraco-text)) = 3.7
Provides: bundled(python%{python3_pkgversion}dist(more-itertools)) = 8.8
Provides: bundled(python%{python3_pkgversion}dist(ordered-set)) = 3.1.1 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(packaging)) = 23
Provides: bundled(python%{python3_pkgversion}dist(pyparsing)) = 2.2.1 Provides: bundled(python%{python3_pkgversion}dist(typing-extensions)) = 4.4
Provides: bundled(python%{python3_pkgversion}dist(typing-extensions)) = 4.0.1
Provides: bundled(python%{python3_pkgversion}dist(zipp)) = 3.7
Provides: bundled(python%{python3_pkgversion}dist(tomli)) = 2.0.1
} }
%package -n python%{python3_pkgversion}-setuptools %package -n python%{python3_pkgversion}-setuptools
Summary: Easily build and distribute Python 3 packages Summary: Easily build and distribute Python 3 packages
%{bundled} %{bundled}
%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' # For users who might see ModuleNotFoundError: No module named 'pkg_resoureces'
# NB: Those are two different provides: one contains underscore, the other hyphen
%py_provides python%{python3_pkgversion}-pkg_resources %py_provides python%{python3_pkgversion}-pkg_resources
%py_provides python%{python3_pkgversion}-pkg-resources %py_provides python%{python3_pkgversion}-pkg-resources
# Provide platform-python-setuptools for backwards compatibility with RHEL 8
Provides: platform-python-setuptools = %{version}-%{release}
%description -n python%{python3_pkgversion}-setuptools %description -n python%{python3_pkgversion}-setuptools
Setuptools is a collection of enhancements to the Python 3 distutils that allow 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 you to more easily build and distribute Python 3 packages, especially ones that
@ -142,13 +124,6 @@ execute the software that requires pkg_resources.
%package -n %{python_wheel_pkg_prefix}-%{srcname}-wheel %package -n %{python_wheel_pkg_prefix}-%{srcname}-wheel
Summary: The setuptools wheel Summary: The setuptools wheel
%{bundled} %{bundled}
Provides: %{name}-wheel = %{version}-%{release}
Obsoletes: %{name}-wheel < %{version}-%{release}
# Older versions of python3-libs expect Python wheels at the old unversioned
# location, so we conflict with the old Python versions that wouldn't work with
# the new wheel location.
Conflicts: python3-libs < 3.9.9-2
%description -n %{python_wheel_pkg_prefix}-%{srcname}-wheel %description -n %{python_wheel_pkg_prefix}-%{srcname}-wheel
A Python wheel of setuptools to use with venv. A Python wheel of setuptools to use with venv.
@ -161,75 +136,65 @@ A Python wheel of setuptools to use with venv.
# If we don't have setuptools installed yet, we use the pre-generated .egg-info # If we don't have setuptools installed yet, we use the pre-generated .egg-info
# See https://github.com/pypa/setuptools/pull/2543 # See https://github.com/pypa/setuptools/pull/2543
# And https://github.com/pypa/setuptools/issues/2550 # And https://github.com/pypa/setuptools/issues/2550
rm -r %{srcname}.egg-info # WARNING: We cannot remove this folder since Python 3.11.1,
# see https://github.com/pypa/setuptools/issues/3761
#rm -r %%{srcname}.egg-info
%endif %endif
# Strip shbang # Strip shbang
find setuptools pkg_resources -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 # Don't ship these
rm setuptools/tests/test_integration.py rm -r docs/conf.py
# We don't do linting or coverage here
sed -i pytest.ini -e 's/ --flake8//' \
-e 's/ --cov//'
%build
%if %{without bootstrap} %if %{without bootstrap}
%py3_build_wheel %generate_buildrequires
%else %pyproject_buildrequires -r %{?with_tests:-x testing}
%endif
%build
%if %{with bootstrap}
%py3_build %py3_build
%else
%pyproject_wheel
%endif %endif
%install %install
%if %{without bootstrap} %if %{with bootstrap}
%py3_install_wheel %{python_wheel_name} # The setup.py install command tries to import distutils
# but the distutils-precedence.pth file is not yet respected
# and Python 3.12+ no longer has distutils in the standard library.
ln -s setuptools/_distutils distutils
PYTHONPATH=$PWD %py3_install
unlink distutils
%else %else
%py3_install %pyproject_install
%pyproject_save_files setuptools pkg_resources _distutils_hack
%endif %endif
# This is not installed (in 45.2.0 anyway), but better be safe than sorry # https://github.com/pypa/setuptools/issues/2709
rm -rf %{buildroot}%{python3_sitelib}/{setuptools,pkg_resources}/tests rm -rf %{buildroot}%{python3_sitelib}/pkg_resources/tests/
%if %{without bootstrap} %if %{without bootstrap}
sed -i '/^setuptools\/tests\//d' %{buildroot}%{python3_record} sed -i '/\/pkg_resources\/tests\b/d' %{pyproject_files}
%endif
find %{buildroot}%{python3_sitelib} -name '*.exe' | xargs rm -f
# Don't ship these
rm -r docs/{conf.py,_*}
%if %{without bootstrap} # Install the wheel for the python-setuptools-wheel package
mkdir -p %{buildroot}%{python_wheel_dir} mkdir -p %{buildroot}%{python_wheel_dir}
install -p dist/%{python_wheel_name} -t %{buildroot}%{python_wheel_dir} install -p %{_pyproject_wheeldir}/%{python_wheel_name} -t %{buildroot}%{python_wheel_dir}
%endif %endif
%if %{with tests}
%check
# Verify bundled provides are up to date
cat pkg_resources/_vendor/vendored.txt setuptools/_vendor/vendored.txt > allvendor.txt
%{_rpmconfigdir}/pythonbundles.py allvendor.txt --namespace 'python%{python3_pkgversion}dist' --compare-with '%{bundled}'
# Regression test, the wheel should not be larger than 600 KiB
# 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
%files -n python%{python3_pkgversion}-setuptools %{?!with_bootstrap:-f %{pyproject_files}}
%files -n python%{python3_pkgversion}-setuptools
%license LICENSE %license LICENSE
%doc docs/* CHANGES.rst README.rst %doc docs/* CHANGES.rst README.rst
%{python3_sitelib}/distutils-precedence.pth
%if %{with bootstrap}
%{python3_sitelib}/setuptools-%{version}-py%{python3_version}.egg-info/
%{python3_sitelib}/pkg_resources/ %{python3_sitelib}/pkg_resources/
%{python3_sitelib}/setuptools*/ %{python3_sitelib}/setuptools/
%{python3_sitelib}/_distutils_hack/ %{python3_sitelib}/_distutils_hack/
%{python3_sitelib}/distutils-precedence.pth %endif
%if %{without bootstrap} %if %{without bootstrap}
%files -n %{python_wheel_pkg_prefix}-%{srcname}-wheel %files -n %{python_wheel_pkg_prefix}-%{srcname}-wheel
@ -241,56 +206,142 @@ PYTHONPATH=$(pwd) %pytest --ignore=pavement.py
%changelog %changelog
* Wed Jul 24 2024 Lumír Balhar <lbalhar@redhat.com> - 53.0.0-12.1 * Thu Jul 18 2024 Sergey Cherevko <s.cherevko@msvsphere-os.ru> - 67.7.2-7
- Security fix for CVE-2024-6345 - Rebuilt for MSVSphere 9.4
Resolves: RHEL-50466
* Fri Jul 21 2023 Fedora Release Engineering <releng@fedoraproject.org> - 67.7.2-7
* Wed Jan 11 2023 Charalampos Stratakis <cstratak@redhat.com> - 53.0.0-12 - Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
- Security fix for CVE-2022-40897
Resolves: rhbz#2158559 * Wed Jul 12 2023 Python Maint <python-maint@redhat.com> - 67.7.2-6
- Rebuilt for Python 3.12
* Wed Sep 07 2022 Miro Hrončok <mhroncok@redhat.com> - 53.0.0-11
- Fix case sensitivity of entry point names and keys in setup.cfg * Tue Jun 13 2023 Python Maint <python-maint@redhat.com> - 67.7.2-5
- Resolves: rhbz#2124281 - Bootstrap for Python 3.12
* Tue Feb 08 2022 Tomas Orsava <torsava@redhat.com> - 53.0.0-10 * Tue Jun 13 2023 Python Maint <python-maint@redhat.com> - 67.7.2-4
- Add automatically generated Obsoletes tag with the python39- prefix - Bootstrap for Python 3.12
for smoother upgrade from RHEL8
- Related: rhbz#1990421 * Fri May 05 2023 Miro Hrončok <mhroncok@redhat.com> - 67.7.2-2
- Adjust the `setup.py install` deprecation notice when building RPM packages
* Wed Jan 12 2022 Miro Hrončok <mhroncok@redhat.com> - 53.0.0-9
- Add License-File field to package metadata * Fri Apr 21 2023 Charalampos Stratakis <cstratak@redhat.com> - 67.7.2-1
- Resolves: rhbz#2033994 - Update to 67.7.2
- Fixes: rhbz#2144132
* Wed Nov 24 2021 Tomas Orsava <torsava@redhat.com> - 53.0.0-8
- Conflict with old Python versions that use the old unversioned wheel location * Thu Apr 20 2023 Charalampos Stratakis <cstratak@redhat.com> - 67.6.1-1
- Resolves: rhbz#1982668 - Update to 67.6.1
- Fixes: rhbz#2144132
* Wed Sep 22 2021 Tomas Orsava <torsava@redhat.com> - 53.0.0-7
- Make the python-setuptools-wheel subpackage versioned (python3-setuptools-wheel), * Tue Mar 28 2023 Miro Hrončok <mhroncok@redhat.com> - 65.5.1-3
and move its contents to a versioned directory /usr/share/python3-wheels - Fix tests with wheel 0.40
- Resolves: rhbz#1982668
* Fri Jan 20 2023 Fedora Release Engineering <releng@fedoraproject.org> - 65.5.1-2
* Tue Aug 10 2021 Mohan Boddu <mboddu@redhat.com> - Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688 * Tue Nov 08 2022 Miro Hrončok <mhroncok@redhat.com> - 65.5.1-1
- Update to 65.5.1
* Wed Jul 28 2021 Tomas Orsava <torsava@redhat.com> - 53.0.0-5 - Fixes: rhbz#2140209
- Provide the platform-python-setuptools name for backwards compatibility
with RHEL 8 * Fri Oct 14 2022 Miro Hrončok <mhroncok@redhat.com> - 65.5.0-1
- Related: rhbz#1891487 - Update to 65.5.0
- Fixes: rhbz#2129562
* Mon Jun 21 2021 Lumír Balhar <lbalhar@redhat.com> - 53.0.0-4
- Add missing bundled provide - ordered-set * Thu Oct 13 2022 Miro Hrončok <mhroncok@redhat.com> - 65.4.1-1
Related: rhbz#1950291 - Update to 65.4.1
- Update the RPM License field to use SPDX expressions
* Thu Apr 22 2021 Miro Hrončok <mhroncok@redhat.com> - 53.0.0-3
* Tue Sep 13 2022 Lumír Balhar <lbalhar@redhat.com> - 65.3.0-1
- Update to 65.3.0
Resolves: rhbz#2102402
* Thu Jul 28 2022 Tomáš Hrnčiar <thrnciar@redhat.com> - 65.0.2-1
- Update to 65.0.2
- Fixes: rhbz#2102402
* Fri Jul 22 2022 Fedora Release Engineering <releng@fedoraproject.org> - 62.6.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
* Tue Jun 14 2022 Charalampos Stratakis <cstratak@redhat.com> - 62.6.0-1
- Update to 62.6.0
- Fixes: rhbz#2064842
* Tue Jun 14 2022 Python Maint <python-maint@redhat.com> - 60.9.3-5
- Rebuilt for Python 3.11
* Mon Jun 13 2022 Python Maint <python-maint@redhat.com> - 60.9.3-4
- Bootstrap for Python 3.11
* Mon Jun 13 2022 Python Maint <python-maint@redhat.com> - 60.9.3-3
- Bootstrap for Python 3.11
* Tue Apr 19 2022 Tomáš Hrnčiar <thrnciar@redhat.com> - 60.9.3-2
- No longer use the deprecated sre_constants module in bundled pyparsing
- Fixes: rhbz#2075487
* Wed Feb 16 2022 Karolina Surma <ksurma@redhat.com> - 60.9.3-1
- Update to 60.9.3
- Fixes rhbz#2033860
* Fri Jan 21 2022 Fedora Release Engineering <releng@fedoraproject.org> - 59.6.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
* Wed Dec 08 2021 Tomáš Hrnčiar <thrnciar@redhat.com> - 59.6.0-1
- Update to 59.6.0
- Fixes: rhbz#2023119
- Fixes: rhbz#2031556
* Wed Nov 10 2021 Karolina Surma <ksurma@redhat.com> - 58.5.3-1
- Update to 58.5.3
- Fixes rhbz#2016715
* Tue Oct 19 2021 Tomáš Hrnčiar <thrnciar@redhat.com> - 58.2.0-1
- Update to 58.2.0
- Fixes rhbz#2001228
* Tue Aug 03 2021 Miro Hrončok <mhroncok@redhat.com> - 57.4.0-1
- Update to 57.4.0
- https://setuptools.readthedocs.io/en/latest/history.html#v57-4-0
- Fixes rhbz#1982493
* Fri Jul 23 2021 Fedora Release Engineering <releng@fedoraproject.org> - 57.1.0-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
* Mon Jul 19 2021 Miro Hrončok <mhroncok@redhat.com> - 57.1.0-2
- Modernize packaging
* Fri Jul 09 2021 Tomas Hrnciar <thrnciar@redhat.com> - 57.1.0-1
- Update to 57.1.0
- Fixes rhbz#1979122
* Thu Jun 17 2021 Lumír Balhar <lbalhar@redhat.com> - 57.0.0-1
- Update to 57.0.0
Resolves: rhbz#1963411
* Fri Jun 04 2021 Python Maint <python-maint@redhat.com> - 56.2.0-4
- Rebuilt for Python 3.10
* Tue Jun 01 2021 Python Maint <python-maint@redhat.com> - 56.2.0-3
- Bootstrap for Python 3.10
* Tue Jun 01 2021 Python Maint <python-maint@redhat.com> - 56.2.0-2
- Bootstrap for Python 3.10
* Mon May 17 2021 Miro Hrončok <mhroncok@redhat.com> - 56.2.0-1
- Update to 56.2.0
- Fixes rhbz#1958677
* Thu May 06 2021 Tomas Hrnciar <thrnciar@redhat.com> - 56.1.0-1
- Update to 56.1.0
* Thu Apr 22 2021 Miro Hrončok <mhroncok@redhat.com> - 56.0.0-2
- Provide python3-pkg_resources - Provide python3-pkg_resources
- Provide python3-pkg-resources - Provide python3-pkg-resources
Resolves: rhbz#1947857
* Fri Apr 16 2021 Mohan Boddu <mboddu@redhat.com> - 53.0.0-2 * Fri Apr 09 2021 Tomas Hrnciar <thrnciar@redhat.com> - 56.0.0-1
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937 - Update to 56.0.0
* Tue Mar 16 2021 Tomas Hrnciar <thrnciar@redhat.com> - 54.1.2-1
- Update to 54.1.2
* Tue Feb 02 2021 Miro Hrončok <mhroncok@redhat.com> - 53.0.0-1 * Tue Feb 02 2021 Miro Hrončok <mhroncok@redhat.com> - 53.0.0-1
- Update to 53.0.0 - Update to 53.0.0

Loading…
Cancel
Save