Update to 22.3.1
This commit is contained in:
parent
a2dfa8738e
commit
c3f04d6b6d
@ -1,92 +0,0 @@
|
|||||||
From 6817fbfb1fd389ad61009f0199db5670b146c8d3 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Tzu-ping Chung <uranusjr@gmail.com>
|
|
||||||
Date: Sat, 6 Aug 2022 06:18:59 +0800
|
|
||||||
Subject: [PATCH] Skip dist if metadata does not have a valid name
|
|
||||||
|
|
||||||
---
|
|
||||||
news/11352.bugfix.rst | 2 ++
|
|
||||||
src/pip/_internal/metadata/importlib/_compat.py | 14 +++++++++++++-
|
|
||||||
src/pip/_internal/metadata/importlib/_envs.py | 14 +++++++++++---
|
|
||||||
3 files changed, 26 insertions(+), 4 deletions(-)
|
|
||||||
create mode 100644 news/11352.bugfix.rst
|
|
||||||
|
|
||||||
diff --git a/news/11352.bugfix.rst b/news/11352.bugfix.rst
|
|
||||||
new file mode 100644
|
|
||||||
index 00000000000..78016c912ef
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/news/11352.bugfix.rst
|
|
||||||
@@ -0,0 +1,2 @@
|
|
||||||
+Ignore distributions with invalid ``Name`` in metadata instead of crashing, when
|
|
||||||
+using the ``importlib.metadata`` backend.
|
|
||||||
diff --git a/src/pip/_internal/metadata/importlib/_compat.py b/src/pip/_internal/metadata/importlib/_compat.py
|
|
||||||
index e0879807ab9..593bff23ede 100644
|
|
||||||
--- a/src/pip/_internal/metadata/importlib/_compat.py
|
|
||||||
+++ b/src/pip/_internal/metadata/importlib/_compat.py
|
|
||||||
@@ -2,6 +2,15 @@
|
|
||||||
from typing import Any, Optional, Protocol, cast
|
|
||||||
|
|
||||||
|
|
||||||
+class BadMetadata(ValueError):
|
|
||||||
+ def __init__(self, dist: importlib.metadata.Distribution, *, reason: str) -> None:
|
|
||||||
+ self.dist = dist
|
|
||||||
+ self.reason = reason
|
|
||||||
+
|
|
||||||
+ def __str__(self) -> str:
|
|
||||||
+ return f"Bad metadata in {self.dist} ({self.reason})"
|
|
||||||
+
|
|
||||||
+
|
|
||||||
class BasePath(Protocol):
|
|
||||||
"""A protocol that various path objects conform.
|
|
||||||
|
|
||||||
@@ -40,4 +49,7 @@ def get_dist_name(dist: importlib.metadata.Distribution) -> str:
|
|
||||||
The ``name`` attribute is only available in Python 3.10 or later. We are
|
|
||||||
targeting exactly that, but Mypy does not know this.
|
|
||||||
"""
|
|
||||||
- return cast(Any, dist).name
|
|
||||||
+ name = cast(Any, dist).name
|
|
||||||
+ if not isinstance(name, str):
|
|
||||||
+ raise BadMetadata(dist, reason="invalid metadata entry 'name'")
|
|
||||||
+ return name
|
|
||||||
diff --git a/src/pip/_internal/metadata/importlib/_envs.py b/src/pip/_internal/metadata/importlib/_envs.py
|
|
||||||
index d5fcfdbfef2..cbec59e2c6d 100644
|
|
||||||
--- a/src/pip/_internal/metadata/importlib/_envs.py
|
|
||||||
+++ b/src/pip/_internal/metadata/importlib/_envs.py
|
|
||||||
@@ -1,5 +1,6 @@
|
|
||||||
import functools
|
|
||||||
import importlib.metadata
|
|
||||||
+import logging
|
|
||||||
import os
|
|
||||||
import pathlib
|
|
||||||
import sys
|
|
||||||
@@ -14,9 +15,11 @@
|
|
||||||
from pip._internal.utils.deprecation import deprecated
|
|
||||||
from pip._internal.utils.filetypes import WHEEL_EXTENSION
|
|
||||||
|
|
||||||
-from ._compat import BasePath, get_dist_name, get_info_location
|
|
||||||
+from ._compat import BadMetadata, BasePath, get_dist_name, get_info_location
|
|
||||||
from ._dists import Distribution
|
|
||||||
|
|
||||||
+logger = logging.getLogger(__name__)
|
|
||||||
+
|
|
||||||
|
|
||||||
def _looks_like_wheel(location: str) -> bool:
|
|
||||||
if not location.endswith(WHEEL_EXTENSION):
|
|
||||||
@@ -56,11 +59,16 @@ def _find_impl(self, location: str) -> Iterator[FoundResult]:
|
|
||||||
# To know exactly where we find a distribution, we have to feed in the
|
|
||||||
# paths one by one, instead of dumping the list to importlib.metadata.
|
|
||||||
for dist in importlib.metadata.distributions(path=[location]):
|
|
||||||
- normalized_name = canonicalize_name(get_dist_name(dist))
|
|
||||||
+ info_location = get_info_location(dist)
|
|
||||||
+ try:
|
|
||||||
+ raw_name = get_dist_name(dist)
|
|
||||||
+ except BadMetadata as e:
|
|
||||||
+ logger.warning("Skipping %s due to %s", info_location, e.reason)
|
|
||||||
+ continue
|
|
||||||
+ normalized_name = canonicalize_name(raw_name)
|
|
||||||
if normalized_name in self._found_names:
|
|
||||||
continue
|
|
||||||
self._found_names.add(normalized_name)
|
|
||||||
- info_location = get_info_location(dist)
|
|
||||||
yield dist, info_location
|
|
||||||
|
|
||||||
def find(self, location: str) -> Iterator[BaseDistribution]:
|
|
@ -1,36 +1,128 @@
|
|||||||
From cacd6d2fa9a27b29415a4ce25d76406fe69fc398 Mon Sep 17 00:00:00 2001
|
From 09c983fdeabe3fa0b90b73f32ddf84a61e498e09 Mon Sep 17 00:00:00 2001
|
||||||
From: Karolina Surma <ksurma@redhat.com>
|
From: Karolina Surma <ksurma@redhat.com>
|
||||||
Date: Mon, 10 May 2021 16:38:50 +0200
|
Date: Tue, 15 Nov 2022 09:22:46 +0100
|
||||||
Subject: [PATCH] Dummy certifi patch
|
Subject: [PATCH] Dummy certifi patch
|
||||||
|
|
||||||
Co-Authored-By: Tomas Hrnciar <thrnciar@redhat.com>
|
|
||||||
---
|
---
|
||||||
src/pip/_vendor/certifi/core.py | 5 ++---
|
src/pip/_vendor/certifi/core.py | 105 ++------------------------------
|
||||||
1 file changed, 2 insertions(+), 3 deletions(-)
|
1 file changed, 6 insertions(+), 99 deletions(-)
|
||||||
|
|
||||||
diff --git a/src/pip/_vendor/certifi/core.py b/src/pip/_vendor/certifi/core.py
|
diff --git a/src/pip/_vendor/certifi/core.py b/src/pip/_vendor/certifi/core.py
|
||||||
index f34045b..a2ada08 100644
|
index c3e5466..eb297f7 100644
|
||||||
--- a/src/pip/_vendor/certifi/core.py
|
--- a/src/pip/_vendor/certifi/core.py
|
||||||
+++ b/src/pip/_vendor/certifi/core.py
|
+++ b/src/pip/_vendor/certifi/core.py
|
||||||
@@ -14,6 +14,7 @@ class _PipPatchedCertificate(Exception):
|
@@ -4,105 +4,12 @@ certifi.py
|
||||||
|
|
||||||
|
This module returns the installation location of cacert.pem or its contents.
|
||||||
|
"""
|
||||||
|
-import sys
|
||||||
|
|
||||||
try:
|
+# The RPM-packaged certifi always uses the system certificates
|
||||||
+ raise ImportError # force fallback
|
+def where() -> str:
|
||||||
# Return a certificate file on disk for a standalone pip zipapp running in
|
+ return '/etc/pki/tls/certs/ca-bundle.crt'
|
||||||
# an isolated build environment to use. Passing --cert to the standalone
|
|
||||||
# pip does not work since requests calls where() unconditionally on import.
|
-if sys.version_info >= (3, 11):
|
||||||
@@ -75,9 +76,7 @@ except ImportError:
|
+def contents() -> str:
|
||||||
# If we don't have importlib.resources, then we will just do the old logic
|
+ with open(where(), encoding='utf=8') as data:
|
||||||
# of assuming we're on the filesystem and munge the path directly.
|
+ return data.read()
|
||||||
def where() -> str:
|
|
||||||
|
- 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__())
|
||||||
|
-
|
||||||
|
- return _CACERT_PATH
|
||||||
|
-
|
||||||
|
- def contents() -> str:
|
||||||
|
- return files("pip._vendor.certifi").joinpath("cacert.pem").read_text(encoding="ascii")
|
||||||
|
-
|
||||||
|
-elif sys.version_info >= (3, 7):
|
||||||
|
-
|
||||||
|
- 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__())
|
||||||
|
-
|
||||||
|
- return _CACERT_PATH
|
||||||
|
-
|
||||||
|
- def contents() -> str:
|
||||||
|
- return read_text("pip._vendor.certifi", "cacert.pem", encoding="ascii")
|
||||||
|
-
|
||||||
|
-else:
|
||||||
|
- import os
|
||||||
|
- import types
|
||||||
|
- from typing import Union
|
||||||
|
-
|
||||||
|
- Package = Union[types.ModuleType, str]
|
||||||
|
- Resource = Union[str, "os.PathLike"]
|
||||||
|
-
|
||||||
|
- # This fallback will work for Python versions prior to 3.7 that lack the
|
||||||
|
- # importlib.resources module but relies on the existing `where` function
|
||||||
|
- # so won't address issues with environments like PyOxidizer that don't set
|
||||||
|
- # __file__ on modules.
|
||||||
|
- def read_text(
|
||||||
|
- package: Package,
|
||||||
|
- resource: Resource,
|
||||||
|
- encoding: str = 'utf-8',
|
||||||
|
- errors: str = 'strict'
|
||||||
|
- ) -> str:
|
||||||
|
- with open(where(), encoding=encoding) as data:
|
||||||
|
- return data.read()
|
||||||
|
-
|
||||||
|
- # 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() -> str:
|
||||||
- f = os.path.dirname(__file__)
|
- f = os.path.dirname(__file__)
|
||||||
-
|
-
|
||||||
- return os.path.join(f, "cacert.pem")
|
- return os.path.join(f, "cacert.pem")
|
||||||
+ return '/etc/pki/tls/certs/ca-bundle.crt'
|
-
|
||||||
|
- def contents() -> str:
|
||||||
|
- return read_text("pip._vendor.certifi", "cacert.pem", encoding="ascii")
|
||||||
def contents() -> str:
|
|
||||||
--
|
--
|
||||||
2.35.3
|
2.37.3
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%global srcname pip
|
%global srcname pip
|
||||||
%global base_version 22.2.2
|
%global base_version 22.3.1
|
||||||
%global upstream_version %{base_version}%{?prerel}
|
%global upstream_version %{base_version}%{?prerel}
|
||||||
%global python_wheel_name %{srcname}-%{upstream_version}-py3-none-any.whl
|
%global python_wheel_name %{srcname}-%{upstream_version}-py3-none-any.whl
|
||||||
|
|
||||||
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
Name: python-%{srcname}
|
Name: python-%{srcname}
|
||||||
Version: %{base_version}%{?prerel:~%{prerel}}
|
Version: %{base_version}%{?prerel:~%{prerel}}
|
||||||
Release: 2%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: A tool for installing and managing Python packages
|
Summary: A tool for installing and managing Python packages
|
||||||
|
|
||||||
# We bundle a lot of libraries with pip, which itself is under MIT license.
|
# We bundle a lot of libraries with pip, which itself is under MIT license.
|
||||||
@ -77,6 +77,7 @@ Patch: remove-existing-dist-only-if-path-conflicts.patch
|
|||||||
|
|
||||||
# Use the system level root certificate instead of the one bundled in certifi
|
# Use the system level root certificate instead of the one bundled in certifi
|
||||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1655253
|
# 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
|
Patch: dummy-certifi.patch
|
||||||
|
|
||||||
# Don't warn the user about pip._internal.main() entrypoint
|
# Don't warn the user about pip._internal.main() entrypoint
|
||||||
@ -89,11 +90,6 @@ Patch: nowarn-pip._internal.main.patch
|
|||||||
# Upstream issue: https://github.com/pypa/packaging/issues/368
|
# Upstream issue: https://github.com/pypa/packaging/issues/368
|
||||||
Patch: no-version-warning.patch
|
Patch: no-version-warning.patch
|
||||||
|
|
||||||
# Ignore distributions with invalid name in metadata instead of crashing, when
|
|
||||||
# using the importlib.metadata backend.
|
|
||||||
# Resolved upstream: https://github.com/pypa/pip/pull/11353
|
|
||||||
Patch: bad-metadata-fix.patch
|
|
||||||
|
|
||||||
# Downstream only patch
|
# Downstream only patch
|
||||||
# Users might have local installations of pip from using
|
# Users might have local installations of pip from using
|
||||||
# `pip install --user --upgrade pip` on older/newer versions.
|
# `pip install --user --upgrade pip` on older/newer versions.
|
||||||
@ -130,27 +126,27 @@ Packages" or "Pip Installs Python".
|
|||||||
# %%{_rpmconfigdir}/pythonbundles.py --namespace 'python%%{1}dist' src/pip/_vendor/vendor.txt
|
# %%{_rpmconfigdir}/pythonbundles.py --namespace 'python%%{1}dist' src/pip/_vendor/vendor.txt
|
||||||
%global bundled() %{expand:
|
%global bundled() %{expand:
|
||||||
Provides: bundled(python%{1}dist(cachecontrol)) = 0.12.11
|
Provides: bundled(python%{1}dist(cachecontrol)) = 0.12.11
|
||||||
Provides: bundled(python%{1}dist(certifi)) = 2022.6.15
|
Provides: bundled(python%{1}dist(certifi)) = 2022.9.24
|
||||||
Provides: bundled(python%{1}dist(chardet)) = 5
|
Provides: bundled(python%{1}dist(chardet)) = 5
|
||||||
Provides: bundled(python%{1}dist(colorama)) = 0.4.5
|
Provides: bundled(python%{1}dist(colorama)) = 0.4.5
|
||||||
Provides: bundled(python%{1}dist(distlib)) = 0.3.5
|
Provides: bundled(python%{1}dist(distlib)) = 0.3.6
|
||||||
Provides: bundled(python%{1}dist(distro)) = 1.7
|
Provides: bundled(python%{1}dist(distro)) = 1.7
|
||||||
Provides: bundled(python%{1}dist(idna)) = 3.3
|
Provides: bundled(python%{1}dist(idna)) = 3.4
|
||||||
Provides: bundled(python%{1}dist(msgpack)) = 1.0.4
|
Provides: bundled(python%{1}dist(msgpack)) = 1.0.4
|
||||||
Provides: bundled(python%{1}dist(packaging)) = 21.3
|
Provides: bundled(python%{1}dist(packaging)) = 21.3
|
||||||
Provides: bundled(python%{1}dist(pep517)) = 0.12
|
Provides: bundled(python%{1}dist(pep517)) = 0.13
|
||||||
Provides: bundled(python%{1}dist(platformdirs)) = 2.5.2
|
Provides: bundled(python%{1}dist(platformdirs)) = 2.5.2
|
||||||
Provides: bundled(python%{1}dist(pygments)) = 2.12
|
Provides: bundled(python%{1}dist(pygments)) = 2.13
|
||||||
Provides: bundled(python%{1}dist(pyparsing)) = 3.0.9
|
Provides: bundled(python%{1}dist(pyparsing)) = 3.0.9
|
||||||
Provides: bundled(python%{1}dist(requests)) = 2.28.1
|
Provides: bundled(python%{1}dist(requests)) = 2.28.1
|
||||||
Provides: bundled(python%{1}dist(resolvelib)) = 0.8.1
|
Provides: bundled(python%{1}dist(resolvelib)) = 0.8.1
|
||||||
Provides: bundled(python%{1}dist(rich)) = 12.5.1
|
Provides: bundled(python%{1}dist(rich)) = 12.5.1
|
||||||
Provides: bundled(python%{1}dist(setuptools)) = 44
|
Provides: bundled(python%{1}dist(setuptools)) = 44
|
||||||
Provides: bundled(python%{1}dist(six)) = 1.16
|
Provides: bundled(python%{1}dist(six)) = 1.16
|
||||||
Provides: bundled(python%{1}dist(tenacity)) = 8.0.1
|
Provides: bundled(python%{1}dist(tenacity)) = 8.1
|
||||||
Provides: bundled(python%{1}dist(tomli)) = 2.0.1
|
Provides: bundled(python%{1}dist(tomli)) = 2.0.1
|
||||||
Provides: bundled(python%{1}dist(typing-extensions)) = 4.3
|
Provides: bundled(python%{1}dist(typing-extensions)) = 4.4
|
||||||
Provides: bundled(python%{1}dist(urllib3)) = 1.26.10
|
Provides: bundled(python%{1}dist(urllib3)) = 1.26.12
|
||||||
Provides: bundled(python%{1}dist(webencodings)) = 0.5.1
|
Provides: bundled(python%{1}dist(webencodings)) = 0.5.1
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -351,26 +347,14 @@ install -p dist/%{python_wheel_name} -t %{buildroot}%{python_wheel_dir}
|
|||||||
|
|
||||||
# Upstream tests
|
# Upstream tests
|
||||||
# bash completion tests only work from installed package
|
# bash completion tests only work from installed package
|
||||||
# needs unaltered sys.path and we cannot do that in %%check
|
pytest_k='not completion'
|
||||||
# test_pep517_and_build_options
|
|
||||||
# test_config_file_venv_option
|
|
||||||
# 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_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'
|
|
||||||
|
|
||||||
# --deselect'ed tests are not compatible with the latest virtualenv
|
# --deselect'ed tests are not compatible with the latest virtualenv
|
||||||
# These files contain almost 500 tests so we should enable them back
|
# These files contain almost 500 tests so we should enable them back
|
||||||
# as soon as pip will be compatible upstream
|
# as soon as pip will be compatible upstream
|
||||||
# https://github.com/pypa/pip/pull/8441
|
# https://github.com/pypa/pip/pull/8441
|
||||||
%pytest -m 'not network' -k "$(echo $pytest_k)" \
|
%pytest -m 'not network' -k "$(echo $pytest_k)" \
|
||||||
--deselect tests/functional --deselect tests/lib/test_lib.py --deselect tests/unit/test_build_env.py
|
--deselect tests/functional --deselect tests/lib/test_lib.py
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
|
|
||||||
@ -406,6 +390,10 @@ pytest_k='not completion and
|
|||||||
%{python_wheel_dir}/%{python_wheel_name}
|
%{python_wheel_dir}/%{python_wheel_name}
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Nov 14 2022 Karolina Surma <ksurma@redhat.com> - 22.3.1-1
|
||||||
|
- Update to 22.3.1
|
||||||
|
Resolves: rhbz#2135044
|
||||||
|
|
||||||
* Mon Sep 05 2022 Python Maint <python-maint@redhat.com> - 22.2.2-2
|
* Mon Sep 05 2022 Python Maint <python-maint@redhat.com> - 22.2.2-2
|
||||||
- Fix crash when an empty dist-info/egg-info is present
|
- Fix crash when an empty dist-info/egg-info is present
|
||||||
Resolves: rhbz#2115001
|
Resolves: rhbz#2115001
|
||||||
|
2
sources
2
sources
@ -1 +1 @@
|
|||||||
SHA512 (pip-22.2.2.tar.gz) = bd59e28b55475b77a8f11ea771cbad3b2602ff974e219f9a55288963a9522c9279a5b00fde40fb65cfebefae0e905d3da3c06fe50b402aa5326b25f70a98a015
|
SHA512 (pip-22.3.1.tar.gz) = c7865c4ce79b0fea7ba469fe593af3be205b3bdb574a6ae019842e0f82a0af406ec905d8c6ff02fbbafe01630c8899a398d071ce74501ca830249160f2f6df98
|
||||||
|
Loading…
Reference in New Issue
Block a user