diff --git a/.fmf/version b/.fmf/version deleted file mode 100644 index d00491f..0000000 --- a/.fmf/version +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/.gitignore b/.gitignore index 72d39d5..8e24ed4 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,4 @@ /pip/ /results_python-pip/ *.rpm -*.whl + diff --git a/changelog b/changelog deleted file mode 100644 index f16cb91..0000000 --- a/changelog +++ /dev/null @@ -1,496 +0,0 @@ -* Mon Jan 22 2024 Miro Hrončok - 23.3.1-5 -- Switched to autogenerated BuildRequires for test dependencies, - which removed some that were no longer necessary - -* Mon Jan 22 2024 Fedora Release Engineering - 23.3.1-4 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild - -* Fri Jan 12 2024 Maxwell G - 23.3.1-3 -- Remove unused python3-mock dependency - -* Wed Jan 03 2024 Maxwell G - 23.3.1-2 -- Remove weak dependency on python3-setuptools - -* Thu Nov 16 2023 Petr Viktorin - 23.3.1-1 -- Update to 23.3.1 -Resolves: rhbz#2244306 - -* Fri Aug 04 2023 Miro Hrončok - 23.2.1-1 -- Update to 23.2.1 -Resolves: rhbz#2223082 - -* Fri Aug 04 2023 Miro Hrončok - 23.1.2-7 -- Actually run the tests and build the docs when building this package - -* Wed Jul 26 2023 Miro Hrončok - 23.1.2-6 -- Drop no-longer-needed custom changes to /usr/bin/pip* -- Stop Recommending libcrypt.so.1 on Python 3.12+ -Resolves: rhbz#2150373 - -* Tue Jul 25 2023 Python Maint - 23.1.2-5 -- Rebuilt for Python 3.12 - -* Fri Jul 21 2023 Fedora Release Engineering - 23.1.2-4 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild - -* Thu Jul 20 2023 Python Maint - 23.1.2-3 -- Rebuilt for Python 3.12 - -* Tue Jun 13 2023 Python Maint - 23.1.2-2 -- Bootstrap for Python 3.12 - -* Fri May 19 2023 Miro Hrončok - 23.1.2-1 -- Update to 23.1.2 -Resolves: rhbz#2186979 - -* Mon Mar 27 2023 Karolina Surma - 23.0.1-2 -- Fix compatibility with Sphinx 6+ -Resolves: rhbz#2180479 - -* Mon Feb 20 2023 Tomáš Hrnčiar - 23.0.1-1 -- Update to 23.0.1 -Resolves: rhbz#2165760 - -* Fri Jan 20 2023 Fedora Release Engineering - 22.3.1-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild - -* Mon Nov 14 2022 Karolina Surma - 22.3.1-1 -- Update to 22.3.1 -Resolves: rhbz#2135044 - -* Mon Sep 05 2022 Python Maint - 22.2.2-2 -- Fix crash when an empty dist-info/egg-info is present -Resolves: rhbz#2115001 -- No longer use the rpm_install prefix to determine RPM-installed packages -Related: rhbz#2026979 - -* Wed Aug 03 2022 Charalampos Stratakis - 22.2.2-1 -- Update to 22.2.2 -Resolves: rhbz#2109468 - -* Fri Jul 22 2022 Charalampos Stratakis - 22.2-1 -- Update to 22.2 -Resolves: rhbz#2109468 - -* Fri Jul 22 2022 Fedora Release Engineering - 22.0.4-5 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild - -* Wed Jun 15 2022 Python Maint - 22.0.4-4 -- Rebuilt for Python 3.11 - -* Mon Jun 13 2022 Python Maint - 22.0.4-3 -- Bootstrap for Python 3.11 - -* Tue Apr 26 2022 Tomáš Hrnčiar - 22.0.4-2 -- Fallback to pep517 if setup.py is present and setuptools cannot be imported -- Fixes: rhbz#2020635 - -* Mon Mar 21 2022 Karolina Surma - 22.0.4-1 -- Update to 22.0.4 -Resolves: rhbz#2061262 - -* Wed Feb 16 2022 Lumír Balhar - 22.0.3-1 -- Update to 22.0.3 -Resolves: rhbz#2048243 - -* Fri Jan 21 2022 Fedora Release Engineering - 21.3.1-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild - -* Mon Oct 25 2021 Miro Hrončok - 21.3.1-1 -- Update to 21.3.1 -- Resolves: rhbz#2016682 - -* Wed Oct 13 2021 Miro Hrončok - 21.3-1 -- Update to 21.3 -- Resolves: rhbz#2013026 -- Fix incomplete pip-updates in virtual environments - -* Wed Oct 06 2021 Charalampos Stratakis - 21.2.3-4 -- Remove bundled windows executables -- Resolves: rhbz#2005453 - -* Thu Sep 23 2021 Miro Hrončok - 21.2.3-3 -- Detect paths not to uninstall from via sysconfig's rpm_prefix install scheme - -* Mon Aug 16 2021 Miro Hrončok - 21.2.3-2 -- Fix broken uninstallation by a bogus downstream patch - -* Mon Aug 09 2021 Miro Hrončok - 21.2.3-1 -- Update to 21.2.3 -- Resolves: rhbz#1985635 - -* Fri Jul 23 2021 Fedora Release Engineering - 21.1.3-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild - -* Tue Jun 29 2021 Lumír Balhar - 21.1.3-1 -- Update to 21.1.3 -Resolves: rhbz#1976449 - -* Mon Jun 07 2021 Karolina Surma - 21.1.2-1 -- Update to 21.1.2 -Resolves: rhbz#1963433 - -* Fri Jun 04 2021 Python Maint - 21.1.1-3 -- Rebuilt for Python 3.10 - -* Tue Jun 01 2021 Python Maint - 21.1.1-2 -- Bootstrap for Python 3.10 - -* Mon May 10 2021 Karolina Surma - 21.1.1-1 -- Update to 21.1.1 - -* Sat Mar 13 2021 Miro Hrončok - 21.0.1-2 -- python-pip-wheel: Remove bundled provides and libcrypt recommends for Python 2 - (The wheel is Python 3 only for a while) - -* Wed Feb 17 2021 Lumír Balhar - 21.0.1-1 -- Update to 21.0.1 -Resolves: rhbz#1922592 - -* Tue Jan 26 2021 Lumír Balhar - 21.0-1 -- Update to 21.0 (#1919530) - -* Thu Dec 17 2020 Petr Viktorin - 20.3.3-1 -- Update to 20.3.3 - -* Mon Nov 30 2020 Miro Hrončok - 20.3-1 -- Update to 20.3 -- Add support for PEP 600: Future manylinux Platform Tags -- New resolver -- Fixes: rhbz#1893470 - -* Mon Oct 19 2020 Lumír Balhar - 20.2.4-1 -- Update to 20.2.4 (#1889112) - -* Wed Aug 05 2020 Tomas Orsava - 20.2.2-1 -- Update to 20.2.2 (#1838553) - -* Wed Jul 29 2020 Fedora Release Engineering - 20.1.1-7 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild - -* Fri Jul 10 2020 Lumír Balhar - 20.1.1-6 -- Do not emit a warning about root privileges when --root is used - -* Wed Jul 08 2020 Miro Hrončok - 20.1.1-5 -- Update bundled provides to match 20.1.1 - -* Tue Jun 16 2020 Lumír Balhar - 20.1.1-4 -- Deselect tests incompatible with the latest virtualenv - -* Sun May 24 2020 Miro Hrončok - 20.1.1-3 -- Rebuilt for Python 3.9 - -* Thu May 21 2020 Miro Hrončok - 20.1.1-2 -- Bootstrap for Python 3.9 - -* Wed May 20 2020 Tomas Hrnciar - 20.1.1-1 -- Update to 20.1.1 - -* Wed Apr 29 2020 Tomas Hrnciar - 20.1-1 -- Update to 20.1 - -* Mon Apr 27 2020 Tomas Hrnciar - 20.1~b1-1 -- Update to 20.1~b1 - -* Wed Apr 15 2020 Miro Hrončok - 20.0.2-4 -- Only recommend setuptools, don't require them - -* Fri Apr 10 2020 Miro Hrončok - 20.0.2-3 -- Allow setting $TMPDIR to $PWD/... during pip wheel (#1806625) - -* Tue Mar 10 2020 Miro Hrončok - 20.0.2-2 -- Don't warn the user about pip._internal.main() entrypoint to fix ensurepip - -* Mon Mar 02 2020 Miro Hrončok - 20.0.2-1 -- Update to 20.0.2 (#1793456) - -* Thu Jan 30 2020 Fedora Release Engineering - 19.3.1-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild - -* Mon Nov 04 2019 Tomas Orsava - 19.3.1-1 -- Update to 19.3.1 (#1761508) -- Drop upstreamed patch that fixed expected output in test to not break with alpha/beta/rc Python versions - -* Wed Oct 30 2019 Miro Hrončok - 19.2.3-2 -- Make /usr/bin/pip(3) work with user-installed pip 19.3+ (#1767212) - -* Mon Sep 02 2019 Miro Hrončok - 19.2.3-1 -- Update to 19.2.3 (#1742230) -- Drop patch that should strip path prefixes from RECORD files, the paths are relative - -* Wed Aug 21 2019 Petr Viktorin - 19.1.1-8 -- Remove python2-pip -- Make pip bootstrap itself, rather than with an extra bootstrap RPM build - -* Sat Aug 17 2019 Miro Hrončok - 19.1.1-7 -- Rebuilt for Python 3.8 - -* Wed Aug 14 2019 Miro Hrončok - 19.1.1-6 -- Bootstrap for Python 3.8 - -* Wed Aug 14 2019 Miro Hrončok - 19.1.1-5 -- Bootstrap for Python 3.8 - -* Fri Jul 26 2019 Fedora Release Engineering - 19.1.1-4 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild - -* Mon Jul 15 2019 Petr Viktorin - 19.1.1-3 -- Recommend libcrypt.so.1 for manylinux1 compatibility -- Make /usr/bin/pip Python 3 - -* Mon Jun 10 2019 Miro Hrončok - 19.1.1-2 -- Fix root warning when pip is invoked via python -m pip -- Remove a redundant second WARNING prefix form the abovementioned warning - -* Wed May 15 2019 Miro Hrončok - 19.1.1-1 -- Update to 19.1.1 (#1706995) - -* Thu Apr 25 2019 Miro Hrončok - 19.1-1 -- Update to 19.1 (#1702525) - -* Wed Mar 06 2019 Miro Hrončok - 19.0.3-1 -- Update to 19.0.3 (#1679277) - -* Wed Feb 13 2019 Miro Hrončok - 19.0.2-1 -- Update to 19.0.2 (#1668492) - -* Sat Feb 02 2019 Fedora Release Engineering - 18.1-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild - -* Mon Dec 03 2018 Miro Hrončok - 18.1-2 -- Use the system level root certificate instead of the one bundled in certifi - -* Thu Nov 22 2018 Miro Hrončok - 18.1-1 -- Update to 18.1 (#1652089) - -* Tue Sep 18 2018 Victor Stinner - 18.0-4 -- Prevent removing of the system packages installed under /usr/lib - when pip install -U is executed. Original patch by Michal Cyprian. - Resolves: rhbz#1550368. - -* Wed Aug 08 2018 Miro Hrončok - 18.0-3 -- Create python-pip-wheel package with the wheel - -* Tue Jul 31 2018 Miro Hrončok - 18.0-2 -- Remove redundant "Unicode" from License - -* Mon Jul 23 2018 Marcel Plch - 18.0-7 -- Update to 18.0 - -* Sat Jul 14 2018 Fedora Release Engineering - 9.0.3-6 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild - -* Mon Jun 18 2018 Miro Hrončok - 9.0.3-5 -- Rebuilt for Python 3.7 - -* Wed Jun 13 2018 Miro Hrončok - 9.0.3-4 -- Bootstrap for Python 3.7 - -* Wed Jun 13 2018 Miro Hrončok - 9.0.3-3 -- Bootstrap for Python 3.7 - -* Fri May 04 2018 Miro Hrončok - 9.0.3-2 -- Allow to import pip10's main from pip9's /usr/bin/pip -- Do not show the "new version of pip" warning outside of venv -Resolves: rhbz#1569488 -Resolves: rhbz#1571650 -Resolves: rhbz#1573755 - -* Thu Mar 29 2018 Charalampos Stratakis - 9.0.3-1 -- Update to 9.0.3 - -* Wed Feb 21 2018 Lumír Balhar - 9.0.1-16 -- Include built HTML documentation (in the new -doc subpackage) and man page - -* Fri Feb 09 2018 Fedora Release Engineering - 9.0.1-15 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild - -* Mon Dec 04 2017 Charalampos Stratakis - 9.0.1-14 -- Reintroduce the ipaddress module in the python3 subpackage. - -* Mon Nov 20 2017 Charalampos Stratakis - 9.0.1-13 -- Add virtual provides for the bundled libraries. (rhbz#1096912) - -* Tue Aug 29 2017 Tomas Orsava - 9.0.1-12 -- Switch macros to bcond's and make Python 2 optional to facilitate building - the Python 2 and Python 3 modules - -* Thu Jul 27 2017 Fedora Release Engineering - 9.0.1-11 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild - -* Tue May 23 2017 Tomas Orsava - 9.0.1-10 -- Modernized package descriptions -Resolves: rhbz#1452568 - -* Tue Mar 21 2017 Tomas Orsava - 9.0.1-9 -- Fix typo in the sudo pip warning - -* Fri Mar 03 2017 Tomas Orsava - 9.0.1-8 -- Patch 1 update: No sudo pip warning in venv or virtualenv - -* Thu Feb 23 2017 Tomas Orsava - 9.0.1-7 -- Patch 1 update: Customize the warning with the proper version of the pip - command - -* Tue Feb 14 2017 Tomas Orsava - 9.0.1-6 -- Added patch 1: Emit a warning when running with root privileges - -* Sat Feb 11 2017 Fedora Release Engineering - 9.0.1-5 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild - -* Mon Jan 02 2017 Tomas Orsava - 9.0.1-4 -- Provide symlinks to executables to comply with Fedora guidelines for Python -Resolves: rhbz#1406922 - -* Fri Dec 09 2016 Charalampos Stratakis - 9.0.1-3 -- Rebuild for Python 3.6 with wheel - -* Fri Dec 09 2016 Charalampos Stratakis - 9.0.1-2 -- Rebuild for Python 3.6 without wheel - -* Fri Nov 18 2016 Orion Poplawski - 9.0.1-1 -- Update to 9.0.1 - -* Fri Nov 18 2016 Orion Poplawski - 8.1.2-5 -- Enable EPEL Python 3 builds -- Use new python macros -- Cleanup spec - -* Fri Aug 05 2016 Tomas Orsava - 8.1.2-4 -- Updated the test sources - -* Fri Aug 05 2016 Tomas Orsava - 8.1.2-3 -- Moved python-pip into the python2-pip subpackage -- Added the python_provide macro - -* Tue Jul 19 2016 Fedora Release Engineering - 8.1.2-2 -- https://fedoraproject.org/wiki/Changes/Automatic_Provides_for_Python_RPM_Packages - -* Tue May 17 2016 Tomas Orsava - 8.1.2-1 -- Update to 8.1.2 -- Moved to a new PyPI URL format -- Updated the prefix-stripping patch because of upstream changes in pip/wheel.py - -* Mon Feb 22 2016 Slavek Kabrda - 8.0.2-1 -- Update to 8.0.2 - -* Thu Feb 04 2016 Fedora Release Engineering - 7.1.0-4 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild - -* Wed Oct 14 2015 Robert Kuska - 7.1.0-3 -- Rebuilt for Python3.5 rebuild -- With wheel set to 1 - -* Tue Oct 13 2015 Robert Kuska - 7.1.0-2 -- Rebuilt for Python3.5 rebuild - -* Wed Jul 01 2015 Slavek Kabrda - 7.1.0-1 -- Update to 7.1.0 - -* Tue Jun 30 2015 Ville Skyttä - 7.0.3-3 -- Install bash completion -- Ship LICENSE.txt as %%license where available - -* Thu Jun 18 2015 Fedora Release Engineering - 7.0.3-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild - -* Thu Jun 04 2015 Matej Stuchlik - 7.0.3-1 -- Update to 7.0.3 - -* Fri Mar 06 2015 Matej Stuchlik - 6.0.8-1 -- Update to 6.0.8 - -* Thu Dec 18 2014 Slavek Kabrda - 1.5.6-5 -- Only enable tests on Fedora. - -* Mon Dec 01 2014 Matej Stuchlik - 1.5.6-4 -- Add tests -- Add patch skipping tests requiring Internet access - -* Tue Nov 18 2014 Matej Stuchlik - 1.5.6-3 -- Added patch for local dos with predictable temp dictionary names - (http://seclists.org/oss-sec/2014/q4/655) - -* Sat Jun 07 2014 Fedora Release Engineering - 1.5.6-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild - -* Sun May 25 2014 Matej Stuchlik - 1.5.6-1 -- Update to 1.5.6 - -* Fri Apr 25 2014 Matej Stuchlik - 1.5.4-4 -- Rebuild as wheel for Python 3.4 - -* Thu Apr 24 2014 Matej Stuchlik - 1.5.4-3 -- Disable build_wheel - -* Thu Apr 24 2014 Matej Stuchlik - 1.5.4-2 -- Rebuild as wheel for Python 3.4 - -* Mon Apr 07 2014 Matej Stuchlik - 1.5.4-1 -- Updated to 1.5.4 - -* Mon Oct 14 2013 Tim Flink - 1.4.1-1 -- Removed patch for CVE 2013-2099 as it has been included in the upstream 1.4.1 release -- Updated version to 1.4.1 - -* Sun Aug 04 2013 Fedora Release Engineering - 1.3.1-5 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild - -* Tue Jul 16 2013 Toshio Kuratomi - 1.3.1-4 -- Fix for CVE 2013-2099 - -* Thu May 23 2013 Tim Flink - 1.3.1-3 -- undo python2 executable rename to python-pip. fixes #958377 -- fix summary to match upstream - -* Mon May 06 2013 Kevin Kofler - 1.3.1-2 -- Fix main package Summary, it's for Python 2, not 3 (#877401) - -* Fri Apr 26 2013 Jon Ciesla - 1.3.1-1 -- Update to 1.3.1, fix for CVE-2013-1888. - -* Thu Feb 14 2013 Fedora Release Engineering - 1.2.1-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild - -* Tue Oct 09 2012 Tim Flink - 1.2.1-2 -- Fixing files for python3-pip - -* Thu Oct 04 2012 Tim Flink - 1.2.1-1 -- Update to upstream 1.2.1 -- Change binary from pip-python to python-pip (RHBZ#855495) -- Add alias from python-pip to pip-python, to be removed at a later date - -* Tue May 15 2012 Tim Flink - 1.1.0-1 -- Update to upstream 1.1.0 - -* Sat Jan 14 2012 Fedora Release Engineering - 1.0.2-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild - -* Sat Oct 22 2011 Tim Flink - 1.0.2-1 -- update to 1.0.2 and added python3 subpackage - -* Wed Jun 22 2011 Tim Flink - 0.8.3-1 -- update to 0.8.3 and project home page - -* Tue Feb 08 2011 Fedora Release Engineering - 0.8.2-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild - -* Mon Dec 20 2010 Luke Macken - 0.8.2-1 -- update to 0.8.2 of pip -* Mon Aug 30 2010 Peter Halliday - 0.8-1 -- update to 0.8 of pip -* Thu Jul 22 2010 David Malcolm - 0.7.2-5 -- Rebuilt for https://fedoraproject.org/wiki/Features/Python_2.7/MassRebuild - -* Wed Jul 7 2010 Peter Halliday - 0.7.2-1 -- update to 0.7.2 of pip -* Sun May 23 2010 Peter Halliday - 0.7.1-1 -- update to 0.7.1 of pip -* Fri Jan 1 2010 Peter Halliday - 0.6.1.4 -- fix dependency issue -* Fri Dec 18 2009 Peter Halliday - 0.6.1-2 -- fix spec file -* Thu Dec 17 2009 Peter Halliday - 0.6.1-1 -- upgrade to 0.6.1 of pip -* Mon Aug 31 2009 Peter Halliday - 0.4-1 -- Initial package diff --git a/don-t-split-git-references-on-unicode-separators.patch b/don-t-split-git-references-on-unicode-separators.patch new file mode 100644 index 0000000..707e1e8 --- /dev/null +++ b/don-t-split-git-references-on-unicode-separators.patch @@ -0,0 +1,34 @@ +From 71ded0935e6c87d6e14439f667990de18bf82cb0 Mon Sep 17 00:00:00 2001 +From: Karolina Surma +Date: Mon, 17 May 2021 13:34:47 +0200 +Subject: [PATCH] Don't split git references on unicode separators + +--- + src/pip/_internal/vcs/git.py | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/src/pip/_internal/vcs/git.py b/src/pip/_internal/vcs/git.py +index a9c7fb6..b38625e 100644 +--- a/src/pip/_internal/vcs/git.py ++++ b/src/pip/_internal/vcs/git.py +@@ -142,9 +142,15 @@ class Git(VersionControl): + pass + + refs = {} +- for line in output.strip().splitlines(): ++ # NOTE: We do not use splitlines here since that would split on other ++ # unicode separators, which can be maliciously used to install a ++ # different revision. ++ for line in output.strip().split("\n"): ++ line = line.rstrip("\r") ++ if not line: ++ continue + try: +- sha, ref = line.split() ++ sha, ref = line.split(" ", maxsplit=2) + except ValueError: + # Include the offending line to simplify troubleshooting if + # this error ever occurs. +-- +2.31.1 + diff --git a/downstream-remove-pytest-subket.patch b/downstream-remove-pytest-subket.patch deleted file mode 100644 index 564794c..0000000 --- a/downstream-remove-pytest-subket.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 35378ae02912d704d466e4809070e17a8d13ad0a Mon Sep 17 00:00:00 2001 -From: Karolina Surma -Date: Thu, 7 Aug 2025 15:05:34 +0200 -Subject: [PATCH] Downstream-Only: Remove pytest-subket from tests - ---- - tests/conftest.py | 17 ----------------- - 1 file changed, 17 deletions(-) - -diff --git a/tests/conftest.py b/tests/conftest.py -index c98b871..ada7a7e 100644 ---- a/tests/conftest.py -+++ b/tests/conftest.py -@@ -451,18 +451,6 @@ def coverage_install( - return _common_wheel_editable_install(tmpdir_factory, common_wheels, "coverage") - - --@pytest.fixture(scope="session") --def socket_install(tmpdir_factory: pytest.TempPathFactory, common_wheels: Path) -> Path: -- lib_dir = _common_wheel_editable_install( -- tmpdir_factory, common_wheels, "pytest_subket" -- ) -- # pytest-subket is only included so it can intercept and block unexpected -- # network requests. It should NOT be visible to the pip under test. -- dist_info = next(lib_dir.glob("*.dist-info")) -- shutil.rmtree(dist_info) -- return lib_dir -- -- - def install_pth_link( - venv: VirtualEnvironment, project_name: str, lib_dir: Path - ) -> None: -@@ -480,7 +468,6 @@ def virtualenv_template( - setuptools_install: Path, - wheel_install: Path, - coverage_install: Path, -- socket_install: Path, - ) -> VirtualEnvironment: - venv_type: VirtualEnvironmentType - if request.config.getoption("--use-venv"): -@@ -495,10 +482,6 @@ def virtualenv_template( - # Install setuptools, wheel, pytest-subket, and pip. - install_pth_link(venv, "setuptools", setuptools_install) - install_pth_link(venv, "wheel", wheel_install) -- install_pth_link(venv, "pytest_subket", socket_install) -- # Also copy pytest-subket's .pth file so it can intercept socket calls. -- with open(venv.site / "pytest_socket.pth", "w") as f: -- f.write(socket_install.joinpath("pytest_socket.pth").read_text()) - - pth, dist_info = pip_editable_parts - --- -2.50.1 - diff --git a/dummy-certifi.patch b/dummy-certifi.patch index ce34415..992aed4 100644 --- a/dummy-certifi.patch +++ b/dummy-certifi.patch @@ -1,103 +1,35 @@ -From 7b5fbac83944e3a0dd975ff17b69358791b68721 Mon Sep 17 00:00:00 2001 -From: Karolina Surma -Date: Thu, 27 Jun 2024 10:38:53 +0200 +From cf96ff346639d1b9f5efa3fd0976694e04df3f5f Mon Sep 17 00:00:00 2001 +From: Tomas Hrnciar +Date: Sun, 26 Apr 2020 21:38:44 +0200 Subject: [PATCH] Dummy certifi patch --- - src/pip/_vendor/certifi/core.py | 80 +++------------------------------ - 1 file changed, 6 insertions(+), 74 deletions(-) + src/pip/_vendor/certifi/core.py | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pip/_vendor/certifi/core.py b/src/pip/_vendor/certifi/core.py -index 2f2f7e0..bec6595 100644 +index 8987449..d174ced 100644 --- a/src/pip/_vendor/certifi/core.py +++ b/src/pip/_vendor/certifi/core.py -@@ -4,80 +4,12 @@ certifi.py +@@ -9,6 +9,7 @@ This module returns the installation location of cacert.pem or its contents. + import os - This module returns the installation location of cacert.pem or its contents. - """ --import sys --import atexit + try: ++ raise ImportError # force fallback + from importlib.resources import path as get_path, read_text --def exit_cacert_ctx() -> None: -- _CACERT_CTX.__exit__(None, None, None) # type: ignore[union-attr] -+# The RPM-packaged certifi always uses the system certificates -+def where() -> str: -+ return '/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem' + _CACERT_CTX = None +@@ -51,9 +52,7 @@ except ImportError: + # If we don't have importlib.resources, then we will just do the old logic + # of assuming we're on the filesystem and munge the path directly. + def where(): +- f = os.path.dirname(__file__) +- +- return os.path.join(f, "cacert.pem") ++ return '/etc/pki/tls/certs/ca-bundle.crt' --if sys.version_info >= (3, 11): -- -- from importlib.resources import as_file, files -- -- _CACERT_CTX = None -- _CACERT_PATH = None -- -- def where() -> str: -- # This is slightly terrible, but we want to delay extracting the file -- # in cases where we're inside of a zipimport situation until someone -- # actually calls where(), but we don't want to re-extract the file -- # on every call of where(), so we'll do it once then store it in a -- # global variable. -- global _CACERT_CTX -- global _CACERT_PATH -- if _CACERT_PATH is None: -- # This is slightly janky, the importlib.resources API wants you to -- # manage the cleanup of this file, so it doesn't actually return a -- # path, it returns a context manager that will give you the path -- # when you enter it and will do any cleanup when you leave it. In -- # the common case of not needing a temporary file, it will just -- # return the file system location and the __exit__() is a no-op. -- # -- # We also have to hold onto the actual context manager, because -- # it will do the cleanup whenever it gets garbage collected, so -- # we will also store that at the global level as well. -- _CACERT_CTX = as_file(files("pip._vendor.certifi").joinpath("cacert.pem")) -- _CACERT_PATH = str(_CACERT_CTX.__enter__()) -- atexit.register(exit_cacert_ctx) -- -- return _CACERT_PATH -- -- def contents() -> str: -- return files("pip._vendor.certifi").joinpath("cacert.pem").read_text(encoding="ascii") -- --else: -- -- from importlib.resources import path as get_path, read_text -- -- _CACERT_CTX = None -- _CACERT_PATH = None -- -- def where() -> str: -- # This is slightly terrible, but we want to delay extracting the -- # file in cases where we're inside of a zipimport situation until -- # someone actually calls where(), but we don't want to re-extract -- # the file on every call of where(), so we'll do it once then store -- # it in a global variable. -- global _CACERT_CTX -- global _CACERT_PATH -- if _CACERT_PATH is None: -- # This is slightly janky, the importlib.resources API wants you -- # to manage the cleanup of this file, so it doesn't actually -- # return a path, it returns a context manager that will give -- # you the path when you enter it and will do any cleanup when -- # you leave it. In the common case of not needing a temporary -- # file, it will just return the file system location and the -- # __exit__() is a no-op. -- # -- # We also have to hold onto the actual context manager, because -- # it will do the cleanup whenever it gets garbage collected, so -- # we will also store that at the global level as well. -- _CACERT_CTX = get_path("pip._vendor.certifi", "cacert.pem") -- _CACERT_PATH = str(_CACERT_CTX.__enter__()) -- atexit.register(exit_cacert_ctx) -- -- return _CACERT_PATH -- -- def contents() -> str: -- return read_text("pip._vendor.certifi", "cacert.pem", encoding="ascii") -+def contents() -> str: -+ with open(where(), encoding='utf=8') as data: -+ return data.read() + def contents(): -- -2.50.1 +2.25.4 diff --git a/emit-a-warning-when-running-with-root-privileges.patch b/emit-a-warning-when-running-with-root-privileges.patch new file mode 100644 index 0000000..7c6a390 --- /dev/null +++ b/emit-a-warning-when-running-with-root-privileges.patch @@ -0,0 +1,51 @@ +From 74bb5d26e232493de43adfa1f4b42b66fd701294 Mon Sep 17 00:00:00 2001 +From: Tomas Hrnciar +Date: Sun, 26 Apr 2020 13:52:24 +0200 +Subject: [PATCH] Downstream only patch + +Emit a warning to the user if pip install is run with root privileges +Issue upstream: https://github.com/pypa/pip/issues/4288 +--- + src/pip/_internal/commands/install.py | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/src/pip/_internal/commands/install.py b/src/pip/_internal/commands/install.py +index 70bda2e2..1e750ae1 100644 +--- a/src/pip/_internal/commands/install.py ++++ b/src/pip/_internal/commands/install.py +@@ -13,6 +13,8 @@ import operator + import os + import shutil + import site ++import sys ++from os import path + from optparse import SUPPRESS_HELP + + from pip._vendor import pkg_resources +@@ -241,6 +243,23 @@ class InstallCommand(RequirementCommand): + raise CommandError("Can not combine '--user' and '--target'") + + cmdoptions.check_install_build_global(options) ++ ++ def is_venv(): ++ return (hasattr(sys, 'real_prefix') or ++ (hasattr(sys, 'base_prefix') and ++ sys.base_prefix != sys.prefix)) ++ ++ # Check whether we have root privileges and aren't in venv/virtualenv ++ if os.getuid() == 0 and not is_venv() and not options.root_path: ++ command = path.basename(sys.argv[0]) ++ if command == "__main__.py": ++ command = path.basename(sys.executable) + " -m pip" ++ logger.warning( ++ "Running pip install with root privileges is " ++ "generally not a good idea. Try `%s install --user` instead." ++ % command ++ ) ++ + upgrade_strategy = "to-satisfy-only" + if options.upgrade: + upgrade_strategy = options.upgrade_strategy +-- +2.23.0 + diff --git a/html_theme_path.patch b/html_theme_path.patch new file mode 100644 index 0000000..4209471 --- /dev/null +++ b/html_theme_path.patch @@ -0,0 +1,11 @@ +diff -ru pip-10.0.1/docs/conf.py pip-10.0.1_patched/docs/conf.py +--- pip-10.0.1/docs/html/conf.py 2018-04-14 13:17:31.000000000 +0200 ++++ pip-10.0.1_patched/docs/html/conf.py 2018-07-23 15:23:31.053267611 +0200 +@@ -134,6 +134,7 @@ + # The theme to use for HTML and HTML Help pages. Major themes that come with + # Sphinx are currently 'default' and 'sphinxdoc'. + html_theme = "pypa_theme" ++html_theme_path = ["pypa", "python-docs-theme"] + + # Theme options are theme-specific and customize the look and feel of a theme + # further. For a list of options available for each theme, see the diff --git a/local-dos.patch b/local-dos.patch new file mode 100644 index 0000000..721ca51 --- /dev/null +++ b/local-dos.patch @@ -0,0 +1,395 @@ +diff --git a/pip/cmdoptions.py b/pip/cmdoptions.py +index 8ed3d91..01b2104 100644 +--- a/pip/cmdoptions.py ++++ b/pip/cmdoptions.py +@@ -9,7 +9,7 @@ To be consistent, all options will follow this design. + """ + import copy + from optparse import OptionGroup, SUPPRESS_HELP, Option +-from pip.locations import build_prefix, default_log_file ++from pip.locations import default_log_file + + + def make_option_group(group, parser): +@@ -297,10 +297,8 @@ build_dir = OptionMaker( + '-b', '--build', '--build-dir', '--build-directory', + dest='build_dir', + metavar='dir', +- default=build_prefix, +- help='Directory to unpack packages into and build in. ' +- 'The default in a virtualenv is "/build". ' +- 'The default for global installs is "/pip_build_".') ++ help='Directory to unpack packages into and build in.', ++) + + install_options = OptionMaker( + '--install-option', +diff --git a/pip/commands/install.py b/pip/commands/install.py +index cbf22a0..cb7d0db 100644 +--- a/pip/commands/install.py ++++ b/pip/commands/install.py +@@ -10,6 +10,7 @@ from pip.basecommand import Command + from pip.index import PackageFinder + from pip.exceptions import InstallationError, CommandError, PreviousBuildDirError + from pip import cmdoptions ++from pip.util import BuildDirectory + + + class InstallCommand(Command): +@@ -188,7 +189,7 @@ class InstallCommand(Command): + if ( + options.no_install or + options.no_download or +- (options.build_dir != build_prefix) or ++ options.build_dir or + options.no_clean + ): + logger.deprecated('1.7', 'DEPRECATION: --no-install, --no-download, --build, ' +@@ -197,7 +198,16 @@ class InstallCommand(Command): + if options.download_dir: + options.no_install = True + options.ignore_installed = True +- options.build_dir = os.path.abspath(options.build_dir) ++ ++ # If we have --no-install or --no-download and no --build we use the ++ # legacy static build dir ++ if (options.build_dir is None ++ and (options.no_install or options.no_download)): ++ options.build_dir = build_prefix ++ ++ if options.build_dir: ++ options.build_dir = os.path.abspath(options.build_dir) ++ + options.src_dir = os.path.abspath(options.src_dir) + install_options = options.install_options or [] + if options.use_user_site: +@@ -246,73 +256,75 @@ class InstallCommand(Command): + + finder = self._build_package_finder(options, index_urls, session) + +- requirement_set = RequirementSet( +- build_dir=options.build_dir, +- src_dir=options.src_dir, +- download_dir=options.download_dir, +- download_cache=options.download_cache, +- upgrade=options.upgrade, +- as_egg=options.as_egg, +- ignore_installed=options.ignore_installed, +- ignore_dependencies=options.ignore_dependencies, +- force_reinstall=options.force_reinstall, +- use_user_site=options.use_user_site, +- target_dir=temp_target_dir, +- session=session, +- pycompile=options.compile, +- ) +- for name in args: +- requirement_set.add_requirement( +- InstallRequirement.from_line(name, None)) +- for name in options.editables: +- requirement_set.add_requirement( +- InstallRequirement.from_editable(name, default_vcs=options.default_vcs)) +- for filename in options.requirements: +- for req in parse_requirements(filename, finder=finder, options=options, session=session): +- requirement_set.add_requirement(req) +- if not requirement_set.has_requirements: +- opts = {'name': self.name} +- if options.find_links: +- msg = ('You must give at least one requirement to %(name)s ' +- '(maybe you meant "pip %(name)s %(links)s"?)' % +- dict(opts, links=' '.join(options.find_links))) +- else: +- msg = ('You must give at least one requirement ' +- 'to %(name)s (see "pip help %(name)s")' % opts) +- logger.warn(msg) +- return +- +- try: +- if not options.no_download: +- requirement_set.prepare_files(finder, force_root_egg_info=self.bundle, bundle=self.bundle) +- else: +- requirement_set.locate_files() +- +- if not options.no_install and not self.bundle: +- requirement_set.install( +- install_options, +- global_options, +- root=options.root_path, +- strip_file_prefix=options.strip_file_prefix) +- installed = ' '.join([req.name for req in +- requirement_set.successfully_installed]) +- if installed: +- logger.notify('Successfully installed %s' % installed) +- elif not self.bundle: +- downloaded = ' '.join([req.name for req in +- requirement_set.successfully_downloaded]) +- if downloaded: +- logger.notify('Successfully downloaded %s' % downloaded) +- elif self.bundle: +- requirement_set.create_bundle(self.bundle_filename) +- logger.notify('Created bundle in %s' % self.bundle_filename) +- except PreviousBuildDirError: +- options.no_clean = True +- raise +- finally: +- # Clean up +- if (not options.no_clean) and ((not options.no_install) or options.download_dir): +- requirement_set.cleanup_files(bundle=self.bundle) ++ build_delete = (not (options.no_clean or options.build_dir)) ++ with BuildDirectory(options.build_dir, delete=build_delete) as build_dir: ++ requirement_set = RequirementSet( ++ build_dir=build_dir, ++ src_dir=options.src_dir, ++ download_dir=options.download_dir, ++ download_cache=options.download_cache, ++ upgrade=options.upgrade, ++ as_egg=options.as_egg, ++ ignore_installed=options.ignore_installed, ++ ignore_dependencies=options.ignore_dependencies, ++ force_reinstall=options.force_reinstall, ++ use_user_site=options.use_user_site, ++ target_dir=temp_target_dir, ++ session=session, ++ pycompile=options.compile, ++ ) ++ for name in args: ++ requirement_set.add_requirement( ++ InstallRequirement.from_line(name, None)) ++ for name in options.editables: ++ requirement_set.add_requirement( ++ InstallRequirement.from_editable(name, default_vcs=options.default_vcs)) ++ for filename in options.requirements: ++ for req in parse_requirements(filename, finder=finder, options=options, session=session): ++ requirement_set.add_requirement(req) ++ if not requirement_set.has_requirements: ++ opts = {'name': self.name} ++ if options.find_links: ++ msg = ('You must give at least one requirement to %(name)s ' ++ '(maybe you meant "pip %(name)s %(links)s"?)' % ++ dict(opts, links=' '.join(options.find_links))) ++ else: ++ msg = ('You must give at least one requirement ' ++ 'to %(name)s (see "pip help %(name)s")' % opts) ++ logger.warn(msg) ++ return ++ ++ try: ++ if not options.no_download: ++ requirement_set.prepare_files(finder, force_root_egg_info=self.bundle, bundle=self.bundle) ++ else: ++ requirement_set.locate_files() ++ ++ if not options.no_install and not self.bundle: ++ requirement_set.install( ++ install_options, ++ global_options, ++ root=options.root_path, ++ strip_file_prefix=options.strip_file_prefix) ++ installed = ' '.join([req.name for req in ++ requirement_set.successfully_installed]) ++ if installed: ++ logger.notify('Successfully installed %s' % installed) ++ elif not self.bundle: ++ downloaded = ' '.join([req.name for req in ++ requirement_set.successfully_downloaded]) ++ if downloaded: ++ logger.notify('Successfully downloaded %s' % downloaded) ++ elif self.bundle: ++ requirement_set.create_bundle(self.bundle_filename) ++ logger.notify('Created bundle in %s' % self.bundle_filename) ++ except PreviousBuildDirError: ++ options.no_clean = True ++ raise ++ finally: ++ # Clean up ++ if (not options.no_clean) and ((not options.no_install) or options.download_dir): ++ requirement_set.cleanup_files(bundle=self.bundle) + + if options.target_dir: + if not os.path.exists(options.target_dir): +diff --git a/pip/commands/wheel.py b/pip/commands/wheel.py +index 6527063..a96631a 100644 +--- a/pip/commands/wheel.py ++++ b/pip/commands/wheel.py +@@ -8,7 +8,7 @@ from pip.index import PackageFinder + from pip.log import logger + from pip.exceptions import CommandError, PreviousBuildDirError + from pip.req import InstallRequirement, RequirementSet, parse_requirements +-from pip.util import normalize_path ++from pip.util import BuildDirectory, normalize_path + from pip.wheel import WheelBuilder + from pip import cmdoptions + +@@ -123,6 +123,9 @@ class WheelCommand(Command): + "--extra-index-url is suggested.") + index_urls += options.mirrors + ++ if options.build_dir: ++ options.build_dir = os.path.abspath(options.build_dir) ++ + session = self._build_session(options) + + finder = PackageFinder(find_links=options.find_links, +@@ -137,59 +140,60 @@ class WheelCommand(Command): + session=session, + ) + +- options.build_dir = os.path.abspath(options.build_dir) +- requirement_set = RequirementSet( +- build_dir=options.build_dir, +- src_dir=None, +- download_dir=None, +- download_cache=options.download_cache, +- ignore_dependencies=options.ignore_dependencies, +- ignore_installed=True, +- session=session, +- wheel_download_dir=options.wheel_dir +- ) +- +- # make the wheelhouse +- if not os.path.exists(options.wheel_dir): +- os.makedirs(options.wheel_dir) +- +- #parse args and/or requirements files +- for name in args: +- requirement_set.add_requirement( +- InstallRequirement.from_line(name, None)) +- +- for filename in options.requirements: +- for req in parse_requirements( +- filename, +- finder=finder, +- options=options, +- session=session): +- if req.editable: +- logger.notify("ignoring %s" % req.url) +- continue +- requirement_set.add_requirement(req) +- +- #fail if no requirements +- if not requirement_set.has_requirements: +- opts = {'name': self.name} +- msg = ('You must give at least one requirement ' +- 'to %(name)s (see "pip help %(name)s")' % opts) +- logger.error(msg) +- return ++ build_delete = (not (options.no_clean or options.build_dir)) ++ with BuildDirectory(options.build_dir, delete=build_delete) as build_dir: ++ requirement_set = RequirementSet( ++ build_dir=build_dir, ++ src_dir=None, ++ download_dir=None, ++ download_cache=options.download_cache, ++ ignore_dependencies=options.ignore_dependencies, ++ ignore_installed=True, ++ session=session, ++ wheel_download_dir=options.wheel_dir ++ ) + +- try: +- #build wheels +- wb = WheelBuilder( +- requirement_set, +- finder, +- options.wheel_dir, +- build_options = options.build_options or [], +- global_options = options.global_options or [] +- ) +- wb.build() +- except PreviousBuildDirError: +- options.no_clean = True +- raise +- finally: +- if not options.no_clean: +- requirement_set.cleanup_files() ++ # make the wheelhouse ++ if not os.path.exists(options.wheel_dir): ++ os.makedirs(options.wheel_dir) ++ ++ #parse args and/or requirements files ++ for name in args: ++ requirement_set.add_requirement( ++ InstallRequirement.from_line(name, None)) ++ ++ for filename in options.requirements: ++ for req in parse_requirements( ++ filename, ++ finder=finder, ++ options=options, ++ session=session): ++ if req.editable: ++ logger.notify("ignoring %s" % req.url) ++ continue ++ requirement_set.add_requirement(req) ++ ++ #fail if no requirements ++ if not requirement_set.has_requirements: ++ opts = {'name': self.name} ++ msg = ('You must give at least one requirement ' ++ 'to %(name)s (see "pip help %(name)s")' % opts) ++ logger.error(msg) ++ return ++ ++ try: ++ #build wheels ++ wb = WheelBuilder( ++ requirement_set, ++ finder, ++ options.wheel_dir, ++ build_options = options.build_options or [], ++ global_options = options.global_options or [] ++ ) ++ wb.build() ++ except PreviousBuildDirError: ++ options.no_clean = True ++ raise ++ finally: ++ if not options.no_clean: ++ requirement_set.cleanup_files() +diff --git a/pip/util.py b/pip/util.py +index f459bb2..f5edeeb 100644 +--- a/pip/util.py ++++ b/pip/util.py +@@ -8,6 +8,7 @@ import zipfile + import tarfile + import subprocess + import textwrap ++import tempfile + + from pip.exceptions import InstallationError, BadCommand, PipError + from pip.backwardcompat import(WindowsError, string_types, raw_input, +@@ -718,3 +719,35 @@ def is_prerelease(vers): + + parsed = version._normalized_key(normalized) + return any([any([y in set(["a", "b", "c", "rc", "dev"]) for y in x]) for x in parsed]) ++ ++ ++class BuildDirectory(object): ++ ++ def __init__(self, name=None, delete=None): ++ # If we were not given an explicit directory, and we were not given an ++ # explicit delete option, then we'll default to deleting. ++ if name is None and delete is None: ++ delete = True ++ ++ if name is None: ++ name = tempfile.mkdtemp(prefix="pip-build-") ++ # If we were not given an explicit directory, and we were not given ++ # an explicit delete option, then we'll default to deleting. ++ if delete is None: ++ delete = True ++ ++ self.name = name ++ self.delete = delete ++ ++ def __repr__(self): ++ return "<{} {!r}>".format(self.__class__.__name__, self.name) ++ ++ def __enter__(self): ++ return self.name ++ ++ def __exit__(self, exc, value, tb): ++ self.cleanup() ++ ++ def cleanup(self): ++ if self.delete: ++ rmtree(self.name) diff --git a/network-tests.patch b/network-tests.patch new file mode 100644 index 0000000..8acf694 --- /dev/null +++ b/network-tests.patch @@ -0,0 +1,683 @@ +From 621800d5c65aea36c6a1d9b685ff88f35cfce476 Mon Sep 17 00:00:00 2001 +From: Tomas Orsava +Date: Fri, 15 Nov 2019 19:44:54 +0100 +Subject: [PATCH] Mark 6 tests as network tests + +=================================== FAILURES =================================== +_______________________________ test_freeze_path _______________________________ +tmpdir = Path('/tmp/pytest-of-mockbuild/pytest-0/test_freeze_path0') +script = +data = + def test_freeze_path(tmpdir, script, data): + """ + Test freeze with --path. + """ +> script.pip('install', '--find-links', data.find_links, + '--target', tmpdir, 'simple==2.0') +tests/functional/test_freeze.py:712: +_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ +tests/lib/__init__.py:593: in run + _check_stderr( +_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ +stderr = "WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'N...t at 0x7fe6435ef280>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/\n" +allow_stderr_warning = False, allow_stderr_error = False + def _check_stderr( + stderr, allow_stderr_warning, allow_stderr_error, + ): + """ + Check the given stderr for logged warnings and errors. + + :param stderr: stderr output as a string. + :param allow_stderr_warning: whether a logged warning (or deprecation + message) is allowed. Must be True if allow_stderr_error is True. + :param allow_stderr_error: whether a logged error is allowed. + """ + assert not (allow_stderr_error and not allow_stderr_warning) + + lines = stderr.splitlines() + for line in lines: + # First check for logging errors, which we don't allow during + # tests even if allow_stderr_error=True (since a logging error + # would signal a bug in pip's code). + # Unlike errors logged with logger.error(), these errors are + # sent directly to stderr and so bypass any configured log formatter. + # The "--- Logging error ---" string is used in Python 3.4+, and + # "Logged from file " is used in Python 2. + if (line.startswith('--- Logging error ---') or + line.startswith('Logged from file ')): + reason = 'stderr has a logging error, which is never allowed' + msg = make_check_stderr_message(stderr, line=line, reason=reason) + raise RuntimeError(msg) + if allow_stderr_error: + continue + + if line.startswith('ERROR: '): + reason = ( + 'stderr has an unexpected error ' + '(pass allow_stderr_error=True to permit this)' + ) + msg = make_check_stderr_message(stderr, line=line, reason=reason) + raise RuntimeError(msg) + if allow_stderr_warning: + continue + + if (line.startswith('WARNING: ') or + line.startswith(DEPRECATION_MSG_PREFIX)): + reason = ( + 'stderr has an unexpected warning ' + '(pass allow_stderr_warning=True to permit this)' + ) + msg = make_check_stderr_message(stderr, line=line, reason=reason) +> raise RuntimeError(msg) +E RuntimeError: stderr has an unexpected warning (pass allow_stderr_warning=True to permit this): +E Caused by line: "WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/" +E Complete stderr: WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/ +E WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/ +E WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/ +E WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/ +E WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/ +tests/lib/__init__.py:404: RuntimeError +________________________ test_freeze_path_exclude_user _________________________ +tmpdir = Path('/tmp/pytest-of-mockbuild/pytest-0/test_freeze_path_exclude_user0') +script = +data = + def test_freeze_path_exclude_user(tmpdir, script, data): + """ + Test freeze with --path and make sure packages from --user are not picked + up. + """ + script.pip_install_local('--find-links', data.find_links, + '--user', 'simple2') +> script.pip('install', '--find-links', data.find_links, + '--target', tmpdir, 'simple==1.0') +tests/functional/test_freeze.py:728: +_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ +tests/lib/__init__.py:593: in run + _check_stderr( +_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ +stderr = "WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'N...t at 0x7f87ae751310>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/\n" +allow_stderr_warning = False, allow_stderr_error = False + def _check_stderr( + stderr, allow_stderr_warning, allow_stderr_error, + ): + """ + Check the given stderr for logged warnings and errors. + + :param stderr: stderr output as a string. + :param allow_stderr_warning: whether a logged warning (or deprecation + message) is allowed. Must be True if allow_stderr_error is True. + :param allow_stderr_error: whether a logged error is allowed. + """ + assert not (allow_stderr_error and not allow_stderr_warning) + + lines = stderr.splitlines() + for line in lines: + # First check for logging errors, which we don't allow during + # tests even if allow_stderr_error=True (since a logging error + # would signal a bug in pip's code). + # Unlike errors logged with logger.error(), these errors are + # sent directly to stderr and so bypass any configured log formatter. + # The "--- Logging error ---" string is used in Python 3.4+, and + # "Logged from file " is used in Python 2. + if (line.startswith('--- Logging error ---') or + line.startswith('Logged from file ')): + reason = 'stderr has a logging error, which is never allowed' + msg = make_check_stderr_message(stderr, line=line, reason=reason) + raise RuntimeError(msg) + if allow_stderr_error: + continue + + if line.startswith('ERROR: '): + reason = ( + 'stderr has an unexpected error ' + '(pass allow_stderr_error=True to permit this)' + ) + msg = make_check_stderr_message(stderr, line=line, reason=reason) + raise RuntimeError(msg) + if allow_stderr_warning: + continue + + if (line.startswith('WARNING: ') or + line.startswith(DEPRECATION_MSG_PREFIX)): + reason = ( + 'stderr has an unexpected warning ' + '(pass allow_stderr_warning=True to permit this)' + ) + msg = make_check_stderr_message(stderr, line=line, reason=reason) +> raise RuntimeError(msg) +E RuntimeError: stderr has an unexpected warning (pass allow_stderr_warning=True to permit this): +E Caused by line: "WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/" +E Complete stderr: WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/ +E WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/ +E WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/ +E WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/ +E WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/ +tests/lib/__init__.py:404: RuntimeError +__________________________ test_freeze_path_multiple ___________________________ +tmpdir = Path('/tmp/pytest-of-mockbuild/pytest-0/test_freeze_path_multiple0') +script = +data = + def test_freeze_path_multiple(tmpdir, script, data): + """ + Test freeze with multiple --path arguments. + """ + path1 = tmpdir / "path1" + os.mkdir(path1) + path2 = tmpdir / "path2" + os.mkdir(path2) +> script.pip('install', '--find-links', data.find_links, + '--target', path1, 'simple==2.0') +tests/functional/test_freeze.py:750: +_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ +tests/lib/__init__.py:593: in run + _check_stderr( +_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ +stderr = "WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'N...t at 0x7f07e6253280>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/\n" +allow_stderr_warning = False, allow_stderr_error = False + def _check_stderr( + stderr, allow_stderr_warning, allow_stderr_error, + ): + """ + Check the given stderr for logged warnings and errors. + + :param stderr: stderr output as a string. + :param allow_stderr_warning: whether a logged warning (or deprecation + message) is allowed. Must be True if allow_stderr_error is True. + :param allow_stderr_error: whether a logged error is allowed. + """ + assert not (allow_stderr_error and not allow_stderr_warning) + + lines = stderr.splitlines() + for line in lines: + # First check for logging errors, which we don't allow during + # tests even if allow_stderr_error=True (since a logging error + # would signal a bug in pip's code). + # Unlike errors logged with logger.error(), these errors are + # sent directly to stderr and so bypass any configured log formatter. + # The "--- Logging error ---" string is used in Python 3.4+, and + # "Logged from file " is used in Python 2. + if (line.startswith('--- Logging error ---') or + line.startswith('Logged from file ')): + reason = 'stderr has a logging error, which is never allowed' + msg = make_check_stderr_message(stderr, line=line, reason=reason) + raise RuntimeError(msg) + if allow_stderr_error: + continue + + if line.startswith('ERROR: '): + reason = ( + 'stderr has an unexpected error ' + '(pass allow_stderr_error=True to permit this)' + ) + msg = make_check_stderr_message(stderr, line=line, reason=reason) + raise RuntimeError(msg) + if allow_stderr_warning: + continue + + if (line.startswith('WARNING: ') or + line.startswith(DEPRECATION_MSG_PREFIX)): + reason = ( + 'stderr has an unexpected warning ' + '(pass allow_stderr_warning=True to permit this)' + ) + msg = make_check_stderr_message(stderr, line=line, reason=reason) +> raise RuntimeError(msg) +E RuntimeError: stderr has an unexpected warning (pass allow_stderr_warning=True to permit this): +E Caused by line: "WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/" +E Complete stderr: WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/ +E WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/ +E WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/ +E WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/ +E WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/simple/ +tests/lib/__init__.py:404: RuntimeError +_________________ test_install_no_binary_builds_pep_517_wheel __________________ +script = +data = , with_wheel = None + def test_install_no_binary_builds_pep_517_wheel(script, data, with_wheel): + to_install = data.packages.joinpath('pep517_setup_and_pyproject') +> res = script.pip( + 'install', '--no-binary=:all:', '-f', data.find_links, to_install + ) +tests/functional/test_install.py:1279: +_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ +self = +args = ('python', '-m', 'pip', 'install', '--no-binary=:all:', '-f', ...) +kw = {'expect_stderr': True} +cwd = Path('/tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/scratch') +run_from = None, allow_stderr_error = False, allow_stderr_warning = False +expect_error = None + def run(self, *args, **kw): + """ + :param allow_stderr_error: whether a logged error is allowed in + stderr. Passing True for this argument implies + `allow_stderr_warning` since warnings are weaker than errors. + :param allow_stderr_warning: whether a logged warning (or + deprecation message) is allowed in stderr. + :param expect_error: if False (the default), asserts that the command + exits with 0. Otherwise, asserts that the command exits with a + non-zero exit code. Passing True also implies allow_stderr_error + and allow_stderr_warning. + :param expect_stderr: whether to allow warnings in stderr (equivalent + to `allow_stderr_warning`). This argument is an abbreviated + version of `allow_stderr_warning` and is also kept for backwards + compatibility. + """ + if self.verbose: + print('>> running %s %s' % (args, kw)) + + cwd = kw.pop('cwd', None) + run_from = kw.pop('run_from', None) + assert not cwd or not run_from, "Don't use run_from; it's going away" + cwd = cwd or run_from or self.cwd + if sys.platform == 'win32': + # Partial fix for ScriptTest.run using `shell=True` on Windows. + args = [str(a).replace('^', '^^').replace('&', '^&') for a in args] + + # Remove `allow_stderr_error` and `allow_stderr_warning` before + # calling run() because PipTestEnvironment doesn't support them. + allow_stderr_error = kw.pop('allow_stderr_error', None) + allow_stderr_warning = kw.pop('allow_stderr_warning', None) + + # Propagate default values. + expect_error = kw.get('expect_error') + if expect_error: + # Then default to allowing logged errors. + if allow_stderr_error is not None and not allow_stderr_error: + raise RuntimeError( + 'cannot pass allow_stderr_error=False with ' + 'expect_error=True' + ) + allow_stderr_error = True + + elif kw.get('expect_stderr'): + # Then default to allowing logged warnings. + if allow_stderr_warning is not None and not allow_stderr_warning: + raise RuntimeError( + 'cannot pass allow_stderr_warning=False with ' + 'expect_stderr=True' + ) + allow_stderr_warning = True + + if allow_stderr_error: + if allow_stderr_warning is not None and not allow_stderr_warning: + raise RuntimeError( + 'cannot pass allow_stderr_warning=False with ' + 'allow_stderr_error=True' + ) + + # Default values if not set. + if allow_stderr_error is None: + allow_stderr_error = False + if allow_stderr_warning is None: + allow_stderr_warning = allow_stderr_error + + # Pass expect_stderr=True to allow any stderr. We do this because + # we do our checking of stderr further on in check_stderr(). + kw['expect_stderr'] = True +> result = super(PipTestEnvironment, self).run(cwd=cwd, *args, **kw) +E AssertionError: Script returned code: 1 +tests/lib/__init__.py:586: AssertionError +----------------------------- Captured stdout call ----------------------------- +Script result: python -m pip install --no-binary=:all: -f file:///tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/data/packages /tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/data/packages/pep517_setup_and_pyproject + return code: 1 +-- stderr: -------------------- + ERROR: Command errored out with exit status 1: + command: /tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/venv/bin/python /builddir/build/BUILDROOT/python-pip-19.3.1-1.fc32.noarch/usr/lib/python3.8/site-packages/pip install --ignore-installed --no-user --prefix /tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/tmp/pip-build-env-ntp1m4dh/overlay --no-warn-script-location --no-binary :all: --only-binary :none: -i https://pypi.org/simple --find-links file:///tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/data/packages -- setuptools + cwd: None + Complete output (28 lines): + Looking in links: file:///tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/data/packages + WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/setuptools/ + WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/setuptools/ + WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/setuptools/ + WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/setuptools/ + WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/setuptools/ + Processing /tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/data/packages/setuptools-0.9.6.tar.gz + ERROR: Command errored out with exit status 1: + command: /tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/venv/bin/python -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/tmp/pip-install-b_6lf4z6/setuptools/setup.py'"'"'; __file__='"'"'/tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/tmp/pip-install-b_6lf4z6/setuptools/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/tmp/pip-install-b_6lf4z6/setuptools/pip-egg-info + cwd: /tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/tmp/pip-install-b_6lf4z6/setuptools/ + Complete output (15 lines): + Traceback (most recent call last): + File "", line 1, in + File "/tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/tmp/pip-install-b_6lf4z6/setuptools/setuptools/__init__.py", line 2, in + from setuptools.extension import Extension, Library + File "/tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/tmp/pip-install-b_6lf4z6/setuptools/setuptools/extension.py", line 5, in + from setuptools.dist import _get_unpatched + File "/tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/tmp/pip-install-b_6lf4z6/setuptools/setuptools/dist.py", line 7, in + from setuptools.command.install import install + File "/tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/tmp/pip-install-b_6lf4z6/setuptools/setuptools/command/__init__.py", line 8, in + from setuptools.command import install_scripts + File "/tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/tmp/pip-install-b_6lf4z6/setuptools/setuptools/command/install_scripts.py", line 3, in + from pkg_resources import Distribution, PathMetadata, ensure_directory + File "/tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/tmp/pip-install-b_6lf4z6/setuptools/pkg_resources.py", line 1545, in + register_loader_type(importlib_bootstrap.SourceFileLoader, DefaultProvider) + AttributeError: module 'importlib._bootstrap' has no attribute 'SourceFileLoader' + ---------------------------------------- + ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output. + ---------------------------------------- +ERROR: Command errored out with exit status 1: /tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/venv/bin/python /builddir/build/BUILDROOT/python-pip-19.3.1-1.fc32.noarch/usr/lib/python3.8/site-packages/pip install --ignore-installed --no-user --prefix /tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/workspace/tmp/pip-build-env-ntp1m4dh/overlay --no-warn-script-location --no-binary :all: --only-binary :none: -i https://pypi.org/simple --find-links file:///tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/data/packages -- setuptools Check the logs for full command output. +-- stdout: -------------------- +Looking in links: file:///tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/data/packages +Processing /tmp/pytest-of-mockbuild/pytest-0/test_install_no_binary_builds_0/data/packages/pep517_setup_and_pyproject + Installing build dependencies: started + Installing build dependencies: finished with status 'error' +_______________________ test_config_file_override_stack ________________________ +script = +virtualenv = + def test_config_file_override_stack(script, virtualenv): + """ + Test config files (global, overriding a global config with a + local, overriding all with a command line flag). + + """ + fd, config_file = tempfile.mkstemp('-pip.cfg', 'test-') + try: +> _test_config_file_override_stack(script, virtualenv, config_file) +tests/functional/test_install_config.py:144: +_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ +tests/functional/test_install_config.py:172: in _test_config_file_override_stack + result = script.pip( +_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ +self = +args = ('python', '-m', 'pip', 'install', '-vvv', '--index-url', ...) +kw = {'expect_stderr': True} +cwd = Path('/tmp/pytest-of-mockbuild/pytest-0/test_config_file_override_stac0/workspace/scratch') +run_from = None, allow_stderr_error = False, allow_stderr_warning = False +expect_error = None + def run(self, *args, **kw): + """ + :param allow_stderr_error: whether a logged error is allowed in + stderr. Passing True for this argument implies + `allow_stderr_warning` since warnings are weaker than errors. + :param allow_stderr_warning: whether a logged warning (or + deprecation message) is allowed in stderr. + :param expect_error: if False (the default), asserts that the command + exits with 0. Otherwise, asserts that the command exits with a + non-zero exit code. Passing True also implies allow_stderr_error + and allow_stderr_warning. + :param expect_stderr: whether to allow warnings in stderr (equivalent + to `allow_stderr_warning`). This argument is an abbreviated + version of `allow_stderr_warning` and is also kept for backwards + compatibility. + """ + if self.verbose: + print('>> running %s %s' % (args, kw)) + + cwd = kw.pop('cwd', None) + run_from = kw.pop('run_from', None) + assert not cwd or not run_from, "Don't use run_from; it's going away" + cwd = cwd or run_from or self.cwd + if sys.platform == 'win32': + # Partial fix for ScriptTest.run using `shell=True` on Windows. + args = [str(a).replace('^', '^^').replace('&', '^&') for a in args] + + # Remove `allow_stderr_error` and `allow_stderr_warning` before + # calling run() because PipTestEnvironment doesn't support them. + allow_stderr_error = kw.pop('allow_stderr_error', None) + allow_stderr_warning = kw.pop('allow_stderr_warning', None) + + # Propagate default values. + expect_error = kw.get('expect_error') + if expect_error: + # Then default to allowing logged errors. + if allow_stderr_error is not None and not allow_stderr_error: + raise RuntimeError( + 'cannot pass allow_stderr_error=False with ' + 'expect_error=True' + ) + allow_stderr_error = True + + elif kw.get('expect_stderr'): + # Then default to allowing logged warnings. + if allow_stderr_warning is not None and not allow_stderr_warning: + raise RuntimeError( + 'cannot pass allow_stderr_warning=False with ' + 'expect_stderr=True' + ) + allow_stderr_warning = True + + if allow_stderr_error: + if allow_stderr_warning is not None and not allow_stderr_warning: + raise RuntimeError( + 'cannot pass allow_stderr_warning=False with ' + 'allow_stderr_error=True' + ) + + # Default values if not set. + if allow_stderr_error is None: + allow_stderr_error = False + if allow_stderr_warning is None: + allow_stderr_warning = allow_stderr_error + + # Pass expect_stderr=True to allow any stderr. We do this because + # we do our checking of stderr further on in check_stderr(). + kw['expect_stderr'] = True +> result = super(PipTestEnvironment, self).run(cwd=cwd, *args, **kw) +E AssertionError: Script returned code: 1 +tests/lib/__init__.py:586: AssertionError +----------------------------- Captured stdout call ----------------------------- +Script result: python -m pip install -vvv --index-url https://pypi.org/simple/ INITools + return code: 1 +-- stderr: -------------------- +WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/initools/ +WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/initools/ +WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/initools/ +WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/initools/ +WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/initools/ +ERROR: Could not find a version that satisfies the requirement INITools (from versions: none) +ERROR: No matching distribution found for INITools +-- stdout: -------------------- +Created temporary directory: /tmp/pytest-of-mockbuild/pytest-0/test_config_file_override_stac0/workspace/tmp/pip-ephem-wheel-cache-6gj33ens +Created temporary directory: /tmp/pytest-of-mockbuild/pytest-0/test_config_file_override_stac0/workspace/tmp/pip-req-tracker-s7_2cwgc +Created requirements tracker '/tmp/pytest-of-mockbuild/pytest-0/test_config_file_override_stac0/workspace/tmp/pip-req-tracker-s7_2cwgc' +Created temporary directory: /tmp/pytest-of-mockbuild/pytest-0/test_config_file_override_stac0/workspace/tmp/pip-install-_91mh3df +Looking in indexes: https://pypi.org/simple/ +1 location(s) to search for versions of INITools: +* https://pypi.org/simple/initools/ +Getting page https://pypi.org/simple/initools/ +Found index url https://pypi.org/simple/ +Looking up "https://pypi.org/simple/initools/" in the cache +Request header has "max_age" as 0, cache bypassed +Starting new HTTPS connection (1): pypi.org:443 +Incremented Retry for (url='/simple/initools/'): Retry(total=4, connect=None, read=None, redirect=None, status=None) +Starting new HTTPS connection (2): pypi.org:443 +Incremented Retry for (url='/simple/initools/'): Retry(total=3, connect=None, read=None, redirect=None, status=None) +Starting new HTTPS connection (3): pypi.org:443 +Incremented Retry for (url='/simple/initools/'): Retry(total=2, connect=None, read=None, redirect=None, status=None) +Starting new HTTPS connection (4): pypi.org:443 +Incremented Retry for (url='/simple/initools/'): Retry(total=1, connect=None, read=None, redirect=None, status=None) +Starting new HTTPS connection (5): pypi.org:443 +Incremented Retry for (url='/simple/initools/'): Retry(total=0, connect=None, read=None, redirect=None, status=None) +Starting new HTTPS connection (6): pypi.org:443 +Could not fetch URL https://pypi.org/simple/initools/: connection error: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/initools/ (Caused by NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')) - skipping +Given no hashes to check 0 links for project 'INITools': discarding no candidates +Cleaning up... +Removed build tracker '/tmp/pytest-of-mockbuild/pytest-0/test_config_file_override_stac0/workspace/tmp/pip-req-tracker-s7_2cwgc' +Exception information: +Traceback (most recent call last): + File "/builddir/build/BUILDROOT/python-pip-19.3.1-1.fc32.noarch/usr/lib/python3.8/site-packages/pip/_internal/cli/base_command.py", line 153, in _main + status = self.run(options, args) + File "/builddir/build/BUILDROOT/python-pip-19.3.1-1.fc32.noarch/usr/lib/python3.8/site-packages/pip/_internal/commands/install.py", line 401, in run + resolver.resolve(requirement_set) + File "/builddir/build/BUILDROOT/python-pip-19.3.1-1.fc32.noarch/usr/lib/python3.8/site-packages/pip/_internal/legacy_resolve.py", line 202, in resolve + self._resolve_one(requirement_set, req) + File "/builddir/build/BUILDROOT/python-pip-19.3.1-1.fc32.noarch/usr/lib/python3.8/site-packages/pip/_internal/legacy_resolve.py", line 368, in _resolve_one + abstract_dist = self._get_abstract_dist_for(req_to_install) + File "/builddir/build/BUILDROOT/python-pip-19.3.1-1.fc32.noarch/usr/lib/python3.8/site-packages/pip/_internal/legacy_resolve.py", line 314, in _get_abstract_dist_for + req.populate_link(self.finder, upgrade_allowed, self.require_hashes) + File "/builddir/build/BUILDROOT/python-pip-19.3.1-1.fc32.noarch/usr/lib/python3.8/site-packages/pip/_internal/req/req_install.py", line 226, in populate_link + self.link = finder.find_requirement(self, upgrade) + File "/builddir/build/BUILDROOT/python-pip-19.3.1-1.fc32.noarch/usr/lib/python3.8/site-packages/pip/_internal/index.py", line 905, in find_requirement + raise DistributionNotFound( +pip._internal.exceptions.DistributionNotFound: No matching distribution found for INITools +_______________________ test_no_upgrade_unless_requested _______________________ +script = + def test_no_upgrade_unless_requested(script): + """ + No upgrade if not specifically requested. + + """ +> script.pip('install', 'INITools==0.1') +tests/functional/test_install_upgrade.py:16: +_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ +self = +args = ('python', '-m', 'pip', 'install', 'INITools==0.1') +kw = {'expect_stderr': True} +cwd = Path('/tmp/pytest-of-mockbuild/pytest-0/test_no_upgrade_unless_request0/workspace/scratch') +run_from = None, allow_stderr_error = False, allow_stderr_warning = False +expect_error = None + def run(self, *args, **kw): + """ + :param allow_stderr_error: whether a logged error is allowed in + stderr. Passing True for this argument implies + `allow_stderr_warning` since warnings are weaker than errors. + :param allow_stderr_warning: whether a logged warning (or + deprecation message) is allowed in stderr. + :param expect_error: if False (the default), asserts that the command + exits with 0. Otherwise, asserts that the command exits with a + non-zero exit code. Passing True also implies allow_stderr_error + and allow_stderr_warning. + :param expect_stderr: whether to allow warnings in stderr (equivalent + to `allow_stderr_warning`). This argument is an abbreviated + version of `allow_stderr_warning` and is also kept for backwards + compatibility. + """ + if self.verbose: + print('>> running %s %s' % (args, kw)) + + cwd = kw.pop('cwd', None) + run_from = kw.pop('run_from', None) + assert not cwd or not run_from, "Don't use run_from; it's going away" + cwd = cwd or run_from or self.cwd + if sys.platform == 'win32': + # Partial fix for ScriptTest.run using `shell=True` on Windows. + args = [str(a).replace('^', '^^').replace('&', '^&') for a in args] + + # Remove `allow_stderr_error` and `allow_stderr_warning` before + # calling run() because PipTestEnvironment doesn't support them. + allow_stderr_error = kw.pop('allow_stderr_error', None) + allow_stderr_warning = kw.pop('allow_stderr_warning', None) + + # Propagate default values. + expect_error = kw.get('expect_error') + if expect_error: + # Then default to allowing logged errors. + if allow_stderr_error is not None and not allow_stderr_error: + raise RuntimeError( + 'cannot pass allow_stderr_error=False with ' + 'expect_error=True' + ) + allow_stderr_error = True + + elif kw.get('expect_stderr'): + # Then default to allowing logged warnings. + if allow_stderr_warning is not None and not allow_stderr_warning: + raise RuntimeError( + 'cannot pass allow_stderr_warning=False with ' + 'expect_stderr=True' + ) + allow_stderr_warning = True + + if allow_stderr_error: + if allow_stderr_warning is not None and not allow_stderr_warning: + raise RuntimeError( + 'cannot pass allow_stderr_warning=False with ' + 'allow_stderr_error=True' + ) + + # Default values if not set. + if allow_stderr_error is None: + allow_stderr_error = False + if allow_stderr_warning is None: + allow_stderr_warning = allow_stderr_error + + # Pass expect_stderr=True to allow any stderr. We do this because + # we do our checking of stderr further on in check_stderr(). + kw['expect_stderr'] = True +> result = super(PipTestEnvironment, self).run(cwd=cwd, *args, **kw) +E AssertionError: Script returned code: 1 +tests/lib/__init__.py:586: AssertionError +----------------------------- Captured stdout call ----------------------------- +Script result: python -m pip install INITools==0.1 + return code: 1 +-- stderr: -------------------- +WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/initools/ +WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/initools/ +WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/initools/ +WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/initools/ +WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/initools/ +ERROR: Could not find a version that satisfies the requirement INITools==0.1 (from versions: none) +ERROR: No matching distribution found for INITools==0.1 +--- + tests/functional/test_freeze.py | 3 +++ + tests/functional/test_install.py | 1 + + tests/functional/test_install_config.py | 1 + + tests/functional/test_install_upgrade.py | 1 + + 4 files changed, 6 insertions(+) + +diff --git a/tests/functional/test_freeze.py b/tests/functional/test_freeze.py +index 546a482..aabb0ca 100644 +--- a/tests/functional/test_freeze.py ++++ b/tests/functional/test_freeze.py +@@ -705,6 +705,7 @@ def test_freeze_user(script, virtualenv, data): + assert 'simple2' not in result.stdout + + ++@pytest.mark.network + def test_freeze_path(tmpdir, script, data): + """ + Test freeze with --path. +@@ -718,6 +719,7 @@ def test_freeze_path(tmpdir, script, data): + _check_output(result.stdout, expected) + + ++@pytest.mark.network + def test_freeze_path_exclude_user(tmpdir, script, data): + """ + Test freeze with --path and make sure packages from --user are not picked +@@ -739,6 +741,7 @@ def test_freeze_path_exclude_user(tmpdir, script, data): + _check_output(result.stdout, expected) + + ++@pytest.mark.network + def test_freeze_path_multiple(tmpdir, script, data): + """ + Test freeze with multiple --path arguments. +diff --git a/tests/functional/test_install.py b/tests/functional/test_install.py +index 0bea054..b816df6 100644 +--- a/tests/functional/test_install.py ++++ b/tests/functional/test_install.py +@@ -1274,6 +1274,7 @@ def test_install_no_binary_disables_building_wheels(script, data, with_wheel): + assert "Running setup.py install for upper" in str(res), str(res) + + ++@pytest.mark.network + def test_install_no_binary_builds_pep_517_wheel(script, data, with_wheel): + to_install = data.packages.joinpath('pep517_setup_and_pyproject') + res = script.pip( +diff --git a/tests/functional/test_install_config.py b/tests/functional/test_install_config.py +index bcf83f1..c9c60a2 100644 +--- a/tests/functional/test_install_config.py ++++ b/tests/functional/test_install_config.py +@@ -133,6 +133,7 @@ def test_command_line_appends_correctly(script, data): + ), 'stdout: {}'.format(result.stdout) + + ++@pytest.mark.network + def test_config_file_override_stack(script, virtualenv): + """ + Test config files (global, overriding a global config with a +diff --git a/tests/functional/test_install_upgrade.py b/tests/functional/test_install_upgrade.py +index 36b518b..c34a961 100644 +--- a/tests/functional/test_install_upgrade.py ++++ b/tests/functional/test_install_upgrade.py +@@ -8,6 +8,7 @@ from tests.lib import assert_all_changes, pyversion + from tests.lib.local_repos import local_checkout + + ++@pytest.mark.network + def test_no_upgrade_unless_requested(script): + """ + No upgrade if not specifically requested. +-- +2.20.1 + diff --git a/nowarn-pip._internal.main.patch b/nowarn-pip._internal.main.patch new file mode 100644 index 0000000..fb3ac92 --- /dev/null +++ b/nowarn-pip._internal.main.patch @@ -0,0 +1,72 @@ +From 7c36cb21910b415e0eb171d0f6c4dbf72382fdaf Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= +Date: Tue, 10 Mar 2020 11:03:22 +0100 +Subject: [PATCH] Don't warn the user about pip._internal.main() entrypoint + +In Fedora, we use that in ensurepip and users cannot do anything about it, +this warning is juts moot. Also, the warning breaks CPython test suite. +--- + src/pip/_internal/__init__.py | 2 +- + src/pip/_internal/utils/entrypoints.py | 19 ++++++++++--------- + tests/functional/test_cli.py | 3 ++- + 3 files changed, 13 insertions(+), 11 deletions(-) + +diff --git a/src/pip/_internal/__init__.py b/src/pip/_internal/__init__.py +index 3aa8a46..0ec017b 100755 +--- a/src/pip/_internal/__init__.py ++++ b/src/pip/_internal/__init__.py +@@ -15,4 +15,4 @@ def main(args=None): + """ + from pip._internal.utils.entrypoints import _wrapper + +- return _wrapper(args) ++ return _wrapper(args, _nowarn=True) +diff --git a/src/pip/_internal/utils/entrypoints.py b/src/pip/_internal/utils/entrypoints.py +index befd01c..d6f3632 100644 +--- a/src/pip/_internal/utils/entrypoints.py ++++ b/src/pip/_internal/utils/entrypoints.py +@@ -7,7 +7,7 @@ if MYPY_CHECK_RUNNING: + from typing import Optional, List + + +-def _wrapper(args=None): ++def _wrapper(args=None, _nowarn=False): + # type: (Optional[List[str]]) -> int + """Central wrapper for all old entrypoints. + +@@ -20,12 +20,13 @@ def _wrapper(args=None): + directing them to an appropriate place for help, we now define all of + our old entrypoints as wrappers for the current one. + """ +- sys.stderr.write( +- "WARNING: pip is being invoked by an old script wrapper. This will " +- "fail in a future version of pip.\n" +- "Please see https://github.com/pypa/pip/issues/5599 for advice on " +- "fixing the underlying issue.\n" +- "To avoid this problem you can invoke Python with '-m pip' instead of " +- "running pip directly.\n" +- ) ++ if not _nowarn: ++ sys.stderr.write( ++ "WARNING: pip is being invoked by an old script wrapper. This will " ++ "fail in a future version of pip.\n" ++ "Please see https://github.com/pypa/pip/issues/5599 for advice on " ++ "fixing the underlying issue.\n" ++ "To avoid this problem you can invoke Python with '-m pip' instead of " ++ "running pip directly.\n" ++ ) + return main(args) +diff --git a/tests/functional/test_cli.py b/tests/functional/test_cli.py +index e416315..7f57f67 100644 +--- a/tests/functional/test_cli.py ++++ b/tests/functional/test_cli.py +@@ -31,4 +31,5 @@ def test_entrypoints_work(entrypoint, script): + result = script.pip("-V") + result2 = script.run("fake_pip", "-V", allow_stderr_warning=True) + assert result.stdout == result2.stdout +- assert "old script wrapper" in result2.stderr ++ if entrypoint[0] != "fake_pip = pip._internal:main": ++ assert "old script wrapper" in result2.stderr +-- +2.24.1 + diff --git a/pip-allow-different-versions.patch b/pip-allow-different-versions.patch new file mode 100644 index 0000000..4a11517 --- /dev/null +++ b/pip-allow-different-versions.patch @@ -0,0 +1,27 @@ +--- /usr/bin/pip3 2019-11-12 17:37:34.793131862 +0100 ++++ pip3 2019-11-12 17:40:42.014107134 +0100 +@@ -2,7 +2,23 @@ + # -*- coding: utf-8 -*- + import re + import sys +-from pip._internal.cli.main import main ++ ++try: ++ from pip._internal.cli.main import main ++except ImportError: ++ try: ++ from pip._internal.main import main ++ except ImportError: ++ try: ++ # If the user has downgraded pip, the above import will fail. ++ # Let's try older methods of invoking it: ++ ++ # pip 19 uses this ++ from pip._internal import main ++ except ImportError: ++ # older pip versions use this ++ from pip import main ++ + if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/plan.fmf b/plan.fmf deleted file mode 100644 index 72ad07b..0000000 --- a/plan.fmf +++ /dev/null @@ -1,111 +0,0 @@ -execute: - how: tmt - -discover: - - name: tests_python - how: shell - url: https://src.fedoraproject.org/tests/python.git - tests: - - name: smoke36 - path: /smoke - test: VERSION=3.6 TOX=false ./venv.sh - - name: smoke39 - path: /smoke - test: VERSION=3.9 ./venv.sh - - name: smoke310 - path: /smoke - test: VERSION=3.10 ./venv.sh - - name: smoke311 - path: /smoke - test: VERSION=3.11 ./venv.sh - - name: smoke312 - path: /smoke - test: VERSION=3.12 ./venv.sh - - name: smoke313 - path: /smoke - test: VERSION=3.13 ./venv.sh - - name: smoke314 - path: /smoke - test: VERSION=3.14 ./venv.sh - - name: smoke315 - path: /smoke - test: VERSION=3.15 ./venv.sh - - name: smoke39_virtualenv - path: /smoke - test: VERSION=3.9 METHOD=virtualenv ./venv.sh - - name: smoke310_virtualenv - path: /smoke - test: VERSION=3.10 METHOD=virtualenv ./venv.sh - - name: smoke311_virtualenv - path: /smoke - test: VERSION=3.11 METHOD=virtualenv ./venv.sh - - name: smoke312_virtualenv - path: /smoke - test: VERSION=3.12 METHOD=virtualenv ./venv.sh - - name: smoke313_virtualenv - path: /smoke - test: VERSION=3.13 METHOD=virtualenv ./venv.sh - - name: smoke314_virtualenv - path: /smoke - test: VERSION=3.14 METHOD=virtualenv ./venv.sh - - name: smoke315_virtualenv - path: /smoke - test: VERSION=3.15 METHOD=virtualenv ./venv.sh - - name: rpms_pyproject-rpm-macros - how: shell - url: https://src.fedoraproject.org/rpms/pyproject-rpm-macros.git - tests: - - name: pyproject_pytest - path: /tests - test: ./mocktest.sh python-pytest - - name: pyproject_entrypoints - path: /tests - test: ./mocktest.sh python-entrypoints - - name: pyproject_pluggy - path: /tests - test: ./mocktest.sh python-pluggy - - name: pyproject_clikit - path: /tests - test: ./mocktest.sh python-clikit - - name: same_repo - how: shell - dist-git-source: true - dist-git-download-only: true - tests: - - name: mock_bootstrap_build - test: | - cd $TMT_SOURCE_DIR && - $TMT_TREE/../discover/rpms_pyproject-rpm-macros/tests/tests/mocktest.sh python-pip --without tests --without man - - name: pip_install_upgrade - path: /tests/pip_install_upgrade/ - test: ./runtest.sh - - name: bash_completion - path: /tests/bash_completion - test: ./pip_completion_full_test.sh -prepare: - - name: Install dependencies - how: install - package: - - gcc - - virtualenv - - python3.6-devel - - python3.9-devel - - python3.10-devel - - python3.11-devel - - python3.12-devel - - python3.13-devel - - python3.14-devel - - python3.15-devel - - python3-devel - - python3-tox - - mock - - rpmdevtools - - rpm-build - - grep - - util-linux - - shadow-utils - - expect - - dnf - - name: Update packages - how: shell - script: dnf upgrade -y diff --git a/python-pip.rpmlintrc b/python-pip.rpmlintrc index d32664b..39079e3 100644 --- a/python-pip.rpmlintrc +++ b/python-pip.rpmlintrc @@ -1,9 +1,19 @@ # This is just temporary, when upstream merges PRs it can be removed +# https://github.com/pypa/pip/pull/7959 +# https://github.com/ActiveState/appdirs/pull/144 # https://github.com/psf/requests/pull/5410 +# https://github.com/chardet/chardet/pull/192 +addFilter(r'(non-executable-script|wrong-script-interpreter) .+/pip/_internal/__init__.py\b') +addFilter(r'(non-executable-script|wrong-script-interpreter) .+/pip/_vendor/appdirs.py\b') addFilter(r'(non-executable-script|wrong-script-interpreter) .+/pip/_vendor/requests/certs.py\b') +addFilter(r'(non-executable-script|wrong-script-interpreter) .+/pip/_vendor/chardet/cli/chardetect.py\b') -# This file is actually a script but in the vendored context of pip, it is never executed -addFilter(r'non-executable-script .+/pip/_vendor/distro/distro.py\b') +# REQUESTED dist-info file is not meant to have any content +# Discussion: https://src.fedoraproject.org/rpms/python-pip/pull-request/69#comment-52525 +addFilter(r'zero-length .+/site-packages/.+\.dist-info/REQUESTED\b') # We ship README with the main package but not with the wheel addFilter(r'python-pip-wheel.noarch: W: no-documentation') + +# SPELLING ERRORS +addFilter(r'W: spelling-error .* venv') diff --git a/python-pip.spec b/python-pip.spec index 8dc0aff..74093da 100644 --- a/python-pip.spec +++ b/python-pip.spec @@ -1,115 +1,131 @@ -# The original RHEL N+1 content set is defined by (build)dependencies -# of the packages in Fedora ELN. Hence we disable tests here -# to prevent pulling many unwanted packages in. -%bcond tests %{defined fedora} -# Whether to build the manual pages (useful for bootstrapping Sphinx) -%bcond man 1 +%bcond_without tests + +%bcond_without doc %global srcname pip -%global base_version 25.3 +%global base_version 20.2.2 %global upstream_version %{base_version}%{?prerel} -%global python_wheel_name %{srcname}-%{upstream_version}-py3-none-any.whl +%global python_wheelname %{srcname}-%{upstream_version}-py2.py3-none-any.whl +%global python_wheeldir %{_datadir}/python-wheels + +%if %{with doc} +# Commit hash to use from the repo https://github.com/pypa/pypa-docs-theme +%global pypa_theme_commit_hash d2e63fbfc62af3b7050f619b2f5bb8658985b931 +%endif + +%global bashcompdir %(pkg-config --variable=completionsdir bash-completion 2>/dev/null) Name: python-%{srcname} +# When updating, update the bundled libraries versions bellow! +# You can use vendor_meta.sh in the dist git repo Version: %{base_version}%{?prerel:~%{prerel}} -Release: %autorelease +Release: 4%{?dist} Summary: A tool for installing and managing Python packages # We bundle a lot of libraries with pip, which itself is under MIT license. # Here is the list of the libraries with corresponding licenses: -# certifi: MPL-2.0 -# CacheControl: Apache-2.0 -# dependency-groups: MIT -# distlib: Python-2.0.1 -# distro: Apache-2.0 -# idna: BSD-3-Clause -# msgpack: Apache-2.0 -# packaging: Apache-2.0 OR BSD-2-Clause -# platformdirs: MIT -# pygments: BSD-2-Clause -# pyproject-hooks: MIT -# requests: Apache-2.0 +# appdirs: MIT +# certifi: MPLv2.0 +# chardet: LGPLv2 +# colorama: BSD +# CacheControl: ASL 2.0 +# contextlib2: Python +# distlib: Python +# distro: ASL 2.0 +# html5lib: MIT +# idna: BSD +# ipaddress: Python +# msgpack: ASL 2.0 +# packaging: ASL 2.0 or BSD +# pep517: MIT +# progress: ISC +# pyparsing: MIT +# requests: ASL 2.0 # resolvelib: ISC -# rich: MIT +# retrying: ASL 2.0 # setuptools: MIT -# truststore: MIT -# tomli: MIT -# tomli-w: MIT +# six: MIT +# toml: MIT # urllib3: MIT +# webencodings: BSD -License: MIT AND Python-2.0.1 AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND MPL-2.0 AND (Apache-2.0 OR BSD-2-Clause) +License: MIT and Python and ASL 2.0 and BSD and ISC and LGPLv2 and MPLv2.0 and (ASL 2.0 or BSD) URL: https://pip.pypa.io/ Source0: https://github.com/pypa/pip/archive/%{upstream_version}/%{srcname}-%{upstream_version}.tar.gz -# The following sources are wheels used only for tests. -# They are not bundled in the built package and do not contribute to the overall license. -# They are pre-built but only contain text files, rebuilding them in %%build has very little benefit. - -# setuptools.whl -# We cannot use RPM-packaged python-setuptools-wheel because upstream pins to <80. -# See https://github.com/pypa/pip/pull/13357 for rationale. -Source1: https://files.pythonhosted.org/packages/0d/6d/b4752b044bf94cb802d88a888dc7d288baaf77d7910b7dedda74b5ceea0c/setuptools-79.0.1-py3-none-any.whl - -# wheel.whl -# We cannot use RPM-packaged python-wheel-wheel because we intent to drop that package in wheel 0.46+. -# That version of wheel has runtime dependencies and is generally useless as a standalone wheel. -# See https://github.com/pypa/pip/pull/13382 as an attempt to drop the requirement from pip tests. -Source2: https://files.pythonhosted.org/packages/0b/2c/87f3254fd8ffd29e4c02732eee68a83a1d3c346ae39bc6822dcbcb697f2b/wheel-0.45.1-py3-none-any.whl - -# flit_core.whl -# This is not built as RPM-packaged wheel in Fedora at all. -Source3: https://files.pythonhosted.org/packages/f2/65/b6ba90634c984a4fcc02c7e3afe523fef500c4980fec67cc27536ee50acf/flit_core-3.12.0-py3-none-any.whl - -# coverage.whl -# There is no RPM-packaged python-coverage-wheel, the package is archful. -# Upstream uses this to measure coverage, which we don't. -# This is a dummy placeholder package that only contains empty coverage.process_startup(). -# That way, we don't need to patch the usage out of conftest.py. -Source4: coverage-0-py3-none-any.whl - BuildArch: noarch %if %{with tests} BuildRequires: /usr/bin/git -BuildRequires: /usr/bin/hg BuildRequires: /usr/bin/bzr BuildRequires: /usr/bin/svn -BuildRequires: python%{python3_pkgversion}-pytest-xdist +BuildRequires: python-setuptools-wheel +BuildRequires: python-wheel-wheel %endif -%if %{with man} -# docs/requirements.txt contains many sphinx extensions -# however, we only build the manual pages thanks to -# https://github.com/pypa/pip/pull/13168 -# We also always use the "main" Sphinx, not python%%{python3_pkgversion}-sphinx -BuildRequires: python3-sphinx +# Themes required to build the docs. +%if %{with doc} +Source1: https://github.com/pypa/pypa-docs-theme/archive/%{pypa_theme_commit_hash}.tar.gz +Source2: https://github.com/python/python-docs-theme/archive/2018.2.tar.gz %endif +# Downstream only patch +# Emit a warning to the user if pip install is run with root privileges +# Issue upstream: https://github.com/pypa/pip/issues/4288 +Patch1: emit-a-warning-when-running-with-root-privileges.patch + +# Add path to the doc themes to conf.py +Patch2: html_theme_path.patch + # Prevent removing of the system packages installed under /usr/lib # when pip install -U is executed. # https://bugzilla.redhat.com/show_bug.cgi?id=1550368#c24 -# Could be replaced with https://www.python.org/dev/peps/pep-0668/ -Patch: remove-existing-dist-only-if-path-conflicts.patch +Patch3: remove-existing-dist-only-if-path-conflicts.patch # Use the system level root certificate instead of the one bundled in certifi # https://bugzilla.redhat.com/show_bug.cgi?id=1655253 -# The same patch is a part of the RPM-packaged python-certifi -Patch: dummy-certifi.patch +Patch4: dummy-certifi.patch -# pytest-subket has been introduced to intercept network calls -# https://github.com/pypa/pip/commit/a4b40f62332ccb3228b12cc5ae1493c75177247a -# We don't need a layer to check that, as we're by default in an offline environment -Patch: downstream-remove-pytest-subket.patch +# Don't warn the user about pip._internal.main() entrypoint +# In Fedora, we use that in ensurepip and users cannot do anything about it, +# this warning is juts moot. Also, the warning breaks CPython test suite. +Patch5: nowarn-pip._internal.main.patch -# Patch for the bundled urllib3 for CVE-2025-50181 -# Redirects are not disabled when retries are disabled on PoolManager instantiation -# Upstream fix: https://github.com/urllib3/urllib3/commit/f05b1329126d5be6de501f9d1e3e36738bc08857 -Patch: urllib3-CVE-2025-50181.patch +# Don't split git references on unicode separators, +# which could be maliciously used to install a different revision on the +# repository. +# Security patch backported from pip 21.1.1 +# Upstream PR: https://github.com/pypa/pip/pull/9827 +Patch8: don-t-split-git-references-on-unicode-separators.patch -# Remove -s from Python shebang - ensure that packages installed with pip -# to user locations are seen by pip itself -%undefine _py3_shebang_s +# Don't put an underscore in the version portion of Python 3.10 compatibility tags +# From https://github.com/pypa/packaging/pull/355 (merged upstream) +# Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1999035 +Patch9: python3.10-abi-tag-fix.patch + +# Downstream only patch +# Users might have local installations of pip from using +# `pip install --user --upgrade pip` on older/newer versions. +# If they do that and they run `pip` or `pip3`, the one from /usr/bin is used. +# However that's the one from this RPM package and the import in there might +# fail (it tries to import from ~/.local, but older or newer pip is there with +# a bit different API). +# We add this patch as a dirty workaround to make /usr/bin/pip* work with +# both pip10+ (from this RPM) and older or newer (19.3+) pip (from whatever). +# A proper fix is to put ~/.local/bin in front of /usr/bin in the PATH, +# however others are against that and we cannot change it for existing +# installs/user homes anyway. +# https://bugzilla.redhat.com/show_bug.cgi?id=1569488 +# https://bugzilla.redhat.com/show_bug.cgi?id=1571650 +# https://bugzilla.redhat.com/show_bug.cgi?id=1767212 +# WARNING: /usr/bin/pip* are entrypoints, this cannot be applied in %%prep! +# %%patch10 doesn't work outside of %%prep, so we add it as a source +# Note that since pip 20, old main() import paths are preserved for backwards +# compatibility: https://github.com/pypa/pip/issues/7498 +# Meaning we don't need to update any of the older pips to support 20+ +# We also don't need to update Pythons to use new import path in ensurepip +Source10: pip-allow-different-versions.patch %description pip is a package management system used to install and manage software packages @@ -123,25 +139,30 @@ Packages" or "Pip Installs Python". # You can generate it with: # %%{_rpmconfigdir}/pythonbundles.py --namespace 'python%%{1}dist' src/pip/_vendor/vendor.txt %global bundled() %{expand: -Provides: bundled(python%{1}dist(cachecontrol)) = 0.14.3 -Provides: bundled(python%{1}dist(certifi)) = 2025.10.5 -Provides: bundled(python%{1}dist(dependency-groups)) = 1.3.1 -Provides: bundled(python%{1}dist(distlib)) = 0.4 -Provides: bundled(python%{1}dist(distro)) = 1.9 -Provides: bundled(python%{1}dist(idna)) = 3.10 -Provides: bundled(python%{1}dist(msgpack)) = 1.1.2 -Provides: bundled(python%{1}dist(packaging)) = 25 -Provides: bundled(python%{1}dist(platformdirs)) = 4.5 -Provides: bundled(python%{1}dist(pygments)) = 2.19.2 -Provides: bundled(python%{1}dist(pyproject-hooks)) = 1.2 -Provides: bundled(python%{1}dist(requests)) = 2.32.5 -Provides: bundled(python%{1}dist(resolvelib)) = 1.2.1 -Provides: bundled(python%{1}dist(rich)) = 14.2 -Provides: bundled(python%{1}dist(setuptools)) = 70.3 -Provides: bundled(python%{1}dist(tomli)) = 2.3 -Provides: bundled(python%{1}dist(tomli-w)) = 1.2 -Provides: bundled(python%{1}dist(truststore)) = 0.10.4 -Provides: bundled(python%{1}dist(urllib3)) = 1.26.20 +Provides: bundled(python%{1}dist(appdirs)) = 1.4.4 +Provides: bundled(python%{1}dist(cachecontrol)) = 0.12.6 +Provides: bundled(python%{1}dist(certifi)) = 2020.6.20 +Provides: bundled(python%{1}dist(chardet)) = 3.0.4 +Provides: bundled(python%{1}dist(colorama)) = 0.4.3 +Provides: bundled(python%{1}dist(contextlib2)) = 0.6^post1 +Provides: bundled(python%{1}dist(distlib)) = 0.3.1 +Provides: bundled(python%{1}dist(distro)) = 1.5 +Provides: bundled(python%{1}dist(html5lib)) = 1.1 +Provides: bundled(python%{1}dist(idna)) = 2.10 +Provides: bundled(python%{1}dist(ipaddress)) = 1.0.23 +Provides: bundled(python%{1}dist(msgpack)) = 1 +Provides: bundled(python%{1}dist(packaging)) = 20.4 +Provides: bundled(python%{1}dist(pep517)) = 0.8.2 +Provides: bundled(python%{1}dist(progress)) = 1.5 +Provides: bundled(python%{1}dist(pyparsing)) = 2.4.7 +Provides: bundled(python%{1}dist(requests)) = 2.24 +Provides: bundled(python%{1}dist(resolvelib)) = 0.4 +Provides: bundled(python%{1}dist(retrying)) = 1.3.3 +Provides: bundled(python%{1}dist(setuptools)) = 44 +Provides: bundled(python%{1}dist(six)) = 1.15 +Provides: bundled(python%{1}dist(toml)) = 0.10.1 +Provides: bundled(python%{1}dist(urllib3)) = 1.25.9 +Provides: bundled(python%{1}dist(webencodings)) = 0.5.1 } # Some manylinux1 wheels need libcrypt.so.1. @@ -155,9 +176,6 @@ Provides: bundled(python%{1}dist(urllib3)) = 1.26.20 # a long time until manylinux1 is phased out). # See: https://github.com/pypa/manylinux/issues/305 # Note that manylinux is only applicable to x86 (both 32 and 64 bits) -# As of Python 3.12, we no longer use this, -# see https://discuss.python.org/t/29455/ -# However, we keep it around for previous Python versions that use the wheel package. %global crypt_compat_recommends() %{expand: Recommends: (libcrypt.so.1()(64bit) if python%{1}(x86-64)) Recommends: (libcrypt.so.1 if python%{1}(x86-32)) @@ -174,16 +192,37 @@ BuildRequires: python%{python3_pkgversion}-devel # Note that the package prefix is always python3-, even if we build for 3.X # The minimal version is for bundled provides verification script BuildRequires: python3-rpm-generators >= 11-8 -BuildRequires: pyproject-rpm-macros -BuildRequires: python%{python3_pkgversion}-flit-core +BuildRequires: python%{python3_pkgversion}-setuptools BuildRequires: bash-completion +%if %{with tests} +BuildRequires: python%{python3_pkgversion}-mock +BuildRequires: python%{python3_pkgversion}-pytest +BuildRequires: python%{python3_pkgversion}-pretend +BuildRequires: python%{python3_pkgversion}-freezegun +BuildRequires: python%{python3_pkgversion}-scripttest +BuildRequires: python%{python3_pkgversion}-virtualenv +BuildRequires: python%{python3_pkgversion}-werkzeug +BuildRequires: python%{python3_pkgversion}-pyyaml +%endif +BuildRequires: python%{python3_pkgversion}-wheel BuildRequires: ca-certificates Requires: ca-certificates +# This was previously required and we keep it recommended because a lot of +# sdists installed via pip will try to import setuptools. +# But pip doesn't actually require setuptools. +# It can install wheels without them and it can build wheels in isolation mode +# (using setuptools/flit/poetry/... installed from PyPI). +# Side note: pip bundles pkg_resources from setuptools for internal usage. +Recommends: python%{python3_pkgversion}-setuptools + # Virtual provides for the packages bundled by pip: -%{bundled %{python3_pkgversion}} +%{bundled 3} Provides: pip = %{version}-%{release} +Conflicts: python-pip < %{version}-%{release} + +%{crypt_compat_recommends 3} %description -n python%{python3_pkgversion}-%{srcname} pip is a package management system used to install and manage software packages @@ -191,173 +230,533 @@ written in Python. Many packages can be found in the Python Package Index (PyPI). pip is a recursive acronym that can stand for either "Pip Installs Packages" or "Pip Installs Python". +%if %{with doc} +%package doc +Summary: A documentation for a tool for installing and managing Python packages -%package -n %{python_wheel_pkg_prefix}-%{srcname}-wheel +BuildRequires: python%{python3_pkgversion}-sphinx + +%description doc +A documentation for a tool for installing and managing Python packages + +%endif + +%package wheel Summary: The pip wheel Requires: ca-certificates # Virtual provides for the packages bundled by pip: -%{bundled %{python3_pkgversion}} +%{bundled 2} +%{bundled 3} -# This is only relevant for Pythons that are older than 3.12 and don't use their own bundled wheels -# It is also only relevant when this wheel is shared across multiple Pythons -%if "%{python_wheel_pkg_prefix}" == "python" -%{crypt_compat_recommends 3.11} -%{crypt_compat_recommends 3.10} -%{crypt_compat_recommends 3.9} -%endif +%{crypt_compat_recommends 2} +%{crypt_compat_recommends 3} -%description -n %{python_wheel_pkg_prefix}-%{srcname}-wheel +%description wheel A Python wheel of pip to use with venv. %prep -%autosetup -p1 -n %{srcname}-%{upstream_version} +%setup -q -n %{srcname}-%{upstream_version} + +%if %{with doc} +pushd docs/html +tar -xf %{SOURCE1} +mv pypa-docs-theme-%{pypa_theme_commit_hash} pypa +tar -xf %{SOURCE2} +mv python-docs-theme-2018.2 python-docs-theme +popd +%endif + +%autopatch -p1 # this goes together with patch4 rm src/pip/_vendor/certifi/*.pem +# tests expect wheels in here +ln -s %{python_wheeldir} tests/data/common_wheels + +# Upstream uses a Python 2/3 compatibility library for csv with Python 3 semantics in tests +# We only target Python 3 and csv23 is not (yet) packaged +# As of 20.1b1, this workaround was sufficient to get around the missing dependency +sed -i -e 's/csv23/csv/g' tests/lib/wheel.py + # Remove windows executable binaries rm -v src/pip/_vendor/distlib/*.exe -sed -i '/\.exe/d' pyproject.toml - -# Remove unused test requirements -sed -Ei '/(pytest-(cov|xdist|rerunfailures|subket)|proxy\.py)/d' pyproject.toml - -# Remove unused pytest-subket options -sed -Ei '/(--disable-socket|--allow-unix-socket|--allow-hosts=localhost)/d' pyproject.toml - -%if %{with tests} -# tests expect wheels in here -mkdir tests/data/common_wheels -cp -a %{SOURCE1} %{SOURCE2} %{SOURCE3} %{SOURCE4} tests/data/common_wheels -%endif - - -%if %{with tests} -%generate_buildrequires -# we only use this to generate test requires -# the "pyproject" part is explicitly disabled as it generates a requirement on pip -%pyproject_buildrequires -N -g test -%endif - +sed -i '/\.exe/d' setup.py %build -export PYTHONPATH=./src/ -%pyproject_wheel +%py3_build_wheel -%if %{with man} -sphinx-build -t man -b man -d docs/build/doctrees/man -c docs/html docs/man docs/build/man +%if %{with doc} +export PYTHONPATH=./src/ +# from tox.ini +sphinx-build-3 -b html docs/html docs/build/html +sphinx-build-3 -b man docs/man docs/build/man -c docs/html +rm -rf docs/build/html/{.doctrees,.buildinfo} %endif %install -export PYTHONPATH=./src/ -%pyproject_install -%pyproject_save_files -l pip +# The following is similar to %%py3_install_wheel, but we don't have +# /usr/bin/pip yet, so we install using the wheel directly. +# (This is not standard wheel usage, but the pip wheel supports it -- see +# pip/__main__.py) +%{__python3} dist/%{python_wheelname}/pip install \ + --root %{buildroot} \ + --no-deps \ + --no-cache-dir \ + --no-index \ + --ignore-installed \ + --find-links dist \ + 'pip==%{upstream_version}' -# We'll install pip as pip3.X -# Later we'll provide symbolic links, manpage links and bashcompletion fixes for alternative names -%if "%{python3_pkgversion}" == "3" -%global alternate_names pip-%{python3_version} pip-3 pip3 pip -%else -%global alternate_names pip-%{python3_version} -%endif - -# Provide symlinks to executables -mv %{buildroot}%{_bindir}/pip %{buildroot}%{_bindir}/pip%{python3_version} -rm %{buildroot}%{_bindir}/pip3 -for pip in %{alternate_names}; do -ln -s ./pip%{python3_version} %{buildroot}%{_bindir}/$pip -done - -%if %{with man} +%if %{with doc} pushd docs/build/man install -d %{buildroot}%{_mandir}/man1 for MAN in *1; do -install -pm0644 $MAN %{buildroot}%{_mandir}/man1/${MAN/pip/pip%{python3_version}} -for pip in %{alternate_names}; do -echo ".so ${MAN/pip/pip%{python3_version}}" > %{buildroot}%{_mandir}/man1/${MAN/pip/$pip} +install -pm0644 $MAN %{buildroot}%{_mandir}/man1/$MAN +for pip in "pip3" "pip-3" "pip%{python3_version}" "pip-%{python3_version}"; do +echo ".so $MAN" > %{buildroot}%{_mandir}/man1/${MAN/pip/$pip} done done popd %endif -mkdir -p %{buildroot}%{bash_completions_dir} +# before we ln -s anything, we apply Source10 patch to all pips: +for PIP in %{buildroot}%{_bindir}/pip*; do + patch -p1 --no-backup-if-mismatch $PIP < %{SOURCE10} +done + +mkdir -p %{buildroot}%{bashcompdir} PYTHONPATH=%{buildroot}%{python3_sitelib} \ - %{buildroot}%{_bindir}/pip%{python3_version} completion --bash \ - > %{buildroot}%{bash_completions_dir}/pip%{python3_version} + %{buildroot}%{_bindir}/pip completion --bash \ + > %{buildroot}%{bashcompdir}/pip3 -# Make bash completion apply to all alternate names symlinks we install -sed -i -e "s/^\\(complete.*\\) pip%{python3_version}\$/\\1 pip%{python3_version} %{alternate_names}/" \ - -e s/_pip_completion/_pip%{python3_version_nodots}_completion/ \ - %{buildroot}%{bash_completions_dir}/pip%{python3_version} - -# Install the built wheel and inject SBOM into it (if the macro is available) -mkdir -p %{buildroot}%{python_wheel_dir} -install -p %{_pyproject_wheeldir}/%{python_wheel_name} -t %{buildroot}%{python_wheel_dir} -%{?python_wheel_inject_sbom:%python_wheel_inject_sbom %{buildroot}%{python_wheel_dir}/%{python_wheel_name}} +# Make bash completion apply to all the 5 symlinks we install +sed -i -e "s/^\\(complete.*\\) pip\$/\\1 pip pip{,-}{3,%{python3_version}}/" \ + -e s/_pip_completion/_pip3_completion/ \ + %{buildroot}%{bashcompdir}/pip3 +# Provide symlinks to executables to comply with Fedora guidelines for Python +ln -s ./pip%{python3_version} %{buildroot}%{_bindir}/pip-%{python3_version} +ln -s ./pip-%{python3_version} %{buildroot}%{_bindir}/pip-3 + + +# Make sure the INSTALLER is not pip, otherwise Patch2 won't work +# %%pyproject macros do this for all packages +echo rpm > %{buildroot}%{python3_sitelib}/pip-%{upstream_version}.dist-info/INSTALLER + +mkdir -p %{buildroot}%{python_wheeldir} +install -p dist/%{python_wheelname} -t %{buildroot}%{python_wheeldir} + + +%if %{with tests} %check # Verify bundled provides are up to date %{_rpmconfigdir}/pythonbundles.py src/pip/_vendor/vendor.txt --compare-with '%{bundled 3}' -# Verify no unwanted files are present in the package -grep "exe$" %{pyproject_files} && exit 1 || true -grep "pem$" %{pyproject_files} && exit 1 || true - -# Verify we can at least run basic commands without crashing -%{py3_test_envvars} %{buildroot}%{_bindir}/pip%{python3_version} --help -%{py3_test_envvars} %{buildroot}%{_bindir}/pip%{python3_version} list -%{py3_test_envvars} %{buildroot}%{_bindir}/pip%{python3_version} show pip - -%if %{with tests} # Upstream tests # bash completion tests only work from installed package -pytest_k='not completion' -# this clashes with our PYTHONPATH -pytest_k="$pytest_k and not environments_with_no_pip" -# this seems to require internet (despite no network marker) -# added in https://github.com/pypa/pip/pull/13378 TODO drop this in the next release -pytest_k="$pytest_k and not test_prompt_for_keyring_if_needed and not test_double_install_fail and not test_install_sdist_links and not test_lock_vcs and not test_lock_archive and not test_backend_sees_config_via_sdist" -# this cannot import breezy, TODO investigate -pytest_k="$pytest_k and not (functional and bazaar)" -# failures to investigate -pytest_k="$pytest_k and not test_all_fields and not test_report_mixed_not_found and not test_basic_show" # "Editable project location" missing -pytest_k="$pytest_k and not test_basic_install_from_wheel" -pytest_k="$pytest_k and not test_check_unsupported" +# needs unaltered sys.path and we cannot do that in %%check +# test_pep517_and_build_options +# test_config_file_venv_option +# TODO investigate failures +# test_uninstall_non_local_distutils +# Incompatible with the latest virtualenv +# test_from_link_vcs_with_source_dir_obtains_commit_id +# test_from_link_vcs_without_source_dir +# test_should_cache_git_sha +pytest_k='not completion and + not test_pep517_and_build_options and + not test_config_file_venv_option and + not test_uninstall_non_local_distutils and + not test_from_link_vcs_with_source_dir_obtains_commit_id and + not test_from_link_vcs_without_source_dir and + not test_should_cache_git_sha' -%pytest -n auto -m 'not network' -k "$(echo $pytest_k)" \ - --ignore tests/functional/test_proxy.py # no proxy.py in Fedora +# --deselect'ed tests are not compatible with the latest virtualenv +# These files contain almost 500 tests so we should enable them back +# as soon as pip will be compatible upstream +# https://github.com/pypa/pip/pull/8441 +%pytest -m 'not network' -k "$(echo $pytest_k)" \ + --deselect tests/functional --deselect tests/lib/test_lib.py --deselect tests/unit/test_build_env.py %endif -%files -n python%{python3_pkgversion}-%{srcname} -f %{pyproject_files} +%files -n python%{python3_pkgversion}-%{srcname} +%license LICENSE.txt %doc README.rst -%if %{with man} -%if "%{python3_pkgversion}" == "3" -%{_mandir}/man1/pip{,3,-3}.1.* -%{_mandir}/man1/pip{,3,-3}-[^3]*.1.* +%if %{with doc} +%{_mandir}/man1/pip.* +%{_mandir}/man1/pip-*.* +%{_mandir}/man1/pip3.* +%{_mandir}/man1/pip3-*.* %endif -%{_mandir}/man1/pip{,-}%{python3_version}.1.* -%{_mandir}/man1/pip{,-}%{python3_version}-*.1.* -%endif -%if "%{python3_pkgversion}" == "3" %{_bindir}/pip %{_bindir}/pip3 %{_bindir}/pip-3 -%endif %{_bindir}/pip%{python3_version} %{_bindir}/pip-%{python3_version} -%dir %{bash_completions_dir} -%{bash_completions_dir}/pip%{python3_version} +%{python3_sitelib}/pip* +%dir %{bashcompdir} +%{bashcompdir}/pip3 +%if %{with doc} +%files doc +%license LICENSE.txt +%doc README.rst +%doc docs/build/html +%endif -%files -n %{python_wheel_pkg_prefix}-%{srcname}-wheel +%files wheel %license LICENSE.txt # we own the dir for simplicity -%dir %{python_wheel_dir}/ -%{python_wheel_dir}/%{python_wheel_name} +%dir %{python_wheeldir}/ +%{python_wheeldir}/%{python_wheelname} %changelog -%autochangelog +* Wed Oct 06 2021 Charalampos Stratakis - 20.2.2-4 +- Remove bundled windows executables +- Resolves: rhbz#2005453 + +* Mon Aug 30 2021 Miro Hrončok - 20.2.2-3 +- Properly recognize Python 3.10 wheel tags +- Fixes: rhbz#1999035 + +* Mon May 17 2021 Karolina Surma - 20.2.2-2 +- Backport security fix from pip 21.1.1 + +* Wed Aug 05 2020 Tomas Orsava - 20.2.2-1 +- Update to 20.2.2 (#1838553) + +* Wed Jul 29 2020 Fedora Release Engineering - 20.1.1-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Fri Jul 10 2020 Lumír Balhar - 20.1.1-6 +- Do not emit a warning about root privileges when --root is used + +* Wed Jul 08 2020 Miro Hrončok - 20.1.1-5 +- Update bundled provides to match 20.1.1 + +* Tue Jun 16 2020 Lumír Balhar - 20.1.1-4 +- Deselect tests incompatible with the latest virtualenv + +* Sun May 24 2020 Miro Hrončok - 20.1.1-3 +- Rebuilt for Python 3.9 + +* Thu May 21 2020 Miro Hrončok - 20.1.1-2 +- Bootstrap for Python 3.9 + +* Wed May 20 2020 Tomas Hrnciar - 20.1.1-1 +- Update to 20.1.1 + +* Wed Apr 29 2020 Tomas Hrnciar - 20.1-1 +- Update to 20.1 + +* Mon Apr 27 2020 Tomas Hrnciar - 20.1~b1-1 +- Update to 20.1~b1 + +* Wed Apr 15 2020 Miro Hrončok - 20.0.2-4 +- Only recommend setuptools, don't require them + +* Fri Apr 10 2020 Miro Hrončok - 20.0.2-3 +- Allow setting $TMPDIR to $PWD/... during pip wheel (#1806625) + +* Tue Mar 10 2020 Miro Hrončok - 20.0.2-2 +- Don't warn the user about pip._internal.main() entrypoint to fix ensurepip + +* Mon Mar 02 2020 Miro Hrončok - 20.0.2-1 +- Update to 20.0.2 (#1793456) + +* Thu Jan 30 2020 Fedora Release Engineering - 19.3.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Mon Nov 04 2019 Tomas Orsava - 19.3.1-1 +- Update to 19.3.1 (#1761508) +- Drop upstreamed patch that fixed expected output in test to not break with alpha/beta/rc Python versions + +* Wed Oct 30 2019 Miro Hrončok - 19.2.3-2 +- Make /usr/bin/pip(3) work with user-installed pip 19.3+ (#1767212) + +* Mon Sep 02 2019 Miro Hrončok - 19.2.3-1 +- Update to 19.2.3 (#1742230) +- Drop patch that should strip path prefixes from RECORD files, the paths are relative + +* Wed Aug 21 2019 Petr Viktorin - 19.1.1-8 +- Remove python2-pip +- Make pip bootstrap itself, rather than with an extra bootstrap RPM build + +* Sat Aug 17 2019 Miro Hrončok - 19.1.1-7 +- Rebuilt for Python 3.8 + +* Wed Aug 14 2019 Miro Hrončok - 19.1.1-6 +- Bootstrap for Python 3.8 + +* Wed Aug 14 2019 Miro Hrončok - 19.1.1-5 +- Bootstrap for Python 3.8 + +* Fri Jul 26 2019 Fedora Release Engineering - 19.1.1-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Mon Jul 15 2019 Petr Viktorin - 19.1.1-3 +- Recommend libcrypt.so.1 for manylinux1 compatibility +- Make /usr/bin/pip Python 3 + +* Mon Jun 10 2019 Miro Hrončok - 19.1.1-2 +- Fix root warning when pip is invoked via python -m pip +- Remove a redundant second WARNING prefix form the abovementioned warning + +* Wed May 15 2019 Miro Hrončok - 19.1.1-1 +- Update to 19.1.1 (#1706995) + +* Thu Apr 25 2019 Miro Hrončok - 19.1-1 +- Update to 19.1 (#1702525) + +* Wed Mar 06 2019 Miro Hrončok - 19.0.3-1 +- Update to 19.0.3 (#1679277) + +* Wed Feb 13 2019 Miro Hrončok - 19.0.2-1 +- Update to 19.0.2 (#1668492) + +* Sat Feb 02 2019 Fedora Release Engineering - 18.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Mon Dec 03 2018 Miro Hrončok - 18.1-2 +- Use the system level root certificate instead of the one bundled in certifi + +* Thu Nov 22 2018 Miro Hrončok - 18.1-1 +- Update to 18.1 (#1652089) + +* Tue Sep 18 2018 Victor Stinner - 18.0-4 +- Prevent removing of the system packages installed under /usr/lib + when pip install -U is executed. Original patch by Michal Cyprian. + Resolves: rhbz#1550368. + +* Wed Aug 08 2018 Miro Hrončok - 18.0-3 +- Create python-pip-wheel package with the wheel + +* Tue Jul 31 2018 Miro Hrončok - 18.0-2 +- Remove redundant "Unicode"" from License + +* Mon Jul 23 2018 Marcel Plch - 18.0-7 +- Update to 18.0 + +* Sat Jul 14 2018 Fedora Release Engineering - 9.0.3-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Mon Jun 18 2018 Miro Hrončok - 9.0.3-5 +- Rebuilt for Python 3.7 + +* Wed Jun 13 2018 Miro Hrončok - 9.0.3-4 +- Bootstrap for Python 3.7 + +* Wed Jun 13 2018 Miro Hrončok - 9.0.3-3 +- Bootstrap for Python 3.7 + +* Fri May 04 2018 Miro Hrončok - 9.0.3-2 +- Allow to import pip10's main from pip9's /usr/bin/pip +- Do not show the "new version of pip" warning outside of venv +Resolves: rhbz#1569488 +Resolves: rhbz#1571650 +Resolves: rhbz#1573755 + +* Thu Mar 29 2018 Charalampos Stratakis - 9.0.3-1 +- Update to 9.0.3 + +* Wed Feb 21 2018 Lumír Balhar - 9.0.1-16 +- Include built HTML documentation (in the new -doc subpackage) and man page + +* Fri Feb 09 2018 Fedora Release Engineering - 9.0.1-15 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Mon Dec 04 2017 Charalampos Stratakis - 9.0.1-14 +- Reintroduce the ipaddress module in the python3 subpackage. + +* Mon Nov 20 2017 Charalampos Stratakis - 9.0.1-13 +- Add virtual provides for the bundled libraries. (rhbz#1096912) + +* Tue Aug 29 2017 Tomas Orsava - 9.0.1-12 +- Switch macros to bcond's and make Python 2 optional to facilitate building + the Python 2 and Python 3 modules + +* Thu Jul 27 2017 Fedora Release Engineering - 9.0.1-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Tue May 23 2017 Tomas Orsava - 9.0.1-10 +- Modernized package descriptions +Resolves: rhbz#1452568 + +* Tue Mar 21 2017 Tomas Orsava - 9.0.1-9 +- Fix typo in the sudo pip warning + +* Fri Mar 03 2017 Tomas Orsava - 9.0.1-8 +- Patch 1 update: No sudo pip warning in venv or virtualenv + +* Thu Feb 23 2017 Tomas Orsava - 9.0.1-7 +- Patch 1 update: Customize the warning with the proper version of the pip + command + +* Tue Feb 14 2017 Tomas Orsava - 9.0.1-6 +- Added patch 1: Emit a warning when running with root privileges + +* Sat Feb 11 2017 Fedora Release Engineering - 9.0.1-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Mon Jan 02 2017 Tomas Orsava - 9.0.1-4 +- Provide symlinks to executables to comply with Fedora guidelines for Python +Resolves: rhbz#1406922 + +* Fri Dec 09 2016 Charalampos Stratakis - 9.0.1-3 +- Rebuild for Python 3.6 with wheel + +* Fri Dec 09 2016 Charalampos Stratakis - 9.0.1-2 +- Rebuild for Python 3.6 without wheel + +* Fri Nov 18 2016 Orion Poplawski - 9.0.1-1 +- Update to 9.0.1 + +* Fri Nov 18 2016 Orion Poplawski - 8.1.2-5 +- Enable EPEL Python 3 builds +- Use new python macros +- Cleanup spec + +* Fri Aug 05 2016 Tomas Orsava - 8.1.2-4 +- Updated the test sources + +* Fri Aug 05 2016 Tomas Orsava - 8.1.2-3 +- Moved python-pip into the python2-pip subpackage +- Added the python_provide macro + +* Tue Jul 19 2016 Fedora Release Engineering - 8.1.2-2 +- https://fedoraproject.org/wiki/Changes/Automatic_Provides_for_Python_RPM_Packages + +* Tue May 17 2016 Tomas Orsava - 8.1.2-1 +- Update to 8.1.2 +- Moved to a new PyPI URL format +- Updated the prefix-stripping patch because of upstream changes in pip/wheel.py + +* Mon Feb 22 2016 Slavek Kabrda - 8.0.2-1 +- Update to 8.0.2 + +* Thu Feb 04 2016 Fedora Release Engineering - 7.1.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Wed Oct 14 2015 Robert Kuska - 7.1.0-3 +- Rebuilt for Python3.5 rebuild +- With wheel set to 1 + +* Tue Oct 13 2015 Robert Kuska - 7.1.0-2 +- Rebuilt for Python3.5 rebuild + +* Wed Jul 01 2015 Slavek Kabrda - 7.1.0-1 +- Update to 7.1.0 + +* Tue Jun 30 2015 Ville Skyttä - 7.0.3-3 +- Install bash completion +- Ship LICENSE.txt as %%license where available + +* Thu Jun 18 2015 Fedora Release Engineering - 7.0.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Thu Jun 04 2015 Matej Stuchlik - 7.0.3-1 +- Update to 7.0.3 + +* Fri Mar 06 2015 Matej Stuchlik - 6.0.8-1 +- Update to 6.0.8 + +* Thu Dec 18 2014 Slavek Kabrda - 1.5.6-5 +- Only enable tests on Fedora. + +* Mon Dec 01 2014 Matej Stuchlik - 1.5.6-4 +- Add tests +- Add patch skipping tests requiring Internet access + +* Tue Nov 18 2014 Matej Stuchlik - 1.5.6-3 +- Added patch for local dos with predictable temp dictionary names + (http://seclists.org/oss-sec/2014/q4/655) + +* Sat Jun 07 2014 Fedora Release Engineering - 1.5.6-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Sun May 25 2014 Matej Stuchlik - 1.5.6-1 +- Update to 1.5.6 + +* Fri Apr 25 2014 Matej Stuchlik - 1.5.4-4 +- Rebuild as wheel for Python 3.4 + +* Thu Apr 24 2014 Matej Stuchlik - 1.5.4-3 +- Disable build_wheel + +* Thu Apr 24 2014 Matej Stuchlik - 1.5.4-2 +- Rebuild as wheel for Python 3.4 + +* Mon Apr 07 2014 Matej Stuchlik - 1.5.4-1 +- Updated to 1.5.4 + +* Mon Oct 14 2013 Tim Flink - 1.4.1-1 +- Removed patch for CVE 2013-2099 as it has been included in the upstream 1.4.1 release +- Updated version to 1.4.1 + +* Sun Aug 04 2013 Fedora Release Engineering - 1.3.1-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Tue Jul 16 2013 Toshio Kuratomi - 1.3.1-4 +- Fix for CVE 2013-2099 + +* Thu May 23 2013 Tim Flink - 1.3.1-3 +- undo python2 executable rename to python-pip. fixes #958377 +- fix summary to match upstream + +* Mon May 06 2013 Kevin Kofler - 1.3.1-2 +- Fix main package Summary, it's for Python 2, not 3 (#877401) + +* Fri Apr 26 2013 Jon Ciesla - 1.3.1-1 +- Update to 1.3.1, fix for CVE-2013-1888. + +* Thu Feb 14 2013 Fedora Release Engineering - 1.2.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Tue Oct 09 2012 Tim Flink - 1.2.1-2 +- Fixing files for python3-pip + +* Thu Oct 04 2012 Tim Flink - 1.2.1-1 +- Update to upstream 1.2.1 +- Change binary from pip-python to python-pip (RHBZ#855495) +- Add alias from python-pip to pip-python, to be removed at a later date + +* Tue May 15 2012 Tim Flink - 1.1.0-1 +- Update to upstream 1.1.0 + +* Sat Jan 14 2012 Fedora Release Engineering - 1.0.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Sat Oct 22 2011 Tim Flink - 1.0.2-1 +- update to 1.0.2 and added python3 subpackage + +* Wed Jun 22 2011 Tim Flink - 0.8.3-1 +- update to 0.8.3 and project home page + +* Tue Feb 08 2011 Fedora Release Engineering - 0.8.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Mon Dec 20 2010 Luke Macken - 0.8.2-1 +- update to 0.8.2 of pip +* Mon Aug 30 2010 Peter Halliday - 0.8-1 +- update to 0.8 of pip +* Thu Jul 22 2010 David Malcolm - 0.7.2-5 +- Rebuilt for https://fedoraproject.org/wiki/Features/Python_2.7/MassRebuild + +* Wed Jul 7 2010 Peter Halliday - 0.7.2-1 +- update to 0.7.2 of pip +* Sun May 23 2010 Peter Halliday - 0.7.1-1 +- update to 0.7.1 of pip +* Fri Jan 1 2010 Peter Halliday - 0.6.1.4 +- fix dependency issue +* Fri Dec 18 2009 Peter Halliday - 0.6.1-2 +- fix spec file +* Thu Dec 17 2009 Peter Halliday - 0.6.1-1 +- upgrade to 0.6.1 of pip +* Mon Aug 31 2009 Peter Halliday - 0.4-1 +- Initial package + diff --git a/python3.10-abi-tag-fix.patch b/python3.10-abi-tag-fix.patch new file mode 100644 index 0000000..a1399af --- /dev/null +++ b/python3.10-abi-tag-fix.patch @@ -0,0 +1,33 @@ +From a6253448766965e34f1d0dd58cdf317790d25dd7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= +Date: Tue, 24 Nov 2020 12:06:14 +0100 +Subject: [PATCH] Don't put an underscore in the version portion of Python 3.10 + compatibility tags + +PEP 641 is rejected. + +See https://discuss.python.org/t/5513/42 +See https://www.python.org/dev/peps/pep-0641/ + +Fixes https://github.com/pypa/packaging/issues/372 + +Co-authored-by: Pradyun Gedam +--- + +diff --git a/src/pip/_vendor/packaging/tags.py b/src/pip/_vendor/packaging/tags.py +index 9064910..5d901e9 100644 +--- a/src/pip/_vendor/packaging/tags.py ++++ b/src/pip/_vendor/packaging/tags.py +@@ -722,11 +722,7 @@ def interpreter_version(**kwargs): + + def _version_nodot(version): + # type: (PythonVersion) -> str +- if any(v >= 10 for v in version): +- sep = "_" +- else: +- sep = "" +- return sep.join(map(str, version)) ++ return "".join(map(str, version)) + + + def sys_tags(**kwargs): diff --git a/remove-existing-dist-only-if-path-conflicts.patch b/remove-existing-dist-only-if-path-conflicts.patch index d280f34..ba3feb6 100644 --- a/remove-existing-dist-only-if-path-conflicts.patch +++ b/remove-existing-dist-only-if-path-conflicts.patch @@ -1,115 +1,94 @@ -From d5cb806a14bb50a96484bca6536e81f2ac316b9d Mon Sep 17 00:00:00 2001 -From: Karolina Surma -Date: Wed, 16 Feb 2022 08:36:21 +0100 +From 854fd7296bb9306d46ba3cc8bb7c6f18a7960ed6 Mon Sep 17 00:00:00 2001 +From: Tomas Hrnciar +Date: Sun, 26 Apr 2020 21:19:03 +0200 Subject: [PATCH] Prevent removing of the system packages installed under - /usr/lib when pip install --upgrade is executed. -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit + /usr/lib + +when pip install -U is executed. Resolves: rhbz#1550368 Co-Authored-By: Michal Cyprian Co-Authored-By: Victor Stinner -Co-Authored-By: Petr Viktorin -Co-Authored-By: Lumir Balhar -Co-Authored-By: Miro Hrončok -Co-Authored-By: Karolina Surma --- - src/pip/_internal/metadata/base.py | 12 +++++++++++- - src/pip/_internal/req/req_install.py | 2 +- - src/pip/_internal/resolution/legacy/resolver.py | 4 +++- - src/pip/_internal/resolution/resolvelib/factory.py | 12 ++++++++++++ - 4 files changed, 27 insertions(+), 3 deletions(-) + src/pip/_internal/req/req_install.py | 3 ++- + src/pip/_internal/resolution/legacy/resolver.py | 5 ++++- + src/pip/_internal/utils/misc.py | 11 +++++++++++ + 3 files changed, 17 insertions(+), 2 deletions(-) -diff --git a/src/pip/_internal/metadata/base.py b/src/pip/_internal/metadata/base.py -index 230e114..8bd5d31 100644 ---- a/src/pip/_internal/metadata/base.py -+++ b/src/pip/_internal/metadata/base.py -@@ -23,7 +23,7 @@ from pip._vendor.packaging.utils import NormalizedName, canonicalize_name - from pip._vendor.packaging.version import Version - - from pip._internal.exceptions import NoneMetadataError --from pip._internal.locations import site_packages, user_site -+from pip._internal.locations import get_scheme, site_packages, user_site - from pip._internal.models.direct_url import ( - DIRECT_URL_METADATA_NAME, - DirectUrl, -@@ -575,6 +575,16 @@ class BaseDistribution(Protocol): - for extra in self._iter_egg_info_extras(): - metadata["Provides-Extra"] = extra - -+ @property -+ def in_install_path(self) -> bool: -+ """ -+ Return True if given Distribution is installed in -+ path matching distutils_scheme layout. -+ """ -+ norm_path = normalize_path(self.installed_location) -+ return norm_path.startswith(normalize_path( -+ get_scheme("").purelib.split('python')[0])) -+ - - class BaseEnvironment: - """An environment containing distributions to introspect.""" diff --git a/src/pip/_internal/req/req_install.py b/src/pip/_internal/req/req_install.py -index c9f6bff..c101826 100644 +index 4759f4a..2e76e35 100644 --- a/src/pip/_internal/req/req_install.py +++ b/src/pip/_internal/req/req_install.py -@@ -453,7 +453,7 @@ class InstallRequirement: - f"lack sys.path precedence to {existing_dist.raw_name} " - f"in {existing_dist.location}" +@@ -39,6 +39,7 @@ from pip._internal.utils.misc import ( + ask_path_exists, + backup_dir, + display_path, ++ dist_in_install_path, + dist_in_site_packages, + dist_in_usersite, + get_distribution, +@@ -446,7 +447,7 @@ class InstallRequirement(object): + "lack sys.path precedence to {} in {}".format( + existing_dist.project_name, existing_dist.location) ) - else: -+ elif existing_dist.in_install_path: ++ elif dist_in_install_path(existing_dist): self.should_reinstall = True else: if self.editable: diff --git a/src/pip/_internal/resolution/legacy/resolver.py b/src/pip/_internal/resolution/legacy/resolver.py -index 33a4fdc..1fe886e 100644 +index c9b4c66..ff361d8 100644 --- a/src/pip/_internal/resolution/legacy/resolver.py +++ b/src/pip/_internal/resolution/legacy/resolver.py -@@ -322,7 +322,9 @@ class Resolver(BaseResolver): +@@ -34,6 +34,7 @@ from pip._internal.resolution.base import BaseResolver + from pip._internal.utils.compatibility_tags import get_supported + from pip._internal.utils.logging import indent_log + from pip._internal.utils.misc import dist_in_usersite, normalize_version_info ++from pip._internal.utils.misc import dist_in_install_path + from pip._internal.utils.packaging import ( + check_requires_python, + get_requires_python, +@@ -207,7 +208,9 @@ class Resolver(BaseResolver): + """ # Don't uninstall the conflict if doing a user install and the # conflict is not a user install. - assert req.satisfied_by is not None -- if not self.use_user_site or req.satisfied_by.in_usersite: +- if not self.use_user_site or dist_in_usersite(req.satisfied_by): + if ((not self.use_user_site -+ or req.satisfied_by.in_usersite) -+ and req.satisfied_by.in_install_path): ++ or dist_in_usersite(req.satisfied_by)) ++ and dist_in_install_path(req.satisfied_by)): req.should_reinstall = True req.satisfied_by = None -diff --git a/src/pip/_internal/resolution/resolvelib/factory.py b/src/pip/_internal/resolution/resolvelib/factory.py -index f23e4cd..1bada79 100644 ---- a/src/pip/_internal/resolution/resolvelib/factory.py -+++ b/src/pip/_internal/resolution/resolvelib/factory.py -@@ -3,6 +3,8 @@ from __future__ import annotations - import contextlib - import functools - import logging -+import sys -+import sysconfig - from collections.abc import Iterable, Iterator, Mapping, Sequence - from typing import ( - TYPE_CHECKING, -@@ -615,6 +617,16 @@ class Factory: - if dist is None: # Not installed, no uninstallation required. - return None +diff --git a/src/pip/_internal/utils/misc.py b/src/pip/_internal/utils/misc.py +index 24a7455..5fd48d3 100644 +--- a/src/pip/_internal/utils/misc.py ++++ b/src/pip/_internal/utils/misc.py +@@ -31,6 +31,7 @@ from pip._vendor.six.moves.urllib.parse import unquote as urllib_unquote + from pip import __version__ + from pip._internal.exceptions import CommandError + from pip._internal.locations import ( ++ distutils_scheme, + get_major_minor_version, + site_packages, + user_site, +@@ -403,6 +404,16 @@ def dist_in_site_packages(dist): + return dist_location(dist).startswith(normalize_path(site_packages)) -+ # Prevent uninstalling packages from /usr -+ try: -+ if dist.installed_location in ( -+ sysconfig.get_path('purelib', scheme='posix_prefix', vars={'base': sys.base_prefix}), -+ sysconfig.get_path('platlib', scheme='posix_prefix', vars={'platbase': sys.base_prefix}), -+ ): -+ return None -+ except KeyError: # this Python doesn't have 'rpm_prefix' scheme yet -+ pass + ++def dist_in_install_path(dist): ++ """ ++ Return True if given Distribution is installed in ++ path matching distutils_scheme layout. ++ """ ++ norm_path = normalize_path(dist_location(dist)) ++ return norm_path.startswith(normalize_path( ++ distutils_scheme("")['purelib'].split('python')[0])) + - # We're installing into global site. The current installation must - # be uninstalled, no matter it's in global or user site, because the - # user site installation has precedence over global. ++ + def dist_is_editable(dist): + # type: (Distribution) -> bool + """ -- -2.50.1 +2.25.4 diff --git a/sources b/sources index 48867fb..2256936 100644 --- a/sources +++ b/sources @@ -1,5 +1,3 @@ -SHA512 (pip-25.3.tar.gz) = f50db092213ec3bb819d3da5669f73d119b5ec7f7ac5e8a587a17c27eafa32bc17a057df09389c526a3769ef3577f5553187d54ceffa89aed63f4b4498ff044e -SHA512 (setuptools-79.0.1-py3-none-any.whl) = fef6cfc6f95a5bb7320f1680e1c665cb8d9a4e4227cde4d8aab8a50bed4bcf04320085b9d7d5343359f887008db5c5a861e57f3d08b7b0b2311a28adaeee6b4a -SHA512 (wheel-0.45.1-py3-none-any.whl) = 86c16248ec804ee0ac95d43b03d47351dceb534d0cdc4025ca1eb073e39e539de44c870b9261f0373144e1537f0e42675a759a318a8d5d346bbd9efcb704061d -SHA512 (flit_core-3.12.0-py3-none-any.whl) = 790c12b1f43201e365fb3f8f2f0a54e1a578876799dfdf8bfeea679a25ea096bf62946d006618c1458ae6e37ce6d00998f37e9aba426d5ab80d32ef2d75da4e0 -SHA512 (coverage-0-py3-none-any.whl) = e734192565347010efe68f8ba600254259c9b647f3c553fd4e5d87b1d7f955cb15d6f7d807716f4a6415d239beed945fbec7210feaf502e9cc849c332845926e +SHA512 (2018.2.tar.gz) = 4c09c43a70ecb3ca3bc9445b01bf209eb382e41d9c969145696dea38551992ed88fd9b725a1264380f3dbdf8acdaf5ada3ef86b44255cdfbdbe4a01a1630912d +SHA512 (d2e63fbfc62af3b7050f619b2f5bb8658985b931.tar.gz) = fc7b11c5cbf6322469ce2eaca2a8d7eb60b17398d316f7465ab5d3d38dabd00ee22a3da7437a28f6312f0115f77f2df0d8bf0abc671e055eef06356c94283409 +SHA512 (pip-20.2.2.tar.gz) = 0b000977f169900eebd4afeabfc7bd59b104246bbb048ce5b4db7f701e20ef1caef22c7ca2311843eafc4a37abbb81a74beddddf655eeaf2e33e3949d5a811e6 diff --git a/tests/bash_completion/main.fmf b/tests/bash_completion/main.fmf deleted file mode 100644 index cde6f68..0000000 --- a/tests/bash_completion/main.fmf +++ /dev/null @@ -1,35 +0,0 @@ -summary: PIP bash completion functionality smoke test -description: | - Comprehensive test for pip bash completion functionality on Fedora/RHEL systems. - - The test performs the following steps: - 1. Finds the bash completion script in the given (e.g. python3-pip) RPM package - 2. Discovers all pip executables in the package (e.g. /usr/bin/pip and /usr/bin/pip3.14) - 3. Sources the completion script and verifies completion for all executables is registered - 4. Runs functional TAB completion tests using expect (for regular and POSIX mode of Bash) - 5. Validates that completion works for basic pip commands - - This is a smoke test to ensure pip bash completion is properly - installed and functional after package installation. - -component: - - python3-pip - -test: ./pip_completion_full_test.sh - -framework: shell - -duration: 5m -tier: 1 - - -require: - - python3-pip - - bash-completion - - expect - - rpm - - bash - - -environment: - PACKAGE: python3-pip diff --git a/tests/bash_completion/pip_completion_full_test.sh b/tests/bash_completion/pip_completion_full_test.sh deleted file mode 100755 index 94fcdb9..0000000 --- a/tests/bash_completion/pip_completion_full_test.sh +++ /dev/null @@ -1,88 +0,0 @@ -#!/bin/bash - -# Comprehensive PIP bash completion test for RHEL -# Finds completion scripts from RPM, tests all pip binaries, and runs functional tests - -PACKAGE="${PACKAGE:-python3-pip}" - - -# Step 1: Find bash completion scripts in python3-pip RPM package -echo "Step 1: Finding bash completion scripts in $PACKAGE RPM package..." - -COMPLETION_FILE=$(rpm -ql $PACKAGE 2>/dev/null | grep -E "/usr/share/bash-completion/completions/" || true) - -if [[ -z "$COMPLETION_FILE" ]]; then - echo "✗ No bash completion files found in $PACKAGE package" - exit 1 -fi - -# Check if there's exactly one completion file -COMPLETION_FILE_COUNT=$(echo "$COMPLETION_FILE" | wc -l) - -if [[ $COMPLETION_FILE_COUNT -gt 1 ]]; then - echo "✗ Multiple bash completion files found in $PACKAGE package:" - echo "$COMPLETION_FILE" | sed 's/^/ - /' - echo "Expected exactly one completion file, found $COMPLETION_FILE_COUNT" - exit 1 -fi - - -echo "✓ Found completion file from $PACKAGE package:" -echo "$COMPLETION_FILE" | sed 's/^/ - /' - -# Step 2: Find all pip binaries -echo -echo "Step 2: Finding all pip binaries..." -PIP_BINARIES=() -PIP_FILES=$(rpm -ql $PACKAGE | grep /bin/p) -for pip_file in $PIP_FILES; do - if [[ -x "$pip_file" ]]; then - pip_cmd=$(basename "$pip_file") - PIP_BINARIES+=("$pip_cmd") - echo "✓ Found: $pip_cmd -> $pip_file" - fi -done - -if [[ ${#PIP_BINARIES[@]} -eq 0 ]]; then - echo "✗ No pip binaries found" - exit 1 -fi - -echo "Total pip binaries found: ${#PIP_BINARIES[@]}" - -# Step 3: Source completion scripts and test each binary -echo -echo "Step 3: Testing completion for each pip binary..." - -for AS_POSIX in 0 1; do - if [[ $AS_POSIX -eq 1 ]]; then - echo "Testing in POSIX mode" - POSIX="--posix" - else - echo "Testing in non-POSIX mode" - POSIX="" - fi - - echo "Sourcing: $COMPLETION_FILE" - if bash --norc $POSIX -c "source $COMPLETION_FILE" ; then - echo "✓ Successfully sourced $COMPLETION_FILE" - else - echo "! Warning: Failed to source $COMPLETION_FILE" - exit 1 - fi - - export AS_POSIX - for pip_exec in "${PIP_BINARIES[@]}"; do - echo "Running expect test with $COMPLETION_FILE and $pip_exec..." - if ./test_pip_completion.exp "$COMPLETION_FILE" "$pip_exec"; then - echo "✓ Functional test passed" - else - echo "✗ Functional test failed" - exit 1 - fi - done - -done - - -echo "✓ All tests completed successfully!" diff --git a/tests/bash_completion/test_pip_completion.exp b/tests/bash_completion/test_pip_completion.exp deleted file mode 100755 index 4389174..0000000 --- a/tests/bash_completion/test_pip_completion.exp +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/expect -f - -# PIP bash completion smoke test using expect -# Tests actual TAB completion functionality -# Usage: test_pip_completion.exp [completion_file] [pip_binary] - -set timeout 5 - - -set completion_file [lindex $argv 0] -set pip_exec [lindex $argv 1] - - -puts "=== PIP Bash Completion Test (using expect) ===" -puts "Testing completion file: $completion_file" -puts "Testing pip binary: $pip_exec" - -# Check if completion file exists first -if {![file exists $completion_file]} { - puts "✗ Completion file not found: $completion_file" - exit 1 -} -puts "✓ Completion file found: $completion_file" - -# Start bash shell -if {[info exists env(AS_POSIX)] && $env(AS_POSIX) == "1"} { - spawn bash --norc --posix -} else { - spawn bash --norc -} -expect "$ " - -# Source the completion file -send "source $completion_file\r" -expect "$ " -puts "Attempted to source completion file" - -# Test 1: Basic pip command completion -puts "\nTest 1: Testing '$pip_exec ' + TAB completion..." -send "$pip_exec " -sleep 0.1 -# Send TAB TAB using hex codes -send "\x09\x09" -expect { - -re "(install|uninstall|list|show)" { - puts "✓ Basic pip commands found in completion" - expect "$ " - } - -re "Display all" { - puts "✓ Completion showing options menu" - send "n\r" - expect "$ " - } - timeout { - puts "✗ Timeout waiting for completion - test failed" - exit 1 - } -} - -# Clear the line and ensure clean prompt -send "\x03" -expect "$ " -send "\r" -expect "$ " - -# Test 2: Test partial command completion (simpler test) -puts "\nTest 2: Testing '$pip_exec insta' + TAB completion..." -send "$pip_exec insta" -sleep 0.1 -# Single TAB for completion -send "\x09" -expect { - -re "install" { - puts "✓ Partial command completion works (insta -> install)" - expect "$ " - } - timeout { - puts "✗ Timeout on partial completion test - test failed" - exit 1 - } -} - -# Clear the line and ensure clean prompt -send "\x03" -expect "$ " -send "\r" -expect "$ " - -# Test 3: Test help completion -puts "\nTest 3: Testing '$pip_exec --' + TAB completion..." -send "$pip_exec --" -sleep 0.1 -send "\x09\x09" -expect { - -re "(--help|--version)" { - puts "✓ Command options found in completion" - expect "$ " - } - timeout { - puts "✗ Timeout on options completion test - test failed" - exit 1 - } -} - -# Final cleanup - make sure we're at clean prompt -send "\x03" -expect "$ " -send "\r" -expect "$ " - -# Exit bash cleanly -send "exit\r" -expect eof - -puts "\n=== Completion Test Complete ===" -puts "PIP bash completion functionality tested!" - diff --git a/tests/pip_install_upgrade/runtest.sh b/tests/pip_install_upgrade/runtest.sh deleted file mode 100755 index 4c520f5..0000000 --- a/tests/pip_install_upgrade/runtest.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/sh -eux -# This script requires root privileges and you should never run it on your own machine -test $EUID -eq 0 - -PYTHON_VERSION=$(/usr/bin/python3 -c 'import sys; print("{}.{}".format(*sys.version_info))') -RPM_SITELIB="/usr/lib/python${PYTHON_VERSION}/site-packages" -LOCAL_SITELIB="/usr/local/lib/python${PYTHON_VERSION}/site-packages" -USER_SITELIB="/home/fedora-test-user/.local/lib/python${PYTHON_VERSION}/site-packages" - -# First, let's install older Pello with pip as if it was installed by RPM -# This is an approximation, but it usually works -RPM_BUILD_ROOT=/ /usr/bin/pip install 'Pello==1.0.1' - -# Now, we'll upgrade it with regular pip -/usr/bin/pip install --upgrade 'Pello==1.0.2' - -# pip should see it -/usr/bin/pip freeze | grep '^Pello==1\.0\.2$' - -# Both installations should still exist -test -d "${RPM_SITELIB}/pello-1.0.1.dist-info" -test -d "${LOCAL_SITELIB}/Pello-1.0.2.dist-info" - -# Let's ditch the local one -/usr/bin/pip uninstall --yes Pello - -# It should only remove one of them -test -d "${RPM_SITELIB}/pello-1.0.1.dist-info" -! test -d "${LOCAL_SITELIB}/Pello-1.0.2.dist-info" - -# And pip should still see the RPM-installed one -/usr/bin/pip freeze | grep '^Pello==1\.0\.1$' - -# Again, but as regular user -useradd fedora-test-user -su fedora-test-user -c '/usr/bin/pip install "Pello==1.0.2"' -test -d "${USER_SITELIB}/Pello-1.0.2.dist-info" -su fedora-test-user -c '/usr/bin/pip freeze' | grep '^Pello==1\.0\.2$' -su fedora-test-user -c '/usr/bin/pip uninstall --yes Pello' -su fedora-test-user -c '/usr/bin/pip freeze' | grep '^Pello==1\.0\.1$' diff --git a/tests/tests.yml b/tests/tests.yml new file mode 100644 index 0000000..dbf1697 --- /dev/null +++ b/tests/tests.yml @@ -0,0 +1,81 @@ +--- +- hosts: localhost + roles: + - role: standard-test-basic + tags: + - classic + repositories: + - repo: "https://src.fedoraproject.org/tests/python.git" + dest: "python" + - repo: "https://src.fedoraproject.org/rpms/pyproject-rpm-macros.git" + dest: "pyproject-rpm-macros" + tests: + - smoke34_optional: + dir: python/smoke + run: VERSION=3.4 INSTALL_OR_SKIP=true ./venv.sh + - smoke35: + dir: python/smoke + run: VERSION=3.5 ./venv.sh + - smoke36: + dir: python/smoke + run: VERSION=3.6 ./venv.sh + - smoke37: + dir: python/smoke + run: VERSION=3.7 ./venv.sh + - smoke38: + dir: python/smoke + run: VERSION=3.8 ./venv.sh + - smoke39: + dir: python/smoke + run: VERSION=3.9 ./venv.sh + - smoke27: + dir: python/smoke + run: VERSION=2.7 METHOD=virtualenv ./venv.sh + - smoke34_virtualenv_optional: + dir: python/smoke + run: VERSION=3.4 METHOD=virtualenv INSTALL_OR_SKIP=true ./venv.sh + - smoke35_virtualenv: + dir: python/smoke + run: VERSION=3.5 METHOD=virtualenv ./venv.sh + - smoke36_virtualenv: + dir: python/smoke + run: VERSION=3.6 METHOD=virtualenv ./venv.sh + - smoke37_virtualenv: + dir: python/smoke + run: VERSION=3.7 METHOD=virtualenv ./venv.sh + - smoke38_virtualenv: + dir: python/smoke + run: VERSION=3.8 METHOD=virtualenv ./venv.sh + - smoke39_virtualenv: + dir: python/smoke + run: VERSION=3.9 METHOD=virtualenv ./venv.sh + - pipenv: + run: pipenv --three && pipenv install six + - pyproject_pytest: + dir: pyproject-rpm-macros/tests + run: ./mocktest.sh python-pytest + - pyproject_entrypoints: + dir: pyproject-rpm-macros/tests + run: ./mocktest.sh python-entrypoints + - pyproject_pluggy: + dir: pyproject-rpm-macros/tests + run: ./mocktest.sh python-pluggy + - pyproject_clikit: + dir: pyproject-rpm-macros/tests + run: ./mocktest.sh python-clikit + required_packages: + - gcc + - virtualenv + - python27 + - python35 + - python36 + - python37 + - python38 + - python39 + - python2-devel + - python3-devel + - python3-tox + - pipenv + - mock + - rpmdevtools + - rpm-build diff --git a/urllib3-CVE-2025-50181.patch b/urllib3-CVE-2025-50181.patch deleted file mode 100644 index 05e6353..0000000 --- a/urllib3-CVE-2025-50181.patch +++ /dev/null @@ -1,51 +0,0 @@ -From b3d543d7e16af844394316360ef1bf0b9d10f1b1 Mon Sep 17 00:00:00 2001 -From: Illia Volochii -Date: Wed, 18 Jun 2025 16:25:01 +0300 -Subject: [PATCH] Security fix for CVE-2025-50181 - -Co-authored-by: Seth Michael Larson -Co-authored-by: Quentin Pradet -Co-authored-by: Seth Michael Larson ---- - src/pip/_vendor/urllib3/poolmanager.py | 18 +++++++++++++++++- - 1 file changed, 17 insertions(+), 1 deletion(-) - -diff --git a/src/pip/_vendor/urllib3/poolmanager.py b/src/pip/_vendor/urllib3/poolmanager.py -index fb51bf7..a8de7c6 100644 ---- a/src/pip/_vendor/urllib3/poolmanager.py -+++ b/src/pip/_vendor/urllib3/poolmanager.py -@@ -170,6 +170,22 @@ class PoolManager(RequestMethods): - - def __init__(self, num_pools=10, headers=None, **connection_pool_kw): - RequestMethods.__init__(self, headers) -+ if "retries" in connection_pool_kw: -+ retries = connection_pool_kw["retries"] -+ if not isinstance(retries, Retry): -+ # When Retry is initialized, raise_on_redirect is based -+ # on a redirect boolean value. -+ # But requests made via a pool manager always set -+ # redirect to False, and raise_on_redirect always ends -+ # up being False consequently. -+ # Here we fix the issue by setting raise_on_redirect to -+ # a value needed by the pool manager without considering -+ # the redirect boolean. -+ raise_on_redirect = retries is not False -+ retries = Retry.from_int(retries, redirect=False) -+ retries.raise_on_redirect = raise_on_redirect -+ connection_pool_kw = connection_pool_kw.copy() -+ connection_pool_kw["retries"] = retries - self.connection_pool_kw = connection_pool_kw - self.pools = RecentlyUsedContainer(num_pools) - -@@ -389,7 +405,7 @@ class PoolManager(RequestMethods): - kw["body"] = None - kw["headers"] = HTTPHeaderDict(kw["headers"])._prepare_for_method_change() - -- retries = kw.get("retries") -+ retries = kw.get("retries", response.retries) - if not isinstance(retries, Retry): - retries = Retry.from_int(retries, redirect=redirect) - --- -2.51.0 - diff --git a/vendor_meta.sh b/vendor_meta.sh new file mode 100755 index 0000000..3ae5204 --- /dev/null +++ b/vendor_meta.sh @@ -0,0 +1,21 @@ +#!/usr/bin/bash -eu + +if [ $# -ne 1 ]; then + echo "Usage: ./vendor_meta.sh pip-10.0.0/src/pip/_vendor/vendor.txt" + exit 1 +fi + +licenses='' + +while read req; do + req=$(echo $req | cut -f1 -d' ') + name=$(echo $req | cut -f1 -d'=') + version=$(echo $req | cut -f3 -d'=' | tr -d '\r') + echo "Provides: bundled(python%{1}dist($name)) = $version" + license="$(pyp2rpm -v ${version} --no-venv ${name} | grep '^License:' | sed -e 's/License:\s*//')" + licenses="$licenses\n$name: $license" +done < $1 + +echo +echo +echo -e "$licenses"