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 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 --- 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 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'. "