|
| 1 | +import errno |
1 | 2 | import functools |
2 | 3 | import json |
3 | 4 | import logging |
4 | 5 | import os |
| 6 | +import shutil |
| 7 | +from shutil import rmtree as _rmtree |
5 | 8 | import sys |
6 | 9 | import warnings |
7 | 10 | from pathlib import Path |
|
10 | 13 |
|
11 | 14 | import pytest |
12 | 15 | import requests |
13 | | - |
14 | 16 | from pipenv.utils.processes import subprocess_run |
15 | 17 | from pipenv.vendor import tomlkit |
16 | 18 | from pipenv.vendor.requirementslib.utils import temp_environ |
| 19 | +from pipenv.vendor.requirementslib.models.setup_info import handle_remove_readonly |
17 | 20 |
|
18 | 21 | log = logging.getLogger(__name__) |
19 | 22 | warnings.simplefilter("default", category=ResourceWarning) |
20 | 23 |
|
21 | 24 |
|
22 | 25 | HAS_WARNED_GITHUB = False |
23 | 26 |
|
24 | | -DEFAULT_PRIVATE_PYPI_SERVER = "http://localhost:8080/simple" |
25 | | - |
26 | 27 |
|
27 | 28 | def try_internet(url="http://httpbin.org/ip", timeout=1.5): |
28 | 29 | resp = requests.get(url, timeout=timeout) |
@@ -281,26 +282,48 @@ def lockfile_path(self): |
281 | 282 | return os.sep.join([self.path, 'Pipfile.lock']) |
282 | 283 |
|
283 | 284 |
|
| 285 | +# Windows python3.8 fails without this patch. Additional details: https://bugs.python.org/issue42796 |
| 286 | +def _rmtree_func(path, ignore_errors=True, onerror=None): |
| 287 | + shutil_rmtree = _rmtree |
| 288 | + if onerror is None: |
| 289 | + onerror = handle_remove_readonly |
| 290 | + try: |
| 291 | + shutil_rmtree(path, ignore_errors=ignore_errors, onerror=onerror) |
| 292 | + except (OSError, FileNotFoundError, PermissionError) as exc: |
| 293 | + # Ignore removal failures where the file doesn't exist |
| 294 | + if exc.errno != errno.ENOENT: |
| 295 | + raise |
| 296 | + |
284 | 297 | @pytest.fixture() |
285 | | -def pipenv_instance_pypi(capfdbinary): |
286 | | - with temp_environ(): |
| 298 | +def pipenv_instance_pypi(capfdbinary, monkeypatch): |
| 299 | + with temp_environ(), monkeypatch.context() as m: |
| 300 | + m.setattr(shutil, "rmtree", _rmtree_func) |
| 301 | + original_umask = os.umask(0o007) |
287 | 302 | os.environ["PIPENV_NOSPIN"] = "1" |
288 | 303 | os.environ["CI"] = "1" |
289 | 304 | os.environ["PIPENV_DONT_USE_PYENV"] = "1" |
290 | 305 | warnings.simplefilter("ignore", category=ResourceWarning) |
291 | 306 | warnings.filterwarnings("ignore", category=ResourceWarning, message="unclosed.*<ssl.SSLSocket.*>") |
292 | | - yield functools.partial(_PipenvInstance, capfd=capfdbinary, index_url="https://pypi.org/simple") |
| 307 | + try: |
| 308 | + yield functools.partial(_PipenvInstance, capfd=capfdbinary, index_url="https://pypi.org/simple") |
| 309 | + finally: |
| 310 | + os.umask(original_umask) |
293 | 311 |
|
294 | 312 |
|
295 | 313 | @pytest.fixture() |
296 | | -def pipenv_instance_private_pypi(capfdbinary): |
297 | | - with temp_environ(): |
| 314 | +def pipenv_instance_private_pypi(capfdbinary, monkeypatch): |
| 315 | + with temp_environ(), monkeypatch.context() as m: |
| 316 | + m.setattr(shutil, "rmtree", _rmtree_func) |
| 317 | + original_umask = os.umask(0o007) |
298 | 318 | os.environ["PIPENV_NOSPIN"] = "1" |
299 | 319 | os.environ["CI"] = "1" |
300 | 320 | os.environ["PIPENV_DONT_USE_PYENV"] = "1" |
301 | 321 | warnings.simplefilter("ignore", category=ResourceWarning) |
302 | 322 | warnings.filterwarnings("ignore", category=ResourceWarning, message="unclosed.*<ssl.SSLSocket.*>") |
303 | | - yield functools.partial(_PipenvInstance, capfd=capfdbinary, index_url="http://localhost:8080/simple") |
| 323 | + try: |
| 324 | + yield functools.partial(_PipenvInstance, capfd=capfdbinary, index_url="http://localhost:8080/simple") |
| 325 | + finally: |
| 326 | + os.umask(original_umask) |
304 | 327 |
|
305 | 328 |
|
306 | 329 | @pytest.fixture() |
|
0 commit comments