You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
python-virtualenv/dont-fail-on-missing-certif...

80 lines
2.7 KiB

diff --git a/tests/test_virtualenv.py b/tests/test_virtualenv.py
index ce45ede..3cd200b 100644
--- a/tests/test_virtualenv.py
+++ b/tests/test_virtualenv.py
@@ -4,11 +4,16 @@ import os
import shutil
import sys
import tempfile
+import zipfile
import pytest
import platform # noqa
from mock import patch, Mock
+try:
+ from pathlib import Path
+except ImportError:
+ from pathlib2 import Path
def test_version():
"""Should have a version string"""
@@ -139,3 +144,44 @@ def test_always_copy_option():
" symlink (to %s)" % (full_name, os.readlink(full_name))
finally:
shutil.rmtree(tmp_virtualenv)
+
+
+def test_missing_certifi_pem(tmp_path):
+ """Make sure that we can still create virtual environment if pip is
+ patched to not use certifi's cacert.pem and the file is removed.
+ This can happen if pip is packaged by Linux distributions."""
+ proj_dir = Path(__file__).parent.parent
+ support_original = proj_dir / "virtualenv_support"
+ pip_wheel = sorted(support_original.glob("pip*whl"))[0]
+ whl_name = pip_wheel.name
+
+ wheeldir = tmp_path / "wheels"
+ wheeldir.mkdir()
+ tmpcert = tmp_path / "tmpcert.pem"
+ cacert = "pip/_vendor/certifi/cacert.pem"
+ certifi = "pip/_vendor/certifi/core.py"
+ oldpath = b"os.path.join(f, 'cacert.pem')"
+ newpath = "r'{}'".format(tmpcert).encode()
+ removed = False
+ replaced = False
+
+ with zipfile.ZipFile(str(pip_wheel), "r") as whlin:
+ with zipfile.ZipFile(str(wheeldir / whl_name), "w") as whlout:
+ for item in whlin.infolist():
+ buff = whlin.read(item.filename)
+ if item.filename == cacert:
+ tmpcert.write_bytes(buff)
+ removed = True
+ continue
+ if item.filename == certifi:
+ nbuff = buff.replace(oldpath, newpath)
+ assert nbuff != buff
+ buff = nbuff
+ replaced = True
+ whlout.writestr(item, buff)
+
+ assert removed and replaced
+
+ venvdir = tmp_path / "venv"
+ search_dirs = [str(wheeldir), str(support_original)]
+ virtualenv.create_environment(str(venvdir), search_dirs=search_dirs)
diff --git a/virtualenv.py b/virtualenv.py
index c1fe7f1..3837250 100755
--- a/virtualenv.py
+++ b/virtualenv.py
@@ -867,6 +867,8 @@ def install_wheel(project_names, py_executable, search_dirs=None,
except ImportError:
from pip import main as _main
cert_data = pkgutil.get_data("pip._vendor.requests", "cacert.pem")
+ except IOError:
+ cert_data = None
if cert_data is not None:
cert_file = tempfile.NamedTemporaryFile(delete=False)