commit:     7e1e27390394fa64b6c44e87a8c3e737ce9ef2e4
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Fri Nov 25 07:10:42 2022 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Nov 25 07:10:42 2022 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=7e1e2739

dev-python/certifi: use importlib

This avoids breaking arbitrary packages on the system because they
happen to use certifi, as certifi will pick up if any other packages
on the system have an unsatisfied requirement - which is often
bogus.

Bug: https://bugs.gentoo.org/826874
Bug: https://bugs.gentoo.org/854294
Bug: https://bugs.gentoo.org/878035
Closes: https://bugs.gentoo.org/878045
Signed-off-by: Sam James <sam <AT> gentoo.org>

 dev-python/certifi/certifi-3021.3.16-r3.ebuild     |  55 +++++++
 .../files/certifi-3021.3.16-use-importlib.patch    | 164 +++++++++++++++++++++
 2 files changed, 219 insertions(+)

diff --git a/dev-python/certifi/certifi-3021.3.16-r3.ebuild 
b/dev-python/certifi/certifi-3021.3.16-r3.ebuild
new file mode 100644
index 000000000000..a36a91db931b
--- /dev/null
+++ b/dev-python/certifi/certifi-3021.3.16-r3.ebuild
@@ -0,0 +1,55 @@
+# Copyright 1999-2022 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+# please keep this ebuild at EAPI 7 -- sys-apps/portage dep
+EAPI=7
+
+DISTUTILS_USE_PEP517=setuptools
+PYTHON_COMPAT=( python3_{8..11} pypy3 )
+
+inherit distutils-r1
+
+MY_P=certifi-system-store-${PV}
+DESCRIPTION="A certifi hack to use system trust store on Linux/FreeBSD"
+HOMEPAGE="
+       https://github.com/tiran/certifi-system-store/
+       https://pypi.org/project/certifi-system-store/
+"
+SRC_URI="
+       https://github.com/tiran/certifi-system-store/archive/v${PV}.tar.gz
+               -> ${MY_P}.tar.gz
+"
+S=${WORKDIR}/${MY_P}
+
+LICENSE="MPL-2.0"
+SLOT="0"
+KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~loong ~m68k ~mips ~ppc ~ppc64 
~riscv ~s390 ~sparc ~x86 ~x64-cygwin ~amd64-linux ~x86-linux ~ppc-macos 
~x64-macos ~sparc-solaris ~sparc64-solaris ~x64-solaris ~x86-solaris"
+
+RDEPEND="
+       app-misc/ca-certificates
+       dev-python/setuptools[${PYTHON_USEDEP}]
+"
+
+PATCHES=(
+       "${FILESDIR}"/${P}-use-importlib.patch
+)
+
+EPYTEST_IGNORE=(
+       # requires Internet
+       tests/test_requests.py
+)
+
+distutils_enable_tests pytest
+
+src_prepare() {
+       sed -i -e "s^/etc^${EPREFIX}/etc^" src/certifi/core.py || die
+       distutils-r1_src_prepare
+}
+
+python_compile() {
+       distutils-r1_python_compile
+       cd "${BUILD_DIR}/install$(python_get_sitedir)" || die
+       local distinfo=( certifi_system_store*.dist-info )
+       [[ -d ${distinfo} ]] || die
+       ln -v -s "${distinfo}" "${distinfo/_system_store}" || die
+}

diff --git a/dev-python/certifi/files/certifi-3021.3.16-use-importlib.patch 
b/dev-python/certifi/files/certifi-3021.3.16-use-importlib.patch
new file mode 100644
index 000000000000..3028bfcb99cf
--- /dev/null
+++ b/dev-python/certifi/files/certifi-3021.3.16-use-importlib.patch
@@ -0,0 +1,164 @@
+1. 
https://github.com/tiran/certifi-system-store/commit/6945f34b7be433dbf22946825cdb225d5d2136d5
+2. https://github.com/tiran/certifi-system-store/pull/21
+
+Avoid repeated instances of https://bugs.gentoo.org/878045 when a package
+has too-strict requirements and then affects other, unrelated Python
+packages on the system.
+
+From 6945f34b7be433dbf22946825cdb225d5d2136d5 Mon Sep 17 00:00:00 2001
+From: Christian Heimes <christ...@python.org>
+Date: Tue, 16 Mar 2021 16:00:08 +0100
+Subject: [PATCH] Relax patch checks (#13)
+
+- only check that version matches, not files are identical
+- compare base directories with samefile. This fixes a problem with
+  lib64 symlink in virtual envs.
+
+Signed-off-by: Christian Heimes <christ...@python.org>
+--- a/src/certifi/_patch.py
++++ b/src/certifi/_patch.py
+@@ -28,7 +28,7 @@ def _patch_dist_info():
+     except pkg_resources.DistributionNotFound:
+         pass
+     else:
+-        if os.path.samefile(css_dist.egg_info, certifi_dist.egg_info):
++        if certifi_dist.version == css_dist.version:
+             return False, css_dist.egg_info, certifi_dist.egg_info
+         else:
+             # blow away certifi's dist-info
+@@ -55,7 +55,9 @@ def _patch_dist_info():
+     certifi_dir = os.path.dirname(os.path.abspath(__file__))
+     dist_dir = os.path.abspath(certifi_dist.egg_info)
+ 
+-    if os.path.dirname(certifi_dir) != os.path.dirname(dist_dir):
++    # compare with samefile instead of string comparison to avoid false
++    # negatives caused by venv lib64 / lib symlinks
++    if not os.path.samefile(os.path.dirname(certifi_dir), 
os.path.dirname(dist_dir)):
+         raise RuntimeError(
+             f"'{certifi_dir} and {dist_dir} have different parent 
directories."
+         )
+
+From cdec6d20b5d716d9853e72a1519a304070395498 Mon Sep 17 00:00:00 2001
+From: Christian Heimes <christ...@python.org>
+Date: Wed, 22 Jun 2022 10:08:18 +0200
+Subject: [PATCH] Use importlib on Python 3.8+
+
+--- a/setup.cfg
++++ b/setup.cfg
+@@ -38,8 +40,9 @@ packages = certifi
+ include_package_data = True
+ zip_safe = True
+ setup_requires = setuptools
+-# hack to prevent installation on unsupported platforms Windows and macOS
+ install_requires =
++    setuptools; python_version < "3.8"
++    # hack to prevent installation on unsupported platforms Windows and macOS
+     certifi-system-store > 4000; sys_platform == "win32" or sys_platform == 
"darwin"
+ python_requires = >=3.6
+ 
+--- a/src/certifi/_patch.py
++++ b/src/certifi/_patch.py
+@@ -1,7 +1,31 @@
+ import os
+ import shutil
+ import sys
+-import pkg_resources
++
++if sys.version_info >= (3, 8):
++    from importlib import metadata
++
++    PackageNotFoundError = metadata.PackageNotFoundError
++
++    def _get_distinfo(name):
++        dist = metadata.distribution(name)
++        egg_info = dist._path
++        return dist.version, egg_info
++
++    def _invalidate_caches():
++        pass
++
++else:
++    import pkg_resources
++
++    PackageNotFoundError = pkg_resources.DistributionNotFound
++
++    def _get_distinfo(name):
++        dist = pkg_resources.get_distribution(name)
++        return dist.version, dist.egg_info
++
++    def _invalidate_caches():
++        pkg_resources.working_set.__init__()
+ 
+ 
+ def _relsymlink(target, linkname):
+@@ -22,22 +46,22 @@ def _relsymlink(target, linkname):
+ 
+ def _patch_dist_info():
+     # distribution object for the canonical project name
+-    css_dist = pkg_resources.get_distribution("certifi_system_store")
++    css_version, css_egg_info = _get_distinfo("certifi_system_store")
+     try:
+-        certifi_dist = pkg_resources.get_distribution("certifi")
+-    except pkg_resources.DistributionNotFound:
++        certifi_version, certifi_egg_info = _get_distinfo("certifi")
++    except PackageNotFoundError:
+         pass
+     else:
+-        if certifi_dist.version == css_dist.version:
+-            return False, css_dist.egg_info, certifi_dist.egg_info
++        if certifi_version == css_version:
++            return False, css_egg_info, certifi_egg_info
+         else:
+             # blow away certifi's dist-info
+-            shutil.rmtree(certifi_dist.egg_info)
++            shutil.rmtree(certifi_egg_info)
+             # reset current working set, so pkg_resources can pick up our hack
+-            pkg_resources.working_set.__init__()
++            _invalidate_caches()
+ 
+     # certifi-system-store's dist-info
+-    abs_css_distinfodir = os.path.abspath(css_dist.egg_info)
++    abs_css_distinfodir = os.path.abspath(css_egg_info)
+     css_basedir, css_distinfodir = os.path.split(abs_css_distinfodir)
+ 
+     # certifi's dist-info in same base directory
+@@ -48,12 +72,12 @@ def _patch_dist_info():
+     _relsymlink(target=abs_css_distinfodir, linkname=abs_certifi_distinfodir)
+ 
+     # get dist info from refreshed working set
+-    css_dist = pkg_resources.get_distribution("certifi_system_store")
+-    certifi_dist = pkg_resources.get_distribution("certifi")
++    css_version, css_egg_info = _get_distinfo("certifi_system_store")
++    certifi_version, certifi_egg_info = _get_distinfo("certifi")
+ 
+     # check that certifi dist-info is in same site-packages as certifi package
+     certifi_dir = os.path.dirname(os.path.abspath(__file__))
+-    dist_dir = os.path.abspath(certifi_dist.egg_info)
++    dist_dir = os.path.abspath(certifi_egg_info)
+ 
+     # compare with samefile instead of string comparison to avoid false
+     # negatives caused by venv lib64 / lib symlinks
+@@ -65,17 +89,17 @@ def _patch_dist_info():
+     # double check versions
+     _verify_dist_info()
+ 
+-    return True, css_dist.egg_info, certifi_dist.egg_info
++    return True, css_egg_info, certifi_egg_info
+ 
+ 
+ def _verify_dist_info():
+-    css_dist = pkg_resources.get_distribution("certifi_system_store")
++    css_version, css_egg_info = _get_distinfo("certifi_system_store")
+     try:
+-        certifi_dist = pkg_resources.get_distribution("certifi")
+-    except pkg_resources.DistributionNotFound as e:
++        certifi_version, certifi_egg_info = _get_distinfo("certifi")
++    except PackageNotFoundError as e:
+         raise RuntimeError(e)
+     else:
+-        if certifi_dist.version != css_dist.version:
++        if certifi_version != css_version:
+             raise RuntimeError(
+                 f"'certifi.dist-info' is not an alias to "
+                 f"'certifi_system_store.dist-info'. "
+

Reply via email to