From f39a290edd84b086f59b296b6d234e1ad3bb127e Mon Sep 17 00:00:00 2001 From: openeuler-ci-bot <80474298@qq.com> Date: Tue, 8 Dec 2020 20:58:56 +0800 Subject: [PATCH 1/3] [patch tracking] 20201208205849756098 - https://github.com/pypa/pip/commit/7c00e6f3fd418975a57a0da180c454bc1f629569 --- ...e6f3fd418975a57a0da180c454bc1f629569.patch | 218 ++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 7c00e6f3fd418975a57a0da180c454bc1f629569.patch diff --git a/7c00e6f3fd418975a57a0da180c454bc1f629569.patch b/7c00e6f3fd418975a57a0da180c454bc1f629569.patch new file mode 100644 index 0000000..34705bd --- /dev/null +++ b/7c00e6f3fd418975a57a0da180c454bc1f629569.patch @@ -0,0 +1,218 @@ +diff --git a/news/9232.bugfix.rst b/news/9232.bugfix.rst +new file mode 100644 +index 0000000000..2d50d1ce41 +--- /dev/null ++++ b/news/9232.bugfix.rst +@@ -0,0 +1,2 @@ ++New resolver: Make constraints also apply to package variants with extras, so ++the resolver correctly avoids backtracking on them. +diff --git a/src/pip/_internal/resolution/resolvelib/base.py b/src/pip/_internal/resolution/resolvelib/base.py +index e2edbe9f42..7eb8a178eb 100644 +--- a/src/pip/_internal/resolution/resolvelib/base.py ++++ b/src/pip/_internal/resolution/resolvelib/base.py +@@ -67,9 +67,25 @@ def is_satisfied_by(self, candidate): + + + class Requirement(object): ++ @property ++ def project_name(self): ++ # type: () -> str ++ """The "project name" of a requirement. ++ ++ This is different from ``name`` if this requirement contains extras, ++ in which case ``name`` would contain the ``[...]`` part, while this ++ refers to the name of the project. ++ """ ++ raise NotImplementedError("Subclass should override") ++ + @property + def name(self): + # type: () -> str ++ """The name identifying this requirement in the resolver. ++ ++ This is different from ``project_name`` if this requirement contains ++ extras, where ``project_name`` would not contain the ``[...]`` part. ++ """ + raise NotImplementedError("Subclass should override") + + def is_satisfied_by(self, candidate): +@@ -86,9 +102,25 @@ def format_for_error(self): + + + class Candidate(object): ++ @property ++ def project_name(self): ++ # type: () -> str ++ """The "project name" of the candidate. ++ ++ This is different from ``name`` if this candidate contains extras, ++ in which case ``name`` would contain the ``[...]`` part, while this ++ refers to the name of the project. ++ """ ++ raise NotImplementedError("Override in subclass") ++ + @property + def name(self): + # type: () -> str ++ """The name identifying this candidate in the resolver. ++ ++ This is different from ``project_name`` if this candidate contains ++ extras, where ``project_name`` would not contain the ``[...]`` part. ++ """ + raise NotImplementedError("Override in subclass") + + @property +diff --git a/src/pip/_internal/resolution/resolvelib/candidates.py b/src/pip/_internal/resolution/resolvelib/candidates.py +index 1fc2ff479a..cd1f188706 100644 +--- a/src/pip/_internal/resolution/resolvelib/candidates.py ++++ b/src/pip/_internal/resolution/resolvelib/candidates.py +@@ -175,13 +175,18 @@ def source_link(self): + return self._source_link + + @property +- def name(self): ++ def project_name(self): + # type: () -> str + """The normalised name of the project the candidate refers to""" + if self._name is None: + self._name = canonicalize_name(self.dist.project_name) + return self._name + ++ @property ++ def name(self): ++ # type: () -> str ++ return self.project_name ++ + @property + def version(self): + # type: () -> _BaseVersion +@@ -390,10 +395,15 @@ def __ne__(self, other): + return not self.__eq__(other) + + @property +- def name(self): ++ def project_name(self): + # type: () -> str + return canonicalize_name(self.dist.project_name) + ++ @property ++ def name(self): ++ # type: () -> str ++ return self.project_name ++ + @property + def version(self): + # type: () -> _BaseVersion +@@ -481,11 +491,16 @@ def __ne__(self, other): + # type: (Any) -> bool + return not self.__eq__(other) + ++ @property ++ def project_name(self): ++ # type: () -> str ++ return self.base.project_name ++ + @property + def name(self): + # type: () -> str + """The normalised name of the project the candidate refers to""" +- return format_name(self.base.name, self.extras) ++ return format_name(self.base.project_name, self.extras) + + @property + def version(self): +@@ -572,11 +587,16 @@ def __str__(self): + return "Python {}".format(self._version) + + @property +- def name(self): ++ def project_name(self): + # type: () -> str + # Avoid conflicting with the PyPI package "Python". + return "" + ++ @property ++ def name(self): ++ # type: () -> str ++ return self.project_name ++ + @property + def version(self): + # type: () -> _BaseVersion +diff --git a/src/pip/_internal/resolution/resolvelib/provider.py b/src/pip/_internal/resolution/resolvelib/provider.py +index c91f252f7b..3883135f12 100644 +--- a/src/pip/_internal/resolution/resolvelib/provider.py ++++ b/src/pip/_internal/resolution/resolvelib/provider.py +@@ -30,6 +30,16 @@ + + + class PipProvider(AbstractProvider): ++ """Pip's provider implementation for resolvelib. ++ ++ :params constraints: A mapping of constraints specified by the user. Keys ++ are canonicalized project names. ++ :params ignore_dependencies: Whether the user specified ``--no-deps``. ++ :params upgrade_strategy: The user-specified upgrade strategy. ++ :params user_requested: A set of canonicalized package names that the user ++ supplied for pip to install/upgrade. ++ """ ++ + def __init__( + self, + factory, # type: Factory +@@ -113,7 +123,7 @@ def find_matches(self, requirements): + # type: (Sequence[Requirement]) -> Iterable[Candidate] + if not requirements: + return [] +- name = requirements[0].name ++ name = requirements[0].project_name + + def _eligible_for_upgrade(name): + # type: (str) -> bool +diff --git a/src/pip/_internal/resolution/resolvelib/requirements.py b/src/pip/_internal/resolution/resolvelib/requirements.py +index 25cddceaf6..d926d0a065 100644 +--- a/src/pip/_internal/resolution/resolvelib/requirements.py ++++ b/src/pip/_internal/resolution/resolvelib/requirements.py +@@ -28,6 +28,12 @@ def __repr__(self): + candidate=self.candidate, + ) + ++ @property ++ def project_name(self): ++ # type: () -> str ++ # No need to canonicalise - the candidate did this ++ return self.candidate.project_name ++ + @property + def name(self): + # type: () -> str +@@ -65,11 +71,15 @@ def __repr__(self): + requirement=str(self._ireq.req), + ) + ++ @property ++ def project_name(self): ++ # type: () -> str ++ return canonicalize_name(self._ireq.req.name) ++ + @property + def name(self): + # type: () -> str +- canonical_name = canonicalize_name(self._ireq.req.name) +- return format_name(canonical_name, self._extras) ++ return format_name(self.project_name, self._extras) + + def format_for_error(self): + # type: () -> str +@@ -121,6 +131,11 @@ def __repr__(self): + specifier=str(self.specifier), + ) + ++ @property ++ def project_name(self): ++ # type: () -> str ++ return self._candidate.project_name ++ + @property + def name(self): + # type: () -> str -- Gitee From 9328accede01fdbb898edeb1a2dd735b69598549 Mon Sep 17 00:00:00 2001 From: openeuler-ci-bot <80474298@qq.com> Date: Tue, 8 Dec 2020 20:58:56 +0800 Subject: [PATCH 2/3] [patch tracking] 20201208205849756098 - https://github.com/pypa/pip/commit/643217bc35cbd26e24ac5e35466f8b7d7d0ed9fb --- ...17bc35cbd26e24ac5e35466f8b7d7d0ed9fb.patch | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 643217bc35cbd26e24ac5e35466f8b7d7d0ed9fb.patch diff --git a/643217bc35cbd26e24ac5e35466f8b7d7d0ed9fb.patch b/643217bc35cbd26e24ac5e35466f8b7d7d0ed9fb.patch new file mode 100644 index 0000000..b56ec45 --- /dev/null +++ b/643217bc35cbd26e24ac5e35466f8b7d7d0ed9fb.patch @@ -0,0 +1,63 @@ +diff --git a/news/9191.bugfix.rst b/news/9191.bugfix.rst +new file mode 100644 +index 0000000000..e1c6d633de +--- /dev/null ++++ b/news/9191.bugfix.rst +@@ -0,0 +1,2 @@ ++Fix crash when logic for redacting authentication information from URLs ++in ``--help`` is given a list of strings, instead of a single string. +diff --git a/src/pip/_internal/cli/parser.py b/src/pip/_internal/cli/parser.py +index ea3b383e2f..7170bfd384 100644 +--- a/src/pip/_internal/cli/parser.py ++++ b/src/pip/_internal/cli/parser.py +@@ -112,15 +112,23 @@ class UpdatingDefaultsHelpFormatter(PrettyHelpFormatter): + """ + + def expand_default(self, option): +- default_value = None ++ default_values = None + if self.parser is not None: + self.parser._update_defaults(self.parser.defaults) +- default_value = self.parser.defaults.get(option.dest) ++ default_values = self.parser.defaults.get(option.dest) + help_text = optparse.IndentedHelpFormatter.expand_default(self, option) + +- if default_value and option.metavar == 'URL': +- help_text = help_text.replace( +- default_value, redact_auth_from_url(default_value)) ++ if default_values and option.metavar == 'URL': ++ if isinstance(default_values, string_types): ++ default_values = [default_values] ++ ++ # If its not a list, we should abort and just return the help text ++ if not isinstance(default_values, list): ++ default_values = [] ++ ++ for val in default_values: ++ help_text = help_text.replace( ++ val, redact_auth_from_url(val)) + + return help_text + +diff --git a/tests/functional/test_help.py b/tests/functional/test_help.py +index 9c2508abb5..a660cdf520 100644 +--- a/tests/functional/test_help.py ++++ b/tests/functional/test_help.py +@@ -74,6 +74,17 @@ def test_help_command_redact_auth_from_url(script): + assert 'secret' not in result.stdout + + ++def test_help_command_redact_auth_from_url_with_extra_index_url(script): ++ """ ++ Test `help` on various subcommands redact auth from url with extra index url ++ """ ++ script.environ['PIP_INDEX_URL'] = 'https://user:secret@example.com' ++ script.environ['PIP_EXTRA_INDEX_URL'] = 'https://user:secret@example2.com' ++ result = script.pip('install', '--help') ++ assert result.returncode == SUCCESS ++ assert 'secret' not in result.stdout ++ ++ + def test_help_commands_equally_functional(in_memory_pip): + """ + Test if `pip help` and 'pip --help' behave the same way. -- Gitee From 2c07480ed448b0d1481bb8e0b3f1bd2283c8a60b Mon Sep 17 00:00:00 2001 From: openeuler-ci-bot <80474298@qq.com> Date: Tue, 8 Dec 2020 20:58:57 +0800 Subject: [PATCH 3/3] [patch tracking] 20201208205849756098 - update spec file --- python-pip.spec | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/python-pip.spec b/python-pip.spec index 3d035b5..e686a8b 100644 --- a/python-pip.spec +++ b/python-pip.spec @@ -6,7 +6,7 @@ pip is the package installer for Python. You can use pip to install packages fro %global bashcompdir %(b=$(pkg-config --variable=completionsdir bash-completion 2>/dev/null); echo ${b:-%{_sysconfdir}/bash_completion.d}) Name: python-%{srcname} Version: 20.2.2 -Release: 3 +Release: 4 Summary: A tool for installing and managing Python packages 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 @@ -16,6 +16,8 @@ Patch1: allow-stripping-given-prefix-from-wheel-RECORD-files.patch Patch2: emit-a-warning-when-running-with-root-privileges.patch Patch3: remove-existing-dist-only-if-path-conflicts.patch Patch6000: dummy-certifi.patch +Patch6001: 7c00e6f3fd418975a57a0da180c454bc1f629569.patch +Patch6002: 643217bc35cbd26e24ac5e35466f8b7d7d0ed9fb.patch Source10: pip-allow-older-versions.patch %description %{_description} @@ -112,6 +114,9 @@ install -p dist/%{python_wheelname} -t %{buildroot}%{python_wheeldir} %{python_wheeldir}/%{python_wheelname} %changelog +* 20201208205849756098 patch-tracking 20.2.2-4 +- append patch file of upstream repository from <7c00e6f3fd418975a57a0da180c454bc1f629569> to <643217bc35cbd26e24ac5e35466f8b7d7d0ed9fb> + * Wed Nov 4 2020 wangjie -20.2.2-3 - Type:NA - ID:NA @@ -161,4 +166,4 @@ install -p dist/%{python_wheelname} -t %{buildroot}%{python_wheeldir} - DESC: Synchronize a patch * Mon Sep 23 2019 openEuler Buildteam - 18.0-6 -- Package init +- Package init \ No newline at end of file -- Gitee