diff --git a/7873.patch b/7873.patch new file mode 100644 index 0000000..8e4a8e4 --- /dev/null +++ b/7873.patch @@ -0,0 +1,151 @@ +From 0ef2645af8871b1722608c36b4f5cdcb8d38067e Mon Sep 17 00:00:00 2001 +From: Tomas Hrnciar +Date: Sun, 19 Apr 2020 20:06:52 +0200 +Subject: [PATCH 1/2] Prevent infinite recursion with pip wheel with $TMPDIR in + $PWD + +During a build of extension module within `pip wheel` the source directory is +recursively copied in a temporary directory. + +See https://github.com/pypa/pip/issues/7555 + +When the temporary directory is inside the source directory +(for example by setting `TMPDIR=$PWD/tmp`) this caused an infinite recursion +that ended in: + + [Errno 36] File name too long + +We prevent that buy never copying the target to the target in _copy_source_tree. + +Fixes https://github.com/pypa/pip/issues/7872 +--- + news/7872.bugfix | 1 + + src/pip/_internal/download.py | 23 ++++++++++++++++++----- + tests/data/src/extension/extension.c | 0 + tests/data/src/extension/setup.py | 4 ++++ + tests/functional/test_wheel.py | 11 +++++++++++ + 5 files changed, 34 insertions(+), 5 deletions(-) + create mode 100644 news/7872.bugfix + create mode 100644 tests/data/src/extension/extension.c + create mode 100644 tests/data/src/extension/setup.py + +diff --git a/news/7872.bugfix b/news/7872.bugfix +new file mode 100644 +index 00000000..3550d573 +--- /dev/null ++++ b/news/7872.bugfix +@@ -0,0 +1 @@ ++Prevent an infinite recursion with ``pip wheel`` when ``$TMPDIR`` is within the source directory. +diff --git a/src/pip/_internal/download.py b/src/pip/_internal/download.py +index 6567fc37..d5c01a41 100644 +--- a/src/pip/_internal/download.py ++++ b/src/pip/_internal/download.py +@@ -350,12 +350,25 @@ def _copy2_ignoring_special_files(src, dest): + + def _copy_source_tree(source, target): + # type: (str, str) -> None ++ target_abspath = os.path.abspath(target) ++ target_basename = os.path.basename(target_abspath) ++ target_dirname = os.path.dirname(target_abspath) ++ + def ignore(d, names): +- # Pulling in those directories can potentially be very slow, +- # exclude the following directories if they appear in the top +- # level dir (and only it). +- # See discussion at https://github.com/pypa/pip/pull/6770 +- return ['.tox', '.nox'] if d == source else [] ++ # type: (str, List[str]) -> List[str] ++ skipped = [] # type: List[str] ++ if d == source: ++ # Pulling in those directories can potentially be very slow, ++ # exclude the following directories if they appear in the top ++ # level dir (and only it). ++ # See discussion at https://github.com/pypa/pip/pull/6770 ++ skipped += ['.tox', '.nox'] ++ if os.path.abspath(d) == target_dirname: ++ # Prevent an infinite recursion if the target is in source. ++ # This can happen when TMPDIR is set to ${PWD}/... ++ # and we copy PWD to TMPDIR. ++ skipped += [target_basename] ++ return skipped + + kwargs = dict(ignore=ignore, symlinks=True) # type: CopytreeKwargs + +diff --git a/tests/data/src/extension/extension.c b/tests/data/src/extension/extension.c +new file mode 100644 +index 00000000..e69de29b +diff --git a/tests/data/src/extension/setup.py b/tests/data/src/extension/setup.py +new file mode 100644 +index 00000000..b26302b0 +--- /dev/null ++++ b/tests/data/src/extension/setup.py +@@ -0,0 +1,4 @@ ++from setuptools import Extension, setup ++ ++module = Extension('extension', sources=['extension.c']) ++setup(name='extension', version='0.0.1', ext_modules = [module]) +diff --git a/tests/functional/test_wheel.py b/tests/functional/test_wheel.py +index 5ebc9ea4..9923c023 100644 +--- a/tests/functional/test_wheel.py ++++ b/tests/functional/test_wheel.py +@@ -228,6 +228,17 @@ def test_pip_wheel_with_user_set_in_config(script, data, common_wheels): + assert "Successfully built withpyproject" in result.stdout, result.stdout + + ++def test_pip_wheel_ext_module_with_tmpdir_inside(script, data, common_wheels): ++ tmpdir = data.src / 'extension/tmp' ++ tmpdir.mkdir() ++ script.environ['TMPDIR'] = str(tmpdir) ++ result = script.pip( ++ 'wheel', data.src / 'extension', ++ '--no-index', '-f', common_wheels ++ ) ++ assert "Successfully built extension" in result.stdout, result.stdout ++ ++ + @pytest.mark.network + def test_pep517_wheels_are_not_confused_with_other_files(script, tmpdir, data): + """Check correct wheels are copied. (#6196) + + +From 168e98adb0f5d03887c4d88fc1733308761c3b8a Mon Sep 17 00:00:00 2001 +From: Tomas Hrnciar +Date: Sun, 19 Apr 2020 20:31:47 +0200 +Subject: [PATCH 2/2] Avoid a test dependency on a C compiler, skip the test on + Windows + +--- + tests/functional/test_wheel.py | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/tests/functional/test_wheel.py b/tests/functional/test_wheel.py +index 9923c023..fa3df239 100644 +--- a/tests/functional/test_wheel.py ++++ b/tests/functional/test_wheel.py +@@ -1,6 +1,7 @@ + """'pip wheel' tests""" + import os + import re ++import sys + from os.path import exists + + import pytest +@@ -228,10 +229,17 @@ def test_pip_wheel_with_user_set_in_config(script, data, common_wheels): + assert "Successfully built withpyproject" in result.stdout, result.stdout + + ++@pytest.mark.skipif(sys.platform.startswith('win'), ++ reason='The empty extension module does not work on Win') + def test_pip_wheel_ext_module_with_tmpdir_inside(script, data, common_wheels): + tmpdir = data.src / 'extension/tmp' + tmpdir.mkdir() + script.environ['TMPDIR'] = str(tmpdir) ++ ++ # To avoid a test dependency on a C compiler, we set the env vars to "noop" ++ # The .c source is empty anyway ++ script.environ['CC'] = script.environ['LDSHARED'] = str('true') ++ + result = script.pip( + 'wheel', data.src / 'extension', + '--no-index', '-f', common_wheels + diff --git a/8744.patch b/8744.patch new file mode 100644 index 0000000..1dfc974 --- /dev/null +++ b/8744.patch @@ -0,0 +1,79 @@ +From 23a2fef3919d773041f0c06e5f1a85471132098c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= +Date: Mon, 3 Aug 2020 10:41:03 +0200 +Subject: [PATCH] When one keyring attempt fails, don't bother with more + +This makes https://github.com/pypa/pip/issues/8090 much less painful. +--- + news/8090.bugfix | 3 +++ + src/pip/_internal/network/auth.py | 2 ++ + tests/unit/test_networking_auth.py | 26 ++++++++++++++++++++++++++ + 3 files changed, 31 insertions(+) + create mode 100644 news/8090.bugfix + +diff --git a/news/8090.bugfix b/news/8090.bugfix +new file mode 100644 +index 0000000..e9f2b7c +--- /dev/null ++++ b/news/8090.bugfix +@@ -0,0 +1,3 @@ ++Only attempt to use the keyring once and if it fails, don't try again. ++This prevents spamming users with several keyring unlock prompts when they ++cannot unlock or don't want to do so. +diff --git a/src/pip/_internal/network/auth.py b/src/pip/_internal/network/auth.py +index 1e1da54..c101f93 100644 +--- a/src/pip/_internal/network/auth.py ++++ b/src/pip/_internal/network/auth.py +@@ -45,6 +45,7 @@ except Exception as exc: + + def get_keyring_auth(url, username): + """Return the tuple auth for a given url from keyring.""" ++ global keyring + if not url or not keyring: + return None + +@@ -70,6 +71,7 @@ def get_keyring_auth(url, username): + logger.warning( + "Keyring is skipped due to an exception: %s", str(exc), + ) ++ keyring = None + + + class MultiDomainBasicAuth(AuthBase): +diff --git a/tests/unit/test_networking_auth.py b/tests/unit/test_networking_auth.py +index 0f0b679..0fc5799 100644 +--- a/tests/unit/test_networking_auth.py ++++ b/tests/unit/test_networking_auth.py +@@ -222,3 +222,29 @@ def test_keyring_get_credential(monkeypatch, url, expect): + assert auth._get_new_credentials( + url, allow_netrc=False, allow_keyring=True + ) == expect ++ ++ ++class KeyringModuleBroken(object): ++ """Represents the current supported API of keyring, but broken""" ++ ++ def __init__(self): ++ self._call_count = 0 ++ ++ def get_credential(self, system, username): ++ self._call_count += 1 ++ raise Exception("This keyring is broken!") ++ ++ ++def test_broken_keyring_disables_keyring(monkeypatch): ++ keyring_broken = KeyringModuleBroken() ++ monkeypatch.setattr(pip._internal.network.auth, 'keyring', keyring_broken) ++ ++ auth = MultiDomainBasicAuth(index_urls=["http://example.com/"]) ++ ++ assert keyring_broken._call_count == 0 ++ for i in range(5): ++ url = "http://example.com/path" + str(i) ++ assert auth._get_new_credentials( ++ url, allow_netrc=False, allow_keyring=True ++ ) == (None, None) ++ assert keyring_broken._call_count == 1 +-- +2.26.2 + diff --git a/python-pip.rpmlintrc b/python-pip.rpmlintrc new file mode 100644 index 0000000..5ccb1f8 --- /dev/null +++ b/python-pip.rpmlintrc @@ -0,0 +1,15 @@ +# 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') + +# 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 9aad3fa..abbcb0b 100644 --- a/python-pip.spec +++ b/python-pip.spec @@ -16,7 +16,7 @@ Name: python-%{srcname} # When updating, update the bundled libraries versions bellow! # You can use vendor_meta.sh in the dist git repo Version: 19.3.1 -Release: 2%{?dist} +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. @@ -47,8 +47,8 @@ Summary: A tool for installing and managing Python packages # webencodings: BSD License: MIT and Python and ASL 2.0 and BSD and ISC and LGPLv2 and MPLv2.0 and (ASL 2.0 or BSD) -URL: http://www.pip-installer.org -Source0: %pypi_source +URL: https://pip.pypa.io/ +Source0: https://github.com/pypa/pip/archive/%{version}/%{srcname}-%{version}.tar.gz BuildArch: noarch @@ -60,18 +60,10 @@ BuildRequires: python-setuptools-wheel BuildRequires: python-wheel-wheel %endif -# to get tests: -# git clone https://github.com/pypa/pip && cd pip -# VERSION= # define the version you want -# git checkout $VERSION && tar -czvf ../pip-$VERSION-tests.tar.gz tests/ -%if %{with tests} -Source1: pip-%{version}-tests.tar.gz -%endif - # Themes required to build the docs. %if %{with doc} -Source2: https://github.com/pypa/pypa-docs-theme/archive/%{pypa_theme_commit_hash}.tar.gz -Source3: https://github.com/python/python-docs-theme/archive/2018.2.tar.gz +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 @@ -106,6 +98,15 @@ Patch5: network-tests.patch # https://github.com/python/cpython/pull/16782 Patch6: callable-main.patch +# Allow setting $TMPDIR to $PWD/... during pip wheel +# This is needed to have proper debugsource packages with pyproject-rpm-macros +# https://bugzilla.redhat.com/show_bug.cgi?id=1806625 +# Backported from https://github.com/pypa/pip/pull/7873 +Patch7: 7873.patch + +# Backported from https://github.com/pypa/pip/pull/8744 +Patch8: 8744.patch + # Downstream only patch # Users might have local installations of pip from using # `pip install --user --upgrade pip` on older/newer versions. @@ -244,14 +245,12 @@ A Python wheel of pip to use with venv. %prep %setup -q -n %{srcname}-%{version} -%if %{with tests} -tar -xf %{SOURCE1} -%endif + %if %{with doc} pushd docs/html -tar -xf %{SOURCE2} +tar -xf %{SOURCE1} mv pypa-docs-theme-%{pypa_theme_commit_hash} pypa -tar -xf %{SOURCE3} +tar -xf %{SOURCE2} mv python-docs-theme-2018.2 python-docs-theme popd %endif @@ -264,15 +263,14 @@ popd %patch5 -p1 %endif %patch6 -p1 +%patch7 -p1 +%patch8 -p1 # this goes together with patch4 rm src/pip/_vendor/certifi/*.pem -sed -i '/\.pem$/d' src/pip.egg-info/SOURCES.txt -%if %{with tests} # tests expect wheels in here ln -s %{python_wheeldir} tests/data/common_wheels -%endif %build @@ -283,7 +281,7 @@ 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 docs/build/html/.buildinfo +rm -rf docs/build/html/{.doctrees,.buildinfo} %endif @@ -303,7 +301,9 @@ pushd docs/build/man install -d %{buildroot}%{_mandir}/man1 for MAN in *1; do install -pm0644 $MAN %{buildroot}%{_mandir}/man1/$MAN -install -pm0644 $MAN %{buildroot}%{_mandir}/man1/${MAN/pip/pip3} +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 @@ -392,6 +392,12 @@ ln -sf %{buildroot}%{_bindir}/pip3 _bin/pip %{python_wheeldir}/%{python_wheelname} %changelog +* Tue Aug 11 2020 Miro Hrončok - 19.3.1-4 +- Only ask for keyring password once (#1859476) + +* Fri Apr 10 2020 Miro Hrončok - 19.3.1-3 +- Allow setting $TMPDIR to $PWD/... during pip wheel (#1806625) + * Thu Jan 30 2020 Fedora Release Engineering - 19.3.1-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild diff --git a/sources b/sources index e005a9b..bbd8d89 100644 --- a/sources +++ b/sources @@ -1,4 +1,3 @@ -SHA512 (pip-19.3.1.tar.gz) = 954b390580e23d0a85d1fa4cbd2f35171df7930fbe346f9a809477fe133e95f7d30208d79b5d07f30c81ab1b0a9b52f36f3ff6c77dc81a1c9ab9beb2bd8e0aa1 -SHA512 (pip-19.3.1-tests.tar.gz) = fb058fcaaff3325341af5f4746be0c7943953c43fb721124758320363532911ca399f254a58e347c72795adc41764600bc6d02efce0e1e27d4b6d130efad9945 +SHA512 (pip-19.3.1.tar.gz) = 39446c0ab6e4495d98f22923a2a76901b024d9047b60d92580b21d447a718e5285cfd66f8ad0c20befcfe1abc7f06be29b6a5644d1b30265d3b67399fe76e033 SHA512 (d2e63fbfc62af3b7050f619b2f5bb8658985b931.tar.gz) = fc7b11c5cbf6322469ce2eaca2a8d7eb60b17398d316f7465ab5d3d38dabd00ee22a3da7437a28f6312f0115f77f2df0d8bf0abc671e055eef06356c94283409 SHA512 (2018.2.tar.gz) = 4c09c43a70ecb3ca3bc9445b01bf209eb382e41d9c969145696dea38551992ed88fd9b725a1264380f3dbdf8acdaf5ada3ef86b44255cdfbdbe4a01a1630912d diff --git a/tests/tests.yml b/tests/tests.yml index 43aa64b..e53bda5 100644 --- a/tests/tests.yml +++ b/tests/tests.yml @@ -7,6 +7,8 @@ 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: dir: python/smoke @@ -43,6 +45,18 @@ run: VERSION=3.8 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 @@ -56,3 +70,6 @@ - python3-devel - python3-tox - pipenv + - mock + - rpmdevtools + - rpm-build