mirror of
https://github.com/kennethreitz/pipenv.git
synced 2026-06-05 06:46:15 +00:00
Convert test runner to use pypiserver package as standalone process (#5284)
* Check point progress on moving tests to pypiserver. * Allow other indexes to mimic the pypi json API for package hashes. * Fix these tests that run on lower python versions only. * Try adding the pypiserver to the github actions to only run once. * Expand the scope of fixtures for pypiserver. * try to accomedate microsoft runner. * Windows networking troubles. * Remove running as a background job. * Try to condtionally invoke different start pypi-server commands * Try to condtionally invoke different start pypi-server commands * Try to condtionally invoke different start pypi-server commands * Try to condtionally invoke different start pypi-server commands * Try to condtionally invoke different start pypi-server commands * Try to condtionally invoke different start pypi-server commands * Try to condtionally invoke different start pypi-server commands * Try to introduce pypi as the root index because setuptools-scm is not in our pypi artifacts. * see if the windows tests run faster (and the other tests) by supplying waitress. * Only use waitress on windows because the others are fast on the default. Fix requests pollution. * Supply a suitable Pipfile instead for these two failing tests. * More requests resolver cross test contamination cleanup. * remove problematic tests because even on my version of python 3.8.12 this does not work due to AttributeError: 'HTMLParser' object has no attribute 'unescape' * fix mirror install test. * Fix Pipfile. * Fix Pipfile for real * Fix tests * Cleanup test naming and more test enhancements. * Save this optimization for a subsequent PR. * Cleanup the TemporaryDirectory between tests. * resolve merge conflict. * Cleanup path initalization -- it hsould always be a TemporaryDirectory for tests that gets cleanedup. * Cleanup path initalization -- it hsould always be a TemporaryDirectory for tests that gets cleanedup. * tableflip on those requests tests that read the setup metadata in reqlib from other tests. * Update developer documentation for running tests. * add news fragment. * Try gunicorn perfoormance for linux/mac * Only use gunicorn on linux based on the results of last run.
This commit is contained in:
@@ -85,7 +85,7 @@ jobs:
|
||||
echo ::set-output name=path::$(python -c "import sys; print(sys.executable)")
|
||||
- name: Install latest pip, setuptools, wheel
|
||||
run: |
|
||||
python -m pip install --upgrade pip setuptools wheel --upgrade
|
||||
python -m pip install --upgrade pip setuptools wheel
|
||||
- name: Install dependencies
|
||||
env:
|
||||
PIPENV_DEFAULT_PYTHON_VERSION: ${{ matrix.python-version }}
|
||||
@@ -97,6 +97,18 @@ jobs:
|
||||
git submodule update --init --recursive
|
||||
python -m pip install -e . --upgrade
|
||||
pipenv install --deploy --dev --python=${{ steps.python-path.outputs.path }}
|
||||
- name: Run pypiserver Windows
|
||||
run: |
|
||||
cmd /c start pipenv run pypi-server run -v --host=0.0.0.0 --port=8080 --hash-algo=sha256 --disable-fallback ./tests/pypi/ ./tests/fixtures
|
||||
if: ${{matrix.os == 'Windows' }}
|
||||
- name: Run pypiserver Mac
|
||||
run: |
|
||||
pipenv run pypi-server run -v --host=0.0.0.0 --port=8080 --hash-algo=sha256 --disable-fallback ./tests/pypi/ ./tests/fixtures &
|
||||
if: ${{matrix.os == 'MacOS' }}
|
||||
- name: Run pypiserver Ubuntu
|
||||
run: |
|
||||
pipenv run pypi-server run -v --host=0.0.0.0 --port=8080 --hash-algo=sha256 --disable-fallback ./tests/pypi/ ./tests/fixtures &
|
||||
if: ${{matrix.os == 'Ubuntu' }}
|
||||
- name: Run tests
|
||||
env:
|
||||
PIPENV_DEFAULT_PYTHON_VERSION: ${{ matrix.python-version }}
|
||||
|
||||
@@ -5,12 +5,15 @@ sphinx-click = "==4.*"
|
||||
sphinxcontrib-spelling = "==7.*"
|
||||
click = "==8.0.3"
|
||||
pytest_pypi = {path = "./tests/pytest-pypi", editable = true}
|
||||
pypiserver = "==1.*"
|
||||
stdeb = {version="*", markers="sys_platform == 'linux'"}
|
||||
zipp = {version = "==3.6.0", markers = "python_version < '3.10'"}
|
||||
pre-commit = "==2.*"
|
||||
atomicwrites = {version = "*", markers="sys_platform == 'win32'"}
|
||||
pytest-cov = "==3.*"
|
||||
typing-extensions = "==4.*"
|
||||
waitress = {version = "*", markers="sys_platform == 'win32'"}
|
||||
gunicorn = {version = "*", markers="sys_platform == 'linux'"}
|
||||
|
||||
[packages]
|
||||
|
||||
|
||||
Generated
+27
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "ce738b1c6cdea3b2fd95ff118ad5434366f05803854bee86c4640d3cdfa4c141"
|
||||
"sha256": "732f0dc59c2417ea9c448ef70f1d642487fa85ca8a743caa583076d0a6ccf32d"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {},
|
||||
@@ -256,6 +256,14 @@
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==2.2.2"
|
||||
},
|
||||
"gunicorn": {
|
||||
"hashes": [
|
||||
"sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e",
|
||||
"sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8"
|
||||
],
|
||||
"markers": "sys_platform == 'linux'",
|
||||
"version": "==20.1.0"
|
||||
},
|
||||
"identify": {
|
||||
"hashes": [
|
||||
"sha256:25851c8c1370effb22aaa3c987b30449e9ff0cece408f810ae6ce408fdd20893",
|
||||
@@ -507,6 +515,14 @@
|
||||
"markers": "python_full_version >= '3.6.8'",
|
||||
"version": "==3.0.9"
|
||||
},
|
||||
"pypiserver": {
|
||||
"hashes": [
|
||||
"sha256:dc689cf5a7b2b3ea941766bbf48b7d85ad01e9babcf90e40897b6aae2ad9f98e",
|
||||
"sha256:fe2cbf08dfb8435767e9e8e2ea9aebf78f9382204c76d40f3bc79b45bb24f6eb"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.5.0"
|
||||
},
|
||||
"pytest": {
|
||||
"hashes": [
|
||||
"sha256:1377bda3466d70b55e3f5cecfa55bb7cfcf219c7964629b967c37cf0bda818b7",
|
||||
@@ -771,6 +787,15 @@
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==0.5.7"
|
||||
},
|
||||
"waitress": {
|
||||
"hashes": [
|
||||
"sha256:7500c9625927c8ec60f54377d590f67b30c8e70ef4b8894214ac6e4cad233d2a",
|
||||
"sha256:780a4082c5fbc0fde6a2fcfe5e26e6efc1e8f425730863c04085769781f51eba"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "sys_platform == 'win32'",
|
||||
"version": "==2.1.2"
|
||||
},
|
||||
"werkzeug": {
|
||||
"hashes": [
|
||||
"sha256:7ea2d48322cc7c0f8b3a215ed73eabd7b5d75d0b50e31ab006286ccff9e00b8f",
|
||||
@@ -784,6 +809,7 @@
|
||||
"sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832",
|
||||
"sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version < '3.10'",
|
||||
"version": "==3.6.0"
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ When contributing code, you'll want to follow this checklist:
|
||||
#. Make your change.
|
||||
#. Run the entire test suite again, confirming that all tests pass *including
|
||||
the ones you just added*.
|
||||
#. Send a GitHub Pull Request to the main repository's ``master`` branch.
|
||||
#. Send a GitHub Pull Request to the main repository's ``main`` branch.
|
||||
GitHub Pull Requests are the expected method of code collaboration on this
|
||||
project.
|
||||
|
||||
@@ -130,6 +130,18 @@ Tests are written in ``pytest`` style and can be run very simply:
|
||||
|
||||
pytest
|
||||
|
||||
However many tests depend on running a private pypi server on localhost:8080.
|
||||
This can be accomplished by using either the ``run-tests.sh`` or ``run-tests.bat`
|
||||
which will start the ``pypiserver`` process ahead of invoking pytest.
|
||||
|
||||
You may also manually perform this step and then invoke pytest as you would normally. Example::
|
||||
|
||||
# Linux or MacOS
|
||||
pipenv run pypi-server run -v --host=0.0.0.0 --port=8080 --hash-algo=sha256 --disable-fallback ./tests/pypi/ ./tests/fixtures &
|
||||
|
||||
# Windows
|
||||
cmd /c start pipenv run pypi-server run -v --host=0.0.0.0 --port=8080 --hash-algo=sha256 --disable-fallback ./tests/pypi/ ./tests/fixtures
|
||||
|
||||
|
||||
This will run all Pipenv tests, which can take awhile. To run a subset of the
|
||||
tests, the standard pytest filters are available, such as:
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
Convert the test runner to use ``pypiserver`` as a standalone process for all tests that referencce internal ``pypi`` artifacts.
|
||||
General refactoring of some test cases to create more variety in packages selected--preferring lighter weight packages--in existing test cases.
|
||||
+4
-13
@@ -1,15 +1,6 @@
|
||||
rem If you want to use a ramdisk, use this section:
|
||||
|
||||
rem imdisk -a -s 4G -m R: -p "FS:NTFS /y"
|
||||
rem if you are using a ram disk, you should comment the following substitution line out
|
||||
subst R: %TEMP%
|
||||
|
||||
set TMP=R:\\
|
||||
set TEMP=R:\\
|
||||
set WORKON_HOME=R:\\
|
||||
set RAM_DISK=R:\\
|
||||
|
||||
R:\.venv\Scripts\pip install -e .[test] --upgrade --upgrade-strategy=only-if-needed
|
||||
R:\.venv\Scripts\pipenv install --dev
|
||||
pip install -e .[test] --upgrade --upgrade-strategy=only-if-needed
|
||||
pipenv install --dev
|
||||
git submodule sync && git submodule update --init --recursive
|
||||
R:\.venv\Scripts\pipenv run pytest -n auto -v tests
|
||||
cmd /c start pipenv run pypi-server run -v --host=0.0.0.0 --port=8080 --hash-algo=sha256 --disable-fallback ./tests/pypi/ ./tests/fixtures
|
||||
pipenv run pytest -n auto -v tests
|
||||
|
||||
@@ -51,6 +51,10 @@ echo "$ git submodule sync && git submodule update --init --recursive"
|
||||
|
||||
git submodule sync && git submodule update --init --recursive
|
||||
|
||||
echo "pipenv run pypi-server run -v --host=0.0.0.0 --port=8080 --hash-algo=sha256 --disable-fallback ./tests/pypi/ ./tests/fixtures &"
|
||||
|
||||
pipenv run pypi-server run -v --host=0.0.0.0 --port=8080 --hash-algo=sha256 --disable-fallback ./tests/pypi/ ./tests/fixtures &
|
||||
|
||||
echo "$pipenv run pytest -v -ra -n auto --cov-config setup.cfg --fulltrace tests"
|
||||
|
||||
PIPENV_PYTHON=${PIPENV_PYTHON} ${PYTHON} -m pipenv run pytest -v -ra -n auto --cov-config setup.cfg --fulltrace tests
|
||||
|
||||
@@ -6,6 +6,7 @@ import os
|
||||
import shlex
|
||||
import shutil
|
||||
import traceback
|
||||
import threading
|
||||
import sys
|
||||
import warnings
|
||||
from pathlib import Path
|
||||
@@ -17,6 +18,7 @@ import requests
|
||||
from click.testing import CliRunner
|
||||
from pytest_pypi.app import prepare_fixtures
|
||||
from pytest_pypi.app import prepare_packages as prepare_pypi_packages
|
||||
import pypiserver
|
||||
|
||||
from pipenv.cli import cli
|
||||
from pipenv.exceptions import VirtualenvActivationException
|
||||
@@ -278,9 +280,9 @@ class _Pipfile:
|
||||
fixture_pypi = os.getenv("ARTIFACT_PYPI_URL")
|
||||
if fixture_pypi:
|
||||
if pkg and not filename:
|
||||
url = f"{fixture_pypi}/artifacts/{pkg}"
|
||||
url = f"{fixture_pypi}/{pkg}"
|
||||
else:
|
||||
url = f"{fixture_pypi}/artifacts/{pkg}/{filename}"
|
||||
url = f"{fixture_pypi}/{pkg}/{filename}"
|
||||
return url
|
||||
if pkg and not filename:
|
||||
return cls.get_fixture_path(file_path).as_uri()
|
||||
@@ -312,28 +314,16 @@ class _PipenvInstance:
|
||||
self.env.pop("PIPENV_VENV_IN_PROJECT", None)
|
||||
|
||||
self.original_dir = Path(__file__).parent.parent.parent
|
||||
path = path if path else os.environ.get("PIPENV_PROJECT_DIR", None)
|
||||
if name is not None:
|
||||
path = Path(os.environ["HOME"]) / "projects" / name
|
||||
path.mkdir(exist_ok=True)
|
||||
if not path:
|
||||
path = TemporaryDirectory(suffix='-project', prefix='pipenv-')
|
||||
if isinstance(path, TemporaryDirectory):
|
||||
self._path = path
|
||||
self._path = path = TemporaryDirectory(prefix='pipenv-', suffix='-project')
|
||||
path = Path(self._path.name)
|
||||
try:
|
||||
self.path = str(path.resolve())
|
||||
except OSError:
|
||||
self.path = str(path.absolute())
|
||||
elif isinstance(path, Path):
|
||||
self._path = path
|
||||
try:
|
||||
self.path = str(path.resolve())
|
||||
except OSError:
|
||||
self.path = str(path.absolute())
|
||||
else:
|
||||
self._path = path
|
||||
self.path = path
|
||||
|
||||
# set file creation perms
|
||||
self.pipfile_path = None
|
||||
self.chdir = chdir
|
||||
@@ -367,13 +357,14 @@ class _PipenvInstance:
|
||||
os.remove(self.pipfile_path)
|
||||
if self.chdir:
|
||||
os.chdir(self.original_dir)
|
||||
self.path = None
|
||||
if self._path and getattr(self._path, "cleanup", None):
|
||||
if self._path:
|
||||
try:
|
||||
self._path.cleanup()
|
||||
except OSError as e:
|
||||
_warn_msg = warn_msg.format(e)
|
||||
warnings.warn(_warn_msg, ResourceWarning)
|
||||
self.path = None
|
||||
self._path = None
|
||||
|
||||
def pipenv(self, cmd, block=True):
|
||||
if self.pipfile_path and os.path.isfile(self.pipfile_path):
|
||||
@@ -447,17 +438,17 @@ def pip_src_dir(request, vistir_tmpdir):
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def PipenvInstance(pip_src_dir, monkeypatch, pypi, capfdbinary):
|
||||
def pipenv_instance_pypi(pip_src_dir, monkeypatch, capfdbinary):
|
||||
with temp_environ(), monkeypatch.context() as m:
|
||||
m.setattr(shutil, "rmtree", _rmtree_func)
|
||||
original_umask = os.umask(0o007)
|
||||
m.setenv("PIPENV_NOSPIN", "1")
|
||||
m.setenv("CI", "1")
|
||||
m.setenv('PIPENV_DONT_USE_PYENV', '1')
|
||||
m.setenv("PIPENV_TEST_INDEX", f"{pypi.url}/simple")
|
||||
m.setenv("PIPENV_TEST_INDEX", "https://pypi.org/simple")
|
||||
m.setenv("PIPENV_PYPI_INDEX", "simple")
|
||||
m.setenv("ARTIFACT_PYPI_URL", pypi.url)
|
||||
m.setenv("PIPENV_PYPI_URL", pypi.url)
|
||||
m.setenv("ARTIFACT_PYPI_URL", "https://pypi.org/")
|
||||
m.setenv("PIPENV_PYPI_URL", "https://pypi.org/")
|
||||
warnings.simplefilter("ignore", category=ResourceWarning)
|
||||
warnings.filterwarnings("ignore", category=ResourceWarning, message="unclosed.*<ssl.SSLSocket.*>")
|
||||
try:
|
||||
@@ -467,15 +458,15 @@ def PipenvInstance(pip_src_dir, monkeypatch, pypi, capfdbinary):
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def PipenvInstance_NoPyPI(monkeypatch, pip_src_dir, pypi, capfdbinary):
|
||||
def pipenv_instance_private_pypi(monkeypatch, pip_src_dir, capfdbinary):
|
||||
with temp_environ(), monkeypatch.context() as m:
|
||||
m.setattr(shutil, "rmtree", _rmtree_func)
|
||||
original_umask = os.umask(0o007)
|
||||
m.setenv("PIPENV_NOSPIN", "1")
|
||||
m.setenv("CI", "1")
|
||||
m.setenv('PIPENV_DONT_USE_PYENV', '1')
|
||||
m.setenv("PIPENV_TEST_INDEX", f"{pypi.url}/simple")
|
||||
m.setenv("ARTIFACT_PYPI_URL", pypi.url)
|
||||
m.setenv("PIPENV_TEST_INDEX", "http://localhost:8080/simple")
|
||||
m.setenv("ARTIFACT_PYPI_URL", "http://localhost:8080/simple")
|
||||
warnings.simplefilter("ignore", category=ResourceWarning)
|
||||
warnings.filterwarnings("ignore", category=ResourceWarning, message="unclosed.*<ssl.SSLSocket.*>")
|
||||
try:
|
||||
|
||||
@@ -13,16 +13,16 @@ from pipenv.utils.shell import normalize_drive
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
def test_pipenv_where(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_pipenv_where(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi() as p:
|
||||
c = p.pipenv("--where")
|
||||
assert c.returncode == 0
|
||||
assert normalize_drive(p.path) in c.stdout
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
def test_pipenv_venv(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_pipenv_venv(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi() as p:
|
||||
c = p.pipenv('--python python')
|
||||
assert c.returncode == 0
|
||||
c = p.pipenv('--venv')
|
||||
@@ -32,8 +32,8 @@ def test_pipenv_venv(PipenvInstance):
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
def test_pipenv_py(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_pipenv_py(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi() as p:
|
||||
c = p.pipenv('--python python')
|
||||
assert c.returncode == 0
|
||||
c = p.pipenv('--py')
|
||||
@@ -43,8 +43,8 @@ def test_pipenv_py(PipenvInstance):
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
def test_pipenv_site_packages(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_pipenv_site_packages(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi() as p:
|
||||
c = p.pipenv('--python python --site-packages')
|
||||
assert c.returncode == 0
|
||||
assert 'Making site-packages available' in c.stderr
|
||||
@@ -57,16 +57,16 @@ def test_pipenv_site_packages(PipenvInstance):
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
def test_pipenv_support(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_pipenv_support(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi() as p:
|
||||
c = p.pipenv('--support')
|
||||
assert c.returncode == 0
|
||||
assert c.stdout
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
def test_pipenv_rm(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_pipenv_rm(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi() as p:
|
||||
c = p.pipenv('--python python')
|
||||
assert c.returncode == 0
|
||||
c = p.pipenv('--venv')
|
||||
@@ -81,8 +81,8 @@ def test_pipenv_rm(PipenvInstance):
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
def test_pipenv_graph(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_pipenv_graph(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi() as p:
|
||||
c = p.pipenv('install tablib')
|
||||
assert c.returncode == 0
|
||||
graph = p.pipenv("graph")
|
||||
@@ -97,8 +97,8 @@ def test_pipenv_graph(PipenvInstance):
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
def test_pipenv_graph_reverse(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_pipenv_graph_reverse(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
c = p.pipenv('install tablib==0.13.0')
|
||||
assert c.returncode == 0
|
||||
c = p.pipenv('graph --reverse')
|
||||
@@ -141,8 +141,8 @@ def test_pipenv_graph_reverse(PipenvInstance):
|
||||
@pytest.mark.cli
|
||||
@pytest.mark.needs_internet(reason='required by check')
|
||||
@flaky
|
||||
def test_pipenv_check(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_pipenv_check(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
c = p.pipenv('install pyyaml')
|
||||
assert c.returncode == 0
|
||||
c = p.pipenv('check')
|
||||
@@ -158,8 +158,8 @@ def test_pipenv_check(PipenvInstance):
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
def test_pipenv_clean_pip_no_warnings(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_pipenv_clean_pip_no_warnings(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
with open('setup.py', 'w') as f:
|
||||
f.write('from setuptools import setup; setup(name="empty")')
|
||||
c = p.pipenv('install -e .')
|
||||
@@ -172,8 +172,8 @@ def test_pipenv_clean_pip_no_warnings(PipenvInstance):
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
def test_pipenv_clean_pip_warnings(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_pipenv_clean_pip_warnings(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
with open('setup.py', 'w') as f:
|
||||
f.write('from setuptools import setup; setup(name="empty")')
|
||||
# create a fake git repo to trigger a pip freeze warning
|
||||
@@ -186,20 +186,20 @@ def test_pipenv_clean_pip_warnings(PipenvInstance):
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
def test_venv_envs(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_venv_envs(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi() as p:
|
||||
assert p.pipenv('--envs').stdout
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
def test_bare_output(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_bare_output(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi() as p:
|
||||
assert p.pipenv('').stdout
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
def test_scripts(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_scripts(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi() as p:
|
||||
with open(p.pipfile_path, "w") as f:
|
||||
contents = """
|
||||
[scripts]
|
||||
@@ -212,21 +212,21 @@ pyver = "which python"
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
def test_help(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_help(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi() as p:
|
||||
assert p.pipenv('--help').stdout
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
def test_man(PipenvInstance):
|
||||
with PipenvInstance():
|
||||
def test_man(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi():
|
||||
c = subprocess_run(["pipenv", "--man"])
|
||||
assert c.returncode == 0, c.stderr
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
def test_install_parse_error(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_install_parse_error(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
|
||||
# Make sure unparseable packages don't wind up in the pipfile
|
||||
# Escape $ for shell input
|
||||
@@ -243,24 +243,24 @@ def test_install_parse_error(PipenvInstance):
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
def test_pipenv_clear(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_pipenv_clear(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi() as p:
|
||||
c = p.pipenv('--clear')
|
||||
assert c.returncode == 0
|
||||
assert 'Clearing caches' in c.stdout
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
def test_pipenv_three(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_pipenv_three(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi() as p:
|
||||
c = p.pipenv('--three')
|
||||
assert c.returncode == 0
|
||||
assert 'Successfully created virtual environment' in c.stderr
|
||||
|
||||
|
||||
@pytest.mark.outdated
|
||||
def test_pipenv_outdated_prerelease(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_pipenv_outdated_prerelease(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
with open(p.pipfile_path, "w") as f:
|
||||
contents = """
|
||||
[packages]
|
||||
@@ -272,24 +272,24 @@ sqlalchemy = "<=1.2.3"
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
def test_pipenv_verify_without_pipfile(PipenvInstance):
|
||||
with PipenvInstance(pipfile=False) as p:
|
||||
def test_pipenv_verify_without_pipfile(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(pipfile=False) as p:
|
||||
c = p.pipenv('verify')
|
||||
assert c.returncode == 1
|
||||
assert 'No Pipfile present at project home.' in c.stderr
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
def test_pipenv_verify_without_pipfile_lock(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_pipenv_verify_without_pipfile_lock(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi() as p:
|
||||
c = p.pipenv('verify')
|
||||
assert c.returncode == 1
|
||||
assert 'Pipfile.lock is out-of-date.' in c.stderr
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
def test_pipenv_verify_locked_passing(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_pipenv_verify_locked_passing(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi() as p:
|
||||
p.pipenv('lock')
|
||||
c = p.pipenv('verify')
|
||||
assert c.returncode == 0
|
||||
@@ -297,8 +297,8 @@ def test_pipenv_verify_locked_passing(PipenvInstance):
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
def test_pipenv_verify_locked_outdated_failing(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_pipenv_verify_locked_outdated_failing(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
p.pipenv('lock')
|
||||
|
||||
# modify the Pipfile
|
||||
|
||||
@@ -13,22 +13,22 @@ from pipenv.utils.shell import normalize_drive, temp_environ
|
||||
|
||||
@pytest.mark.dotvenv
|
||||
@pytest.mark.parametrize("true_value", TRUE_VALUES)
|
||||
def test_venv_in_project(true_value, PipenvInstance):
|
||||
def test_venv_in_project(true_value, pipenv_instance_pypi):
|
||||
with temp_environ():
|
||||
os.environ['PIPENV_VENV_IN_PROJECT'] = true_value
|
||||
with PipenvInstance() as p:
|
||||
c = p.pipenv('install requests')
|
||||
with pipenv_instance_pypi() as p:
|
||||
c = p.pipenv('install dataclasses-json')
|
||||
assert c.returncode == 0
|
||||
assert normalize_drive(p.path) in p.pipenv('--venv').stdout
|
||||
|
||||
|
||||
@pytest.mark.dotvenv
|
||||
@pytest.mark.parametrize("false_value", FALSE_VALUES)
|
||||
def test_venv_in_project_disabled_ignores_venv(false_value, PipenvInstance):
|
||||
def test_venv_in_project_disabled_ignores_venv(false_value, pipenv_instance_pypi):
|
||||
venv_name = "my_project"
|
||||
with temp_environ():
|
||||
os.environ['PIPENV_VENV_IN_PROJECT'] = false_value
|
||||
with PipenvInstance() as p:
|
||||
with pipenv_instance_pypi() as p:
|
||||
file_path = os.path.join(p.path, '.venv')
|
||||
with open(file_path, 'w') as f:
|
||||
f.write(venv_name)
|
||||
@@ -37,7 +37,7 @@ def test_venv_in_project_disabled_ignores_venv(false_value, PipenvInstance):
|
||||
prefix='pipenv-', suffix='temp_workon_home'
|
||||
) as workon_home:
|
||||
os.environ['WORKON_HOME'] = workon_home
|
||||
c = p.pipenv('install requests')
|
||||
c = p.pipenv('install dataclasses-json')
|
||||
assert c.returncode == 0
|
||||
c = p.pipenv('--venv')
|
||||
assert c.returncode == 0
|
||||
@@ -51,9 +51,9 @@ def test_venv_in_project_disabled_ignores_venv(false_value, PipenvInstance):
|
||||
|
||||
@pytest.mark.dotvenv
|
||||
@pytest.mark.parametrize("true_value", TRUE_VALUES)
|
||||
def test_venv_at_project_root(true_value, PipenvInstance):
|
||||
def test_venv_at_project_root(true_value, pipenv_instance_pypi):
|
||||
with temp_environ():
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
os.environ['PIPENV_VENV_IN_PROJECT'] = true_value
|
||||
c = p.pipenv('install')
|
||||
assert c.returncode == 0
|
||||
@@ -66,21 +66,21 @@ def test_venv_at_project_root(true_value, PipenvInstance):
|
||||
|
||||
|
||||
@pytest.mark.dotvenv
|
||||
def test_reuse_previous_venv(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_reuse_previous_venv(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
os.mkdir('.venv')
|
||||
c = p.pipenv('install requests')
|
||||
c = p.pipenv('install dataclasses-json')
|
||||
assert c.returncode == 0
|
||||
assert normalize_drive(p.path) in p.pipenv('--venv').stdout
|
||||
|
||||
|
||||
@pytest.mark.dotvenv
|
||||
@pytest.mark.parametrize('venv_name', ('test-venv', os.path.join('foo', 'test-venv')))
|
||||
def test_venv_file(venv_name, PipenvInstance):
|
||||
def test_venv_file(venv_name, pipenv_instance_pypi):
|
||||
"""Tests virtualenv creation when a .venv file exists at the project root
|
||||
and contains a venv name.
|
||||
"""
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
file_path = os.path.join(p.path, '.venv')
|
||||
with open(file_path, 'w') as f:
|
||||
f.write(venv_name)
|
||||
@@ -109,10 +109,10 @@ def test_venv_file(venv_name, PipenvInstance):
|
||||
|
||||
|
||||
@pytest.mark.dotvenv
|
||||
def test_empty_venv_file(PipenvInstance):
|
||||
def test_empty_venv_file(pipenv_instance_pypi):
|
||||
"""Tests virtualenv creation when an empty .venv file exists at the project root
|
||||
"""
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
file_path = os.path.join(p.path, '.venv')
|
||||
with open(file_path, 'w'):
|
||||
pass
|
||||
@@ -139,10 +139,10 @@ def test_empty_venv_file(PipenvInstance):
|
||||
|
||||
|
||||
@pytest.mark.dotvenv
|
||||
def test_venv_in_project_default_when_venv_exists(PipenvInstance):
|
||||
def test_venv_in_project_default_when_venv_exists(pipenv_instance_pypi):
|
||||
"""Tests virtualenv creation when a .venv file exists at the project root.
|
||||
"""
|
||||
with temp_environ(), PipenvInstance(chdir=True) as p:
|
||||
with temp_environ(), pipenv_instance_pypi(chdir=True) as p:
|
||||
with TemporaryDirectory(
|
||||
prefix='pipenv-', suffix='-test_venv'
|
||||
) as venv_path:
|
||||
@@ -164,10 +164,10 @@ def test_venv_in_project_default_when_venv_exists(PipenvInstance):
|
||||
|
||||
|
||||
@pytest.mark.dotenv
|
||||
def test_venv_name_accepts_custom_name_environment_variable(PipenvInstance):
|
||||
def test_venv_name_accepts_custom_name_environment_variable(pipenv_instance_pypi):
|
||||
"""Tests that virtualenv reads PIPENV_CUSTOM_VENV_NAME and accepts it as a name
|
||||
"""
|
||||
with PipenvInstance(chdir=True, venv_in_project=False) as p:
|
||||
with pipenv_instance_pypi(chdir=True, venv_in_project=False) as p:
|
||||
test_name = "sensible_custom_venv_name"
|
||||
with temp_environ():
|
||||
os.environ['PIPENV_CUSTOM_VENV_NAME'] = test_name
|
||||
|
||||
@@ -11,8 +11,8 @@ from pipenv.project import Project
|
||||
@pytest.mark.cli
|
||||
@pytest.mark.deploy
|
||||
@pytest.mark.system
|
||||
def test_auth_with_pw_redacted(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_auth_with_pw_redacted(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
p.pipenv("run shell")
|
||||
project = Project()
|
||||
requirements_file = tempfile.NamedTemporaryFile(mode="w+", delete=False)
|
||||
@@ -26,8 +26,8 @@ def test_auth_with_pw_redacted(PipenvInstance):
|
||||
@pytest.mark.cli
|
||||
@pytest.mark.deploy
|
||||
@pytest.mark.system
|
||||
def test_auth_with_username_redacted(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_auth_with_username_redacted(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
p.pipenv("run shell")
|
||||
project = Project()
|
||||
requirements_file = tempfile.NamedTemporaryFile(mode="w+", delete=False)
|
||||
@@ -41,8 +41,8 @@ def test_auth_with_username_redacted(PipenvInstance):
|
||||
@pytest.mark.cli
|
||||
@pytest.mark.deploy
|
||||
@pytest.mark.system
|
||||
def test_auth_with_pw_are_variables_passed_to_pipfile(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_auth_with_pw_are_variables_passed_to_pipfile(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
p.pipenv("run shell")
|
||||
project = Project()
|
||||
requirements_file = tempfile.NamedTemporaryFile(mode="w+", delete=False)
|
||||
@@ -55,8 +55,8 @@ def test_auth_with_pw_are_variables_passed_to_pipfile(PipenvInstance):
|
||||
@pytest.mark.cli
|
||||
@pytest.mark.deploy
|
||||
@pytest.mark.system
|
||||
def test_auth_with_only_username_variable_passed_to_pipfile(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_auth_with_only_username_variable_passed_to_pipfile(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
p.pipenv("run shell")
|
||||
project = Project()
|
||||
requirements_file = tempfile.NamedTemporaryFile(mode="w+", delete=False)
|
||||
|
||||
@@ -15,9 +15,9 @@ from pipenv.utils.shell import temp_environ
|
||||
@pytest.mark.setup
|
||||
@pytest.mark.basic
|
||||
@pytest.mark.install
|
||||
def test_basic_setup(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
with PipenvInstance(pipfile=False) as p:
|
||||
def test_basic_setup(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
with pipenv_instance_private_pypi(pipfile=False) as p:
|
||||
c = p.pipenv("install requests")
|
||||
assert c.returncode == 0
|
||||
|
||||
@@ -32,8 +32,8 @@ def test_basic_setup(PipenvInstance):
|
||||
@flaky
|
||||
@pytest.mark.basic
|
||||
@pytest.mark.install
|
||||
def test_basic_install(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_basic_install(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
c = p.pipenv("install requests")
|
||||
assert c.returncode == 0
|
||||
assert "requests" in p.pipfile["packages"]
|
||||
@@ -47,15 +47,13 @@ def test_basic_install(PipenvInstance):
|
||||
@flaky
|
||||
@pytest.mark.basic
|
||||
@pytest.mark.install
|
||||
def test_mirror_install(PipenvInstance):
|
||||
with temp_environ(), PipenvInstance(chdir=True) as p:
|
||||
mirror_url = os.environ.pop(
|
||||
"PIPENV_TEST_INDEX", "https://pypi.python.org/simple"
|
||||
)
|
||||
def test_mirror_install(pipenv_instance_pypi):
|
||||
with temp_environ(), pipenv_instance_pypi(chdir=True) as p:
|
||||
mirror_url = "https://pypi.python.org/simple"
|
||||
assert "pypi.org" not in mirror_url
|
||||
# This should sufficiently demonstrate the mirror functionality
|
||||
# since pypi.org is the default when PIPENV_TEST_INDEX is unset.
|
||||
c = p.pipenv(f"install requests --pypi-mirror {mirror_url}")
|
||||
c = p.pipenv(f"install dataclasses-json --pypi-mirror {mirror_url}")
|
||||
assert c.returncode == 0
|
||||
# Ensure the --pypi-mirror parameter hasn't altered the Pipfile or Pipfile.lock sources
|
||||
assert len(p.pipfile["source"]) == 1
|
||||
@@ -63,41 +61,33 @@ def test_mirror_install(PipenvInstance):
|
||||
assert "https://pypi.org/simple" == p.pipfile["source"][0]["url"]
|
||||
assert "https://pypi.org/simple" == p.lockfile["_meta"]["sources"][0]["url"]
|
||||
|
||||
assert "requests" in p.pipfile["packages"]
|
||||
assert "requests" in p.lockfile["default"]
|
||||
assert "chardet" in p.lockfile["default"]
|
||||
assert "idna" in p.lockfile["default"]
|
||||
assert "urllib3" in p.lockfile["default"]
|
||||
assert "certifi" in p.lockfile["default"]
|
||||
assert "dataclasses-json" in p.pipfile["packages"]
|
||||
assert "dataclasses-json" in p.lockfile["default"]
|
||||
|
||||
|
||||
@flaky
|
||||
@pytest.mark.basic
|
||||
@pytest.mark.install
|
||||
@pytest.mark.needs_internet
|
||||
def test_bad_mirror_install(PipenvInstance):
|
||||
with temp_environ(), PipenvInstance(chdir=True) as p:
|
||||
def test_bad_mirror_install(pipenv_instance_pypi):
|
||||
with temp_environ(), pipenv_instance_pypi(chdir=True) as p:
|
||||
# This demonstrates that the mirror parameter is being used
|
||||
os.environ.pop("PIPENV_TEST_INDEX", None)
|
||||
c = p.pipenv("install requests --pypi-mirror https://pypi.example.org")
|
||||
c = p.pipenv("install dataclasses-json --pypi-mirror https://pypi.example.org")
|
||||
assert c.returncode != 0
|
||||
|
||||
|
||||
@flaky
|
||||
@pytest.mark.dev
|
||||
@pytest.mark.run
|
||||
def test_basic_dev_install(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
c = p.pipenv("install requests --dev")
|
||||
def test_basic_dev_install(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi() as p:
|
||||
c = p.pipenv("install dataclasses-json --dev")
|
||||
assert c.returncode == 0
|
||||
assert "requests" in p.pipfile["dev-packages"]
|
||||
assert "requests" in p.lockfile["develop"]
|
||||
assert "chardet" in p.lockfile["develop"]
|
||||
assert "idna" in p.lockfile["develop"]
|
||||
assert "urllib3" in p.lockfile["develop"]
|
||||
assert "certifi" in p.lockfile["develop"]
|
||||
assert "dataclasses-json" in p.pipfile["dev-packages"]
|
||||
assert "dataclasses-json" in p.lockfile["develop"]
|
||||
|
||||
c = p.pipenv("run python -m requests.help")
|
||||
c = p.pipenv("run python -c 'from dataclasses_json import dataclass_json'")
|
||||
assert c.returncode == 0
|
||||
|
||||
|
||||
@@ -105,9 +95,9 @@ def test_basic_dev_install(PipenvInstance):
|
||||
@pytest.mark.dev
|
||||
@pytest.mark.basic
|
||||
@pytest.mark.install
|
||||
def test_install_without_dev(PipenvInstance):
|
||||
def test_install_without_dev(pipenv_instance_private_pypi):
|
||||
"""Ensure that running `pipenv install` doesn't install dev packages"""
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_private_pypi(chdir=True) as p:
|
||||
with open(p.pipfile_path, "w") as f:
|
||||
contents = """
|
||||
[packages]
|
||||
@@ -132,8 +122,8 @@ tablib = "*"
|
||||
@flaky
|
||||
@pytest.mark.basic
|
||||
@pytest.mark.install
|
||||
def test_install_without_dev_section(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_install_without_dev_section(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi() as p:
|
||||
with open(p.pipfile_path, "w") as f:
|
||||
contents = """
|
||||
[packages]
|
||||
@@ -154,8 +144,8 @@ six = "*"
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.extras
|
||||
@pytest.mark.install
|
||||
def test_extras_install(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_extras_install(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi(chdir=True) as p:
|
||||
c = p.pipenv("install requests[socks]")
|
||||
assert c.returncode == 0
|
||||
assert "requests" in p.pipfile["packages"]
|
||||
@@ -172,18 +162,18 @@ def test_extras_install(PipenvInstance):
|
||||
@pytest.mark.pin
|
||||
@pytest.mark.basic
|
||||
@pytest.mark.install
|
||||
def test_windows_pinned_pipfile(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_pinned_pipfile(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi() as p:
|
||||
with open(p.pipfile_path, "w") as f:
|
||||
contents = """
|
||||
[packages]
|
||||
requests = "==2.19.1"
|
||||
dataclasses-json = "==0.5.7"
|
||||
""".strip()
|
||||
f.write(contents)
|
||||
c = p.pipenv("install")
|
||||
assert c.returncode == 0
|
||||
assert "requests" in p.pipfile["packages"]
|
||||
assert "requests" in p.lockfile["default"]
|
||||
assert "dataclasses-json" in p.pipfile["packages"]
|
||||
assert "dataclasses-json" in p.lockfile["default"]
|
||||
|
||||
|
||||
@flaky
|
||||
@@ -191,8 +181,8 @@ requests = "==2.19.1"
|
||||
@pytest.mark.install
|
||||
@pytest.mark.resolver
|
||||
@pytest.mark.backup_resolver
|
||||
def test_backup_resolver(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_backup_resolver(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
with open(p.pipfile_path, "w") as f:
|
||||
contents = """
|
||||
[packages]
|
||||
@@ -208,8 +198,8 @@ def test_backup_resolver(PipenvInstance):
|
||||
@flaky
|
||||
@pytest.mark.run
|
||||
@pytest.mark.alt
|
||||
def test_alternative_version_specifier(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_alternative_version_specifier(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
with open(p.pipfile_path, "w") as f:
|
||||
contents = """
|
||||
[packages]
|
||||
@@ -233,8 +223,8 @@ requests = {version = "*"}
|
||||
@flaky
|
||||
@pytest.mark.run
|
||||
@pytest.mark.alt
|
||||
def test_outline_table_specifier(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_outline_table_specifier(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
with open(p.pipfile_path, "w") as f:
|
||||
contents = """
|
||||
[packages.requests]
|
||||
@@ -258,8 +248,8 @@ version = "*"
|
||||
@pytest.mark.bad
|
||||
@pytest.mark.basic
|
||||
@pytest.mark.install
|
||||
def test_bad_packages(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_bad_packages(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
c = p.pipenv("install NotAPackage")
|
||||
assert c.returncode > 0
|
||||
|
||||
@@ -268,20 +258,20 @@ def test_bad_packages(PipenvInstance):
|
||||
@pytest.mark.extras
|
||||
@pytest.mark.install
|
||||
@pytest.mark.requirements
|
||||
def test_requirements_to_pipfile(PipenvInstance, pypi):
|
||||
def test_requirements_to_pipfile(pipenv_instance_private_pypi):
|
||||
|
||||
with PipenvInstance(pipfile=False, chdir=True) as p:
|
||||
with pipenv_instance_private_pypi(pipfile=False, chdir=True) as p:
|
||||
|
||||
# Write a requirements file
|
||||
with open("requirements.txt", "w") as f:
|
||||
f.write(
|
||||
f"-i {pypi.url}\n"
|
||||
"# -i https://private.pypi.org/simple\n"
|
||||
f"-i {os.environ['PIPENV_TEST_INDEX']}\n"
|
||||
"requests[socks]==2.19.1\n"
|
||||
)
|
||||
|
||||
c = p.pipenv("install")
|
||||
assert c.returncode == 0
|
||||
os.unlink("requirements.txt")
|
||||
print(c.stdout)
|
||||
print(c.stderr)
|
||||
# assert stuff in pipfile
|
||||
@@ -302,13 +292,13 @@ def test_requirements_to_pipfile(PipenvInstance, pypi):
|
||||
@pytest.mark.basic
|
||||
@pytest.mark.install
|
||||
@pytest.mark.requirements
|
||||
def test_skip_requirements_when_pipfile(PipenvInstance):
|
||||
def test_skip_requirements_when_pipfile(pipenv_instance_private_pypi):
|
||||
"""Ensure requirements.txt is NOT imported when
|
||||
|
||||
1. We do `pipenv install [package]`
|
||||
2. A Pipfile already exists when we run `pipenv install`.
|
||||
"""
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_private_pypi(chdir=True) as p:
|
||||
with open("requirements.txt", "w") as f:
|
||||
f.write("requests==2.18.1\n")
|
||||
c = p.pipenv("install six")
|
||||
@@ -329,19 +319,18 @@ six = "*"
|
||||
|
||||
@pytest.mark.cli
|
||||
@pytest.mark.clean
|
||||
def test_clean_on_empty_venv(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_clean_on_empty_venv(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi() as p:
|
||||
c = p.pipenv("clean")
|
||||
assert c.returncode == 0
|
||||
|
||||
|
||||
@pytest.mark.basic
|
||||
@pytest.mark.install
|
||||
def test_install_does_not_extrapolate_environ(PipenvInstance):
|
||||
def test_install_does_not_extrapolate_environ(pipenv_instance_pypi):
|
||||
"""Ensure environment variables are not expanded in lock file.
|
||||
"""
|
||||
with temp_environ(), PipenvInstance(chdir=True) as p:
|
||||
# os.environ["PYPI_URL"] = pypi.url
|
||||
with temp_environ(), pipenv_instance_pypi(chdir=True) as p:
|
||||
os.environ["PYPI_URL"] = p.pypi
|
||||
|
||||
with open(p.pipfile_path, "w") as f:
|
||||
@@ -371,8 +360,8 @@ name = 'mockpi'
|
||||
@pytest.mark.editable
|
||||
@pytest.mark.badparameter
|
||||
@pytest.mark.install
|
||||
def test_editable_no_args(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_editable_no_args(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi() as p:
|
||||
c = p.pipenv("install -e")
|
||||
assert c.returncode != 0
|
||||
assert "Error: Option '-e' requires an argument" in c.stderr
|
||||
@@ -381,10 +370,10 @@ def test_editable_no_args(PipenvInstance):
|
||||
@pytest.mark.basic
|
||||
@pytest.mark.install
|
||||
@pytest.mark.virtualenv
|
||||
def test_install_venv_project_directory(PipenvInstance):
|
||||
def test_install_venv_project_directory(pipenv_instance_pypi):
|
||||
"""Test the project functionality during virtualenv creation.
|
||||
"""
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
with temp_environ(), TemporaryDirectory(
|
||||
prefix="pipenv-", suffix="temp_workon_home"
|
||||
) as workon_home:
|
||||
@@ -404,8 +393,8 @@ def test_install_venv_project_directory(PipenvInstance):
|
||||
@pytest.mark.cli
|
||||
@pytest.mark.deploy
|
||||
@pytest.mark.system
|
||||
def test_system_and_deploy_work(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_system_and_deploy_work(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi(chdir=True) as p:
|
||||
c = p.pipenv("install tablib")
|
||||
assert c.returncode == 0
|
||||
c = p.pipenv("--rm")
|
||||
@@ -428,8 +417,8 @@ tablib = "*"
|
||||
|
||||
@pytest.mark.basic
|
||||
@pytest.mark.install
|
||||
def test_install_creates_pipfile(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_install_creates_pipfile(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
if os.path.isfile(p.pipfile_path):
|
||||
os.unlink(p.pipfile_path)
|
||||
if "PIPENV_PIPFILE" in os.environ:
|
||||
@@ -442,8 +431,8 @@ def test_install_creates_pipfile(PipenvInstance):
|
||||
|
||||
@pytest.mark.basic
|
||||
@pytest.mark.install
|
||||
def test_install_non_exist_dep(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_install_non_exist_dep(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
c = p.pipenv("install dateutil")
|
||||
assert c.returncode
|
||||
assert "dateutil" not in p.pipfile["packages"]
|
||||
@@ -451,8 +440,8 @@ def test_install_non_exist_dep(PipenvInstance):
|
||||
|
||||
@pytest.mark.basic
|
||||
@pytest.mark.install
|
||||
def test_install_package_with_dots(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_install_package_with_dots(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi(chdir=True) as p:
|
||||
c = p.pipenv("install backports.html")
|
||||
assert c.returncode == 0
|
||||
assert "backports.html" in p.pipfile["packages"]
|
||||
@@ -460,8 +449,8 @@ def test_install_package_with_dots(PipenvInstance):
|
||||
|
||||
@pytest.mark.basic
|
||||
@pytest.mark.install
|
||||
def test_rewrite_outline_table(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_rewrite_outline_table(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi(chdir=True) as p:
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
contents = """
|
||||
[packages]
|
||||
@@ -487,9 +476,9 @@ extras = ["socks"]
|
||||
@pytest.mark.basic
|
||||
@pytest.mark.install
|
||||
@pytest.mark.needs_internet
|
||||
def test_install_with_unnamed_source(PipenvInstance):
|
||||
def test_install_with_unnamed_source(pipenv_instance_pypi):
|
||||
"""Ensure that running `pipenv install` doesn't break with an unamed index"""
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
with open(p.pipfile_path, "w") as f:
|
||||
contents = """
|
||||
[[source]]
|
||||
@@ -502,18 +491,19 @@ url = "https://pypi.org/simple"
|
||||
verify_ssl = true
|
||||
|
||||
[packages]
|
||||
requests = {version="*", index="pypi"}
|
||||
dataclasses-json = {version="*", index="pypi"}
|
||||
""".strip()
|
||||
f.write(contents)
|
||||
c = p.pipenv("install")
|
||||
assert c.returncode == 0
|
||||
|
||||
|
||||
@pytest.mark.dev
|
||||
@pytest.mark.install
|
||||
def test_install_dev_use_default_constraints(PipenvInstance):
|
||||
def test_install_dev_use_default_constraints(pipenv_instance_private_pypi):
|
||||
# See https://github.com/pypa/pipenv/issues/4371
|
||||
# See https://github.com/pypa/pipenv/issues/2987
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_private_pypi(chdir=True) as p:
|
||||
|
||||
c = p.pipenv("install requests==2.14.0")
|
||||
assert c.returncode == 0
|
||||
@@ -538,9 +528,9 @@ def test_install_dev_use_default_constraints(PipenvInstance):
|
||||
@pytest.mark.basic
|
||||
@pytest.mark.install
|
||||
@pytest.mark.needs_internet
|
||||
def test_install_does_not_exclude_packaging(PipenvInstance):
|
||||
def test_install_does_not_exclude_packaging(pipenv_instance_pypi):
|
||||
"""Ensure that running `pipenv install` doesn't exclude packaging when its required. """
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
c = p.pipenv("install dataclasses-json")
|
||||
assert c.returncode == 0
|
||||
c = p.pipenv("run python -c 'from dataclasses_json import DataClassJsonMixin'")
|
||||
@@ -550,8 +540,8 @@ def test_install_does_not_exclude_packaging(PipenvInstance):
|
||||
@pytest.mark.basic
|
||||
@pytest.mark.install
|
||||
@pytest.mark.needs_internet
|
||||
def test_install_will_supply_extra_pip_args(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_install_will_supply_extra_pip_args(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
c = p.pipenv("""install dataclasses-json --extra-pip-args=""--use-feature=truststore --proxy=test""")
|
||||
assert c.returncode == 1
|
||||
assert "truststore feature" in c.stderr
|
||||
@@ -560,9 +550,9 @@ def test_install_will_supply_extra_pip_args(PipenvInstance):
|
||||
@pytest.mark.basic
|
||||
@pytest.mark.install
|
||||
@pytest.mark.needs_internet
|
||||
def test_install_tarball_is_actually_installed(PipenvInstance):
|
||||
def test_install_tarball_is_actually_installed(pipenv_instance_pypi):
|
||||
""" Test case for Issue 5326"""
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
with open(p.pipfile_path, "w") as f:
|
||||
contents = """
|
||||
[[source]]
|
||||
|
||||
@@ -11,9 +11,9 @@ from pipenv.utils.shell import temp_environ
|
||||
|
||||
@flaky
|
||||
@pytest.mark.markers
|
||||
def test_package_environment_markers(PipenvInstance):
|
||||
def test_package_environment_markers(pipenv_instance_pypi):
|
||||
|
||||
with PipenvInstance() as p:
|
||||
with pipenv_instance_pypi() as p:
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
contents = """
|
||||
[packages]
|
||||
@@ -31,11 +31,11 @@ fake_package = {version = "*", markers="os_name=='splashwear'"}
|
||||
|
||||
@flaky
|
||||
@pytest.mark.markers
|
||||
def test_platform_python_implementation_marker(PipenvInstance):
|
||||
def test_platform_python_implementation_marker(pipenv_instance_private_pypi):
|
||||
"""Markers should be converted during locking to help users who input this
|
||||
incorrectly.
|
||||
"""
|
||||
with PipenvInstance() as p:
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
c = p.pipenv('install depends-on-marked-package')
|
||||
assert c.returncode == 0
|
||||
|
||||
@@ -51,30 +51,30 @@ def test_platform_python_implementation_marker(PipenvInstance):
|
||||
@pytest.mark.alt
|
||||
@pytest.mark.markers
|
||||
@pytest.mark.install
|
||||
def test_specific_package_environment_markers(PipenvInstance):
|
||||
def test_specific_package_environment_markers(pipenv_instance_pypi):
|
||||
|
||||
with PipenvInstance() as p:
|
||||
with pipenv_instance_pypi() as p:
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
contents = """
|
||||
[packages]
|
||||
fake-package = {version = "*", os_name = "== 'splashwear'"}
|
||||
six = {version = "*", os_name = "== 'splashwear'"}
|
||||
""".strip()
|
||||
f.write(contents)
|
||||
|
||||
c = p.pipenv('install')
|
||||
assert c.returncode == 0
|
||||
assert 'markers' in p.lockfile['default']['fake-package']
|
||||
assert 'markers' in p.lockfile['default']['six']
|
||||
|
||||
c = p.pipenv('run python -c "import fake_package;"')
|
||||
c = p.pipenv('run python -c "import six;"')
|
||||
assert c.returncode == 1
|
||||
|
||||
|
||||
@flaky
|
||||
@pytest.mark.markers
|
||||
def test_top_level_overrides_environment_markers(PipenvInstance):
|
||||
def test_top_level_overrides_environment_markers(pipenv_instance_pypi):
|
||||
"""Top-level environment markers should take precedence.
|
||||
"""
|
||||
with PipenvInstance() as p:
|
||||
with pipenv_instance_pypi() as p:
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
contents = """
|
||||
[packages]
|
||||
@@ -92,14 +92,14 @@ funcsigs = {version = "*", os_name = "== 'splashwear'"}
|
||||
@flaky
|
||||
@pytest.mark.markers
|
||||
@pytest.mark.install
|
||||
def test_global_overrides_environment_markers(PipenvInstance):
|
||||
def test_global_overrides_environment_markers(pipenv_instance_pypi):
|
||||
"""Empty (unconditional) dependency should take precedence.
|
||||
If a dependency is specified without environment markers, it should
|
||||
override dependencies with environment markers. In this example,
|
||||
APScheduler requires funcsigs only on Python 2, but since funcsigs is
|
||||
also specified as an unconditional dep, its markers should be empty.
|
||||
"""
|
||||
with PipenvInstance() as p:
|
||||
with pipenv_instance_pypi() as p:
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
contents = """
|
||||
[packages]
|
||||
@@ -117,7 +117,7 @@ funcsigs = "*"
|
||||
@flaky
|
||||
@pytest.mark.markers
|
||||
@pytest.mark.complex
|
||||
def test_resolver_unique_markers(PipenvInstance):
|
||||
def test_resolver_unique_markers(pipenv_instance_pypi):
|
||||
"""vcrpy has a dependency on `yarl` which comes with a marker
|
||||
of 'python version in "3.4, 3.5, 3.6" - this marker duplicates itself:
|
||||
|
||||
@@ -125,7 +125,7 @@ def test_resolver_unique_markers(PipenvInstance):
|
||||
|
||||
This verifies that we clean that successfully.
|
||||
"""
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
c = p.pipenv('install vcrpy==2.0.1')
|
||||
assert c.returncode == 0
|
||||
assert 'yarl' in p.lockfile['default']
|
||||
@@ -142,8 +142,8 @@ def test_resolver_unique_markers(PipenvInstance):
|
||||
@flaky
|
||||
@pytest.mark.project
|
||||
@pytest.mark.needs_internet
|
||||
def test_environment_variable_value_does_not_change_hash(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_environment_variable_value_does_not_change_hash(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi(chdir=True) as p:
|
||||
with temp_environ():
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
f.write("""
|
||||
|
||||
@@ -12,10 +12,10 @@ from pipenv.utils.shell import mkdir_p, temp_environ
|
||||
@pytest.mark.extras
|
||||
@pytest.mark.install
|
||||
@pytest.mark.local
|
||||
def test_local_extras_install(PipenvInstance):
|
||||
def test_local_extras_install(pipenv_instance_pypi):
|
||||
"""Ensure -e .[extras] installs.
|
||||
"""
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
setup_py = os.path.join(p.path, "setup.py")
|
||||
with open(setup_py, "w") as fh:
|
||||
contents = """
|
||||
@@ -94,10 +94,10 @@ setup(
|
||||
assert c.returncode == 0
|
||||
assert "test-private-dependency" in pipenv_instance.lockfile["default"]
|
||||
|
||||
def test_https_dependency_links_install(self, PipenvInstance):
|
||||
def test_https_dependency_links_install(self, pipenv_instance_pypi):
|
||||
"""Ensure dependency_links are parsed and installed (needed for private repo dependencies).
|
||||
"""
|
||||
with temp_environ(), PipenvInstance(chdir=True) as p:
|
||||
with temp_environ(), pipenv_instance_pypi(chdir=True) as p:
|
||||
os.environ["PIP_NO_BUILD_ISOLATION"] = '1'
|
||||
TestDirectDependencies.helper_dependency_links_install_test(
|
||||
p,
|
||||
@@ -105,8 +105,8 @@ setup(
|
||||
)
|
||||
|
||||
@pytest.mark.needs_github_ssh
|
||||
def test_ssh_dependency_links_install(self, PipenvInstance):
|
||||
with temp_environ(), PipenvInstance(chdir=True) as p:
|
||||
def test_ssh_dependency_links_install(self, pipenv_instance_pypi):
|
||||
with temp_environ(), pipenv_instance_pypi(chdir=True) as p:
|
||||
os.environ['PIP_PROCESS_DEPENDENCY_LINKS'] = '1'
|
||||
os.environ["PIP_NO_BUILD_ISOLATION"] = '1'
|
||||
TestDirectDependencies.helper_dependency_links_install_test(
|
||||
@@ -118,11 +118,11 @@ setup(
|
||||
@pytest.mark.install
|
||||
@pytest.mark.multiprocessing
|
||||
@flaky
|
||||
def test_multiprocess_bug_and_install(PipenvInstance):
|
||||
def test_multiprocess_bug_and_install(pipenv_instance_pypi):
|
||||
with temp_environ():
|
||||
os.environ["PIPENV_MAX_SUBPROCESS"] = "2"
|
||||
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
with open(p.pipfile_path, "w") as f:
|
||||
contents = """
|
||||
[packages]
|
||||
@@ -146,9 +146,9 @@ urllib3 = "*"
|
||||
@pytest.mark.install
|
||||
@pytest.mark.sequential
|
||||
@flaky
|
||||
def test_sequential_mode(PipenvInstance):
|
||||
def test_sequential_mode(pipenv_instance_pypi):
|
||||
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
with open(p.pipfile_path, "w") as f:
|
||||
contents = """
|
||||
[packages]
|
||||
@@ -171,8 +171,8 @@ pytz = "*"
|
||||
|
||||
@pytest.mark.run
|
||||
@pytest.mark.install
|
||||
def test_normalize_name_install(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_normalize_name_install(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
with open(p.pipfile_path, "w") as f:
|
||||
contents = """
|
||||
# Pre comment
|
||||
@@ -205,15 +205,15 @@ Requests = "==2.14.0" # Inline comment
|
||||
@pytest.mark.files
|
||||
@pytest.mark.local
|
||||
@pytest.mark.resolver
|
||||
@pytest.mark.skip # extracting this package where it does mamy be causing the pip_to_deps failures
|
||||
def test_local_package(PipenvInstance, pip_src_dir, testsroot):
|
||||
@pytest.mark.skip # extracting this package may be where its causing the pip_to_deps failures
|
||||
def test_local_package(pipenv_instance_private_pypi, pip_src_dir, testsroot):
|
||||
"""This test ensures that local packages (directories with a setup.py)
|
||||
installed in editable mode have their dependencies resolved as well"""
|
||||
file_name = "requests-2.19.1.tar.gz"
|
||||
package = "requests-2.19.1"
|
||||
# Not sure where travis/appveyor run tests from
|
||||
source_path = os.path.abspath(os.path.join(testsroot, "test_artifacts", file_name))
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_private_pypi(chdir=True) as p:
|
||||
# This tests for a bug when installing a zipfile in the current dir
|
||||
copy_to = os.path.join(p.path, file_name)
|
||||
shutil.copy(source_path, copy_to)
|
||||
@@ -232,12 +232,12 @@ def test_local_package(PipenvInstance, pip_src_dir, testsroot):
|
||||
@pytest.mark.files
|
||||
@pytest.mark.local
|
||||
@flaky
|
||||
def test_local_zipfiles(PipenvInstance, testsroot):
|
||||
def test_local_zipfiles(pipenv_instance_private_pypi, testsroot):
|
||||
file_name = "requests-2.19.1.tar.gz"
|
||||
# Not sure where travis/appveyor run tests from
|
||||
source_path = os.path.join(testsroot, "test_artifacts", file_name)
|
||||
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_private_pypi(chdir=True) as p:
|
||||
# This tests for a bug when installing a zipfile in the current dir
|
||||
destination = os.path.join(p.path, file_name)
|
||||
shutil.copy(source_path, destination)
|
||||
@@ -260,11 +260,11 @@ def test_local_zipfiles(PipenvInstance, testsroot):
|
||||
@pytest.mark.local
|
||||
@pytest.mark.files
|
||||
@flaky
|
||||
def test_relative_paths(PipenvInstance, testsroot):
|
||||
def test_relative_paths(pipenv_instance_private_pypi, testsroot):
|
||||
file_name = "requests-2.19.1.tar.gz"
|
||||
source_path = os.path.abspath(os.path.join(testsroot, "test_artifacts", file_name))
|
||||
|
||||
with PipenvInstance() as p:
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
artifact_dir = "artifacts"
|
||||
artifact_path = os.path.join(p.path, artifact_dir)
|
||||
mkdir_p(artifact_path)
|
||||
@@ -285,8 +285,8 @@ def test_relative_paths(PipenvInstance, testsroot):
|
||||
@pytest.mark.local
|
||||
@pytest.mark.local_file
|
||||
@flaky
|
||||
def test_install_local_file_collision(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_install_local_file_collision(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
target_package = "alembic"
|
||||
fake_file = os.path.join(p.path, target_package)
|
||||
with open(fake_file, "w") as f:
|
||||
@@ -300,10 +300,10 @@ def test_install_local_file_collision(PipenvInstance):
|
||||
|
||||
@pytest.mark.urls
|
||||
@pytest.mark.install
|
||||
def test_install_local_uri_special_character(PipenvInstance, testsroot):
|
||||
def test_install_local_uri_special_character(pipenv_instance_pypi, testsroot):
|
||||
file_name = "six-1.11.0+mkl-py2.py3-none-any.whl"
|
||||
source_path = os.path.abspath(os.path.join(testsroot, "test_artifacts", file_name))
|
||||
with PipenvInstance() as p:
|
||||
with pipenv_instance_pypi() as p:
|
||||
artifact_dir = "artifacts"
|
||||
artifact_path = os.path.join(p.path, artifact_dir)
|
||||
mkdir_p(artifact_path)
|
||||
@@ -325,7 +325,7 @@ six = {{path = "./artifacts/{}"}}
|
||||
@pytest.mark.run
|
||||
@pytest.mark.files
|
||||
@pytest.mark.install
|
||||
def test_multiple_editable_packages_should_not_race(PipenvInstance, testsroot):
|
||||
def test_multiple_editable_packages_should_not_race(pipenv_instance_private_pypi, testsroot):
|
||||
"""Test for a race condition that can occur when installing multiple 'editable' packages at
|
||||
once, and which causes some of them to not be importable.
|
||||
|
||||
@@ -342,7 +342,7 @@ def test_multiple_editable_packages_should_not_race(PipenvInstance, testsroot):
|
||||
[packages]
|
||||
"""
|
||||
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_private_pypi(chdir=True) as p:
|
||||
for pkg_name in pkgs:
|
||||
source_path = p._pipfile.get_fixture_path(f"git/{pkg_name}/").as_posix()
|
||||
shutil.copytree(source_path, pkg_name)
|
||||
@@ -360,8 +360,8 @@ def test_multiple_editable_packages_should_not_race(PipenvInstance, testsroot):
|
||||
|
||||
|
||||
@pytest.mark.outdated
|
||||
def test_outdated_should_compare_postreleases_without_failing(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_outdated_should_compare_postreleases_without_failing(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi(chdir=True) as p:
|
||||
c = p.pipenv("install ibm-db-sa-py3==0.3.0")
|
||||
assert c.returncode == 0
|
||||
c = p.pipenv("update --outdated")
|
||||
|
||||
@@ -14,8 +14,8 @@ from pipenv.utils.processes import subprocess_run
|
||||
@pytest.mark.vcs
|
||||
@pytest.mark.install
|
||||
@pytest.mark.needs_internet
|
||||
def test_basic_vcs_install(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_basic_vcs_install(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
c = p.pipenv("install git+https://github.com/benjaminp/six.git@1.11.0#egg=six")
|
||||
assert c.returncode == 0
|
||||
# edge case where normal package starts with VCS name shouldn't be flagged as vcs
|
||||
@@ -34,8 +34,8 @@ def test_basic_vcs_install(PipenvInstance):
|
||||
@pytest.mark.vcs
|
||||
@pytest.mark.install
|
||||
@pytest.mark.needs_internet
|
||||
def test_basic_vcs_install_with_env_var(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_basic_vcs_install_with_env_var(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
p._pipfile.add("six", {"git": "https://${GIT_HOST}/benjaminp/six.git", "ref": "1.11.0"})
|
||||
os.environ["GIT_HOST"] = "github.com"
|
||||
c = p.pipenv("install")
|
||||
@@ -53,8 +53,8 @@ def test_basic_vcs_install_with_env_var(PipenvInstance):
|
||||
@pytest.mark.install
|
||||
@pytest.mark.needs_internet
|
||||
@pytest.mark.needs_github_ssh
|
||||
def test_ssh_vcs_install(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_ssh_vcs_install(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
c = p.pipenv("install git+ssh://git@github.com/benjaminp/six.git@1.11.0#egg=six")
|
||||
assert c.returncode == 0
|
||||
assert "six" in p.pipfile["packages"]
|
||||
@@ -69,12 +69,12 @@ def test_ssh_vcs_install(PipenvInstance):
|
||||
@pytest.mark.urls
|
||||
@pytest.mark.files
|
||||
@pytest.mark.needs_internet
|
||||
def test_urls_work(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_urls_work(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
# the library this installs is "django-cms"
|
||||
path = p._pipfile.get_url("django", "3.4.x.zip")
|
||||
url = "https://github.com/lidatong/dataclasses-json/archive/refs/tags/v0.5.7.zip"
|
||||
c = p.pipenv(
|
||||
"install {0}".format(path)
|
||||
"install {0}".format(url)
|
||||
)
|
||||
assert c.returncode == 0
|
||||
|
||||
@@ -82,14 +82,14 @@ def test_urls_work(PipenvInstance):
|
||||
assert "file" in dep, p.pipfile
|
||||
|
||||
# now that we handle resolution with requirementslib, this will resolve to a name
|
||||
dep = p.lockfile["default"]["django-cms"]
|
||||
dep = p.lockfile["default"]["dataclasses-json"]
|
||||
assert "file" in dep, p.lockfile
|
||||
|
||||
|
||||
@pytest.mark.urls
|
||||
@pytest.mark.files
|
||||
def test_file_urls_work(PipenvInstance, pip_src_dir):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_file_urls_work(pipenv_instance_pypi, pip_src_dir):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
whl = Path(__file__).parent.parent.joinpath(
|
||||
"pypi", "six", "six-1.11.0-py2.py3-none-any.whl"
|
||||
)
|
||||
@@ -107,10 +107,10 @@ def test_file_urls_work(PipenvInstance, pip_src_dir):
|
||||
@pytest.mark.urls
|
||||
@pytest.mark.files
|
||||
@pytest.mark.needs_internet
|
||||
def test_local_vcs_urls_work(PipenvInstance, tmpdir):
|
||||
def test_local_vcs_urls_work(pipenv_instance_pypi, tmpdir):
|
||||
six_dir = tmpdir.join("six")
|
||||
six_path = Path(six_dir.strpath)
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
c = subprocess_run(
|
||||
["git", "clone", "https://github.com/benjaminp/six.git", six_dir.strpath]
|
||||
)
|
||||
@@ -126,30 +126,23 @@ def test_local_vcs_urls_work(PipenvInstance, tmpdir):
|
||||
@pytest.mark.urls
|
||||
@pytest.mark.install
|
||||
@pytest.mark.needs_internet
|
||||
def test_editable_vcs_install(PipenvInstance_NoPyPI):
|
||||
with PipenvInstance_NoPyPI(chdir=True) as p:
|
||||
def test_editable_vcs_install(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
c = p.pipenv(
|
||||
"install -e git+https://github.com/kennethreitz/requests.git#egg=requests"
|
||||
"install -e git+https://github.com/lidatong/dataclasses-json.git#egg=dataclasses-json"
|
||||
)
|
||||
assert c.returncode == 0
|
||||
assert "requests" in p.pipfile["packages"]
|
||||
assert "git" in p.pipfile["packages"]["requests"]
|
||||
assert "editable" in p.pipfile["packages"]["requests"]
|
||||
assert "editable" in p.lockfile["default"]["requests"]
|
||||
assert "chardet" in p.lockfile["default"]
|
||||
assert "idna" in p.lockfile["default"]
|
||||
assert "urllib3" in p.lockfile["default"]
|
||||
assert "certifi" in p.lockfile["default"]
|
||||
assert "dataclasses-json" in p.pipfile["packages"]
|
||||
|
||||
|
||||
@pytest.mark.vcs
|
||||
@pytest.mark.urls
|
||||
@pytest.mark.install
|
||||
@pytest.mark.needs_internet
|
||||
def test_install_editable_git_tag(PipenvInstance_NoPyPI):
|
||||
def test_install_editable_git_tag(pipenv_instance_private_pypi):
|
||||
# This uses the real PyPI since we need Internet to access the Git
|
||||
# dependency anyway.
|
||||
with PipenvInstance_NoPyPI(chdir=True) as p:
|
||||
with pipenv_instance_private_pypi(chdir=True) as p:
|
||||
c = p.pipenv(
|
||||
"install -e git+https://github.com/benjaminp/six.git@1.11.0#egg=six"
|
||||
)
|
||||
@@ -168,8 +161,8 @@ def test_install_editable_git_tag(PipenvInstance_NoPyPI):
|
||||
@pytest.mark.index
|
||||
@pytest.mark.install
|
||||
@pytest.mark.needs_internet
|
||||
def test_install_named_index_alias(PipenvInstance_NoPyPI):
|
||||
with PipenvInstance_NoPyPI() as p:
|
||||
def test_install_named_index_alias(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
with open(p.pipfile_path, "w") as f:
|
||||
contents = """
|
||||
[[source]]
|
||||
@@ -196,8 +189,8 @@ six = "*"
|
||||
@pytest.mark.index
|
||||
@pytest.mark.install
|
||||
@pytest.mark.needs_internet
|
||||
def test_install_specifying_index_url(PipenvInstance_NoPyPI):
|
||||
with PipenvInstance_NoPyPI() as p:
|
||||
def test_install_specifying_index_url(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
with open(p.pipfile_path, "w") as f:
|
||||
contents = """
|
||||
[[source]]
|
||||
@@ -223,8 +216,8 @@ six = "*"
|
||||
@pytest.mark.urls
|
||||
@pytest.mark.install
|
||||
@pytest.mark.needs_internet
|
||||
def test_install_local_vcs_not_in_lockfile(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_install_local_vcs_not_in_lockfile(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
# six_path = os.path.join(p.path, "six")
|
||||
six_path = p._pipfile.get_fixture_path("git/six/").as_posix()
|
||||
c = subprocess_run(["git", "clone", six_path, "./six"])
|
||||
@@ -240,8 +233,8 @@ def test_install_local_vcs_not_in_lockfile(PipenvInstance):
|
||||
@pytest.mark.urls
|
||||
@pytest.mark.install
|
||||
@pytest.mark.needs_internet
|
||||
def test_get_vcs_refs(PipenvInstance_NoPyPI):
|
||||
with PipenvInstance_NoPyPI(chdir=True) as p:
|
||||
def test_get_vcs_refs(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi(chdir=True) as p:
|
||||
c = p.pipenv(
|
||||
"install -e git+https://github.com/benjaminp/six.git@1.9.0#egg=six"
|
||||
)
|
||||
@@ -269,12 +262,12 @@ def test_get_vcs_refs(PipenvInstance_NoPyPI):
|
||||
@pytest.mark.urls
|
||||
@pytest.mark.install
|
||||
@pytest.mark.needs_internet
|
||||
def test_vcs_entry_supersedes_non_vcs(PipenvInstance):
|
||||
def test_vcs_entry_supersedes_non_vcs(pipenv_instance_pypi):
|
||||
"""See issue #2181 -- non-editable VCS dep was specified, but not showing up
|
||||
in the lockfile -- due to not running pip install before locking and not locking
|
||||
the resolution graph of non-editable vcs dependencies.
|
||||
"""
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
jinja2_uri = p._pipfile.get_fixture_path("git/jinja2").as_uri()
|
||||
with open(p.pipfile_path, "w") as f:
|
||||
f.write(
|
||||
@@ -306,8 +299,8 @@ Jinja2 = {{ref = "2.11.0", git = "{0}"}}
|
||||
@pytest.mark.urls
|
||||
@pytest.mark.install
|
||||
@pytest.mark.needs_internet
|
||||
def test_vcs_can_use_markers(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_vcs_can_use_markers(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
path = p._pipfile.get_fixture_path("git/six/.git")
|
||||
p._pipfile.install("six", {"git": "{0}".format(path.as_uri()), "markers": "sys_platform == 'linux'"})
|
||||
assert "six" in p.pipfile["packages"]
|
||||
|
||||
+70
-124
@@ -13,10 +13,10 @@ from pipenv.utils.shell import temp_environ
|
||||
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.requirements
|
||||
def test_lock_handle_eggs(PipenvInstance):
|
||||
def test_lock_handle_eggs(pipenv_instance_private_pypi):
|
||||
"""Ensure locking works with packages providing egg formats.
|
||||
"""
|
||||
with PipenvInstance() as p:
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
f.write("""
|
||||
[packages]
|
||||
@@ -30,9 +30,9 @@ RandomWords = "*"
|
||||
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.requirements
|
||||
def test_lock_requirements_file(PipenvInstance):
|
||||
def test_lock_requirements_file(pipenv_instance_private_pypi):
|
||||
|
||||
with PipenvInstance() as p:
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
contents = """
|
||||
[packages]
|
||||
@@ -61,7 +61,7 @@ flask = "==0.12.2"
|
||||
|
||||
|
||||
@pytest.mark.lock
|
||||
def test_lock_includes_hashes_for_all_platforms(PipenvInstance):
|
||||
def test_lock_includes_hashes_for_all_platforms(pipenv_instance_private_pypi):
|
||||
""" Locking should include hashes for *all* platforms, not just the
|
||||
platform we're running lock on. """
|
||||
|
||||
@@ -72,7 +72,7 @@ def test_lock_includes_hashes_for_all_platforms(PipenvInstance):
|
||||
# 'yarl-1.3.0-cp35-cp35m-manylinux1_x86_64.whl' -> 'sha256:3890ab952d508523ef4881457c4099056546593fa05e93da84c7250516e632eb'
|
||||
return f"sha256:{releases[release_name].hash}"
|
||||
|
||||
with PipenvInstance() as p:
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
contents = """
|
||||
[packages]
|
||||
@@ -97,9 +97,9 @@ yarl = "==1.3.0"
|
||||
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.keep_outdated
|
||||
def test_lock_keep_outdated(PipenvInstance):
|
||||
def test_lock_keep_outdated(pipenv_instance_pypi):
|
||||
|
||||
with PipenvInstance() as p:
|
||||
with pipenv_instance_pypi() as p:
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
contents = """
|
||||
[packages]
|
||||
@@ -135,8 +135,8 @@ pytest = "*"
|
||||
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.keep_outdated
|
||||
def test_keep_outdated_doesnt_remove_lockfile_entries(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_keep_outdated_doesnt_remove_lockfile_entries(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi(chdir=True) as p:
|
||||
p._pipfile.add("requests", "==2.18.4")
|
||||
p._pipfile.add("colorama", {"version": "*", "markers": "os_name=='FakeOS'"})
|
||||
c = p.pipenv("install")
|
||||
@@ -149,8 +149,8 @@ def test_keep_outdated_doesnt_remove_lockfile_entries(PipenvInstance):
|
||||
|
||||
|
||||
@pytest.mark.lock
|
||||
def test_resolve_skip_unmatched_requirements(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_resolve_skip_unmatched_requirements(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
p._pipfile.add("missing-package", {"markers": "os_name=='FakeOS'"})
|
||||
c = p.pipenv("lock")
|
||||
assert c.returncode == 0
|
||||
@@ -162,8 +162,8 @@ def test_resolve_skip_unmatched_requirements(PipenvInstance):
|
||||
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.keep_outdated
|
||||
def test_keep_outdated_doesnt_upgrade_pipfile_pins(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_keep_outdated_doesnt_upgrade_pipfile_pins(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi(chdir=True) as p:
|
||||
p._pipfile.add("urllib3", "==1.21.1")
|
||||
c = p.pipenv("install")
|
||||
assert c.returncode == 0
|
||||
@@ -177,8 +177,8 @@ def test_keep_outdated_doesnt_upgrade_pipfile_pins(PipenvInstance):
|
||||
|
||||
|
||||
@pytest.mark.lock
|
||||
def test_keep_outdated_keeps_markers_not_removed(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_keep_outdated_keeps_markers_not_removed(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
c = p.pipenv("install six click")
|
||||
assert c.returncode == 0
|
||||
lockfile = Path(p.lockfile_path)
|
||||
@@ -194,8 +194,8 @@ def test_keep_outdated_keeps_markers_not_removed(PipenvInstance):
|
||||
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.keep_outdated
|
||||
def test_keep_outdated_doesnt_update_satisfied_constraints(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_keep_outdated_doesnt_update_satisfied_constraints(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi(chdir=True) as p:
|
||||
p._pipfile.add("requests", "==2.18.4")
|
||||
c = p.pipenv("install")
|
||||
assert c.returncode == 0
|
||||
@@ -215,10 +215,10 @@ def test_keep_outdated_doesnt_update_satisfied_constraints(PipenvInstance):
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.complex
|
||||
@pytest.mark.needs_internet
|
||||
def test_complex_lock_with_vcs_deps(local_tempdir, PipenvInstance, pip_src_dir):
|
||||
def test_complex_lock_with_vcs_deps(local_tempdir, pipenv_instance_private_pypi, pip_src_dir):
|
||||
# This uses the real PyPI since we need Internet to access the Git
|
||||
# dependency anyway.
|
||||
with PipenvInstance() as p, local_tempdir:
|
||||
with pipenv_instance_private_pypi() as p, local_tempdir:
|
||||
requests_uri = p._pipfile.get_fixture_path("git/requests").as_uri()
|
||||
dateutil_uri = p._pipfile.get_fixture_path("git/dateutil").as_uri()
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
@@ -251,9 +251,9 @@ requests = {git = "%s"}
|
||||
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.requirements
|
||||
def test_lock_with_prereleases(PipenvInstance):
|
||||
def test_lock_with_prereleases(pipenv_instance_private_pypi):
|
||||
|
||||
with PipenvInstance() as p:
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
contents = """
|
||||
[packages]
|
||||
@@ -274,9 +274,9 @@ allow_prereleases = true
|
||||
@pytest.mark.complex
|
||||
@pytest.mark.needs_internet
|
||||
@flaky
|
||||
def test_complex_deps_lock_and_install_properly(PipenvInstance, pip_src_dir):
|
||||
def test_complex_deps_lock_and_install_properly(pipenv_instance_pypi, pip_src_dir):
|
||||
# This uses the real PyPI because Maya has too many dependencies...
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
contents = """
|
||||
[packages]
|
||||
@@ -293,8 +293,8 @@ maya = "*"
|
||||
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.extras
|
||||
def test_lock_extras_without_install(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_lock_extras_without_install(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
contents = """
|
||||
[packages]
|
||||
@@ -319,8 +319,8 @@ requests = {version = "*", extras = ["socks"]}
|
||||
@pytest.mark.install # private indexes need to be uncached for resolution
|
||||
@pytest.mark.skip_lock
|
||||
@pytest.mark.needs_internet
|
||||
def test_private_index_skip_lock(PipenvInstance_NoPyPI):
|
||||
with PipenvInstance_NoPyPI() as p:
|
||||
def test_private_index_skip_lock(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
contents = """
|
||||
[[source]]
|
||||
@@ -347,9 +347,8 @@ requests = "*"
|
||||
@pytest.mark.install # private indexes need to be uncached for resolution
|
||||
@pytest.mark.requirements
|
||||
@pytest.mark.needs_internet
|
||||
def test_private_index_lock_requirements(PipenvInstance_NoPyPI):
|
||||
# Don't use the local fake pypi
|
||||
with PipenvInstance_NoPyPI() as p:
|
||||
def test_private_index_lock_requirements(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
contents = """
|
||||
[[source]]
|
||||
@@ -376,9 +375,9 @@ requests = "*"
|
||||
@pytest.mark.install # private indexes need to be uncached for resolution
|
||||
@pytest.mark.requirements
|
||||
@pytest.mark.needs_internet
|
||||
def test_private_index_lock_requirements(PipenvInstance_NoPyPI):
|
||||
def test_private_index_lock_requirements(pipenv_instance_pypi):
|
||||
# Don't use the local fake pypi
|
||||
with temp_environ(), PipenvInstance_NoPyPI(chdir=True) as p:
|
||||
with temp_environ(), pipenv_instance_pypi(chdir=True) as p:
|
||||
# Using pypi.python.org as pipenv-test-public-package is not
|
||||
# included in the local pypi mirror
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
@@ -402,64 +401,11 @@ pipenv-test-public-package = "*"
|
||||
assert c.returncode == 0
|
||||
|
||||
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.install
|
||||
@pytest.mark.skip_windows
|
||||
@pytest.mark.skipif(sys.version_info >= (3, 9), reason="old setuptools doesn't work")
|
||||
@pytest.mark.needs_internet
|
||||
def test_outdated_setuptools_with_pep517_legacy_build_meta_is_updated(PipenvInstance):
|
||||
"""
|
||||
This test ensures we are using build isolation and a pep517 backend
|
||||
because the package in question includes ``pyproject.toml`` but lacks
|
||||
a ``build-backend`` declaration. In this case, ``pip`` defaults to using
|
||||
``setuptools.build_meta:__legacy__`` as a builder, but without ``pep517``
|
||||
enabled and with ``setuptools==40.2.0`` installed, this build backend was
|
||||
not yet available. ``setuptools<40.8`` will not be aware of this backend.
|
||||
|
||||
If pip is able to build in isolation with a pep517 backend, this will not
|
||||
matter and the test will still pass as pip will by default install a more
|
||||
recent version of ``setuptools``.
|
||||
"""
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
c = p.pipenv('run pip install "setuptools<=40.2"')
|
||||
assert c.returncode == 0
|
||||
c = p.pipenv("run python -c 'import setuptools; print(setuptools.__version__)'")
|
||||
assert c.returncode == 0
|
||||
assert c.stdout.strip() == "40.2.0"
|
||||
c = p.pipenv("install legacy-backend-package")
|
||||
assert c.returncode == 0
|
||||
assert "vistir" in p.lockfile["default"]
|
||||
|
||||
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.install
|
||||
@pytest.mark.skip_windows
|
||||
@pytest.mark.skipif(sys.version_info >= (3, 9), reason="old setuptools doesn't work")
|
||||
@pytest.mark.needs_internet
|
||||
def test_outdated_setuptools_with_pep517_cython_import_in_setuppy(PipenvInstance):
|
||||
"""
|
||||
This test ensures we are using build isolation and a pep517 backend
|
||||
because the package in question declares 'cython' as a build dependency
|
||||
in ``pyproject.toml``, then imports it in ``setup.py``. The pep517
|
||||
backend will have to install it first, so this will only pass if the
|
||||
resolver is buliding with a proper backend.
|
||||
"""
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
c = p.pipenv('run pip install "setuptools<=40.2"')
|
||||
assert c.returncode == 0
|
||||
c = p.pipenv("run python -c 'import setuptools; print(setuptools.__version__)'")
|
||||
assert c.returncode == 0
|
||||
assert c.stdout.strip() == "40.2.0"
|
||||
c = p.pipenv("install cython-import-package")
|
||||
assert c.returncode == 0
|
||||
assert "vistir" in p.lockfile["default"]
|
||||
|
||||
|
||||
@pytest.mark.index
|
||||
@pytest.mark.install
|
||||
def test_lock_updated_source(PipenvInstance):
|
||||
def test_lock_updated_source(pipenv_instance_private_pypi):
|
||||
|
||||
with PipenvInstance() as p:
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
contents = """
|
||||
[[source]]
|
||||
@@ -494,8 +440,8 @@ requests = "==2.14.0"
|
||||
@pytest.mark.vcs
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.needs_internet
|
||||
def test_lock_editable_vcs_without_install(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_lock_editable_vcs_without_install(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi(chdir=True) as p:
|
||||
requests_uri = p._pipfile.get_fixture_path("git/requests").as_uri()
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
f.write("""
|
||||
@@ -514,8 +460,8 @@ requests = {git = "%s", editable = true}
|
||||
@pytest.mark.vcs
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.needs_internet
|
||||
def test_lock_editable_vcs_with_ref_in_git(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_lock_editable_vcs_with_ref_in_git(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi(chdir=True) as p:
|
||||
requests_uri = p._pipfile.get_fixture_path("git/requests").as_uri()
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
f.write("""
|
||||
@@ -534,8 +480,8 @@ requests = {git = "%s@883caaf", editable = true}
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.extras
|
||||
@pytest.mark.needs_internet
|
||||
def test_lock_editable_vcs_with_extras_without_install(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_lock_editable_vcs_with_extras_without_install(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi(chdir=True) as p:
|
||||
requests_uri = p._pipfile.get_fixture_path("git/requests").as_uri()
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
f.write("""
|
||||
@@ -558,8 +504,8 @@ requests = {git = "%s", editable = true, extras = ["socks"]}
|
||||
@pytest.mark.vcs
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.needs_internet
|
||||
def test_lock_editable_vcs_with_markers_without_install(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_lock_editable_vcs_with_markers_without_install(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi(chdir=True) as p:
|
||||
requests_uri = p._pipfile.get_fixture_path("git/requests").as_uri()
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
f.write("""
|
||||
@@ -577,8 +523,8 @@ requests = {git = "%s", editable = true, markers = "python_version >= '2.6'"}
|
||||
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.install
|
||||
def test_lockfile_corrupted(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_lockfile_corrupted(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi() as p:
|
||||
with open(p.lockfile_path, 'w') as f:
|
||||
f.write('{corrupted}')
|
||||
c = p.pipenv('install')
|
||||
@@ -589,8 +535,8 @@ def test_lockfile_corrupted(PipenvInstance):
|
||||
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.install
|
||||
def test_lockfile_with_empty_dict(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_lockfile_with_empty_dict(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi() as p:
|
||||
with open(p.lockfile_path, 'w') as f:
|
||||
f.write('{}')
|
||||
c = p.pipenv('install')
|
||||
@@ -602,8 +548,8 @@ def test_lockfile_with_empty_dict(PipenvInstance):
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.install
|
||||
@pytest.mark.skip_lock
|
||||
def test_lock_with_incomplete_source(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_lock_with_incomplete_source(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi(chdir=True) as p:
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
f.write("""
|
||||
[[source]]
|
||||
@@ -621,8 +567,8 @@ requests = "*"
|
||||
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.install
|
||||
def test_lock_no_warnings(PipenvInstance, recwarn):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_lock_no_warnings(pipenv_instance_pypi, recwarn):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
c = p.pipenv("install six")
|
||||
assert c.returncode == 0
|
||||
assert len(recwarn) == 0
|
||||
@@ -631,7 +577,7 @@ def test_lock_no_warnings(PipenvInstance, recwarn):
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.install
|
||||
@pytest.mark.skipif(sys.version_info >= (3, 5), reason="scandir doesn't get installed on python 3.5+")
|
||||
def test_lock_missing_cache_entries_gets_all_hashes(PipenvInstance, tmpdir):
|
||||
def test_lock_missing_cache_entries_gets_all_hashes(pipenv_instance_pypi, tmpdir):
|
||||
"""
|
||||
Test locking pathlib2 on python2.7 which needs `scandir`, but fails to resolve when
|
||||
using a fresh dependency cache.
|
||||
@@ -639,7 +585,7 @@ def test_lock_missing_cache_entries_gets_all_hashes(PipenvInstance, tmpdir):
|
||||
|
||||
with temp_environ():
|
||||
os.environ["PIPENV_CACHE_DIR"] = str(tmpdir.strpath)
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
p._pipfile.add("pathlib2", "*")
|
||||
assert "pathlib2" in p.pipfile["packages"]
|
||||
c = p.pipenv("install")
|
||||
@@ -654,10 +600,10 @@ def test_lock_missing_cache_entries_gets_all_hashes(PipenvInstance, tmpdir):
|
||||
|
||||
@pytest.mark.vcs
|
||||
@pytest.mark.lock
|
||||
def test_vcs_lock_respects_top_level_pins(PipenvInstance):
|
||||
def test_vcs_lock_respects_top_level_pins(pipenv_instance_private_pypi):
|
||||
"""Test that locking VCS dependencies respects top level packages pinned in Pipfiles"""
|
||||
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_private_pypi(chdir=True) as p:
|
||||
requests_uri = p._pipfile.get_fixture_path("git/requests").as_uri()
|
||||
p._pipfile.add("requests", {
|
||||
"editable": True, "git": f"{requests_uri}",
|
||||
@@ -673,8 +619,8 @@ def test_vcs_lock_respects_top_level_pins(PipenvInstance):
|
||||
|
||||
|
||||
@pytest.mark.lock
|
||||
def test_lock_after_update_source_name(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_lock_after_update_source_name(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
contents = """
|
||||
[[source]]
|
||||
url = "{}"
|
||||
@@ -698,13 +644,13 @@ six = "*"
|
||||
|
||||
|
||||
@pytest.mark.lock
|
||||
def test_lock_nested_direct_url(PipenvInstance):
|
||||
def test_lock_nested_direct_url(pipenv_instance_private_pypi):
|
||||
"""
|
||||
The dependency 'test_package' has a declared dependency on
|
||||
a PEP508 style VCS URL. This ensures that we capture the dependency
|
||||
here along with its own dependencies.
|
||||
"""
|
||||
with PipenvInstance() as p:
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
c = p.pipenv("install -v test_package")
|
||||
assert c.returncode == 0
|
||||
assert "vistir" in p.lockfile["default"]
|
||||
@@ -714,8 +660,8 @@ def test_lock_nested_direct_url(PipenvInstance):
|
||||
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.needs_internet
|
||||
def test_lock_nested_vcs_direct_url(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_lock_nested_vcs_direct_url(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
p._pipfile.add("pep508_package", {
|
||||
"git": "https://github.com/techalchemy/test-project.git",
|
||||
"editable": True, "ref": "master",
|
||||
@@ -732,8 +678,8 @@ def test_lock_nested_vcs_direct_url(PipenvInstance):
|
||||
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.install
|
||||
def test_lock_package_with_wildcard_version(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_lock_package_with_wildcard_version(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
c = p.pipenv("install 'six==1.11.*'")
|
||||
assert c.returncode == 0
|
||||
assert "six" in p.pipfile["packages"]
|
||||
@@ -745,8 +691,8 @@ def test_lock_package_with_wildcard_version(PipenvInstance):
|
||||
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.install
|
||||
def test_default_lock_overwrite_dev_lock(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_default_lock_overwrite_dev_lock(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
c = p.pipenv("install 'click==6.7'")
|
||||
assert c.returncode == 0
|
||||
c = p.pipenv("install -d flask")
|
||||
@@ -759,8 +705,8 @@ def test_default_lock_overwrite_dev_lock(PipenvInstance):
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.install
|
||||
@pytest.mark.needs_internet
|
||||
def test_pipenv_respects_package_index_restrictions(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_pipenv_respects_package_index_restrictions(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
contents = """
|
||||
[[source]]
|
||||
@@ -769,13 +715,13 @@ verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[[source]]
|
||||
url = "{url}/simple"
|
||||
url = "{url}"
|
||||
verify_ssl = true
|
||||
name = "local"
|
||||
|
||||
[packages]
|
||||
requests = {requirement}
|
||||
""".strip().format(url=p.pypi, requirement='{version="*", index="local"}')
|
||||
""".strip().format(url=os.environ['PIPENV_TEST_INDEX'], requirement='{version="*", index="local"}')
|
||||
f.write(contents)
|
||||
|
||||
c = p.pipenv('lock')
|
||||
@@ -795,10 +741,10 @@ requests = {requirement}
|
||||
@pytest.mark.dev
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.install
|
||||
def test_dev_lock_use_default_packages_as_constraint(PipenvInstance):
|
||||
def test_dev_lock_use_default_packages_as_constraint(pipenv_instance_private_pypi):
|
||||
# See https://github.com/pypa/pipenv/issues/4371
|
||||
# See https://github.com/pypa/pipenv/issues/2987
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_private_pypi(chdir=True) as p:
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
contents = """
|
||||
[packages]
|
||||
|
||||
@@ -14,13 +14,13 @@ from pipenv.utils.shell import temp_environ
|
||||
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.deploy
|
||||
def test_deploy_works(PipenvInstance):
|
||||
def test_deploy_works(pipenv_instance_pypi):
|
||||
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
contents = """
|
||||
[packages]
|
||||
requests = "==2.19.1"
|
||||
dataclasses-json = "==0.5.7"
|
||||
flask = "==1.1.2"
|
||||
|
||||
[dev-packages]
|
||||
@@ -37,7 +37,7 @@ pytest = "==4.6.9"
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
contents = """
|
||||
[packages]
|
||||
requests = "==2.19.1"
|
||||
dataclasses-json = "==0.5.7"
|
||||
""".strip()
|
||||
f.write(contents)
|
||||
|
||||
@@ -47,8 +47,8 @@ requests = "==2.19.1"
|
||||
|
||||
@pytest.mark.update
|
||||
@pytest.mark.lock
|
||||
def test_update_locks(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_update_locks(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
c = p.pipenv('install jdcal==1.3')
|
||||
assert c.returncode == 0
|
||||
assert p.lockfile['default']['jdcal']['version'] == '==1.3'
|
||||
@@ -69,8 +69,8 @@ def test_update_locks(PipenvInstance):
|
||||
|
||||
@pytest.mark.project
|
||||
@pytest.mark.proper_names
|
||||
def test_proper_names_unamanged_virtualenv(PipenvInstance):
|
||||
with PipenvInstance(chdir=True):
|
||||
def test_proper_names_unmanaged_virtualenv(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True):
|
||||
c = subprocess_run(['python', '-m', 'virtualenv', '.venv'])
|
||||
assert c.returncode == 0
|
||||
project = Project()
|
||||
@@ -78,9 +78,9 @@ def test_proper_names_unamanged_virtualenv(PipenvInstance):
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
def test_directory_with_leading_dash(raw_venv, PipenvInstance):
|
||||
def test_directory_with_leading_dash(raw_venv, pipenv_instance_pypi):
|
||||
with temp_environ():
|
||||
with PipenvInstance(chdir=True, venv_in_project=False, name="-project-with-dash") as p:
|
||||
with pipenv_instance_pypi(chdir=True, venv_in_project=False, name="-project-with-dash") as p:
|
||||
c = p.pipenv('run pip freeze')
|
||||
assert c.returncode == 0
|
||||
c = p.pipenv('--venv')
|
||||
|
||||
@@ -14,8 +14,8 @@ from pipenv.vendor.vistir.path import is_in_path, normalize_path
|
||||
@pytest.mark.project
|
||||
@pytest.mark.sources
|
||||
@pytest.mark.environ
|
||||
def test_pipfile_envvar_expansion(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_pipfile_envvar_expansion(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
with temp_environ():
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
f.write("""
|
||||
@@ -36,8 +36,8 @@ pytz = "*"
|
||||
@pytest.mark.project
|
||||
@pytest.mark.sources
|
||||
@pytest.mark.parametrize('lock_first', [True, False])
|
||||
def test_get_source(PipenvInstance, lock_first):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_get_source(pipenv_instance_private_pypi, lock_first):
|
||||
with pipenv_instance_private_pypi(chdir=True) as p:
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
contents = """
|
||||
[[source]]
|
||||
@@ -83,8 +83,8 @@ six = {{version = "*", index = "pypi"}}
|
||||
@pytest.mark.install
|
||||
@pytest.mark.project
|
||||
@pytest.mark.parametrize('newlines', ['\n', '\r\n'])
|
||||
def test_maintain_file_line_endings(PipenvInstance, newlines):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_maintain_file_line_endings(pipenv_instance_pypi, newlines):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
# Initial pipfile + lockfile generation
|
||||
c = p.pipenv('install pytz')
|
||||
assert c.returncode == 0
|
||||
@@ -120,8 +120,8 @@ def test_maintain_file_line_endings(PipenvInstance, newlines):
|
||||
@pytest.mark.project
|
||||
@pytest.mark.sources
|
||||
@pytest.mark.needs_internet
|
||||
def test_many_indexes(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_many_indexes(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
contents = """
|
||||
[[source]]
|
||||
@@ -152,11 +152,11 @@ six = {{version = "*", index = "pypi"}}
|
||||
|
||||
@pytest.mark.install
|
||||
@pytest.mark.project
|
||||
def test_include_editable_packages(PipenvInstance, testsroot, pathlib_tmpdir):
|
||||
def test_include_editable_packages(pipenv_instance_pypi, testsroot, pathlib_tmpdir):
|
||||
file_name = "tablib-0.12.1.tar.gz"
|
||||
package = pathlib_tmpdir.joinpath("tablib-0.12.1")
|
||||
source_path = os.path.abspath(os.path.join(testsroot, "pypi", "tablib", file_name))
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
with tarfile.open(source_path, "r:gz") as tarinfo:
|
||||
tarinfo.extractall(path=str(pathlib_tmpdir))
|
||||
c = p.pipenv(f'install -e {package.as_posix()}')
|
||||
@@ -170,8 +170,8 @@ def test_include_editable_packages(PipenvInstance, testsroot, pathlib_tmpdir):
|
||||
|
||||
@pytest.mark.project
|
||||
@pytest.mark.virtualenv
|
||||
def test_run_in_virtualenv_with_global_context(PipenvInstance, virtualenv):
|
||||
with PipenvInstance(chdir=True, venv_root=virtualenv.as_posix(), ignore_virtualenvs=False, venv_in_project=False) as p:
|
||||
def test_run_in_virtualenv_with_global_context(pipenv_instance_pypi, virtualenv):
|
||||
with pipenv_instance_pypi(chdir=True, venv_root=virtualenv.as_posix(), ignore_virtualenvs=False, venv_in_project=False) as p:
|
||||
c = p.pipenv("run pip freeze")
|
||||
assert c.returncode == 0, (c.stdout, c.stderr)
|
||||
assert 'Creating a virtualenv' not in c.stderr, c.stderr
|
||||
@@ -198,8 +198,8 @@ def test_run_in_virtualenv_with_global_context(PipenvInstance, virtualenv):
|
||||
|
||||
@pytest.mark.project
|
||||
@pytest.mark.virtualenv
|
||||
def test_run_in_virtualenv(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_run_in_virtualenv(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
c = p.pipenv('run pip freeze')
|
||||
assert c.returncode == 0
|
||||
assert 'Creating a virtualenv' in c.stderr
|
||||
@@ -220,8 +220,8 @@ def test_run_in_virtualenv(PipenvInstance):
|
||||
|
||||
@pytest.mark.project
|
||||
@pytest.mark.sources
|
||||
def test_no_sources_in_pipfile(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_no_sources_in_pipfile(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
contents = """
|
||||
[packages]
|
||||
|
||||
@@ -6,8 +6,8 @@ from pipenv.utils.shell import temp_environ
|
||||
|
||||
|
||||
@pytest.mark.requirements
|
||||
def test_requirements_generates_requirements_from_lockfile(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_requirements_generates_requirements_from_lockfile(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
packages = ('requests', '2.14.0')
|
||||
dev_packages = ('flask', '0.12.2')
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
@@ -43,8 +43,8 @@ def test_requirements_generates_requirements_from_lockfile(PipenvInstance):
|
||||
|
||||
|
||||
@pytest.mark.requirements
|
||||
def test_requirements_generates_requirements_from_lockfile_multiple_sources(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_requirements_generates_requirements_from_lockfile_multiple_sources(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
packages = ('requests', '2.14.0')
|
||||
dev_packages = ('flask', '0.12.2')
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
@@ -73,7 +73,7 @@ def test_requirements_generates_requirements_from_lockfile_multiple_sources(Pipe
|
||||
|
||||
|
||||
@pytest.mark.requirements
|
||||
def test_requirements_with_git_requirements(PipenvInstance):
|
||||
def test_requirements_with_git_requirements(pipenv_instance_pypi):
|
||||
req_name, req_hash = 'example-repo', 'cc858e89f19bc0dbd70983f86b811ab625dc9292'
|
||||
lockfile = {
|
||||
"_meta": {"sources": []},
|
||||
@@ -87,7 +87,7 @@ def test_requirements_with_git_requirements(PipenvInstance):
|
||||
"develop": {}
|
||||
}
|
||||
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
with open(p.lockfile_path, 'w') as f:
|
||||
json.dump(lockfile, f)
|
||||
|
||||
@@ -98,7 +98,7 @@ def test_requirements_with_git_requirements(PipenvInstance):
|
||||
|
||||
|
||||
@pytest.mark.requirements
|
||||
def test_requirements_markers_get_included(PipenvInstance):
|
||||
def test_requirements_markers_get_included(pipenv_instance_pypi):
|
||||
package, version, markers = "werkzeug", "==2.1.2", "python_version >= '3.7'"
|
||||
lockfile = {
|
||||
"_meta": {"sources": []},
|
||||
@@ -115,7 +115,7 @@ def test_requirements_markers_get_included(PipenvInstance):
|
||||
"develop": {}
|
||||
}
|
||||
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
with open(p.lockfile_path, 'w') as f:
|
||||
json.dump(lockfile, f)
|
||||
|
||||
@@ -125,7 +125,7 @@ def test_requirements_markers_get_included(PipenvInstance):
|
||||
|
||||
|
||||
@pytest.mark.requirements
|
||||
def test_requirements_markers_get_excluded(PipenvInstance):
|
||||
def test_requirements_markers_get_excluded(pipenv_instance_pypi):
|
||||
package, version, markers = "werkzeug", "==2.1.2", "python_version >= '3.7'"
|
||||
lockfile = {
|
||||
"_meta": {"sources": []},
|
||||
@@ -142,7 +142,7 @@ def test_requirements_markers_get_excluded(PipenvInstance):
|
||||
"develop": {}
|
||||
}
|
||||
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
with open(p.lockfile_path, 'w') as f:
|
||||
json.dump(lockfile, f)
|
||||
|
||||
@@ -152,7 +152,7 @@ def test_requirements_markers_get_excluded(PipenvInstance):
|
||||
|
||||
|
||||
def test_requirements_generates_requirements_from_lockfile_without_env_var_expansion(
|
||||
PipenvInstance,
|
||||
pipenv_instance_pypi,
|
||||
):
|
||||
lockfile = {
|
||||
"_meta": {
|
||||
@@ -167,7 +167,7 @@ def test_requirements_generates_requirements_from_lockfile_without_env_var_expan
|
||||
"default": {},
|
||||
}
|
||||
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
with open(p.lockfile_path, "w") as f:
|
||||
json.dump(lockfile, f)
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@ from pipenv.utils.shell import subprocess_run, temp_environ
|
||||
|
||||
@pytest.mark.run
|
||||
@pytest.mark.dotenv
|
||||
def test_env(PipenvInstance):
|
||||
with PipenvInstance(pipfile=False, chdir=True) as p:
|
||||
def test_env(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(pipfile=False, chdir=True) as p:
|
||||
with open(os.path.join(p.path, ".env"), "w") as f:
|
||||
f.write("HELLO=WORLD")
|
||||
c = subprocess_run(['pipenv', 'run', 'python', '-c', "import os; print(os.environ['HELLO'])"], env=p.env)
|
||||
@@ -18,8 +18,8 @@ def test_env(PipenvInstance):
|
||||
|
||||
|
||||
@pytest.mark.run
|
||||
def test_scripts(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_scripts(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
f.write(r"""
|
||||
[scripts]
|
||||
@@ -65,8 +65,8 @@ multicommand = "bash -c \"cd docs && make html\""
|
||||
|
||||
@pytest.mark.run
|
||||
@pytest.mark.skip_windows
|
||||
def test_run_with_usr_env_shebang(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_run_with_usr_env_shebang(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
p.pipenv('install')
|
||||
script_path = os.path.join(p.path, "test_script")
|
||||
with open(script_path, "w") as f:
|
||||
@@ -86,8 +86,8 @@ def test_run_with_usr_env_shebang(PipenvInstance):
|
||||
|
||||
@pytest.mark.run
|
||||
@pytest.mark.parametrize('quiet', [True, False])
|
||||
def test_scripts_resolve_dot_env_vars(quiet, PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_scripts_resolve_dot_env_vars(quiet, pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi() as p:
|
||||
with open(".env", "w") as f:
|
||||
contents = """
|
||||
HELLO_VAR=WORLD
|
||||
@@ -110,8 +110,8 @@ hello = "echo $HELLO_VAR"
|
||||
|
||||
@pytest.mark.run
|
||||
@pytest.mark.parametrize('quiet', [True, False])
|
||||
def test_pipenv_run_pip_freeze_has_expected_output(quiet, PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_pipenv_run_pip_freeze_has_expected_output(quiet, pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi() as p:
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
contents = """
|
||||
[packages]
|
||||
|
||||
@@ -8,8 +8,8 @@ from pipenv.utils.shell import temp_environ
|
||||
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.sync
|
||||
def test_sync_error_without_lockfile(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
def test_sync_error_without_lockfile(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
f.write("""
|
||||
[packages]
|
||||
@@ -22,9 +22,9 @@ def test_sync_error_without_lockfile(PipenvInstance):
|
||||
|
||||
@pytest.mark.sync
|
||||
@pytest.mark.lock
|
||||
def test_mirror_lock_sync(PipenvInstance):
|
||||
with temp_environ(), PipenvInstance(chdir=True) as p:
|
||||
mirror_url = os.environ.pop('PIPENV_TEST_INDEX', "https://pypi.kennethreitz.org/simple")
|
||||
def test_mirror_lock_sync(pipenv_instance_private_pypi):
|
||||
with temp_environ(), pipenv_instance_private_pypi(chdir=True) as p:
|
||||
mirror_url = os.environ.get('PIPENV_TEST_INDEX')
|
||||
assert 'pypi.org' not in mirror_url
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
f.write("""
|
||||
@@ -44,10 +44,10 @@ six = "*"
|
||||
|
||||
@pytest.mark.sync
|
||||
@pytest.mark.lock
|
||||
def test_sync_should_not_lock(PipenvInstance):
|
||||
def test_sync_should_not_lock(pipenv_instance_pypi):
|
||||
"""Sync should not touch the lock file, even if Pipfile is changed.
|
||||
"""
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
f.write("""
|
||||
[packages]
|
||||
@@ -72,8 +72,8 @@ six = "*"
|
||||
|
||||
@pytest.mark.sync
|
||||
@pytest.mark.lock
|
||||
def test_sync_sequential_detect_errors(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_sync_sequential_detect_errors(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
contents = """
|
||||
[packages]
|
||||
@@ -95,10 +95,10 @@ requests = "*"
|
||||
|
||||
|
||||
@pytest.mark.sync
|
||||
def test_sync_consider_pip_target(PipenvInstance):
|
||||
def test_sync_consider_pip_target(pipenv_instance_pypi):
|
||||
"""
|
||||
"""
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
f.write("""
|
||||
[packages]
|
||||
|
||||
@@ -8,12 +8,12 @@ from pipenv.utils.shell import temp_environ
|
||||
|
||||
@pytest.mark.uninstall
|
||||
@pytest.mark.install
|
||||
def test_uninstall_requests(PipenvInstance):
|
||||
def test_uninstall_requests(pipenv_instance_private_pypi):
|
||||
# Uninstalling requests can fail even when uninstall Django below
|
||||
# succeeds, if requests was de-vendored.
|
||||
# See https://github.com/pypa/pipenv/issues/3644 for problems
|
||||
# caused by devendoring
|
||||
with PipenvInstance() as p:
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
c = p.pipenv("install requests")
|
||||
assert c.returncode == 0
|
||||
assert "requests" in p.pipfile["packages"]
|
||||
@@ -30,8 +30,8 @@ def test_uninstall_requests(PipenvInstance):
|
||||
|
||||
|
||||
@pytest.mark.uninstall
|
||||
def test_uninstall_django(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_uninstall_django(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
c = p.pipenv("install Django")
|
||||
assert c.returncode == 0
|
||||
assert "django" in p.pipfile["packages"]
|
||||
@@ -53,8 +53,8 @@ def test_uninstall_django(PipenvInstance):
|
||||
|
||||
@pytest.mark.install
|
||||
@pytest.mark.uninstall
|
||||
def test_mirror_uninstall(PipenvInstance):
|
||||
with temp_environ(), PipenvInstance(chdir=True) as p:
|
||||
def test_mirror_uninstall(pipenv_instance_private_pypi):
|
||||
with temp_environ(), pipenv_instance_private_pypi(chdir=True) as p:
|
||||
|
||||
mirror_url = os.environ.pop(
|
||||
"PIPENV_TEST_INDEX", "https://pypi.python.org/simple"
|
||||
@@ -93,12 +93,12 @@ def test_mirror_uninstall(PipenvInstance):
|
||||
@pytest.mark.files
|
||||
@pytest.mark.install
|
||||
@pytest.mark.uninstall
|
||||
def test_uninstall_all_local_files(PipenvInstance, testsroot):
|
||||
def test_uninstall_all_local_files(pipenv_instance_private_pypi, testsroot):
|
||||
file_name = "tablib-0.12.1.tar.gz"
|
||||
# Not sure where travis/appveyor run tests from
|
||||
source_path = os.path.abspath(os.path.join(testsroot, "pypi", "tablib", file_name))
|
||||
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_private_pypi(chdir=True) as p:
|
||||
shutil.copy(source_path, os.path.join(p.path, file_name))
|
||||
os.mkdir(os.path.join(p.path, "tablib"))
|
||||
c = p.pipenv(f"install {file_name}")
|
||||
@@ -113,8 +113,8 @@ def test_uninstall_all_local_files(PipenvInstance, testsroot):
|
||||
|
||||
@pytest.mark.install
|
||||
@pytest.mark.uninstall
|
||||
def test_uninstall_all_dev(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_uninstall_all_dev(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
c = p.pipenv("install --dev Django==1.11.13 six")
|
||||
assert c.returncode == 0
|
||||
|
||||
@@ -147,8 +147,8 @@ def test_uninstall_all_dev(PipenvInstance):
|
||||
|
||||
|
||||
@pytest.mark.uninstall
|
||||
def test_normalize_name_uninstall(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
def test_normalize_name_uninstall(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
with open(p.pipfile_path, "w") as f:
|
||||
contents = """
|
||||
# Pre comment
|
||||
@@ -171,9 +171,9 @@ python_DateUtil = "*"
|
||||
|
||||
@pytest.mark.install
|
||||
@pytest.mark.uninstall
|
||||
def test_uninstall_all_dev_with_shared_dependencies(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
c = p.pipenv("install pytest")
|
||||
def test_uninstall_all_dev_with_shared_dependencies(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi() as p:
|
||||
c = p.pipenv("install pytest==4.6.11")
|
||||
assert c.returncode == 0
|
||||
|
||||
c = p.pipenv("install --dev six")
|
||||
@@ -186,9 +186,9 @@ def test_uninstall_all_dev_with_shared_dependencies(PipenvInstance):
|
||||
|
||||
|
||||
@pytest.mark.uninstall
|
||||
def test_uninstall_missing_parameters(PipenvInstance):
|
||||
with PipenvInstance() as p:
|
||||
c = p.pipenv("install requests")
|
||||
def test_uninstall_missing_parameters(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi() as p:
|
||||
c = p.pipenv("install dataclasses-json")
|
||||
assert c.returncode == 0
|
||||
|
||||
c = p.pipenv("uninstall")
|
||||
|
||||
@@ -10,10 +10,10 @@ pytestmark = pytest.mark.skipif(os.name != 'nt', reason="only relevant on window
|
||||
|
||||
|
||||
@pytest.mark.project
|
||||
def test_case_changes_windows(PipenvInstance):
|
||||
def test_case_changes_windows(pipenv_instance_pypi):
|
||||
"""Test project matching for case changes on Windows.
|
||||
"""
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
c = p.pipenv('install pytz')
|
||||
assert c.returncode == 0
|
||||
|
||||
@@ -38,7 +38,7 @@ def test_case_changes_windows(PipenvInstance):
|
||||
|
||||
@pytest.mark.files
|
||||
@pytest.mark.local
|
||||
def test_local_path_windows(PipenvInstance):
|
||||
def test_local_path_windows(pipenv_instance_pypi):
|
||||
whl = (
|
||||
Path(__file__).parent.parent
|
||||
.joinpath('pypi', 'six', 'six-1.11.0-py2.py3-none-any.whl')
|
||||
@@ -47,14 +47,14 @@ def test_local_path_windows(PipenvInstance):
|
||||
whl = whl.resolve()
|
||||
except OSError:
|
||||
whl = whl.absolute()
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
c = p.pipenv(f'install "{whl}"')
|
||||
assert c.returncode == 0
|
||||
|
||||
|
||||
@pytest.mark.local
|
||||
@pytest.mark.files
|
||||
def test_local_path_windows_forward_slash(PipenvInstance):
|
||||
def test_local_path_windows_forward_slash(pipenv_instance_pypi):
|
||||
whl = (
|
||||
Path(__file__).parent.parent
|
||||
.joinpath('pypi', 'six', 'six-1.11.0-py2.py3-none-any.whl')
|
||||
@@ -63,15 +63,15 @@ def test_local_path_windows_forward_slash(PipenvInstance):
|
||||
whl = whl.resolve()
|
||||
except OSError:
|
||||
whl = whl.absolute()
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
c = p.pipenv(f'install "{whl.as_posix()}"')
|
||||
assert c.returncode == 0
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
def test_pipenv_clean_windows(PipenvInstance):
|
||||
with PipenvInstance(chdir=True) as p:
|
||||
c = p.pipenv('install requests')
|
||||
def test_pipenv_clean_windows(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi(chdir=True) as p:
|
||||
c = p.pipenv('install dataclasses-json')
|
||||
assert c.returncode == 0
|
||||
c = p.pipenv(f'run pip install -i {p.index_url} click')
|
||||
assert c.returncode == 0
|
||||
@@ -80,8 +80,9 @@ def test_pipenv_clean_windows(PipenvInstance):
|
||||
assert c.returncode == 0
|
||||
assert 'click' in c.stdout.strip()
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
def test_pipenv_run_with_special_chars_windows(PipenvInstance):
|
||||
with PipenvInstance():
|
||||
def test_pipenv_run_with_special_chars_windows(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi():
|
||||
c = subprocess_run(["pipenv", "run", "echo", "[3-1]"])
|
||||
assert c.returncode == 0, c.stderr
|
||||
|
||||
+16
-22
@@ -1,7 +1,6 @@
|
||||
import os
|
||||
from unittest import mock
|
||||
|
||||
from flaky import flaky
|
||||
import pytest
|
||||
|
||||
import pipenv.utils.shell
|
||||
@@ -80,7 +79,6 @@ def mock_unpack(link, source_dir, download_dir, only_download=False, session=Non
|
||||
return
|
||||
|
||||
|
||||
@flaky
|
||||
@pytest.mark.utils
|
||||
@pytest.mark.parametrize("deps, expected", DEP_PIP_PAIRS)
|
||||
@pytest.mark.needs_internet
|
||||
@@ -90,25 +88,22 @@ def test_convert_deps_to_pip(deps, expected):
|
||||
assert dependencies.convert_deps_to_pip(deps) == [expected]
|
||||
|
||||
|
||||
@flaky
|
||||
@pytest.mark.utils
|
||||
@pytest.mark.needs_internet
|
||||
def test_convert_deps_to_pip_flaky():
|
||||
deps = {"requests": "*"}
|
||||
expected = "requests"
|
||||
def test_convert_deps_to_pip_star_specifier():
|
||||
deps = {"six": "*"}
|
||||
expected = "six"
|
||||
assert dependencies.convert_deps_to_pip(deps) == [expected]
|
||||
|
||||
|
||||
@flaky
|
||||
@pytest.mark.utils
|
||||
@pytest.mark.needs_internet
|
||||
def test_convert_deps_to_pip_flaky2():
|
||||
deps = {"requests": {"extras": ["socks"], "version": "*"}}
|
||||
expected = "requests[socks]"
|
||||
def test_convert_deps_to_pip_extras_no_version():
|
||||
deps = {"uvicorn": {"extras": ["standard"], "version": "*"}}
|
||||
expected = "uvicorn[standard]"
|
||||
assert dependencies.convert_deps_to_pip(deps) == [expected]
|
||||
|
||||
|
||||
@flaky
|
||||
@pytest.mark.utils
|
||||
@pytest.mark.parametrize(
|
||||
"deps, expected",
|
||||
@@ -135,13 +130,13 @@ def test_convert_deps_to_pip_flaky2():
|
||||
),
|
||||
(
|
||||
{
|
||||
"requests": {
|
||||
"git": "https://github.com/requests/requests.git",
|
||||
"uvicorn": {
|
||||
"git": "https://github.com/encode/uvicorn.git",
|
||||
"ref": "master",
|
||||
"extras": ["security"],
|
||||
"extras": ["standard"],
|
||||
}
|
||||
},
|
||||
"git+https://github.com/requests/requests.git@master#egg=requests[security]",
|
||||
"git+https://github.com/encode/uvicorn.git@master#egg=uvicorn[standard]",
|
||||
),
|
||||
],
|
||||
)
|
||||
@@ -149,11 +144,10 @@ def test_convert_deps_to_pip_one_way(deps, expected):
|
||||
assert dependencies.convert_deps_to_pip(deps) == [expected.lower()]
|
||||
|
||||
|
||||
@flaky
|
||||
@pytest.mark.utils
|
||||
def test_convert_deps_to_pip_one_way_flaky():
|
||||
deps = {"requests": dict()}
|
||||
expected = "requests"
|
||||
def test_convert_deps_to_pip_one_way():
|
||||
deps = {"uvicorn": dict()}
|
||||
expected = "uvicorn"
|
||||
assert dependencies.convert_deps_to_pip(deps) == [expected.lower()]
|
||||
|
||||
|
||||
@@ -161,11 +155,11 @@ def test_convert_deps_to_pip_one_way_flaky():
|
||||
@pytest.mark.parametrize(
|
||||
"deps, expected",
|
||||
[
|
||||
({"requests": {}}, ["requests"]),
|
||||
({"uvicorn": {}}, ["uvicorn"]),
|
||||
({"FooProject": {"path": ".", "editable": "true"}}, []),
|
||||
({"FooProject": {"version": "==1.2"}}, ["fooproject==1.2"]),
|
||||
({"requests": {"extras": ["security"]}}, []),
|
||||
({"requests": {"extras": []}}, ["requests"]),
|
||||
({"uvicorn": {"extras": ["standard"]}}, []),
|
||||
({"uvicorn": {"extras": []}}, ["uvicorn"]),
|
||||
({"extras": {}}, ["extras"]),
|
||||
({"uvicorn[standard]": {}}, [])
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user