Merge branch 'master' into 2310-prepare-vcs-deps-before-resolving

This commit is contained in:
Dan Ryan
2018-06-08 09:40:16 -04:00
committed by GitHub
10 changed files with 265 additions and 20 deletions
+17
View File
@@ -38,6 +38,23 @@ If you'd like a specific package to be installed with a specific package index,
Very fancy.
☤ Using a PyPI Mirror
----------------------------
If you'd like to override the default PyPI index urls with the url for a PyPI mirror, you can use the following::
$ pipenv install --pypi-mirror <mirror_url>
$ pipenv update --pypi-mirror <mirror_url>
$ pipenv sync --pypi-mirror <mirror_url>
$ pipenv lock --pypi-mirror <mirror_url>
$ pipenv uninstall --pypi-mirror <mirror_url>
Alternatively, you can set the ``PIPENV_PYPI_MIRROR`` environment variable.
☤ Injecting credentials into Pipfiles via environment variables
-----------------------------------------------------------------
+55 -6
View File
@@ -24,6 +24,7 @@ from .__version__ import __version__
from . import environments
from .environments import *
from .utils import is_valid_url
# Enable shell completion.
init_completion()
@@ -79,7 +80,10 @@ def validate_python_path(ctx, param, value):
raise BadParameter('Expected Python at path %s does not exist' % value)
return value
def validate_pypi_mirror(ctx, param, value):
if value and not is_valid_url(value):
raise BadParameter('Invalid PyPI mirror URL: %s' % value)
return value
@group(
cls=PipenvGroup,
invoke_without_command=True,
@@ -302,6 +306,13 @@ def cli(
callback=validate_python_path,
help="Specify which version of Python virtualenv should use.",
)
@option(
'--pypi-mirror',
default=PIPENV_PYPI_MIRROR,
nargs=1,
callback=validate_pypi_mirror,
help="Specify a PyPI mirror.",
)
@option(
'--system', is_flag=True, default=False, help="System pip management."
)
@@ -368,6 +379,7 @@ def install(
dev=False,
three=False,
python=False,
pypi_mirror=None,
system=False,
lock=True,
ignore_pipfile=False,
@@ -389,6 +401,7 @@ def install(
dev=dev,
three=three,
python=python,
pypi_mirror=pypi_mirror,
system=system,
lock=lock,
ignore_pipfile=ignore_pipfile,
@@ -452,6 +465,13 @@ def install(
default=False,
help=u"Keep outdated dependencies from being updated in Pipfile.lock.",
)
@option(
'--pypi-mirror',
default=PIPENV_PYPI_MIRROR,
nargs=1,
callback=validate_pypi_mirror,
help="Specify a PyPI mirror.",
)
def uninstall(
package_name=False,
more_packages=False,
@@ -463,6 +483,7 @@ def uninstall(
all=False,
verbose=False,
keep_outdated=False,
pypi_mirror=None,
):
from .core import do_uninstall
@@ -477,6 +498,7 @@ def uninstall(
all=all,
verbose=verbose,
keep_outdated=keep_outdated,
pypi_mirror=pypi_mirror,
)
@@ -494,6 +516,13 @@ def uninstall(
callback=validate_python_path,
help="Specify which version of Python virtualenv should use.",
)
@option(
'--pypi-mirror',
default=PIPENV_PYPI_MIRROR,
nargs=1,
callback=validate_pypi_mirror,
help="Specify a PyPI mirror.",
)
@option(
'--verbose',
'-v',
@@ -531,6 +560,7 @@ def uninstall(
def lock(
three=None,
python=False,
pypi_mirror=None,
verbose=False,
requirements=False,
dev=False,
@@ -543,9 +573,9 @@ def lock(
# Ensure that virtualenv is available.
ensure_project(three=three, python=python)
if requirements:
do_init(dev=dev, requirements=requirements)
do_init(dev=dev, requirements=requirements, pypi_mirror=pypi_mirror)
do_lock(
verbose=verbose, clear=clear, pre=pre, keep_outdated=keep_outdated
verbose=verbose, clear=clear, pre=pre, keep_outdated=keep_outdated, pypi_mirror=pypi_mirror
)
@@ -695,6 +725,13 @@ def check(
callback=validate_python_path,
help="Specify which version of Python virtualenv should use.",
)
@option(
'--pypi-mirror',
default=PIPENV_PYPI_MIRROR,
nargs=1,
callback=validate_pypi_mirror,
help="Specify a PyPI mirror.",
)
@option(
'--verbose',
'-v',
@@ -747,6 +784,7 @@ def update(
ctx,
three=None,
python=False,
pypi_mirror=None,
system=False,
verbose=False,
clear=False,
@@ -774,7 +812,7 @@ def update(
if not outdated:
outdated = bool(dry_run)
if outdated:
do_outdated()
do_outdated(pypi_mirror=pypi_mirror)
if not package:
echo(
'{0} {1} {2} {3}{4}'.format(
@@ -786,7 +824,7 @@ def update(
)
)
do_lock(
verbose=verbose, clear=clear, pre=pre, keep_outdated=keep_outdated
verbose=verbose, clear=clear, pre=pre, keep_outdated=keep_outdated, pypi_mirror=pypi_mirror
)
do_sync(
ctx=ctx,
@@ -801,6 +839,7 @@ def update(
clear=clear,
unused=False,
sequential=sequential,
pypi_mirror=pypi_mirror,
)
else:
for package in ([package] + list(more_packages) or []):
@@ -814,7 +853,7 @@ def update(
err=True,
)
sys.exit(1)
ensure_lockfile(keep_outdated=project.lockfile_exists)
ensure_lockfile(keep_outdated=project.lockfile_exists, pypi_mirror=pypi_mirror)
# Install the dependencies.
do_install(
package_name=package,
@@ -822,6 +861,7 @@ def update(
dev=dev,
three=three,
python=python,
pypi_mirror=pypi_mirror,
system=system,
lock=True,
ignore_pipfile=False,
@@ -922,6 +962,13 @@ def run_open(module, three=None, python=None):
callback=validate_python_path,
help="Specify which version of Python virtualenv should use.",
)
@option(
'--pypi-mirror',
default=PIPENV_PYPI_MIRROR,
nargs=1,
callback=validate_pypi_mirror,
help="Specify a PyPI mirror.",
)
@option('--bare', is_flag=True, default=False, help="Minimal output.")
@option(
'--clear', is_flag=True, default=False, help="Clear the dependency cache."
@@ -946,6 +993,7 @@ def sync(
unused=False,
package_name=None,
sequential=False,
pypi_mirror=None,
):
from .core import do_sync
@@ -962,6 +1010,7 @@ def sync(
clear=clear,
unused=unused,
sequential=sequential,
pypi_mirror=pypi_mirror,
)
+32 -12
View File
@@ -40,6 +40,8 @@ from .utils import (
prepare_pip_source_args,
temp_environ,
is_valid_url,
is_pypi_url,
create_mirror_source,
download_file,
is_pinned,
is_star,
@@ -717,6 +719,7 @@ def do_install_dependencies(
verbose=False,
concurrent=True,
requirements_dir=None,
pypi_mirror = False,
):
""""Executes the install functionality.
@@ -819,6 +822,7 @@ def do_install_dependencies(
index=index,
requirements_dir=requirements_dir,
extra_indexes=extra_indexes,
pypi_mirror=pypi_mirror,
)
c.dep = dep
c.ignore_hash = ignore_hash
@@ -1001,6 +1005,7 @@ def do_lock(
pre=False,
keep_outdated=False,
write=True,
pypi_mirror = None,
):
"""Executes the freeze functionality."""
from .utils import get_vcs_deps
@@ -1055,6 +1060,7 @@ def do_lock(
clear=clear,
pre=pre,
allow_global=system,
pypi_mirror=pypi_mirror,
)
# Add develop dependencies to lockfile.
for dep in results:
@@ -1075,7 +1081,7 @@ def do_lock(
lockfile['develop'][dep['name']]['markers'] = dep['markers']
# Add refs for VCS installs.
# TODO: be smarter about this.
vcs_dev_lines, vcs_dev_lockfiles = get_vcs_deps(project, pip_freeze, which=which, verbose=verbose, clear=clear, pre=pre, allow_global=system, dev=True)
vcs_dev_lines, vcs_dev_lockfiles = get_vcs_deps(project, pip_freeze, which=which, verbose=verbose, clear=clear, pre=pre, allow_global=system, dev=True, pypi_mirror=pypi_mirror)
for lf in vcs_dev_lockfiles:
try:
name = first(lf.keys())
@@ -1105,6 +1111,7 @@ def do_lock(
clear=False,
pre=pre,
allow_global=system,
pypi_mirror=pypi_mirror,
)
# Add default dependencies to lockfile.
for dep in results:
@@ -1131,7 +1138,7 @@ def do_lock(
lockfile['default'][dep['name']]['markers'] = dep['markers']
# Add refs for VCS installs.
# TODO: be smarter about this.
_vcs_deps, vcs_lockfiles = get_vcs_deps(project, pip_freeze, which=which, verbose=verbose, clear=clear, pre=pre, allow_global=system, dev=False)
_vcs_deps, vcs_lockfiles = get_vcs_deps(project, pip_freeze, which=which, verbose=verbose, clear=clear, pre=pre, allow_global=system, dev=False, pypi_mirror=pypi_mirror)
for lf in vcs_lockfiles:
try:
name = first(lf.keys())
@@ -1280,6 +1287,7 @@ def do_init(
pre=False,
keep_outdated=False,
requirements_dir=None,
pypi_mirror=None,
):
"""Executes the init functionality."""
if not system:
@@ -1337,7 +1345,7 @@ def do_init(
),
err=True,
)
do_lock(system=system, pre=pre, keep_outdated=keep_outdated)
do_lock(system=system, pre=pre, keep_outdated=keep_outdated, pypi_mirror=pypi_mirror)
# Write out the lockfile if it doesn't exist.
if not project.lockfile_exists and not skip_lock:
# Unless we're in a virtualenv not managed by pipenv, abort if we're
@@ -1363,6 +1371,7 @@ def do_init(
pre=pre,
keep_outdated=keep_outdated,
verbose=verbose,
pypi_mirror=pypi_mirror,
)
do_install_dependencies(
dev=dev,
@@ -1372,6 +1381,7 @@ def do_init(
verbose=verbose,
concurrent=concurrent,
requirements_dir=requirements_dir.name,
pypi_mirror=pypi_mirror,
)
requirements_dir.cleanup()
# Activate virtualenv instructions.
@@ -1392,6 +1402,7 @@ def pip_install(
selective_upgrade=False,
requirements_dir=None,
extra_indexes=None,
pypi_mirror = None,
):
from notpip._internal import logger as piplogger
from notpip._vendor.pyparsing import ParseException
@@ -1463,6 +1474,8 @@ def pip_install(
sources.append({'url': idx['url']})
else:
sources = project.pipfile_sources
if pypi_mirror:
sources = [create_mirror_source(pypi_mirror) if is_pypi_url(source['url']) else source for source in sources]
if package_name.startswith('-e '):
install_reqs = ' -e "{0}"'.format(package_name.split('-e ')[1])
elif r:
@@ -1684,7 +1697,7 @@ def warn_in_virtualenv():
)
def ensure_lockfile(keep_outdated=False):
def ensure_lockfile(keep_outdated=False, pypi_mirror=None):
"""Ensures that the lockfile is uptodate."""
if not keep_outdated:
keep_outdated = project.settings.get('keep_outdated')
@@ -1702,9 +1715,9 @@ def ensure_lockfile(keep_outdated=False):
),
err=True,
)
do_lock(keep_outdated=keep_outdated)
do_lock(keep_outdated=keep_outdated, pypi_mirror=pypi_mirror)
else:
do_lock(keep_outdated=keep_outdated)
do_lock(keep_outdated=keep_outdated, pypi_mirror=pypi_mirror)
def do_py(system=False):
@@ -1714,7 +1727,7 @@ def do_py(system=False):
click.echo(crayons.red('No project found!'))
def do_outdated():
def do_outdated(pypi_mirror=None):
packages = {}
results = delegator.run('{0} freeze'.format(which('pip'))).out.strip(
).split(
@@ -1725,7 +1738,7 @@ def do_outdated():
dep = Requirement.from_line(result)
packages.update(dep.as_pipfile())
updated_packages = {}
lockfile = do_lock(write=False)
lockfile = do_lock(write=False, pypi_mirror=pypi_mirror)
for section in ('develop', 'default'):
for package in lockfile[section]:
try:
@@ -1757,6 +1770,7 @@ def do_install(
dev=False,
three=False,
python=False,
pypi_mirror=None,
system=False,
lock=True,
ignore_pipfile=False,
@@ -1909,7 +1923,7 @@ def do_install(
# Capture . argument and assign it to nothing
if package_name == '.':
package_name = False
# Install editable local packages before locking - this givves us acceess to dist-info
# Install editable local packages before locking - this gives us access to dist-info
if project.pipfile_exists and (
not project.lockfile_exists or not project.virtualenv_exists
):
@@ -1941,6 +1955,7 @@ def do_install(
deploy=deploy,
pre=pre,
requirements_dir=requirements_directory,
pypi_mirror=pypi_mirror,
)
requirements_directory.cleanup()
sys.exit(0)
@@ -1986,6 +2001,7 @@ def do_install(
requirements_dir=requirements_directory.name,
index=index,
extra_indexes=extra_indexes,
pypi_mirror=pypi_mirror,
)
# Warn if --editable wasn't passed.
try:
@@ -2060,6 +2076,7 @@ def do_install(
keep_outdated=keep_outdated,
requirements_dir=requirements_directory,
deploy=deploy,
pypi_mirror=pypi_mirror,
)
requirements_directory.cleanup()
@@ -2075,6 +2092,7 @@ def do_uninstall(
all=False,
verbose=False,
keep_outdated=False,
pypi_mirror=None,
):
# Automatically use an activated virtualenv.
if PIPENV_USE_SYSTEM:
@@ -2147,7 +2165,7 @@ def do_uninstall(
project.remove_package_from_pipfile(package_name, dev=True)
project.remove_package_from_pipfile(package_name, dev=False)
if lock:
do_lock(system=system, keep_outdated=keep_outdated)
do_lock(system=system, keep_outdated=keep_outdated, pypi_mirror=pypi_mirror)
def do_shell(three=None, python=False, fancy=False, shell_args=None):
@@ -2546,6 +2564,7 @@ def do_sync(
clear=False,
unused=False,
sequential=False,
pypi_mirror=None,
):
# The lock file needs to exist because sync won't write to it.
if not project.lockfile_exists:
@@ -2571,17 +2590,18 @@ def do_sync(
concurrent=(not sequential),
requirements_dir=requirements_dir,
ignore_pipfile=True, # Don't check if Pipfile and lock match.
pypi_mirror=pypi_mirror,
)
requirements_dir.cleanup()
click.echo(crayons.green('All dependencies are now up-to-date!'))
def do_clean(
ctx, three=None, python=None, dry_run=False, bare=False, verbose=False
ctx, three=None, python=None, dry_run=False, bare=False, verbose=False, pypi_mirror=None
):
# Ensure that virtualenv is available.
ensure_project(three=three, python=python, validate=False)
ensure_lockfile()
ensure_lockfile(pypi_mirror=pypi_mirror)
installed_package_names = []
pip_freeze_command = delegator.run('{0} freeze'.format(which_pip()))
+2
View File
@@ -76,3 +76,5 @@ PYENV_INSTALLED = (
SESSION_IS_INTERACTIVE = bool(os.isatty(sys.stdout.fileno()))
PIPENV_SHELL = os.environ.get('SHELL') or os.environ.get('PYENV_SHELL')
PIPENV_CACHE_DIR = os.environ.get('PIPENV_CACHE_DIR', user_cache_dir('pipenv'))
# Tells pipenv to override PyPI index urls with a mirror.
PIPENV_PYPI_MIRROR = os.environ.get('PIPENV_PYPI_MIRROR')
+2 -1
View File
@@ -48,6 +48,7 @@ def main():
for i, package in enumerate(packages):
if package.startswith('--'):
del packages[i]
pypi_mirror_source = pipenv.utils.create_mirror_source(os.environ['PIPENV_PYPI_MIRROR']) if 'PIPENV_PYPI_MIRROR' in os.environ else None
project = pipenv.core.project
def resolve(packages, pre, sources, verbose, clear, system):
@@ -66,7 +67,7 @@ def main():
results = resolve(
packages,
pre=do_pre,
sources=project.pipfile_sources,
sources = pipenv.utils.replace_pypi_sources(project.pipfile_sources, pypi_mirror_source) if pypi_mirror_source else project.pipfile_sources,
verbose=is_verbose,
clear=do_clear,
system=system,
+16 -1
View File
@@ -325,7 +325,7 @@ def actually_resolve_deps(
def venv_resolve_deps(
deps, which, project, pre=False, verbose=False, clear=False, allow_global=False
deps, which, project, pre=False, verbose=False, clear=False, allow_global=False, pypi_mirror=None
):
from .vendor import delegator
from . import resolver
@@ -343,6 +343,8 @@ def venv_resolve_deps(
)
with temp_environ():
os.environ['PIPENV_PACKAGES'] = '\n'.join(deps)
if pypi_mirror:
os.environ['PIPENV_PYPI_MIRROR'] = str(pypi_mirror)
c = delegator.run(cmd, block=True)
try:
assert c.return_code == 0
@@ -922,6 +924,16 @@ def is_valid_url(url):
return all([pieces.scheme, pieces.netloc])
def is_pypi_url(url):
return bool(re.match(r'^http[s]?:\/\/pypi(?:\.python)?\.org\/simple[\/]?$', url))
def replace_pypi_sources(sources, pypi_replacement_source):
return [pypi_replacement_source] + [source for source in sources if not is_pypi_url(source['url'])]
def create_mirror_source(url):
return {'url': url, 'verify_ssl': url.startswith('https://'), 'name': urlparse(url).hostname}
def download_file(url, filename):
"""Downloads file from url to a path with filename"""
r = _get_requests_session().get(url, stream=True)
@@ -1145,6 +1157,7 @@ def get_vcs_deps(
pre=False,
allow_global=False,
dev=False,
pypi_mirror=None,
):
from .patched.notpip._internal.vcs import VcsSupport
from ._compat import TemporaryDirectory
@@ -1209,6 +1222,7 @@ def get_vcs_deps(
clear=clear,
pre=pre,
allow_global=allow_global,
pypi_mirror=pypi_mirror,
)
)
else:
@@ -1221,6 +1235,7 @@ def get_vcs_deps(
clear=clear,
pre=pre,
allow_global=allow_global,
pypi_mirror=pypi_mirror,
)
)
return lines, lockfiles
+35
View File
@@ -40,6 +40,41 @@ def test_basic_install(PipenvInstance, pypi):
assert 'certifi' in p.lockfile['default']
@pytest.mark.install
@flaky
def test_mirror_install(PipenvInstance, pypi):
with temp_environ(), PipenvInstance(chdir=True) as p:
mirror_url = os.environ.pop('PIPENV_TEST_INDEX', "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('install requests --pypi-mirror {0}'.format(mirror_url))
assert c.return_code == 0
# Ensure the --pypi-mirror parameter hasn't altered the Pipfile or Pipfile.lock sources
assert len(p.pipfile['source']) == 1
assert len(p.lockfile["_meta"]["sources"]) == 1
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']
@pytest.mark.install
@pytest.mark.needs_internet
@flaky
def test_bad_mirror_install(PipenvInstance, pypi):
with temp_environ(), PipenvInstance(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')
assert c.return_code != 0
@pytest.mark.complex
@pytest.mark.lock
@pytest.mark.skip(reason='Does not work unless you can explicitly install into py2')
+42
View File
@@ -1,6 +1,8 @@
import pytest
import os
from pipenv.utils import temp_environ
from flaky import flaky
@@ -250,6 +252,46 @@ requests = "*"
assert '--extra-index-url https://test.pypi.org/simple' in c.out.strip()
@pytest.mark.requirements
@pytest.mark.lock
@pytest.mark.index
@pytest.mark.install # private indexes need to be uncached for resolution
@pytest.mark.needs_internet
def test_private_index_mirror_lock_requirements(PipenvInstance):
# Don't use the local fake pypi
with temp_environ(), PipenvInstance(chdir=True) as p:
# Using pypi.python.org as pipenv-test-public-package is not
# included in the local pypi mirror
mirror_url = "https://pypi.python.org/simple"
os.environ.pop('PIPENV_TEST_INDEX', None)
with open(p.pipfile_path, 'w') as f:
contents = """
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[[source]]
url = "https://test.pypi.org/simple"
verify_ssl = true
name = "testpypi"
[packages]
pipenv-test-private-package = {version = "*", index = "testpypi"}
requests = "*"
""".strip()
f.write(contents)
c = p.pipenv('install --pypi-mirror {0}'.format(mirror_url))
assert c.return_code == 0
c = p.pipenv('lock -r --pypi-mirror {0}'.format(mirror_url))
assert c.return_code == 0
assert '-i https://pypi.org/simple' in c.out.strip()
assert '--extra-index-url https://test.pypi.org/simple' in c.out.strip()
# Mirror url should not have replaced source URLs
assert '-i {0}'.format(mirror_url) not in c.out.strip()
assert '--extra-index-url {}'.format(mirror_url) not in c.out.strip()
@pytest.mark.install
@pytest.mark.index
def test_lock_updated_source(PipenvInstance, pypi):
+21
View File
@@ -1,3 +1,7 @@
import os
from pipenv.utils import temp_environ
import pytest
@@ -14,6 +18,23 @@ def test_sync_error_without_lockfile(PipenvInstance, pypi):
assert 'Pipfile.lock is missing!' in c.err
@pytest.mark.sync
@pytest.mark.lock
def test_mirror_lock_sync(PipenvInstance, pypi):
with temp_environ(), PipenvInstance(chdir=True) as p:
mirror_url = os.environ.pop('PIPENV_TEST_INDEX', "https://pypi.python.org/simple")
assert 'pypi.org' not in mirror_url
with open(p.pipfile_path, 'w') as f:
f.write("""
[packages]
six = "*"
""".strip())
c = p.pipenv('lock --pypi-mirror {0}'.format(mirror_url))
assert c.return_code == 0
c = p.pipenv('sync --pypi-mirror {0}'.format(mirror_url))
assert c.return_code == 0
@pytest.mark.sync
@pytest.mark.lock
def test_sync_should_not_lock(PipenvInstance, pypi):
+43
View File
@@ -1,6 +1,8 @@
import os
import shutil
from pipenv.utils import temp_environ
import pytest
@@ -31,6 +33,47 @@ def test_uninstall(PipenvInstance, pypi):
assert c.return_code > 0
@pytest.mark.run
@pytest.mark.uninstall
@pytest.mark.install
def test_mirror_uninstall(PipenvInstance, pypi):
with temp_environ(), PipenvInstance(chdir=True) as p:
mirror_url = os.environ.pop('PIPENV_TEST_INDEX', "https://pypi.python.org/simple")
assert 'pypi.org' not in mirror_url
c = p.pipenv('install requests --pypi-mirror {0}'.format(mirror_url))
assert c.return_code == 0
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']
# Ensure the --pypi-mirror parameter hasn't altered the Pipfile or Pipfile.lock sources
assert len(p.pipfile['source']) == 1
assert len(p.lockfile["_meta"]["sources"]) == 1
assert 'https://pypi.org/simple' == p.pipfile['source'][0]['url']
assert 'https://pypi.org/simple' == p.lockfile['_meta']['sources'][0]['url']
c = p.pipenv('uninstall requests --pypi-mirror {0}'.format(mirror_url))
assert c.return_code == 0
assert 'requests' not in p.pipfile['dev-packages']
assert 'requests' not in p.lockfile['develop']
assert 'chardet' not in p.lockfile['develop']
assert 'idna' not in p.lockfile['develop']
assert 'urllib3' not in p.lockfile['develop']
assert 'certifi' not in p.lockfile['develop']
# Ensure the --pypi-mirror parameter hasn't altered the Pipfile or Pipfile.lock sources
assert len(p.pipfile['source']) == 1
assert len(p.lockfile["_meta"]["sources"]) == 1
assert 'https://pypi.org/simple' == p.pipfile['source'][0]['url']
assert 'https://pypi.org/simple' == p.lockfile['_meta']['sources'][0]['url']
c = p.pipenv('run python -m requests.help')
assert c.return_code > 0
@pytest.mark.files
@pytest.mark.uninstall
@pytest.mark.install