mirror of
https://github.com/kennethreitz/pipenv.git
synced 2026-06-05 22:50:18 +00:00
Merge branch 'master' into windows-run-non-executable
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
Pipenv: Python Development Workflow for Humans
|
||||
==============================================
|
||||
|
||||
[](https://pypi.python.org/pypi/pipenv)
|
||||
[](https://pypi.python.org/pypi/pipenv)
|
||||
[](https://python.org/pypi/pipenv)
|
||||
[](https://python.org/pypi/pipenv)
|
||||
[](https://code.kennethreitz.org/source/pipenv/)
|
||||
[](https://pypi.python.org/pypi/pipenv)
|
||||
[](https://python.org/pypi/pipenv)
|
||||
[](https://saythanks.io/to/kennethreitz)
|
||||
|
||||
------------------------------------------------------------------------
|
||||
@@ -216,6 +216,29 @@ Install packages:
|
||||
To activate this project's virtualenv, run the following:
|
||||
$ pipenv shell
|
||||
|
||||
Installing from git:
|
||||
|
||||
You can install packages with pipenv from git and other version control systems using URLs formatted according to the following rule:
|
||||
|
||||
<vcs_type>+<scheme>://<location>/<user_or_organizatoin>/<repository>@<branch_or_tag>#<package_name>
|
||||
|
||||
The only optional section is the `@<branch_or_tag>` section. When using git over SSH, you may use the shorthand vcs and scheme alias `git+git@<location>:<user_or_organization>/<repository>@<branch_or_tag>#<package_name>`. Note that this is translated to `git+ssh://git@<location>` when parsed.
|
||||
|
||||
Valid values for `<vcs_type>` include `git`, `bzr`, `svn`, and `hg`. Valid values for `<scheme>` include `http,`, `https`, `ssh`, and `file`. In specific cases you also have access to other schemes: `svn` may be combined with `svn` as a scheme, and `bzr` can be combined with `sftp` and `lp`.
|
||||
|
||||
Note that it is **strongly recommended** that you install any version-controlled dependencies in editable mode, using `pipenv install -e`, in order to ensure that dependency resolution can be performed with an up to date copy of the repository each time it is performed, and that it includes all known dependencies.
|
||||
|
||||
Below is an example usage which installs the git repository located at `https://github.com/requests/requests.git` from tag `v2.19.1` as package name `requests`:
|
||||
|
||||
$ pipenv install -e git+https://github.com/requests/requests.git@v2.19#egg=requests
|
||||
Creating a Pipfile for this project...
|
||||
Installing -e git+https://github.com/requests/requests.git@v2.19.1#egg=requests...
|
||||
[...snipped...]
|
||||
Adding -e git+https://github.com/requests/requests.git@v2.19.1#egg=requests to Pipfile's [packages]...
|
||||
[...]
|
||||
|
||||
You can read more about [pip's implementation of vcs support here](https://pip.pypa.io/en/stable/reference/pip_install/#vcs-support).
|
||||
|
||||
Install a dev dependency:
|
||||
|
||||
$ pipenv install pytest --dev
|
||||
|
||||
Vendored
+1
-1
@@ -60,7 +60,7 @@
|
||||
</style>
|
||||
|
||||
<!-- GitHub Logo -->
|
||||
<a href="https://github.com/kennethreitz/pipenv" class="github-corner" aria-label="View source on Github">
|
||||
<a href="https://github.com/kennethreitz/pipenv" class="github-corner" aria-label="View source on GitHub">
|
||||
<svg width="80" height="80" viewBox="0 0 250 250" style="fill:#151513; color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true">
|
||||
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
|
||||
<path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path>
|
||||
|
||||
+18
-5
@@ -334,17 +334,30 @@ If you experience issues with ``$ pipenv shell``, just check the ``PIPENV_SHELL`
|
||||
☤ A Note about VCS Dependencies
|
||||
-------------------------------
|
||||
|
||||
Pipenv will resolve the sub–dependencies of VCS dependencies, but only if they are installed in editable mode::
|
||||
You can install packages with pipenv from git and other version control systems using URLs formatted according to the following rule::
|
||||
|
||||
$ pipenv install -e git+https://github.com/requests/requests.git#egg=requests
|
||||
<vcs_type>+<scheme>://<location>/<user_or_organizatoin>/<repository>@<branch_or_tag>#<package_name>
|
||||
|
||||
The only optional section is the ``@<branch_or_tag>`` section. When using git over SSH, you may use the shorthand vcs and scheme alias ``git+git@<location>:<user_or_organization>/<repository>@<branch_or_tag>#<package_name>``. Note that this is translated to ``git+ssh://git@<location>`` when parsed.
|
||||
|
||||
Note that it is **strongly recommended** that you install any version-controlled dependencies in editable mode, using ``pipenv install -e``, in order to ensure that dependency resolution can be performed with an up to date copy of the repository each time it is performed, and that it includes all known dependencies.
|
||||
|
||||
Below is an example usage which installs the git repository located at ``https://github.com/requests/requests.git`` from tag ``v2.19.1`` as package name ``requests``::
|
||||
|
||||
$ pipenv install -e git+https://github.com/requests/requests.git@v2.19#egg=requests
|
||||
Creating a Pipfile for this project...
|
||||
Installing -e git+https://github.com/requests/requests.git@v2.19.1#egg=requests...
|
||||
[...snipped...]
|
||||
Adding -e git+https://github.com/requests/requests.git@v2.19.1#egg=requests to Pipfile's [packages]...
|
||||
[...]
|
||||
|
||||
$ cat Pipfile
|
||||
[packages]
|
||||
requests = {git = "https://github.com/requests/requests.git", editable=true}
|
||||
requests = {git = "https://github.com/requests/requests.git", editable = true, ref = "2.19.1"}
|
||||
|
||||
If editable is not true, sub–dependencies will not be resolved.
|
||||
Valid values for ``<vcs_type>`` include ``git``, ``bzr``, ``svn``, and ``hg``. Valid values for ``<scheme>`` include ``http``, ``https``, ``ssh``, and ``file``. In specific cases you also have access to other schemes: ``svn`` may be combined with ``svn`` as a scheme, and ``bzr`` can be combined with ``sftp`` and ``lp``.
|
||||
|
||||
For more information about other options available when specifying VCS dependencies, please check the `Pipfile spec <https://github.com/pypa/pipfile>`__.
|
||||
You can read more about pip's implementation of VCS support `here <https://pip.pypa.io/en/stable/reference/pip_install/#vcs-support>`_. For more information about other options available when specifying VCS dependencies, please check the `Pipfile spec <https://github.com/pypa/pipfile>`_.
|
||||
|
||||
|
||||
☤ Pipfile.lock Security Features
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
Added simple example to README.md for installing from git.
|
||||
@@ -0,0 +1 @@
|
||||
Added additional information to error messaging during failed resolution.
|
||||
+1
-1
@@ -134,7 +134,7 @@ def validate_pypi_mirror(ctx, param, value):
|
||||
@option(
|
||||
"--support",
|
||||
is_flag=True,
|
||||
help="Output diagnostic information for use in Github issues.",
|
||||
help="Output diagnostic information for use in GitHub issues.",
|
||||
)
|
||||
@option("--clear", is_flag=True, help="Clears caches (pipenv, pip, and pip-tools).")
|
||||
@version_option(prog_name=crayons.normal("pipenv", bold=True), version=__version__)
|
||||
|
||||
+8
-6
@@ -113,9 +113,10 @@ class Bar(object):
|
||||
self.etadisp = self.format_time(self.eta)
|
||||
x = int(self.width * progress / self.expected_size)
|
||||
if not self.hide:
|
||||
if (progress % self.every) == 0 or ( # True every "every" updates
|
||||
progress == self.expected_size
|
||||
): # And when we're done
|
||||
if (
|
||||
progress % self.every == 0 # True every "every" updates
|
||||
or progress == self.expected_size # And when we're done
|
||||
):
|
||||
STREAM.write(
|
||||
BAR_TEMPLATE
|
||||
% (
|
||||
@@ -208,9 +209,10 @@ def mill(it, label="", hide=None, expected_size=None, every=1):
|
||||
|
||||
def _show(_i):
|
||||
if not hide:
|
||||
if (_i % every) == 0 or (
|
||||
_i == count
|
||||
): # True every "every" updates # And when we're done
|
||||
if (
|
||||
_i % every == 0 # True every "every" updates
|
||||
or _i == count # And when we're done
|
||||
):
|
||||
STREAM.write(MILL_TEMPLATE % (label, _mill_char(_i), _i, count))
|
||||
STREAM.flush()
|
||||
|
||||
|
||||
+12
-1
@@ -34,6 +34,7 @@ from .utils import (
|
||||
is_star,
|
||||
get_workon_home,
|
||||
is_virtual_environment,
|
||||
looks_like_dir
|
||||
)
|
||||
from .environments import (
|
||||
PIPENV_MAX_DEPTH,
|
||||
@@ -267,7 +268,17 @@ class Project(object):
|
||||
def get_location_for_virtualenv(self):
|
||||
if self.is_venv_in_project():
|
||||
return os.path.join(self.project_directory, ".venv")
|
||||
return str(get_workon_home().joinpath(self.virtualenv_name))
|
||||
|
||||
name = self.virtualenv_name
|
||||
if self.project_directory:
|
||||
venv_path = os.path.join(self.project_directory, ".venv")
|
||||
if os.path.exists(venv_path) and not os.path.isdir(".venv"):
|
||||
with io.open(venv_path, "r") as f:
|
||||
name = f.read().strip()
|
||||
# Assume file's contents is a path if it contains slashes.
|
||||
if looks_like_dir(name):
|
||||
return Path(name).absolute().as_posix()
|
||||
return str(get_workon_home().joinpath(name))
|
||||
|
||||
def get_installed_packages(self):
|
||||
from . import PIPENV_ROOT, PIPENV_VENDOR, PIPENV_PATCHED
|
||||
|
||||
+10
-3
@@ -310,11 +310,13 @@ def actually_resolve_deps(
|
||||
click_echo(
|
||||
"{0}: Your dependencies could not be resolved. You likely have a "
|
||||
"mismatch in your sub-dependencies.\n "
|
||||
"You can use {1} to bypass this mechanism, then run {2} to inspect "
|
||||
"the situation.\n "
|
||||
"Hint: try {3} if it is a pre-release dependency."
|
||||
"First try clearing your dependency cache with {1}, then try the original command again.\n "
|
||||
"Alternatively, you can use {2} to bypass this mechanism, then run "
|
||||
"{3} to inspect the situation.\n "
|
||||
"Hint: try {4} if it is a pre-release dependency."
|
||||
"".format(
|
||||
crayons.red("Warning", bold=True),
|
||||
crayons.red("$ pipenv lock --clear"),
|
||||
crayons.red("$ pipenv install --skip-lock"),
|
||||
crayons.red("$ pipenv graph"),
|
||||
crayons.red("$ pipenv lock --pre"),
|
||||
@@ -1374,3 +1376,8 @@ def chdir(path):
|
||||
yield
|
||||
finally:
|
||||
os.chdir(prev_cwd)
|
||||
|
||||
|
||||
def looks_like_dir(path):
|
||||
seps = (sep for sep in (os.path.sep, os.path.altsep) if sep is not None)
|
||||
return any(sep in path for sep in seps)
|
||||
|
||||
@@ -6,6 +6,7 @@ set -eo pipefail
|
||||
|
||||
export PYTHONIOENCODING="utf-8"
|
||||
export LANG=C.UTF-8
|
||||
export PIP_PROCESS_DEPENDENCY_LINKS="1"
|
||||
|
||||
prefix() {
|
||||
sed "s/^/ $1: /"
|
||||
|
||||
@@ -16,6 +16,9 @@ if six.PY2:
|
||||
pass
|
||||
|
||||
|
||||
HAS_WARNED_GITHUB = False
|
||||
|
||||
|
||||
def check_internet():
|
||||
try:
|
||||
# Kenneth represents the Internet LGTM.
|
||||
@@ -40,13 +43,15 @@ def check_github_ssh():
|
||||
res = True if c.return_code == 1 else False
|
||||
except Exception:
|
||||
pass
|
||||
if not res:
|
||||
global HAS_WARNED_GITHUB
|
||||
if not res and not HAS_WARNED_GITHUB:
|
||||
warnings.warn(
|
||||
'Cannot connect to GitHub via SSH', ResourceWarning
|
||||
)
|
||||
warnings.warn(
|
||||
'Will skip tests requiring SSH access to GitHub', ResourceWarning
|
||||
)
|
||||
HAS_WARNED_GITHUB = True
|
||||
return res
|
||||
|
||||
|
||||
|
||||
@@ -41,15 +41,17 @@ def test_reuse_previous_venv(PipenvInstance, pypi):
|
||||
assert c.return_code == 0
|
||||
assert normalize_drive(p.path) in p.pipenv('--venv').out
|
||||
|
||||
|
||||
@pytest.mark.dotvenv
|
||||
def test_venv_file_exists(PipenvInstance, pypi):
|
||||
"""Tests virtualenv creation & package installation when a .venv file exists
|
||||
at the project root.
|
||||
@pytest.mark.parametrize('venv_name', ('test-venv', os.path.join('foo', 'test-venv')))
|
||||
def test_venv_file(venv_name, PipenvInstance, pypi):
|
||||
"""Tests virtualenv creation when a .venv file exists at the project root
|
||||
and contains a venv name.
|
||||
"""
|
||||
with PipenvInstance(pypi=pypi, chdir=True) as p:
|
||||
file_path = os.path.join(p.path, '.venv')
|
||||
with open(file_path, 'w') as f:
|
||||
f.write('')
|
||||
f.write(venv_name)
|
||||
|
||||
with temp_environ(), TemporaryDirectory(
|
||||
prefix='pipenv-', suffix='temp_workon_home'
|
||||
@@ -58,12 +60,43 @@ def test_venv_file_exists(PipenvInstance, pypi):
|
||||
if 'PIPENV_VENV_IN_PROJECT' in os.environ:
|
||||
del os.environ['PIPENV_VENV_IN_PROJECT']
|
||||
|
||||
c = p.pipenv('install requests')
|
||||
c = p.pipenv('install')
|
||||
assert c.return_code == 0
|
||||
|
||||
venv_loc = None
|
||||
for line in c.err.splitlines():
|
||||
if line.startswith('Virtualenv location:'):
|
||||
venv_loc = Path(line.split(':', 1)[-1].strip())
|
||||
assert venv_loc is not None
|
||||
c = p.pipenv('--venv')
|
||||
assert c.return_code == 0
|
||||
venv_loc = Path(c.out.strip()).absolute()
|
||||
assert venv_loc.exists()
|
||||
assert venv_loc.joinpath('.project').exists()
|
||||
venv_path = venv_loc.as_posix()
|
||||
if os.path.sep in venv_name:
|
||||
venv_expected_path = Path(p.path).joinpath(venv_name).absolute().as_posix()
|
||||
else:
|
||||
venv_expected_path = Path(workon_home.name).joinpath(venv_name).absolute().as_posix()
|
||||
assert venv_path == venv_expected_path
|
||||
|
||||
|
||||
@pytest.mark.dotvenv
|
||||
def test_venv_file_with_path(PipenvInstance, pypi):
|
||||
"""Tests virtualenv creation when a .venv file exists at the project root
|
||||
and contains an absolute path.
|
||||
"""
|
||||
with temp_environ(), PipenvInstance(chdir=True, pypi=pypi) as p:
|
||||
with TemporaryDirectory(
|
||||
prefix='pipenv-', suffix='-test_venv'
|
||||
) as venv_path:
|
||||
if 'PIPENV_VENV_IN_PROJECT' in os.environ:
|
||||
del os.environ['PIPENV_VENV_IN_PROJECT']
|
||||
|
||||
file_path = os.path.join(p.path, '.venv')
|
||||
with open(file_path, 'w') as f:
|
||||
f.write(venv_path.name)
|
||||
|
||||
c = p.pipenv('install')
|
||||
assert c.return_code == 0
|
||||
c = p.pipenv('--venv')
|
||||
assert c.return_code == 0
|
||||
venv_loc = Path(c.out.strip())
|
||||
|
||||
assert venv_loc.joinpath('.project').exists()
|
||||
assert venv_loc == Path(venv_path.name)
|
||||
|
||||
@@ -44,7 +44,7 @@ def test_basic_install(PipenvInstance, pypi):
|
||||
@pytest.mark.install
|
||||
@flaky
|
||||
def test_mirror_install(PipenvInstance, pypi):
|
||||
with temp_environ(), PipenvInstance(chdir=True) as p:
|
||||
with temp_environ(), PipenvInstance(chdir=True, pypi=pypi) as p:
|
||||
mirror_url = os.environ.pop(
|
||||
"PIPENV_TEST_INDEX", "https://pypi.python.org/simple"
|
||||
)
|
||||
|
||||
@@ -15,7 +15,7 @@ import os.path
|
||||
def where():
|
||||
"""Return the preferred certificate bundle."""
|
||||
# vendored bundle inside Requests
|
||||
return os.path.join(os.path.dirname(__file__), 'certs', 'cacert.pem')
|
||||
return os.path.join(os.path.abspath(os.path.dirname(__file__)), 'certs', 'cacert.pem')
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(where())
|
||||
|
||||
Reference in New Issue
Block a user