diff --git a/Dockerfile b/Dockerfile index f69886e4..4bab57e2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,11 @@ FROM ubuntu:17.10 # -- Install Pipenv: -RUN apt update -RUN apt install software-properties-common python-software-properties -y -RUN add-apt-repository ppa:pypa/ppa -y -RUN apt update -RUN apt install git pipenv -y +RUN apt-get update \ + && apt-get install software-properties-common python-software-properties -y \ + && add-apt-repository ppa:pypa/ppa -y \ + && apt-get update \ + && apt-get install git pipenv -y ENV LC_ALL C.UTF-8 ENV LANG C.UTF-8 diff --git a/Pipfile.lock b/Pipfile.lock index 1435c2d9..df32d972 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -65,6 +65,14 @@ "index": "pypi", "version": "==6.7" }, + "colorama": { + "hashes": [ + "sha256:463f8483208e921368c9f306094eb6f725c6ca42b0f97e313cb5d5512459feda", + "sha256:48eb22f4f8461b1df5734a074b57042430fb06e1d61bd1e11b078c0fe6d7a1f1" + ], + "markers": "sys_platform == 'win32'", + "version": "==0.3.9" + }, "docutils": { "hashes": [ "sha256:02aec4bd92ab067f6ff27a38a38a41173bf01bed8f89157768c1573f53e474a6", @@ -143,6 +151,14 @@ "index": "pypi", "version": "==2.0.0" }, + "more-itertools": { + "hashes": [ + "sha256:0dd8f72eeab0d2c3bd489025bb2f6a1b8342f9b198f6fc37b52d15cfa4531fea", + "sha256:11a625025954c20145b37ff6309cd54e39ca94f72f6bb9576d1195db6fa2442e", + "sha256:c9ce7eccdcb901a2c75d326ea134e0886abfbea5f93e91cc95de9507c0816c44" + ], + "version": "==4.1.0" + }, "pathlib": { "hashes": [ "sha256:6940718dfc3eff4258203ad5021090933e5c04707d5ca8cc9e73c94a7894ea9f" @@ -176,10 +192,10 @@ }, "py": { "hashes": [ - "sha256:8cca5c229d225f8c1e3085be4fcf306090b00850fefad892f9d96c7b6e2f310f", - "sha256:ca18943e28235417756316bfada6cd96b23ce60dd532642690dcfdaba988a76d" + "sha256:29c9fab495d7528e80ba1e343b958684f4ace687327e6f789a94bf3d1915f881", + "sha256:983f77f3331356039fdd792e9220b7b8ee1aa6bd2b25f567a963ff1de5a64f6a" ], - "version": "==1.5.2" + "version": "==1.5.3" }, "pycodestyle": { "hashes": [ @@ -204,11 +220,11 @@ }, "pytest": { "hashes": [ - "sha256:062027955bccbc04d2fcd5d79690947e018ba31abe4c90b2c6721abec734261b", - "sha256:117bad36c1a787e1a8a659df35de53ba05f9f3398fb9e4ac17e80ad5903eb8c5" + "sha256:6266f87ab64692112e5477eba395cfedda53b1933ccd29478e671e73b420c19c", + "sha256:fae491d1874f199537fd5872b5e1f0e74a009b979df9d53d1553fd03da1703e1" ], "index": "pypi", - "version": "==3.4.2" + "version": "==3.5.0" }, "pytest-forked": { "hashes": [ @@ -289,11 +305,11 @@ }, "sphinx-click": { "hashes": [ - "sha256:612a00b497e0434271d2ef808369d627d0002936d66ec21e11c07e79f886fbd5", - "sha256:fcab79e81120256f21ae86e099186a78abfe0fff45002b33ed04ccf38dba8490" + "sha256:0eef2d55ee4b5ebc448d8aa52e6084b5085fd2e7852d7571abb090411217c4df", + "sha256:c2680d84e8608bf47141e16924f1a981c653caff0faefe47a1d41c1438fbd5b4" ], "index": "pypi", - "version": "==1.0.4" + "version": "==1.1.0" }, "stdeb": { "hashes": [ @@ -319,11 +335,11 @@ }, "twine": { "hashes": [ - "sha256:c3540f2b98667698412b0dc9f5e40c8c1a08a9e79e255c9c21339105eb4ca57a", - "sha256:eff86e20fdffef8abb0b638784c62d0348dac4c80380907e39b732c56e9192fb" + "sha256:08eb132bbaec40c6d25b358f546ec1dc96ebd2638a86eea68769d9e67fe2b129", + "sha256:2fd9a4d9ff0bcacf41fdc40c8cb0cfaef1f1859457c9653fd1b92237cc4e9f25" ], "index": "pypi", - "version": "==1.10.0" + "version": "==1.11.0" }, "urllib3": { "hashes": [ @@ -334,10 +350,10 @@ }, "virtualenv": { "hashes": [ - "sha256:02f8102c2436bb03b3ee6dede1919d1dac8a427541652e5ec95171ec8adbc93a", - "sha256:39d88b533b422825d644087a21e78c45cf5af0ef7a99a1fc9fbb7b481e5c85b0" + "sha256:1d7e241b431e7afce47e77f8843a276f652699d1fa4f93b9d8ce0076fd7b0b54", + "sha256:e8e05d4714a1c51a2f5921e62f547fcb0f713ebbe959e0a7f585cc8bef71d11f" ], - "version": "==15.1.0" + "version": "==15.2.0" }, "virtualenv-clone": { "hashes": [ diff --git a/docs/advanced.rst b/docs/advanced.rst index be2d8905..a97ee2de 100644 --- a/docs/advanced.rst +++ b/docs/advanced.rst @@ -12,7 +12,7 @@ This document covers some of Pipenv's more glorious and advanced features. - Dependencies of wheels provided in a ``Pipfile`` will not be captured by ``$ pipenv lock``. - There are some known issues with using private indexes, related to hashing. We're actively working to solve this problem. You may have great luck with this, however. -- Installation is intended to be as determinstic as possible — use the ``--sequential`` flag to increase this, if experiencing issues. +- Installation is intended to be as deterministic as possible — use the ``--sequential`` flag to increase this, if experiencing issues. ☤ Specifying Package Indexes ---------------------------- @@ -517,9 +517,9 @@ at all, use the `PIP_IGNORE_INSTALLED` setting:: There is a subtle but very important distinction to be made between **applications** and **libraries**. This is a very common source of confusion in the Python community. -Libraries provide reusable functionality to other libraries and applications (let's use the umbrella term **projects** here). They are required to work alongside other libraries, all with their own set of subdependencies. They define **abstract dependencies**. To avoid version conflicts in subdependencies of different libraries within a project, libraries should never ever pin dependency versions. Although they may specifiy lower or (less frequently) upper bounds, if they rely on some specific feature/fix/bug. Library dependencies are specified via ``install_requires`` in ``setup.py``. +Libraries provide reusable functionality to other libraries and applications (let's use the umbrella term **projects** here). They are required to work alongside other libraries, all with their own set of subdependencies. They define **abstract dependencies**. To avoid version conflicts in subdependencies of different libraries within a project, libraries should never ever pin dependency versions. Although they may specify lower or (less frequently) upper bounds, if they rely on some specific feature/fix/bug. Library dependencies are specified via ``install_requires`` in ``setup.py``. -Libaries are ultimately meant to be used in some **application**. Applications are different in that they usually are not depended on by other projects. They are meant to be deployed into some specific environment and only then should the exact versions of all their dependencies and subdependencies be made concrete. To make this process easier is currently the main goal of ``pipenv``. +Libraries are ultimately meant to be used in some **application**. Applications are different in that they usually are not depended on by other projects. They are meant to be deployed into some specific environment and only then should the exact versions of all their dependencies and subdependencies be made concrete. To make this process easier is currently the main goal of ``pipenv``. To summarize: diff --git a/docs/basics.rst b/docs/basics.rst index c8dd89eb..f77d850b 100644 --- a/docs/basics.rst +++ b/docs/basics.rst @@ -124,7 +124,7 @@ Example Pipfile.lock ------------------------------------------- - Generally, keep both ``Pipfile`` and ``Pipfile.lock`` in version control. -- Do not keep ``Pipfile.lock`` in version control if multiple versions of Python are being targetted. +- Do not keep ``Pipfile.lock`` in version control if multiple versions of Python are being targeted. - Specify your target Python version in your `Pipfile`'s ``[requires]`` section. Ideally, you should only have one target Python version, as this is a deployment tool. diff --git a/pipenv/core.py b/pipenv/core.py index 3e7c570d..b083ed9d 100644 --- a/pipenv/core.py +++ b/pipenv/core.py @@ -4,7 +4,6 @@ import logging import os import sys import shutil -import shlex import signal import time import tempfile @@ -17,10 +16,8 @@ import crayons import dotenv import delegator import pexpect -import requests import pipfile import pipdeptree -import semver from pipreqs import pipreqs from blindspin import spinner @@ -41,19 +38,15 @@ from .utils import ( is_vcs, python_version, find_windows_executable, - is_file, prepare_pip_source_args, temp_environ, is_valid_url, download_file, get_requirement, - need_update_check, - touch_update_stamp, is_pinned, is_star, TemporaryDirectory, ) -from .__version__ import __version__ from .import pep508checker, progress from .environments import ( PIPENV_COLORBLIND, @@ -685,8 +678,6 @@ def shorten_path(location, bold=False): return os.sep.join(short) - - # return short def do_where(virtualenv=False, bare=True): """Executes the where functionality.""" diff --git a/pipenv/help.py b/pipenv/help.py index 7d219714..e08c6173 100644 --- a/pipenv/help.py +++ b/pipenv/help.py @@ -1,7 +1,6 @@ # coding: utf-8 import os import sys -import crayons import pipenv from pprint import pprint diff --git a/pipenv/project.py b/pipenv/project.py index ddc5f336..f349298c 100644 --- a/pipenv/project.py +++ b/pipenv/project.py @@ -36,7 +36,6 @@ from .environments import ( PIPENV_PIPFILE, PIPENV_VENV_IN_PROJECT, PIPENV_VIRTUALENV, - PIPENV_NO_INHERIT, PIPENV_TEST_INDEX, PIPENV_PYTHON, ) @@ -316,7 +315,6 @@ class Project(object): return self._parse_pipfile(contents) - def clear_pipfile_cache(self): """Clear pipfile cache (e.g., so we can mutate parsed pipfile)""" _pipfile_cache.clear() diff --git a/pipenv/utils.py b/pipenv/utils.py index 8faa9d9f..25031c2c 100644 --- a/pipenv/utils.py +++ b/pipenv/utils.py @@ -6,7 +6,6 @@ import tempfile import sys import shutil import logging -import errno import click import crayons import delegator @@ -50,7 +49,7 @@ from pip9.index import Link from pip9._vendor.requests.exceptions import HTTPError, ConnectionError from .pep508checker import lookup -from .environments import SESSION_IS_INTERACTIVE, PIPENV_MAX_ROUNDS, PIPENV_CACHE_DIR +from .environments import PIPENV_MAX_ROUNDS, PIPENV_CACHE_DIR if six.PY2: @@ -1025,7 +1024,7 @@ def find_windows_executable(bin_path, exe_name): return find_executable(exe_name) -def get_converted_relative_path(path, relative_to= os.curdir): +def get_converted_relative_path(path, relative_to=os.curdir): """Given a vague relative path, return the path relative to the given location""" return os.path.join('.', os.path.relpath(path, start=relative_to)) @@ -1072,8 +1071,6 @@ def find_requirements(max_depth=3): raise RuntimeError('No requirements.txt found!') - - # Borrowed from pew to avoid importing pew which imports psutil # See https://github.com/berdario/pew/blob/master/pew/_utils.py#L82 @contextmanager diff --git a/run-tests.sh b/run-tests.sh index f66a7fd2..92dadae5 100755 --- a/run-tests.sh +++ b/run-tests.sh @@ -37,7 +37,7 @@ else echo "Clearing Caches…" rm -fr ~/Library/Caches/pip - rm -fr ~/Libary/Caches/pipenv + rm -fr ~/Library/Caches/pipenv # Otherwise, assume Linux… else @@ -48,7 +48,7 @@ else # If the lockfile hasn't changed, skip installs. - echo "Instaling Pipenv…" + echo "Installing Pipenv…" pip install -e "$(pwd)" --upgrade-strategy=only-if-needed echo "Installing dependencies…" diff --git a/tests/pytest-pypi/README.md b/tests/pytest-pypi/README.md index cb830b04..a9ba37c2 100644 --- a/tests/pytest-pypi/README.md +++ b/tests/pytest-pypi/README.md @@ -103,7 +103,7 @@ and your tests executed by pytest all will have access to the `httpbin` and `htt ## Support and dependencies -pytest-httpbin suports Python 2.6, 2.7, 3.4, and pypy. It will automatically install httpbin and flask when you install it from pypi. +pytest-httpbin supports Python 2.6, 2.7, 3.4, and pypy. It will automatically install httpbin and flask when you install it from pypi. [httpbin](https://github.com/kennethreitz/httpbin) itself does not support python 2.6 as of version 0.6.0, when the Flask-common dependency was added. If you need python 2.6 support pin the httpbin version to 0.5.0 diff --git a/tests/test_pipenv.py b/tests/test_pipenv.py index 92c4427c..9b36a556 100644 --- a/tests/test_pipenv.py +++ b/tests/test_pipenv.py @@ -1,14 +1,12 @@ import os -from pkg_resources import parse_version import re -import tempfile import shutil import json import pytest import warnings from pipenv.core import activate_virtualenv from pipenv.utils import ( - temp_environ, get_windows_path, mkdir_p, normalize_drive, rmtree, TemporaryDirectory + temp_environ, get_windows_path, mkdir_p, normalize_drive, TemporaryDirectory ) from pipenv.vendor import toml from pipenv.vendor import delegator @@ -374,7 +372,6 @@ tablib = "*" assert 'requests' in p.lockfile['develop'] assert 'flask' in p.lockfile['develop'] - c = p.pipenv('uninstall --all-dev') assert c.return_code == 0 assert 'requests' not in p.pipfile['dev-packages'] @@ -384,7 +381,6 @@ tablib = "*" assert 'tpfd' in p.pipfile['packages'] assert 'tpfd' in p.lockfile['default'] - c = p.pipenv('run python -m requests.help') assert c.return_code > 0 @@ -776,7 +772,6 @@ requests = {version = "*"} out, _ = process.communicate() assert any(req.startswith('requests') for req in out.splitlines()) is True - @pytest.mark.run @pytest.mark.dotenv def test_env(self): @@ -1065,7 +1060,6 @@ requests = "==2.14.0" assert c.return_code == 0 assert all(pkg in p.lockfile['default'] for pkg in ['xlrd', 'xlwt', 'pyyaml', 'odfpy']) - @pytest.mark.install @pytest.mark.files def test_local_zipfiles(self): @@ -1090,7 +1084,6 @@ requests = "==2.14.0" assert 'file' in dep or 'path' in dep - @pytest.mark.install @pytest.mark.files @pytest.mark.urls @@ -1110,7 +1103,6 @@ requests = "==2.14.0" assert 'requests' in p.lockfile['default'] assert 'records' in p.lockfile['default'] - @pytest.mark.install @pytest.mark.files def test_relative_paths(self, pypi): @@ -1152,12 +1144,12 @@ requests = "==2.14.0" c = p.pipenv('clean') assert c.return_code == 0 - @pytest.mark.install - def test_environment_variable_value_does_not_change_hash(self, pypi, monkeypatch): + def test_environment_variable_value_does_not_change_hash(self, pypi): with PipenvInstance(chdir=True, pypi=pypi) as p: - with open(p.pipfile_path, 'w') as f: - f.write(""" + with temp_environ(): + with open(p.pipfile_path, 'w') as f: + f.write(""" [[source]] url = 'https://${PYPI_USERNAME}:${PYPI_PASSWORD}@pypi.python.org/simple' verify_ssl = true @@ -1169,22 +1161,22 @@ python_version = '2.7' [packages] flask = "==0.12.2" """) - monkeypatch.setitem(os.environ, 'PYPI_USERNAME', 'whatever') - monkeypatch.setitem(os.environ, 'PYPI_PASSWORD', 'pass') - assert Project().get_lockfile_hash() is None - c = p.pipenv('install') - lock_hash = Project().get_lockfile_hash() - assert lock_hash is not None - assert lock_hash == Project().calculate_pipfile_hash() - # sanity check on pytest - assert 'PYPI_USERNAME' not in str(pipfile.load(p.pipfile_path)) - assert c.return_code == 0 - assert Project().get_lockfile_hash() == Project.calculate_pipfile_hash() - monkeypatch.setitem(os.environ, 'PYPI_PASSWORD', 'pass2') - assert Project().get_lockfile_hash() == Project.calculate_pipfile_hash() - with open(p.pipfile_path, 'a') as f: - f.write('requests = "==2.14.0"\n') - assert Project().get_lockfile_hash() != Project.calculate_pipfile_hash() + os.environ['PYPI_USERNAME'] = 'whatever' + os.environ['PYPI_PASSWORD'] = 'pass' + assert Project().get_lockfile_hash() is None + c = p.pipenv('install') + lock_hash = Project().get_lockfile_hash() + assert lock_hash is not None + assert lock_hash == Project().calculate_pipfile_hash() + # sanity check on pytest + assert 'PYPI_USERNAME' not in str(pipfile.load(p.pipfile_path)) + assert c.return_code == 0 + assert Project().get_lockfile_hash() == Project().calculate_pipfile_hash() + os.environ['PYPI_PASSWORD'] = 'pass2' + assert Project().get_lockfile_hash() == Project().calculate_pipfile_hash() + with open(p.pipfile_path, 'a') as f: + f.write('requests = "==2.14.0"\n') + assert Project().get_lockfile_hash() != Project().calculate_pipfile_hash() @pytest.mark.run def test_scripts_basic(self):