diff --git a/pipenv/cli.py b/pipenv/cli.py index 0cb06878..729b4d78 100644 --- a/pipenv/cli.py +++ b/pipenv/cli.py @@ -1958,7 +1958,7 @@ def uninstall( system = True # Ensure that virtualenv is available. - ensure_project(three=three, python=python, system=system) + ensure_project(three=three, python=python) # Load the --pre settings from the Pipfile. pre = project.settings.get('pre') @@ -2049,10 +2049,7 @@ def uninstall( @click.option('--dev', '-d', is_flag=True, default=False, help="Generate output compatible with requirements.txt for the development dependencies.") @click.option('--clear', is_flag=True, default=False, help="Clear the dependency cache.") @click.option('--pre', is_flag=True, default=False, help=u"Allow pre–releases.") -def lock( - three=None, python=False, verbose=False, requirements=False, dev=False, - clear=False, pre=False -): +def lock(three=None, python=False, verbose=False, requirements=False, dev=False, clear=False, pre=False): # Ensure that virtualenv is available. ensure_project(three=three, python=python) @@ -2231,17 +2228,6 @@ def inline_activate_virtualenv(): @click.option('--three/--two', is_flag=True, default=None, help="Use Python 3/2 when creating virtualenv.") @click.option('--python', default=False, nargs=1, help="Specify which version of Python virtualenv should use.") def run(command, args, three=None, python=False): - - if not project.virtualenv_exists: - click.echo( - crayons.red( - u'This project has no virtualenv yet! Use $ pipenv install, for example, to create one.', - bold=True - ), - err=True - ) - sys.exit(1) - # Ensure that virtualenv is available. ensure_project(three=three, python=python, validate=False) @@ -2502,11 +2488,7 @@ def run_open(module, three=None, python=None): @click.option('--clear', is_flag=True, default=False, help="Clear the dependency cache.") @click.option('--sequential', is_flag=True, default=False, help="Install dependencies one-at-a-time, instead of concurrently.") @click.pass_context -def update( - ctx, dev=False, three=None, python=None, dry_run=False, bare=False, - dont_upgrade=False, user=False, verbose=False, clear=False, unused=False, - package_name=None, sequential=False -): +def update(ctx, dev=False, three=None, python=None, dry_run=False, bare=False, dont_upgrade=False, user=False, verbose=False, clear=False, unused=False, package_name=None, sequential=False): # Ensure that virtualenv is available. ensure_project(three=three, python=python, validate=False) @@ -2538,10 +2520,7 @@ def update( pass # Resolve dependency tree. - for result in resolve_deps( - deps, sources=project.sources, clear=clear, which=which, - which_pip=which_pip, project=project - ): + for result in resolve_deps(deps, sources=project.sources, clear=clear, which=which, which_pip=which_pip, project=project): name = result['name'] latest = result['version'] @@ -2580,7 +2559,7 @@ def update( do_purge() # Lock. - do_lock(pre=pre) + do_lock(clear=clear, pre=pre) # Install everything. do_init(dev=dev, verbose=verbose, concurrent=concurrent) diff --git a/tests/test_pipenv.py b/tests/test_pipenv.py index 8f4bb9b8..68d799bd 100644 --- a/tests/test_pipenv.py +++ b/tests/test_pipenv.py @@ -894,21 +894,78 @@ maya = "*" assert c.return_code == 0 @pytest.mark.lock + @pytest.mark.requirements @pytest.mark.complex + def test_complex_lock_changing_candidate(self): + # The requests candidate will change from latest to <2.12. + + with PipenvInstance() as p: + with open(p.pipfile_path, 'w') as f: + contents = """ +[packages] +"docker-compose" = "==1.16.0" +docker = "<2.7" +requests = "*" + """.strip() + f.write(contents) + + c = p.pipenv('lock') + assert c.return_code == 0 + assert parse_version(p.lockfile['default']['requests']['version'][2:]) < parse_version('2.12') + + c = p.pipenv('install') + assert c.return_code == 0 + + @pytest.mark.extras + @pytest.mark.lock + @pytest.mark.requirements + @pytest.mark.complex + def test_complex_lock_deep_extras(self): + # records[pandas] requires tablib[pandas] which requires pandas. + + with PipenvInstance() as p: + with open(p.pipfile_path, 'w') as f: + contents = """ +[packages] +records = {extras = ["pandas"], version = "==0.5.2"} + """.strip() + f.write(contents) + + c = p.pipenv('lock') + assert c.return_code == 0 + assert 'tablib' in p.lockfile['default'] + assert 'pandas' in p.lockfile['default'] + c = p.pipenv('install') + assert c.return_code == 0 + + @pytest.mark.lock + @pytest.mark.install + @pytest.mark.system + @pytest.mark.skipif(os.name != 'posix', reason="Windows doesn't have a root") def test_resolve_system_python_no_virtualenv(self): + """Ensure we don't error out when we are in a folder off of / and doing an install using --system, + which used to cause the resolver and PIP_PYTHON_PATH to point at /bin/python + + Sample dockerfile: + FROM python:3.6-alpine3.6 + + RUN set -ex && pip install pipenv --upgrade + RUN set -ex && mkdir /app + COPY Pipfile /app/Pipfile + + WORKDIR /app + """ with temp_environ(): os.environ['PIPENV_IGNORE_VIRTUALENVS'] = '1' os.environ['PIPENV_USE_SYSTEM'] = '1' - os.environ['PIP_PYTHON_PATH'] = '/bin/python' - with PipenvInstance() as p: - with open(p.pipfile_path, 'w') as f: - contents = """ -[packages] -tablib = "*" - """.strip() - f.write(contents) - c = p.pipenv('install --system') - assert c.return_code == 0 + with PipenvInstance(chdir=True) as p: + os.chdir('/tmp') + c = p.pipenv('install --system xlrd') + assert c.return_code == 0 + for fn in ['Pipfile', 'Pipfile.lock']: + path = os.path.join('/tmp', fn) + if os.path.exists(path): + os.unlink(path) @pytest.mark.lock