1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323
|
import os
import re
import sys
from pathlib import Path
import pytest
from pipenv.utils.processes import subprocess_run
from pipenv.utils.shell import normalize_drive
@pytest.mark.cli
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(pipenv_instance_pypi):
with pipenv_instance_pypi() as p:
c = p.pipenv('install dataclasses-json')
assert c.returncode == 0
c = p.pipenv('--venv')
assert c.returncode == 0
venv_path = c.stdout.strip()
assert os.path.isdir(venv_path)
@pytest.mark.cli
@pytest.mark.skipif(sys.version_info[:2] == (3, 8) and os.name == "nt", reason="Python 3.8 on Windows is not supported")
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')
assert c.returncode == 0
python = c.stdout.strip()
assert os.path.basename(python).startswith('python')
@pytest.mark.cli
@pytest.mark.skipif(os.name == 'nt' and sys.version_info[:2] == (3, 8), reason='Test issue with windows 3.8 CIs')
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
# no-global-site-packages.txt under stdlib dir should not exist.
c = p.pipenv('run python -c "import sysconfig; print(sysconfig.get_path(\'stdlib\'))"')
assert c.returncode == 0
stdlib_path = c.stdout.strip()
assert not os.path.isfile(os.path.join(stdlib_path, 'no-global-site-packages.txt'))
@pytest.mark.cli
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(pipenv_instance_pypi):
with pipenv_instance_pypi() as p:
c = p.pipenv('--python python')
assert c.returncode == 0
c = p.pipenv('--venv')
assert c.returncode == 0
venv_path = c.stdout.strip()
assert os.path.isdir(venv_path)
c = p.pipenv('--rm')
assert c.returncode == 0
assert c.stdout
assert not os.path.isdir(venv_path)
@pytest.mark.cli
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")
assert graph.returncode == 0
assert "tablib" in graph.stdout
graph_json = p.pipenv("graph --json")
assert graph_json.returncode == 0
assert "tablib" in graph_json.stdout
graph_json_tree = p.pipenv("graph --json-tree")
assert graph_json_tree.returncode == 0
assert "tablib" in graph_json_tree.stdout
@pytest.mark.cli
def test_pipenv_graph_reverse(pipenv_instance_private_pypi):
from pipenv.cli import cli
from pipenv.vendor.click.testing import CliRunner # not thread safe but graph is a tricky test
with pipenv_instance_private_pypi() as p:
c = p.pipenv('install tablib==0.13.0')
assert c.returncode == 0
cli_runner = CliRunner(mix_stderr=False)
c = cli_runner.invoke(cli, "graph --reverse")
assert c.exit_code == 0
output = c.stdout
requests_dependency = [
('backports.csv', 'backports.csv'),
('odfpy', 'odfpy'),
('openpyxl', 'openpyxl>=2.4.0'),
('pyyaml', 'pyyaml'),
('xlrd', 'xlrd'),
('xlwt', 'xlwt'),
]
for dep_name, dep_constraint in requests_dependency:
pat = fr'{dep_name}==[\d.]+'
dep_match = re.search(pat,
output,
flags=re.MULTILINE | re.IGNORECASE)
assert dep_match is not None, f'{pat} not found in {output}'
# openpyxl should be indented
if dep_name == 'openpyxl':
openpyxl_dep = re.search(r'^openpyxl',
output,
flags=re.MULTILINE | re.IGNORECASE)
assert openpyxl_dep is None, f'openpyxl should not appear at beginning of lines in {output}'
if sys.version_info[:2] == (3, 12):
assert 'openpyxl==2.5.4 [requires: et_xmlfile]' in output
else:
assert 'openpyxl==2.5.4 [requires: et-xmlfile]' in output
else:
dep_match = re.search(fr'^[ -]*{dep_name}==[\d.]+$',
output,
flags=re.MULTILINE | re.IGNORECASE)
assert dep_match is not None, f'{dep_name} not found at beginning of line in {output}'
dep_requests_match = re.search(fr'└── tablib==0.13.0 \[requires: {dep_constraint}',
output,
flags=re.MULTILINE | re.IGNORECASE)
assert dep_requests_match is not None, f'constraint {dep_constraint} not found in {output}'
assert dep_requests_match.start() > dep_match.start()
@pytest.mark.skip(reason="There is a disputed vulnerability about pip 24.0 messing up this test.")
@pytest.mark.cli
@pytest.mark.needs_internet(reason='required by check')
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 --use-installed')
assert c.returncode != 0
assert 'pyyaml' in c.stdout
c = p.pipenv('uninstall pyyaml')
assert c.returncode == 0
c = p.pipenv('install six')
assert c.returncode == 0
c = p.pipenv("run python -m pip install --upgrade pip")
assert c.returncode == 0
# Note: added
# 51457: py <=1.11.0 resolved (1.11.0 installed)!
# this is installed via pytest, and causes a false positive
# https://github.com/pytest-dev/py/issues/287
# the issue above is still not resolved.
# added also 51499
# https://github.com/pypa/wheel/issues/481
c = p.pipenv('check --use-installed --ignore 35015 -i 51457 -i 51499')
assert c.returncode == 0
assert 'Ignoring' in c.stderr
@pytest.mark.cli
@pytest.mark.needs_internet(reason='required by check')
@pytest.mark.parametrize("category", ["CVE", "packages"])
def test_pipenv_check_check_lockfile_categories(pipenv_instance_pypi, category):
with pipenv_instance_pypi() as p:
c = p.pipenv(f'install wheel==0.37.1 --categories={category}')
assert c.returncode == 0
c = p.pipenv(f'check --categories={category}')
assert c.returncode != 0
assert 'wheel' in c.stdout
@pytest.mark.cli
@pytest.mark.skipif(sys.version_info[:2] == (3, 8) and os.name == "nt", reason="This test is not working om Windows Python 3. 8")
def test_pipenv_clean(pipenv_instance_private_pypi):
with pipenv_instance_private_pypi() as p:
with open('setup.py', 'w') as f:
f.write('from setuptools import setup; setup(name="empty")')
c = p.pipenv('install -e .')
assert c.returncode == 0
c = p.pipenv(f'run pip install -i {p.index_url} six')
assert c.returncode == 0
c = p.pipenv('clean')
assert c.returncode == 0
assert 'six' in c.stdout, f"{c.stdout} -- STDERR: {c.stderr}"
@pytest.mark.cli
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(pipenv_instance_pypi):
with pipenv_instance_pypi() as p:
assert p.pipenv('').stdout
@pytest.mark.cli
def test_scripts(pipenv_instance_pypi):
with pipenv_instance_pypi() as p:
with open(p.pipfile_path, "w") as f:
contents = """
[scripts]
pyver = "which python"
""".strip()
f.write(contents)
c = p.pipenv('scripts')
assert 'pyver' in c.stdout
assert 'which python' in c.stdout
@pytest.mark.cli
def test_help(pipenv_instance_pypi):
with pipenv_instance_pypi() as p:
assert p.pipenv('--help').stdout
@pytest.mark.cli
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(pipenv_instance_private_pypi):
with pipenv_instance_private_pypi() as p:
# Make sure unparsable packages don't wind up in the pipfile
# Escape $ for shell input
with open(p.pipfile_path, 'w') as f:
contents = """
[packages]
[dev-packages]
""".strip()
f.write(contents)
c = p.pipenv('install requests u/\\/p@r\\$34b13+pkg')
assert c.returncode != 0
assert 'u/\\/p@r$34b13+pkg' not in p.pipfile['packages']
@pytest.mark.skip(reason="This test clears the cache that other tests may be using.")
@pytest.mark.cli
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.outdated
def test_pipenv_outdated_prerelease(pipenv_instance_pypi):
with pipenv_instance_pypi() as p:
with open(p.pipfile_path, "w") as f:
contents = """
[packages]
sqlalchemy = "<=1.2.3"
""".strip()
f.write(contents)
c = p.pipenv('update --pre --outdated')
assert c.returncode == 0
@pytest.mark.cli
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(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(pipenv_instance_pypi):
with pipenv_instance_pypi() as p:
p.pipenv('lock')
c = p.pipenv('verify')
assert c.returncode == 0
assert 'Pipfile.lock is up-to-date.' in c.stdout
@pytest.mark.cli
def test_pipenv_verify_locked_outdated_failing(pipenv_instance_private_pypi):
with pipenv_instance_private_pypi() as p:
p.pipenv('lock')
# modify the Pipfile
pf = Path(p.path).joinpath('Pipfile')
pf_data = pf.read_text()
pf_new = re.sub(r'\[packages\]', '[packages]\nrequests = "*"', pf_data)
pf.write_text(pf_new)
c = p.pipenv('verify')
assert c.returncode == 1
assert 'Pipfile.lock is out-of-date.' in c.stderr
|