Merge branch 'master' into feature/lock-r

This commit is contained in:
Nick Coghlan
2020-04-10 15:41:25 +10:00
committed by GitHub
62 changed files with 344 additions and 279 deletions
+11
View File
@@ -0,0 +1,11 @@
./examples
./tests
./docs
./news
./pipenv
./.git
./.buildkite
./peeps
./.github
./tasks
./.azure-pipelines
+1 -1
View File
@@ -5,7 +5,7 @@ about: Create a report to help us improve
Be sure to check the existing issues (both open and closed!), and make sure you are running the latest version of Pipenv.
Check the [diagnose documentation](https://docs.pipenv.org/en/latest/diagnose/) for common issues before posting! We may close your issue if it is very similar to one of them. Please be considerate, or be on your way.
Check the [diagnose documentation](https://pipenv.pypa.io/en/latest/diagnose/) for common issues before posting! We may close your issue if it is very similar to one of them. Please be considerate, or be on your way.
Make sure to mention your debugging experience if the documented solution failed.
+2 -2
View File
@@ -6,7 +6,7 @@
url = https://github.com/pinax/pinax.git
[submodule "tests/test_artifacts/git/requests"]
path = tests/test_artifacts/git/requests
url = https://github.com/kennethreitz/requests.git
url = https://github.com/psf/requests.git
[submodule "tests/test_artifacts/git/six"]
path = tests/test_artifacts/git/six
url = https://github.com/benjaminp/six.git
@@ -24,7 +24,7 @@
url = https://github.com/pallets/flask.git
[submodule "tests/test_artifacts/git/requests-2.18.4"]
path = tests/test_artifacts/git/requests-2.18.4
url = https://github.com/kennethreitz/requests
url = https://github.com/psf/requests
[submodule "tests/pypi"]
path = tests/pypi
url = https://github.com/sarugaku/pipenv-test-artifacts.git
+1 -1
View File
@@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright 2017 Kenneth Reitz
Copyright 2020 Python Packaging Authority
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+4 -11
View File
@@ -5,7 +5,6 @@ Pipenv: Python Development Workflow for Humans
[![image](https://img.shields.io/pypi/l/pipenv.svg)](https://python.org/pypi/pipenv)
[![Azure Pipelines Build Status](https://dev.azure.com/pypa/pipenv/_apis/build/status/Pipenv%20CI?branchName=master)](https://dev.azure.com/pypa/pipenv/_build/latest?definitionId=16&branchName=master)
[![image](https://img.shields.io/pypi/pyversions/pipenv.svg)](https://python.org/pypi/pipenv)
[![image](https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg)](https://saythanks.io/to/kennethreitz)
------------------------------------------------------------------------
@@ -18,7 +17,7 @@ well as adds/removes packages from your `Pipfile` as you
install/uninstall packages. It also generates the ever-important
`Pipfile.lock`, which is used to produce deterministic builds.
![image](https://s3.amazonaws.com/media.kennethreitz.com/pipenv.gif)
![GIF demonstrating Pipenv's usage](https://gist.githubusercontent.com/jlusk/855d611bbcfa2b159839db73d07f6ce9/raw/7f5743401809f7e630ee8ff458faa980e19924a0/pipenv.gif)
The problems that Pipenv seeks to solve are multi-faceted:
@@ -48,7 +47,7 @@ Or, if you\'re using Debian Buster+:
$ sudo apt install pipenv
Or, if you\'re using Fedora 28:
Or, if you\'re using Fedora:
$ sudo dnf install pipenv
@@ -56,19 +55,13 @@ Or, if you\'re using FreeBSD:
# pkg install py36-pipenv
Otherwise, refer to the [documentation](https://docs.pipenv.org/en/latest/install/#installing-pipenv) for instructions.
Otherwise, refer to the [documentation](https://pipenv.pypa.io/en/latest/#install-pipenv-today) for instructions.
✨🍰✨
☤ User Testimonials
-------------------
**Jannis Leidel**, former pip maintainer---
: *Pipenv is the porcelain I always wanted to build for pip. It fits
my brain and mostly replaces virtualenvwrapper and manual pip calls
for me. Use it.*
**David Gang**---
: *This package manager is really awesome. For the first time I know
@@ -303,4 +296,4 @@ Use the shell:
☤ Documentation
---------------
Documentation resides over at [pipenv.org](http://pipenv.org/).
Documentation resides over at [pipenv.pypa.io](https://pipenv.pypa.io/en/latest/).
-3
View File
@@ -40,7 +40,6 @@ jobs:
python.architecture: x64
maxParallel: 4
steps:
- template: .azure-pipelines/steps/reinstall-pythons.yml
- template: .azure-pipelines/steps/run-tests.yml
parameters:
vmImage: 'Ubuntu-16.04'
@@ -52,7 +51,6 @@ jobs:
python.version: '3.7'
python.architecture: x64
steps:
- template: .azure-pipelines/steps/reinstall-pythons.yml
- template: .azure-pipelines/steps/run-vendor-scripts.yml
parameters:
vmImage: 'Ubuntu-16.04'
@@ -64,7 +62,6 @@ jobs:
python.version: '3.7'
python.architecture: x64
steps:
- template: .azure-pipelines/steps/reinstall-pythons.yml
- template: .azure-pipelines/steps/build-package.yml
parameters:
vmImage: 'Ubuntu-16.04'
+1 -1
View File
@@ -59,7 +59,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/pypa/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>
+4 -6
View File
@@ -37,9 +37,8 @@
<h3>Stay Informed</h3>
<p>Receive updates on new releases and upcoming projects.</p>
<p><a href="https://twitter.com/kennethreitz" class="twitter-follow-button" data-show-count="false">Follow @kennethreitz</a> <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script></p>
<p><a href="https://saythanks.io/to/kennethreitz">Say Thanks!</a></p>
<p><a href="http://tinyletter.com/kennethreitz">Join Mailing List</a>.</p>
<p><a href="https://twitter.com/ThePyPA" class="twitter-follow-button" data-show-count="false">Follow @ThePyPA</a> <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script></p>
<p><a href="https://mail.python.org/mailman3/lists/distutils-sig.python.org/">Join Mailing List</a>.</p>
<h3>Other Projects</h3>
@@ -47,7 +46,7 @@
<li><a href="https://pipenv-pipes.readthedocs.io/en/latest/">Pipenv-Pipes</a></li>
</ul>
<p>More <a href="http://kennethreitz.org/">Kenneth Reitz</a> projects:</p>
<p>More projects founded by <a href="http://kennethreitz.org/">Kenneth Reitz</a>:</p>
<ul>
<li><a href="http://pep8.org/">pep8.org</a></li>
<li><a href="http://httpbin.org/">httpbin.org</a></li>
@@ -56,7 +55,7 @@
<li><a href="http://python-requests.org/">Requests: HTTP for Humans</a></li>
<li><a href="https://github.com/kennethreitz/maya">Maya: Datetimes for Humans</a></li>
<li><a href="https://github.com/kennethreitz/records">Records: SQL for Humans</a></li>
<li><a href="http://www.git-legit.org">Legit: Git for Humans</a></li>
<li><a href="https://frostming.github.io/legit">Legit: Git for Humans</a></li>
<li><a href="http://docs.python-tablib.org/en/latest/">Tablib: Tabular Datasets</a></li>
</ul>
@@ -75,4 +74,3 @@
<li><a href="https://pipenv-ja.readthedocs.io/ja/translate-ja/">日本語</a></li>
<li><a href="https://pipenv-es.readthedocs.io/es/latest/">Español</a></li>
</ul>
+7 -9
View File
@@ -38,12 +38,11 @@
<h3>Stay Informed</h3>
<p>Receive updates on new releases and upcoming projects.</p>
<p><iframe src="https://ghbtns.com/github-btn.html?user=kennethreitz&type=follow&count=true"
<p><iframe src="https://ghbtns.com/github-btn.html?user=pypa&type=follow&count=true"
allowtransparency="true" frameborder="0" scrolling="0" width="200" height="20"></iframe></p>
<p><a href="https://twitter.com/kennethreitz" class="twitter-follow-button" data-show-count="false">Follow @kennethreitz</a> <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script></p>
<p><a href="https://saythanks.io/to/kennethreitz">Say Thanks!</a></p>
<p><a href="http://tinyletter.com/kennethreitz">Join Mailing List</a>.</p>
<p><a href="https://twitter.com/ThePyPA" class="twitter-follow-button" data-show-count="false">Follow @ThePyPA</a> <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script></p>
<p><a href="https://mail.python.org/mailman3/lists/distutils-sig.python.org/">Join Mailing List</a>.</p>
<h3>Other Projects</h3>
@@ -51,7 +50,7 @@
<li><a href="https://pipenv-pipes.readthedocs.io/en/latest/">Pipenv-Pipes</a></li>
</ul>
<p>More <a href="http://kennethreitz.org/">Kenneth Reitz</a> projects:</p>
<p>More projects founded by <a href="http://kennethreitz.org/">Kenneth Reitz</a>:</p>
<ul>
<li><a href="http://pep8.org/">pep8.org</a></li>
<li><a href="http://httpbin.org/">httpbin.org</a></li>
@@ -59,7 +58,7 @@
<li><a href="http://python-guide.org">The Python Guide</a></li>
<li><a href="http://python-requests.org/">Requests: HTTP for Humans</a></li>
<li><a href="https://github.com/kennethreitz/records">Records: SQL for Humans</a></li>
<li><a href="http://www.git-legit.org">Legit: Git for Humans</a></li>
<li><a href="https://frostming.github.io/legit">Legit: Git for Humans</a></li>
<li><a href="http://docs.python-tablib.org/en/latest/">Tablib: Tabular Datasets</a></li>
<li><a href="http://markdownplease.com">Markdown, Please!</a></li>
</ul>
@@ -72,11 +71,10 @@
<p></p>
<li><a href="http://github.com/pypa/pipenv">Pipenv @ GitHub</a></li>
<li><a href="http://pypi.python.org/pypi/pipenv">Pipenv @ PyPI</a></li>
<li><a href="http://pypi.org/project/pipenv">Pipenv @ PyPI</a></li>
<li><a href="https://launchpad.net/~pypa/+archive/ubuntu/ppa">Pipenv PPA (PyPA)</a></li>
<li><a href="http://github.com/kennethreitz/pipenv/issues">Issue Tracker</a></li>
<li><a href="http://github.com/pypa/pipenv/issues">Issue Tracker</a></li>
<hr>
<li><a href="http://pipenv-ja.readthedocs.io/ja/translate-ja/">日本語</a></li>
<li><a href="https://pipenv-es.readthedocs.io/es/latest/">Español</a></li>
</ul>
+19 -2
View File
@@ -20,7 +20,7 @@ This document covers some of Pipenv's more glorious and advanced features.
If you'd like a specific package to be installed with a specific package index, you can do the following::
[[source]]
url = "https://pypi.python.org/simple"
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
@@ -344,6 +344,21 @@ If a ``.env`` file is present in your project, ``$ pipenv shell`` and ``$ pipenv
>>> os.environ['HELLO']
'WORLD'
Shell like variable expansion is available in ``.env`` files using `${VARNAME}` syntax.::
$ cat .env
CONFIG_PATH=${HOME}/.config/foo
$ pipenv run python
Loading .env environment variables…
Python 3.7.6 (default, Dec 19 2019, 22:52:49)
[GCC 9.2.1 20190827 (Red Hat 9.2.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.environ['CONFIG_PATH']
'/home/kennethreitz/.config/foo'
This is very useful for keeping production credentials out of your codebase.
We do not recommend committing ``.env`` files into source control!
@@ -355,6 +370,8 @@ To prevent pipenv from loading the ``.env`` file, set the ``PIPENV_DONT_LOAD_ENV
$ PIPENV_DONT_LOAD_ENV=1 pipenv shell
See `theskumar/python-dotenv <https://github.com/theskumar/python-dotenv>`_ for more information on ``.env`` files.
☤ Custom Script Shortcuts
-------------------------
@@ -525,7 +542,7 @@ probably a good idea in any case.
A 3rd party plugin, `tox-pipenv`_ is also available to use Pipenv natively with tox.
.. _Requests: https://github.com/kennethreitz/requests
.. _Requests: https://github.com/psf/requests
.. _tox: https://tox.readthedocs.io/en/latest/
.. _tox-pipenv: https://tox-pipenv.readthedocs.io/en/latest/
.. _Travis-CI: https://travis-ci.org/
+11 -4
View File
@@ -10,6 +10,12 @@ This document covers some of Pipenv's more basic features.
☤ Example Pipfile & Pipfile.lock
--------------------------------
Pipfiles contain information for the dependencies of the project, and supercede
the requirements.txt present in Python projects. You should add Pipfile in the
Git repository letting users who clone the repository the only thing required would be
installing Pipenv in the machine and type ``pipenv install``. Pipenv is a reference
implementation for using Pipfile.
.. _example_files:
Here is a simple example of a ``Pipfile`` and the resulting ``Pipfile.lock``.
@@ -125,7 +131,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 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.
- 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. ``python_version`` should be in the format ``X.Y`` and ``python_full_version`` should be in ``X.Y.Z`` format.
- ``pipenv install`` is fully compatible with ``pip install`` syntax, for which the full documentation can be found `here <https://pip.pypa.io/en/stable/user_guide/#installing-packages>`_.
- Note that the ``Pipfile`` uses the `TOML Spec <https://github.com/toml-lang/toml#user-content-spec>`_.
@@ -188,7 +194,7 @@ You can specify versions of a package using the `Semantic Versioning scheme <htt
For example, to install requests you can use: ::
$ pipenv install requests~=1.2 # equivalent to requests~=1.2.0
$ pipenv install requests~=1.2
Pipenv will install version ``1.2`` and any minor update, but not ``2.0``.
@@ -196,7 +202,7 @@ This will update your ``Pipfile`` to reflect this requirement, automatically.
In general, Pipenv uses the same specifier format as pip. However, note that according to `PEP 440`_ , you can't use versions containing a hyphen or a plus sign.
.. _`PEP 440`: <https://www.python.org/dev/peps/pep-0440/>
.. _`PEP 440`: https://www.python.org/dev/peps/pep-0440/
To make inclusive or exclusive version comparisons you can use: ::
@@ -216,7 +222,7 @@ To avoid installing a specific version you can use the ``!=`` identifier.
For an in depth explanation of the valid identifiers and more complex use cases check `the relevant section of PEP-440`_.
.. _`the relevant section of PEP-440`: https://www.python.org/dev/peps/pep-0440/#version-specifiers>
.. _`the relevant section of PEP-440`: https://www.python.org/dev/peps/pep-0440/#version-specifiers
☤ Specifying Versions of Python
-------------------------------
@@ -315,6 +321,7 @@ The user can provide these additional parameters:
- ``--dev`` — Install both ``develop`` and ``default`` packages from ``Pipfile``.
- ``--system`` — Use the system ``pip`` command rather than the one from your virtualenv.
- ``--deploy`` — Make sure the packages are properly locked in Pipfile.lock, and abort if the lock file is out-of-date.
- ``--ignore-pipfile`` — Ignore the ``Pipfile`` and install from the ``Pipfile.lock``.
- ``--skip-lock`` — Ignore the ``Pipfile.lock`` and install from the ``Pipfile``. In addition, do not write out a ``Pipfile.lock`` reflecting changes to the ``Pipfile``.
+8
View File
@@ -0,0 +1,8 @@
.. _cli:
Pipenv CLI Reference
======================================
.. click:: pipenv:cli
:prog: pipenv
:show-nested:
+2 -2
View File
@@ -57,8 +57,8 @@ master_doc = 'index'
# General information about the project.
project = u'pipenv'
copyright = u'2017. A <a href="http://kennethreitz.com/pages/open-projects.html">Kenneth Reitz</a> Project'
author = u'Kenneth Reitz'
copyright = u'2020. A project founded by <a href="http://kennethreitz.com/pages/open-projects.html">Kenneth Reitz</a>'
author = u'Python Packaging Authority'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
+2
View File
@@ -7,6 +7,8 @@ Pipenv is an open but opinionated tool, created by an open but opinionated devel
Management Style
~~~~~~~~~~~~~~~~
**To be updated (as of March 2020)**.
`Kenneth Reitz <http://kennethreitz.org>`__ is the BDFL. He has final say in any decision related to the Pipenv project. Kenneth is responsible for the direction and form of the library, as well as its presentation. In addition to making decisions based on technical merit, he is responsible for making decisions based on the development philosophy of Pipenv.
`Dan Ryan <http://github.com/techalchemy>`__, `Tzu-ping Chung <https://github.com/uranusjr>`__, and `Nate Prewitt <https://github.com/nateprewitt>`__ are the core contributors.
+1 -10
View File
@@ -15,9 +15,6 @@ Pipenv: Python Dev Workflow for Humans
.. image:: https://img.shields.io/pypi/pyversions/pipenv.svg
:target: https://pypi.python.org/pypi/pipenv
.. image:: https://img.shields.io/badge/Say%20Thanks!-🦉-1EAEDB.svg
:target: https://saythanks.io/to/kennethreitz
---------------
**Pipenv** is a tool that aims to bring the best of all packaging worlds (bundler, composer, npm, cargo, yarn, etc.) to the Python world. *Windows is a first-class citizen, in our world.*
@@ -120,6 +117,7 @@ Further Documentation Guides
basics
advanced
cli
diagnose
Contribution Guides
@@ -131,13 +129,6 @@ Contribution Guides
dev/philosophy
dev/contributing
☤ Pipenv Usage
--------------
.. click:: pipenv:cli
:prog: pipenv
:show-nested:
Indices and tables
==================
+1 -1
View File
@@ -146,7 +146,7 @@ To upgrade pipenv at any time::
If you don't even have pip installed, you can use this crude installation method, which will bootstrap your whole system::
$ curl https://raw.githubusercontent.com/kennethreitz/pipenv/master/get-pipenv.py | python
$ curl https://raw.githubusercontent.com/pypa/pipenv/master/get-pipenv.py | python
☤ Installing packages for your project
+1
View File
@@ -0,0 +1 @@
Move CLI docs to its own page.
+1
View File
@@ -0,0 +1 @@
Pass ``--pre`` and ``--clear`` options to ``pipenv update --outdated``.
+1
View File
@@ -0,0 +1 @@
Remove a misleading code comment from Specifying Versions documentation.
+1
View File
@@ -0,0 +1 @@
Fix link to GIF in README.md demonstrating Pipenv's usage, and add descriptive alt text.
+1
View File
@@ -0,0 +1 @@
Added a line describing potential issues in fancy extension.
+1
View File
@@ -0,0 +1 @@
Documental description of how Pipfile works and association with Pipenv.
+1
View File
@@ -0,0 +1 @@
Clarify the proper value of `python_version` and `python_full_version`.
+1
View File
@@ -0,0 +1 @@
Write description for --deploy extension and few extensions differences.
+1
View File
@@ -0,0 +1 @@
Added support for automatic python installs via ``asdf`` and associated ``PIPENV_DONT_USE_ASDF`` environment variable.
+1
View File
@@ -0,0 +1 @@
Honor PIPENV_SPINNER environment variable
+1
View File
@@ -0,0 +1 @@
More documentation for ``.env`` files
+1
View File
@@ -0,0 +1 @@
Updated documentation to point to working links.
+2 -2
View File
@@ -8,7 +8,7 @@ import os
import sys
import warnings
from .__version__ import __version__
from .__version__ import __version__ # noqa
PIPENV_ROOT = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
@@ -53,7 +53,7 @@ sys.stdout = stdout
sys.stderr = stderr
from .cli import cli
from . import resolver
from . import resolver # noqa
if __name__ == "__main__":
cli()
+2 -4
View File
@@ -4,8 +4,6 @@
Exposes a standard API that enables compatibility across python versions,
operating systems, etc.
"""
import os
import sys
import warnings
@@ -132,7 +130,7 @@ def decode_output(output):
output = output.encode(DEFAULT_ENCODING)
except (AttributeError, UnicodeDecodeError, UnicodeEncodeError):
if six.PY2:
output = unicode.translate(vistir.misc.to_text(output),
output = unicode.translate(vistir.misc.to_text(output), # noqa
UNICODE_TO_ASCII_TRANSLATION_MAP)
else:
output = output.translate(UNICODE_TO_ASCII_TRANSLATION_MAP)
@@ -147,5 +145,5 @@ def fix_utf8(text):
text = decode_output(text)
except UnicodeDecodeError:
if six.PY2:
text = unicode.translate(vistir.misc.to_text(text), UNICODE_TO_ASCII_TRANSLATION_MAP)
text = unicode.translate(vistir.misc.to_text(text), UNICODE_TO_ASCII_TRANSLATION_MAP) # noqa
return text
+1 -1
View File
@@ -1,4 +1,4 @@
# -*- coding=utf-8 -*-
from __future__ import absolute_import
from .command import cli
from .command import cli # noqa
+8 -9
View File
@@ -8,17 +8,15 @@ from click import (
argument, echo, edit, group, option, pass_context, secho, version_option
)
from ..vendor import click_completion
from ..vendor import delegator
from ..patched import crayons
from ..__version__ import __version__
from ..patched import crayons
from ..vendor import click_completion, delegator
from .options import (
CONTEXT_SETTINGS, PipenvGroup, code_option, common_options, deploy_option,
general_options, install_options, lock_options, pass_state,
pypi_mirror_option, python_option, requirementstxt_option,
skip_lock_option, sync_options, system_option, three_option,
uninstall_options, verbose_option, site_packages_option
pypi_mirror_option, python_option, site_packages_option, skip_lock_option,
sync_options, system_option, three_option, uninstall_options,
verbose_option
)
@@ -344,7 +342,8 @@ def lock(
"--fancy",
is_flag=True,
default=False,
help="Run in shell in fancy mode (for elegantly configured shells).",
help="Run in shell in fancy mode. Make sure the shell have no path manipulating"
" scripts. Run $pipenv shell for issues with compatibility mode.",
)
@option(
"--anyway",
@@ -484,7 +483,7 @@ def update(
if not outdated:
outdated = bool(dry_run)
if outdated:
do_outdated(pypi_mirror=state.pypi_mirror)
do_outdated(clear=state.clear, pre=state.installstate.pre, pypi_mirror=state.pypi_mirror)
packages = [p for p in state.installstate.packages if p]
editable = [p for p in state.installstate.editables if p]
if not packages:
+43 -42
View File
@@ -1,49 +1,48 @@
# -*- coding=utf-8 -*-
from __future__ import absolute_import, print_function
import io
import json as simplejson
import logging
import os
import shutil
import sys
import time
import warnings
import click
import six
import urllib3.util as urllib3_util
import vistir
from click_completion import init as init_completion
import delegator
import dotenv
import pipfile
import vistir
from click_completion import init as init_completion
from .patched import crayons
from . import environments, exceptions, pep508checker, progress
from ._compat import fix_utf8, decode_for_output
from ._compat import decode_for_output, fix_utf8
from .cmdparse import Script
from .environments import (
PIPENV_CACHE_DIR, PIPENV_COLORBLIND, PIPENV_DEFAULT_PYTHON_VERSION,
PIPENV_DONT_USE_PYENV, PIPENV_HIDE_EMOJIS, PIPENV_MAX_SUBPROCESS,
PIPENV_PYUP_API_KEY, PIPENV_SHELL_FANCY, PIPENV_SKIP_VALIDATION,
PIPENV_YES, SESSION_IS_INTERACTIVE, PIP_EXISTS_ACTION, PIPENV_RESOLVE_VCS,
is_type_checking
PIP_EXISTS_ACTION, PIPENV_CACHE_DIR, PIPENV_COLORBLIND,
PIPENV_DEFAULT_PYTHON_VERSION, PIPENV_DONT_USE_PYENV, PIPENV_DONT_USE_ASDF,
PIPENV_HIDE_EMOJIS, PIPENV_MAX_SUBPROCESS, PIPENV_PYUP_API_KEY,
PIPENV_RESOLVE_VCS, PIPENV_SHELL_FANCY, PIPENV_SKIP_VALIDATION, PIPENV_YES,
SESSION_IS_INTERACTIVE, is_type_checking
)
from .project import Project, SourceNotFound
from .patched import crayons
from .project import Project
from .utils import (
convert_deps_to_pip, create_mirror_source, create_spinner, download_file,
escape_cmd, escape_grouped_arguments, find_windows_executable,
get_canonical_names, is_pinned, is_pypi_url, is_required_version, is_star,
is_valid_url, parse_indexes, pep423_name, prepare_pip_source_args,
proper_case, python_version, venv_resolve_deps, run_command,
is_python_command, find_python, make_posix, interrupt_handled_subprocess,
get_indexes_from_requirement, get_source_list, get_project_index,
convert_deps_to_pip, create_spinner, download_file,
escape_grouped_arguments, find_python, find_windows_executable,
get_canonical_names, get_source_list, interrupt_handled_subprocess,
is_pinned, is_python_command, is_required_version, is_star, is_valid_url,
parse_indexes, pep423_name, prepare_pip_source_args, proper_case,
python_version, run_command, venv_resolve_deps
)
if is_type_checking():
from typing import Dict, List, Mapping, Optional, Union, Text
from typing import Dict, List, Optional, Union, Text
from pipenv.vendor.requirementslib.models.requirements import Requirement
TSourceDict = Dict[Text, Union[Text, bool]]
@@ -393,28 +392,36 @@ def ensure_python(three=None, python=None):
),
err=True,
)
# Pyenv is installed
from .vendor.pythonfinder.environment import PYENV_INSTALLED
# check for python installers
from .vendor.pythonfinder.environment import PYENV_INSTALLED, ASDF_INSTALLED
from .installers import Pyenv, Asdf, InstallerError
if not PYENV_INSTALLED:
# prefer pyenv if both pyenv and asdf are installed as it's
# dedicated to python installs so probably the preferred
# method of the user for new python installs.
if PYENV_INSTALLED and not PIPENV_DONT_USE_PYENV:
installer = Pyenv("pyenv")
elif ASDF_INSTALLED and not PIPENV_DONT_USE_ASDF:
installer = Asdf("asdf")
else:
installer = None
if not installer:
abort()
else:
if (not PIPENV_DONT_USE_PYENV) and (SESSION_IS_INTERACTIVE or PIPENV_YES):
from .pyenv import Runner, PyenvError
pyenv = Runner("pyenv")
if SESSION_IS_INTERACTIVE or PIPENV_YES:
try:
version = pyenv.find_version_to_install(python)
version = installer.find_version_to_install(python)
except ValueError:
abort()
except PyenvError as e:
except InstallerError as e:
click.echo(fix_utf8("Something went wrong…"))
click.echo(crayons.blue(e.err), err=True)
abort()
s = "{0} {1} {2}".format(
"Would you like us to install",
crayons.green("CPython {0}".format(version)),
"with pyenv?",
"with {0}?".format(installer),
)
# Prompt the user to continue…
if not (PIPENV_YES or click.confirm(s, default=True)):
@@ -425,15 +432,15 @@ def ensure_python(three=None, python=None):
u"{0} {1} {2} {3}{4}".format(
crayons.normal(u"Installing", bold=True),
crayons.green(u"CPython {0}".format(version), bold=True),
crayons.normal(u"with pyenv", bold=True),
crayons.normal(u"with {0}".format(installer), bold=True),
crayons.normal(u"(this may take a few minutes)"),
crayons.normal(fix_utf8(""), bold=True),
)
)
with create_spinner("Installing python...") as sp:
try:
c = pyenv.install(version)
except PyenvError as e:
c = installer.install(version)
except InstallerError as e:
sp.fail(environments.PIPENV_SPINNER_FAIL_TEXT.format(
"Failed...")
)
@@ -711,8 +718,6 @@ def batch_install(deps_list, procs, failed_deps_queue,
label=label
)
indexes = []
trusted_hosts = []
# Install these because
for dep in deps_list_bar:
@@ -723,9 +728,6 @@ def batch_install(deps_list, procs, failed_deps_queue,
dep.markers = str(strip_extras_markers_from_requirement(dep.get_markers()))
# Install the module.
is_artifact = False
if no_deps:
link = getattr(dep.req, "link", None)
is_wheel = getattr(link, "is_wheel", False) if link else False
if dep.is_file_or_url and (dep.is_direct_url or any(
dep.req.uri.endswith(ext) for ext in ["zip", "tar.gz"]
)):
@@ -1053,7 +1055,6 @@ def do_lock(
# Resolve dev-package dependencies, with pip-tools.
for is_dev in [True, False]:
pipfile_section = "dev-packages" if is_dev else "packages"
lockfile_section = "develop" if is_dev else "default"
if project.pipfile_exists:
packages = project.parsed_pipfile.get(pipfile_section, {})
else:
@@ -1355,7 +1356,7 @@ def get_requirement_line(
return ["-e", line]
return '-e {0}'.format(line)
if not format_for_file:
return [line,]
return [line]
return line
return requirement.as_line(include_hashes=include_hashes, as_list=not format_for_file)
@@ -1767,7 +1768,7 @@ def do_py(system=False):
click.echo(crayons.red("No project found!"))
def do_outdated(pypi_mirror=None):
def do_outdated(pypi_mirror=None, pre=False, clear=False):
# TODO: Allow --skip-lock here?
from .vendor.requirementslib.models.requirements import Requirement
from .vendor.requirementslib.models.utils import get_version
@@ -1789,7 +1790,7 @@ def do_outdated(pypi_mirror=None):
dep = Requirement.from_line(str(result.as_requirement()))
packages.update(dep.as_pipfile())
updated_packages = {}
lockfile = do_lock(write=False, pypi_mirror=pypi_mirror)
lockfile = do_lock(clear=clear, pre=pre, write=False, pypi_mirror=pypi_mirror)
for section in ("develop", "default"):
for package in lockfile[section]:
try:
+5 -6
View File
@@ -10,7 +10,6 @@ import os
import site
import sys
from distutils.sysconfig import get_python_lib
from sysconfig import get_paths, get_python_version
import itertools
@@ -620,7 +619,7 @@ class Environment(object):
else:
d['required_version'] = d['installed_version']
get_children = lambda n: key_tree.get(n.key, [])
get_children = lambda n: key_tree.get(n.key, []) # noqa
d['dependencies'] = [
cls._get_requirements_for_package(c, key_tree, parent=node,
@@ -805,7 +804,7 @@ class Environment(object):
sys.path = self.sys_path
sys.prefix = self.sys_prefix
site.addsitedir(self.base_paths["purelib"])
pip = self.safe_import("pip")
pip = self.safe_import("pip") # noqa
pip_vendor = self.safe_import("pip._vendor")
pep517_dir = os.path.join(os.path.dirname(pip_vendor.__file__), "pep517")
site.addsitedir(pep517_dir)
@@ -865,7 +864,7 @@ class Environment(object):
def install(self, requirements):
if not isinstance(requirements, (tuple, list)):
requirements = [requirements,]
requirements = [requirements]
with self.get_finder() as finder:
args = []
for format_control in ('no_binary', 'only_binary'):
@@ -917,7 +916,7 @@ class Environment(object):
pathset_base = pip_shims.UninstallPathSet
pathset_base._permitted = PatchedUninstaller._permitted
dist = next(
iter(filter(lambda d: d.project_name == pkgname, self.get_working_set())),
iter(d for d in self.get_working_set() if d.project_name == pkgname),
None
)
pathset = pathset_base.from_dist(dist)
@@ -925,7 +924,7 @@ class Environment(object):
pathset.remove(auto_confirm=auto_confirm, verbose=verbose)
try:
yield pathset
except Exception as e:
except Exception:
if pathset is not None:
pathset.rollback()
else:
+7
View File
@@ -68,6 +68,12 @@ PIPENV_DONT_USE_PYENV = bool(os.environ.get("PIPENV_DONT_USE_PYENV"))
Default is to install Python automatically via pyenv when needed, if possible.
"""
PIPENV_DONT_USE_ASDF = bool(os.environ.get("PIPENV_DONT_USE_ASDF"))
"""If set, Pipenv does not attempt to install Python with asdf.
Default is to install Python automatically via asdf when needed, if possible.
"""
PIPENV_DOTENV_LOCATION = os.environ.get("PIPENV_DOTENV_LOCATION")
"""If set, Pipenv loads the ``.env`` file at the specified location.
@@ -151,6 +157,7 @@ if PIPENV_IS_CI:
PIPENV_NOSPIN = True
PIPENV_SPINNER = "dots" if not os.name == "nt" else "bouncingBar"
PIPENV_SPINNER = os.environ.get("PIPENV_SPINNER", PIPENV_SPINNER)
"""Sets the default spinner type.
Spinners are identitcal to the node.js spinners and can be found at
+7 -8
View File
@@ -84,7 +84,7 @@ class PipenvException(ClickException):
file = vistir.misc.get_text_stderr()
if self.extra:
if isinstance(self.extra, STRING_TYPES):
self.extra = [self.extra,]
self.extra = [self.extra]
for extra in self.extra:
extra = "[pipenv.exceptions.{0!s}]: {1}".format(
self.__class__.__name__, extra
@@ -163,14 +163,13 @@ class PipenvUsageError(UsageError):
color = self.ctx.color
if self.extra:
if isinstance(self.extra, STRING_TYPES):
self.extra = [self.extra,]
self.extra = [self.extra]
for extra in self.extra:
if color:
extra = getattr(crayons, color, "blue")(extra)
click_echo(decode_for_output(extra, file), file=file)
hint = ''
if (self.cmd is not None and
self.cmd.get_help_option(self.ctx) is not None):
if self.cmd is not None and self.cmd.get_help_option(self.ctx) is not None:
hint = ('Try "%s %s" for help.\n'
% (self.ctx.command_path, self.ctx.help_option_names[0]))
if self.ctx is not None:
@@ -199,7 +198,7 @@ class PipenvFileError(FileError):
file = vistir.misc.get_text_stderr()
if self.extra:
if isinstance(self.extra, STRING_TYPES):
self.extra = [self.extra,]
self.extra = [self.extra]
for extra in self.extra:
click_echo(decode_for_output(extra, file), file=file)
click_echo(self.message, file=file)
@@ -312,7 +311,7 @@ class VirtualenvCreationException(VirtualenvException):
extra = ANSI_REMOVAL_RE.sub("", "{0}".format(extra))
if "KeyboardInterrupt" in extra:
extra = crayons.red("Virtualenv creation interrupted by user", bold=True)
self.extra = extra = [extra,]
self.extra = extra = [extra]
VirtualenvException.__init__(self, message, extra=extra)
@@ -321,9 +320,9 @@ class UninstallError(PipenvException):
extra = [
"{0} {1}".format(
crayons.blue("Attempted to run command: "),
crayons.yellow("$ {0!r}".format(command), bold=True
crayons.yellow("$ {0!r}".format(command), bold=True)
)
)]
]
extra.extend([crayons.blue(line.strip()) for line in return_values.splitlines()])
if isinstance(package, (tuple, list, set)):
package = " ".join(package)
+64 -18
View File
@@ -48,19 +48,22 @@ class Version(object):
return (self.major, self.minor) == (other.major, other.minor)
class PyenvError(RuntimeError):
class InstallerError(RuntimeError):
def __init__(self, desc, c):
super(PyenvError, self).__init__(desc)
super(InstallerError, self).__init__(desc)
self.out = c.out
self.err = c.err
class Runner(object):
class Installer(object):
def __init__(self, pyenv):
self._cmd = pyenv
def __init__(self, cmd):
self._cmd = cmd
def _pyenv(self, *args, **kwargs):
def __str__(self):
return self._cmd
def _run(self, *args, **kwargs):
timeout = kwargs.pop('timeout', delegator.TIMEOUT)
if kwargs:
k = list(kwargs.keys())[0]
@@ -69,21 +72,16 @@ class Runner(object):
c = delegator.run(args, block=False, timeout=timeout)
c.block()
if c.return_code != 0:
raise PyenvError('faild to run {0}'.format(args), c)
raise InstallerError('faild to run {0}'.format(args), c)
return c
def iter_installable_versions(self):
"""Iterate through CPython versions available for Pipenv to install.
"""
for name in self._pyenv('install', '--list').out.splitlines():
try:
version = Version.parse(name.strip())
except ValueError:
continue
yield version
raise NotImplementedError
def find_version_to_install(self, name):
"""Find a version in pyenv from the version supplied.
"""Find a version in the installer from the version supplied.
A ValueError is raised if a matching version cannot be found.
"""
@@ -103,16 +101,64 @@ class Runner(object):
return best_match
def install(self, version):
"""Install the given version with pyenv.
"""Install the given version with runner implementation.
The version must be a ``Version`` instance representing a version
found in pyenv.
found in the Installer.
A ValueError is raised if the given version does not have a match in
pyenv. A PyenvError is raised if the pyenv command fails.
the runner. A InstallerError is raised if the runner command fails.
"""
c = self._pyenv(
raise NotImplementedError
class Pyenv(Installer):
def iter_installable_versions(self):
"""Iterate through CPython versions available for Pipenv to install.
"""
for name in self._run('install', '--list').out.splitlines():
try:
version = Version.parse(name.strip())
except ValueError:
continue
yield version
def install(self, version):
"""Install the given version with pyenv.
The version must be a ``Version`` instance representing a version
found in pyenv.
A ValueError is raised if the given version does not have a match in
pyenv. A InstallerError is raised if the pyenv command fails.
"""
c = self._run(
'install', '-s', str(version),
timeout=PIPENV_INSTALL_TIMEOUT,
)
return c
class Asdf(Installer):
def iter_installable_versions(self):
"""Iterate through CPython versions available for asdf to install.
"""
for name in self._run('list-all', 'python').out.splitlines():
try:
version = Version.parse(name.strip())
except ValueError:
continue
yield version
def install(self, version):
"""Install the given version with asdf.
The version must be a ``Version`` instance representing a version
found in asdf.
A ValueError is raised if the given version does not have a match in
asdf. A InstallerError is raised if the asdf command fails.
"""
c = self._run(
'install', 'python', str(version),
timeout=PIPENV_INSTALL_TIMEOUT,
)
return c
+2 -2
View File
@@ -275,7 +275,7 @@ If you don\(aqt even have pip installed, you can use this crude installation met
.sp
.nf
.ft C
$ curl https://raw.githubusercontent.com/kennethreitz/pipenv/master/get\-pipenv.py | python
$ curl https://raw.githubusercontent.com/pypa/pipenv/master/get\-pipenv.py | python
.ft P
.fi
.UNINDENT
@@ -4121,6 +4121,6 @@ search
.SH AUTHOR
Kenneth Reitz
.SH COPYRIGHT
2017. A <a href="http://kennethreitz.com/pages/open-projects.html">Kenneth Reitz</a> Project
2017. A project founded by <a href="http://kennethreitz.com/pages/open-projects.html">Kenneth Reitz</a>
.\" Generated by docutils manpage writer.
.
+10 -13
View File
@@ -15,8 +15,6 @@ import toml
import tomlkit
import vistir
from first import first
import pipfile
import pipfile.api
@@ -209,14 +207,12 @@ class Project(object):
# First exclude anything that is a vcs entry either in the key or value
if not (
any(is_vcs(i) for i in [k, v])
or
# Then exclude any installable files that are not directories
# Because pip-tools can resolve setup.py for example
any(is_installable_file(i) for i in [k, v])
or
or any(is_installable_file(i) for i in [k, v])
# Then exclude any URLs because they need to be editable also
# Things that are excluded can only be 'shallow resolved'
any(is_valid_url(i) for i in [k, v])
or any(is_valid_url(i) for i in [k, v])
):
ps.update({k: v})
return ps
@@ -337,7 +333,7 @@ class Project(object):
if not self._environment:
prefix = self.virtualenv_location
is_venv = is_in_virtualenv()
sources = self.sources if self.sources else [DEFAULT_SOURCE,]
sources = self.sources if self.sources else [DEFAULT_SOURCE]
self._environment = Environment(
prefix=prefix, is_venv=is_venv, sources=sources, pipfile=self.parsed_pipfile,
project=self
@@ -421,8 +417,10 @@ class Project(object):
def virtualenv_location(self):
# if VIRTUAL_ENV is set, use that.
virtualenv_env = os.getenv("VIRTUAL_ENV")
if ("PIPENV_ACTIVE" not in os.environ and
not PIPENV_IGNORE_VIRTUALENVS and virtualenv_env):
if (
"PIPENV_ACTIVE" not in os.environ
and not PIPENV_IGNORE_VIRTUALENVS and virtualenv_env
):
return virtualenv_env
if not self._virtualenv_location: # Use cached version, if available.
@@ -542,7 +540,6 @@ class Project(object):
def build_requires(self):
return self._build_system.get("requires", ["setuptools>=40.8.0", "wheel"])
@property
def build_backend(self):
return self._build_system.get("build-backend", get_default_pyproject_backend())
@@ -688,7 +685,7 @@ class Project(object):
.lstrip("\n")
.split("\n")
)
sources = [DEFAULT_SOURCE,]
sources = [DEFAULT_SOURCE]
for i, index in enumerate(indexes):
if not index:
continue
@@ -756,7 +753,7 @@ class Project(object):
if not sources:
sources = self.pipfile_sources
elif not isinstance(sources, list):
sources = [sources,]
sources = [sources]
lockfile_dict["_meta"]["sources"] = [
self.populate_source(s) for s in sources
]
@@ -775,7 +772,7 @@ class Project(object):
else:
sources = [dict(source) for source in self.parsed_pipfile["source"]]
if not isinstance(sources, list):
sources = [sources,]
sources = [sources]
return {
"hash": {"sha256": self.calculate_pipfile_hash()},
"pipfile-spec": PIPFILE_SPEC_CURRENT,
-9
View File
@@ -516,7 +516,6 @@ class Entry(object):
:raises: :exc:`~pipenv.exceptions.DependencyConflict` if resolution is impossible
"""
# ensure that we satisfy the parent dependencies of this dep
from pipenv.vendor.packaging.specifiers import Specifier
parent_dependencies = set()
has_mismatch = False
can_use_original = True
@@ -527,7 +526,6 @@ class Entry(object):
# parents with no requirements can't conflict
if not p.requirements:
continue
needed = p.requirements.get("dependencies", [])
entry_ref = p.get_dependency(self.name)
required = entry_ref.get("required_version", "*")
required = self.clean_specifier(required)
@@ -633,7 +631,6 @@ def clean_results(results, resolver, project, dev=False):
return results
lockfile = project.lockfile_content
section = "develop" if dev else "default"
pipfile_section = "dev-packages" if dev else "packages"
reverse_deps = project.environment.reverse_dependencies()
new_results = [r for r in results if r["name"] not in lockfile[section]]
for result in results:
@@ -646,17 +643,11 @@ def clean_results(results, resolver, project, dev=False):
def clean_outdated(results, resolver, project, dev=False):
from pipenv.vendor.requirementslib.models.requirements import Requirement
from pipenv.environments import is_verbose
if not project.lockfile_exists:
return results
lockfile = project.lockfile_content
section = "develop" if dev else "default"
pipfile_section = "dev-packages" if dev else "packages"
pipfile = project.parsed_pipfile[pipfile_section]
reverse_deps = project.environment.reverse_dependencies()
deptree = project.environment.get_package_requirements()
overlapping_results = [r for r in results if r["name"] in lockfile[section]]
new_results = [r for r in results if r["name"] not in lockfile[section]]
for result in results:
name = result.get("name")
+22 -22
View File
@@ -1,46 +1,41 @@
# -*- coding: utf-8 -*-
from __future__ import print_function
import contextlib
import errno
import logging
import os
import posixpath
import re
import signal
import shutil
import signal
import stat
import sys
import warnings
from contextlib import contextmanager
from distutils.spawn import find_executable
import six
import toml
import tomlkit
from click import echo as click_echo
from six.moves.urllib.parse import urlparse
from .vendor.vistir.compat import ResourceWarning, lru_cache, Mapping, Sequence, Set
from .vendor.vistir.misc import fs_str, run
import crayons
import parse
import tomlkit
from . import environments
from .exceptions import (
PipenvUsageError, RequirementError, PipenvCmdError, ResolutionFailure
)
from .exceptions import PipenvCmdError, PipenvUsageError, RequirementError, ResolutionFailure
from .pep508checker import lookup
from .vendor.packaging.markers import Marker
from .vendor.urllib3 import util as urllib3_util
from .vendor.vistir.compat import Mapping, ResourceWarning, Sequence, Set, lru_cache
from .vendor.vistir.misc import fs_str, run
if environments.MYPY_RUNNING:
from typing import Tuple, Dict, Any, List, Union, Optional, Text
from .vendor.requirementslib.models.requirements import Requirement, Line
from .vendor.requirementslib.models.pipfile import Pipfile
from .vendor.packaging.markers import Marker
from .vendor.packaging.specifiers import Specifier
from .project import Project, TSource
@@ -316,7 +311,7 @@ def get_source_list(
sources.append(get_project_index(index))
if extra_indexes:
if isinstance(extra_indexes, six.string_types):
extra_indexes = [extra_indexes,]
extra_indexes = [extra_indexes]
for source in extra_indexes:
extra_src = get_project_index(source)
if not sources or extra_src["url"] != sources[0]["url"]:
@@ -555,8 +550,8 @@ class Resolver(object):
# but leave it on for local, installable folders on the filesystem
if environments.PIPENV_RESOLVE_VCS or (
req.editable or parsed_line.is_wheel or (
req.is_file_or_url and parsed_line.is_local and
is_installable_dir(parsed_line.path)
req.is_file_or_url and parsed_line.is_local
and is_installable_dir(parsed_line.path)
)
):
requirements = [v for v in getattr(setup_info, "requires", {}).values()]
@@ -920,8 +915,10 @@ class Resolver(object):
# We also don't want to try to hash directories as this will fail
# as these are editable deps and are not hashable.
if (ireq.link.scheme == "file" and
Path(to_native_string(url_to_path(ireq.link.url))).is_dir()):
if (
ireq.link.scheme == "file"
and Path(to_native_string(url_to_path(ireq.link.url))).is_dir()
):
return False
return True
@@ -1069,7 +1066,6 @@ def actually_resolve_deps(
req_dir=None,
):
from pipenv.vendor.vistir.path import create_tracked_tempdir
from pipenv.vendor.requirementslib.models.requirements import Requirement
if not req_dir:
req_dir = create_tracked_tempdir(suffix="-requirements", prefix="pipenv-")
@@ -1290,7 +1286,11 @@ def venv_resolve_deps(
os.environ["PIPENV_VERBOSITY"] = str(environments.PIPENV_VERBOSITY)
os.environ["PIPENV_REQ_DIR"] = fs_str(req_dir)
os.environ["PIP_NO_INPUT"] = fs_str("1")
os.environ["PIPENV_SITE_DIR"] = get_pipenv_sitedir()
pipenv_site_dir = get_pipenv_sitedir()
if pipenv_site_dir is not None:
os.environ["PIPENV_SITE_DIR"] = pipenv_site_dir
else:
os.environ.pop("PIPENV_SITE_DIR", None)
if keep_outdated:
os.environ["PIPENV_KEEP_OUTDATED"] = fs_str("1")
with create_spinner(text=decode_for_output("Locking...")) as sp:
@@ -1889,7 +1889,7 @@ def translate_markers(pipfile_entry):
"""
if not isinstance(pipfile_entry, Mapping):
raise TypeError("Entry is not a pipfile formatted mapping.")
from .vendor.packaging.markers import Marker, default_environment
from .vendor.packaging.markers import default_environment
from .vendor.vistir.misc import dedup
allowed_marker_keys = ["markers"] + list(default_environment().keys())
@@ -2217,8 +2217,8 @@ def is_python_command(line):
from pipenv.vendor.pythonfinder.utils import PYTHON_IMPLEMENTATIONS
is_version = re.match(r'[\d\.]+', line)
if (line.startswith("python") or is_version or
any(line.startswith(v) for v in PYTHON_IMPLEMENTATIONS)):
if (line.startswith("python") or is_version
or any(line.startswith(v) for v in PYTHON_IMPLEMENTATIONS)):
return True
# we are less sure about this but we can guess
if line.startswith("py"):
-25
View File
@@ -1,25 +0,0 @@
[pytest]
addopts = -ra -n auto
plugins = xdist
testpaths = tests
; Add vendor and patched in addition to the default list of ignored dirs
; Additionally, ignore tasks, news, test subdirectories and peeps directory
norecursedirs =
.* build
dist
CVS
_darcs
{arch}
*.egg
vendor
patched
news
tasks
docs
tests/test_artifacts
tests/pytest-pypi
tests/pypi
peeps
filterwarnings =
ignore::DeprecationWarning
ignore::PendingDeprecationWarning
+31 -2
View File
@@ -4,7 +4,9 @@ license = MIT
license_file = LICENSE
[flake8]
exclude = .git,__pycache__,docs/,pipenv/vendor/,get-pipenv.py,setup.py
exclude =
.git,__pycache__,docs/,pipenv/vendor/,pipenv/patched,get-pipenv.py,
.eggs/,setup.py,tests/fixtures/
ignore =
# The default ignore list:
E121,E123,E126,E226,E24,E704,
@@ -17,13 +19,14 @@ ignore =
# E402: module level import not at top of file
# E501: line too long
# W503: line break before binary operator
E402,E501,W503
E402,E501,W503,E203
[isort]
atomic=true
lines_after_imports=2
lines_between_types=1
multi_line_output=5
line_length=80
not_skip=__init__.py
known_first_party =
pipenv
@@ -36,3 +39,29 @@ follow_imports=skip
html_report=mypyhtml
python_version=3.6
mypy_path=typeshed/pyi:typeshed/imports
[tool:pytest]
addopts = -ra -n auto
plugins = xdist
testpaths = tests
; Add vendor and patched in addition to the default list of ignored dirs
; Additionally, ignore tasks, news, test subdirectories and peeps directory
norecursedirs =
.* build
dist
CVS
_darcs
{arch}
*.egg
vendor
patched
news
tasks
docs
tests/test_artifacts
tests/pytest-pypi
tests/pypi
peeps
filterwarnings =
ignore::DeprecationWarning
ignore::PendingDeprecationWarning
+3 -2
View File
@@ -45,6 +45,7 @@ extras = {
"tests": ["pytest<5.0", "pytest-tap", "pytest-xdist", "flaky", "mock"],
}
# https://pypi.python.org/pypi/stdeb/0.8.5#quickstart-2-just-tell-me-the-fastest-way-to-make-a-deb
class DebCommand(Command):
"""Support for setup.py deb"""
@@ -117,8 +118,8 @@ setup(
description="Python Development Workflow for Humans.",
long_description=long_description,
long_description_content_type='text/markdown',
author="Kenneth Reitz",
author_email="me@kennethreitz.org",
author="Pipenv maintainer team",
author_email="distutils-sig@python.org",
url="https://github.com/pypa/pipenv",
packages=find_packages(exclude=["tests", "tests.*", "tasks", "tasks.*"]),
entry_points={
-2
View File
@@ -1,8 +1,6 @@
# -*- coding=utf-8 -*-
# Copied from pip's vendoring process
# see https://github.com/pypa/pip/blob/95bcf8c5f6394298035a7332c441868f3b0169f4/tasks/__init__.py
import re
from pathlib import Path
import invoke
-3
View File
@@ -3,7 +3,6 @@ import datetime
import os
import pathlib
import re
import sys
import invoke
@@ -240,8 +239,6 @@ def bump_version(ctx, dry_run=False, dev=False, pre=False, tag=None, commit=Fals
current_version = Version.parse(__version__)
today = datetime.date.today()
tomorrow = today + datetime.timedelta(days=1)
next_month = datetime.date.today().replace(month=today.month + 1, day=1)
next_year = datetime.date.today().replace(year=today.year + 1, month=1, day=1)
if pre and not tag:
print('Using "pre" requires a corresponding tag.')
return
+1 -11
View File
@@ -41,7 +41,7 @@ LIBRARY_DIRNAMES = {
'enum': 'backports/enum'
}
PY2_DOWNLOAD = ['enum34',]
PY2_DOWNLOAD = ['enum34']
# from time to time, remove the no longer needed ones
HARDCODED_LICENSE_URLS = {
@@ -93,7 +93,6 @@ LICENSE_RENAMES = {
}
def drop_dir(path):
if path.exists() and path.is_dir():
shutil.rmtree(str(path), ignore_errors=True)
@@ -379,7 +378,6 @@ def vendor(ctx, vendor_dir, package=None, rewrite=True):
post_install_cleanup(ctx, vendor_dir)
# Detect the vendored packages/modules
vendored_libs = detect_vendored_libs(_get_vendor_dir(ctx))
patched_libs = detect_vendored_libs(_get_patched_dir(ctx))
log("Detected vendored libraries: %s" % ", ".join(vendored_libs))
# Apply pre-patches
@@ -509,14 +507,6 @@ def download_licenses(
new_requirements_file = fh.name
new_requirements_file = Path(new_requirements_file)
log(requirements)
requirement = "-r {0}".format(new_requirements_file.as_posix())
if package:
if not only:
# for packages we want to add to the requirements file
requirement = _ensure_package_in_requirements(ctx, requirements_file, package)
else:
# for packages we want to get the license for by themselves
requirement = package
tmp_dir = vendor_dir / '__tmp__'
# TODO: Fix this whenever it gets sorted out (see https://github.com/pypa/pip/issues/5739)
cmd = "pip download --no-binary :all: --only-binary requests_download --no-deps"
+1 -1
View File
@@ -2,7 +2,7 @@ import invoke
from pipenv._compat import TemporaryDirectory
from . import _get_git_root, _get_vendor_dir, log
from . import _get_vendor_dir, log
@invoke.task
+14 -11
View File
@@ -1,30 +1,34 @@
# -*- coding=utf-8 -*-
from __future__ import absolute_import, print_function
import errno
import json
import logging
import os
import shutil
import signal
import socket
import sys
import time
import warnings
from shutil import copyfileobj, rmtree as _rmtree
from shutil import rmtree as _rmtree
import pytest
import requests
from pipenv.vendor.vistir.compat import ResourceWarning, fs_str, fs_encode, FileNotFoundError, PermissionError, TemporaryDirectory
from pipenv.vendor.vistir.misc import run
from pipenv.vendor.vistir.contextmanagers import temp_environ
from pipenv.vendor.vistir.path import mkdir_p, create_tracked_tempdir, handle_remove_readonly
from pipenv._compat import Path
from pipenv.exceptions import VirtualenvActivationException
from pipenv.vendor import delegator, toml, tomlkit
from pytest_pypi.app import prepare_fixtures, prepare_packages as prepare_pypi_packages
from pipenv.vendor.vistir.compat import (
FileNotFoundError, PermissionError, ResourceWarning, TemporaryDirectory,
fs_encode, fs_str
)
from pipenv.vendor.vistir.contextmanagers import temp_environ
from pipenv.vendor.vistir.misc import run
from pipenv.vendor.vistir.path import (
create_tracked_tempdir, handle_remove_readonly, mkdir_p
)
from pytest_pypi.app import prepare_fixtures
from pytest_pypi.app import prepare_packages as prepare_pypi_packages
log = logging.getLogger(__name__)
warnings.simplefilter("default", category=ResourceWarning)
@@ -399,7 +403,6 @@ class _PipenvInstance(object):
def _rmtree_func(path, ignore_errors=True, onerror=None):
directory = fs_encode(path)
global _rmtree
shutil_rmtree = _rmtree
if onerror is None:
onerror = handle_remove_readonly
+14 -1
View File
@@ -223,7 +223,7 @@ def test_install_parse_error(PipenvInstance):
[dev-packages]
""".strip()
f.write(contents)
c = p.pipenv('install requests u/\\/p@r\$34b13+pkg')
c = p.pipenv('install requests u/\\/p@r\\$34b13+pkg')
assert c.return_code != 0
assert 'u/\\/p@r$34b13+pkg' not in p.pipfile['packages']
@@ -265,3 +265,16 @@ def test_pipenv_three(PipenvInstance):
c = p.pipenv('--three')
assert c.return_code == 0
assert 'Successfully created virtual environment' in c.err
@pytest.mark.outdated
def test_pipenv_outdated_prerelease(PipenvInstance):
with PipenvInstance(chdir=True) 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.return_code == 0
+1 -3
View File
@@ -5,9 +5,7 @@ import os
import pytest
from pipenv._compat import Path, TemporaryDirectory
from pipenv.project import Project
from pipenv.utils import get_windows_path, normalize_drive, temp_environ
from pipenv.vendor import delegator
from pipenv.utils import normalize_drive, temp_environ
@pytest.mark.dotvenv
-1
View File
@@ -7,7 +7,6 @@ import pytest
from flaky import flaky
from pipenv._compat import Path, TemporaryDirectory
from pipenv.project import Project
from pipenv.utils import temp_environ
from pipenv.vendor import delegator
@@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function
import os
import sys
import pytest
-2
View File
@@ -9,7 +9,6 @@ import pytest
from flaky import flaky
from pipenv._compat import Path
from pipenv.project import Project
from pipenv.utils import mkdir_p, temp_environ
from pipenv.vendor import delegator
@@ -40,7 +39,6 @@ setup(
""".strip()
fh.write(contents)
line = "-e .[dev]"
pipfile = {"testpipenv": {"path": ".", "editable": True, "extras": ["dev"]}}
with open(os.path.join(p.path, 'Pipfile'), 'w') as fh:
fh.write("""
[packages]
+10 -10
View File
@@ -15,7 +15,7 @@ from pipenv.utils import temp_environ
@pytest.mark.lock
@pytest.mark.requirements
def test_lock_handle_eggs(PipenvInstance):
"""Ensure locking works with packages provoding egg formats.
"""Ensure locking works with packages providing egg formats.
"""
with PipenvInstance() as p:
with open(p.pipfile_path, 'w') as f:
@@ -174,7 +174,7 @@ def test_complex_lock_with_vcs_deps(PipenvInstance, pip_src_dir):
click = "==6.7"
[dev-packages]
requests = {git = "https://github.com/kennethreitz/requests.git"}
requests = {git = "https://github.com/psf/requests.git"}
""".strip()
f.write(contents)
@@ -429,7 +429,7 @@ def test_lock_editable_vcs_without_install(PipenvInstance):
with open(p.pipfile_path, 'w') as f:
f.write("""
[packages]
requests = {git = "https://github.com/kennethreitz/requests.git", ref = "master", editable = true}
requests = {git = "https://github.com/psf/requests.git", ref = "master", editable = true}
""".strip())
c = p.pipenv('lock')
assert c.return_code == 0
@@ -448,11 +448,11 @@ def test_lock_editable_vcs_with_ref_in_git(PipenvInstance):
with open(p.pipfile_path, 'w') as f:
f.write("""
[packages]
requests = {git = "https://github.com/kennethreitz/requests.git@883caaf", editable = true}
requests = {git = "https://github.com/psf/requests.git@883caaf", editable = true}
""".strip())
c = p.pipenv('lock')
assert c.return_code == 0
assert p.lockfile['default']['requests']['git'] == 'https://github.com/kennethreitz/requests.git'
assert p.lockfile['default']['requests']['git'] == 'https://github.com/psf/requests.git'
assert p.lockfile['default']['requests']['ref'] == '883caaf145fbe93bd0d208a6b864de9146087312'
c = p.pipenv('install')
assert c.return_code == 0
@@ -466,11 +466,11 @@ def test_lock_editable_vcs_with_ref(PipenvInstance):
with open(p.pipfile_path, 'w') as f:
f.write("""
[packages]
requests = {git = "https://github.com/kennethreitz/requests.git", ref = "883caaf", editable = true}
requests = {git = "https://github.com/psf/requests.git", ref = "883caaf", editable = true}
""".strip())
c = p.pipenv('lock')
assert c.return_code == 0
assert p.lockfile['default']['requests']['git'] == 'https://github.com/kennethreitz/requests.git'
assert p.lockfile['default']['requests']['git'] == 'https://github.com/psf/requests.git'
assert p.lockfile['default']['requests']['ref'] == '883caaf145fbe93bd0d208a6b864de9146087312'
c = p.pipenv('install')
assert c.return_code == 0
@@ -485,7 +485,7 @@ def test_lock_editable_vcs_with_extras_without_install(PipenvInstance):
with open(p.pipfile_path, 'w') as f:
f.write("""
[packages]
requests = {git = "https://github.com/kennethreitz/requests.git", editable = true, extras = ["socks"]}
requests = {git = "https://github.com/psf/requests.git", editable = true, extras = ["socks"]}
""".strip())
c = p.pipenv('lock')
assert c.return_code == 0
@@ -505,7 +505,7 @@ def test_lock_editable_vcs_with_markers_without_install(PipenvInstance):
with open(p.pipfile_path, 'w') as f:
f.write("""
[packages]
requests = {git = "https://github.com/kennethreitz/requests.git", ref = "master", editable = true, markers = "python_version >= '2.6'"}
requests = {git = "https://github.com/psf/requests.git", ref = "master", editable = true, markers = "python_version >= '2.6'"}
""".strip())
c = p.pipenv('lock')
assert c.return_code == 0
@@ -659,4 +659,4 @@ six = "*"
c = p.pipenv("lock --clear")
assert c.return_code == 0
assert "index" in p.lockfile["default"]["six"]
assert p.lockfile["default"]["six"]["index"] == "custom", Path(p.lockfile_path).read_text() # p.lockfile["default"]["six"]
assert p.lockfile["default"]["six"]["index"] == "custom", Path(p.lockfile_path).read_text() # p.lockfile["default"]["six"]
-1
View File
@@ -11,7 +11,6 @@ from pipenv.project import Project
from pipenv.utils import temp_environ
from pipenv.vendor.vistir.path import is_in_path
from pipenv.vendor.delegator import run as delegator_run
import pipenv.environments
@pytest.mark.project
-1
View File
@@ -5,7 +5,6 @@ import os
import pytest
from pipenv._compat import Path
from pipenv.project import Project
# This module is run only on Windows.
-1
View File
@@ -4,7 +4,6 @@ import contextlib
import io
import json
import os
import sys
from tarfile import is_tarfile
from zipfile import is_zipfile
+1
View File
@@ -17,5 +17,6 @@ def where():
# vendored bundle inside Requests
return os.path.join(os.path.abspath(os.path.dirname(__file__)), 'certs', 'cacert.pem')
if __name__ == '__main__':
print(where())
+2
View File
@@ -3,6 +3,7 @@ import pytest
from .app import app as pypi_app
from . import serve, certs
@pytest.fixture(scope='session')
def pypi(request):
server = serve.Server(application=pypi_app)
@@ -31,6 +32,7 @@ def pypi_both(request, pypi, pypi_secure):
def class_based_pypi(request, pypi):
request.cls.pypi = pypi
@pytest.fixture(scope='class')
def class_based_pypi_secure(request, pypi_secure):
request.cls.pypi_secure = pypi_secure
+1
View File
@@ -122,6 +122,7 @@ get_extras_links_scenarios = {
),
}
@pytest.mark.parametrize(
'scenarios,expected',
list(get_extras_links_scenarios.values()),
+5 -12
View File
@@ -3,11 +3,7 @@ import os
import pytest
from first import first
from mock import Mock, patch
import pipenv.utils
import pythonfinder.utils
from pipenv.exceptions import PipenvUsageError
@@ -129,11 +125,8 @@ def test_convert_deps_to_pip(monkeypatch, deps, expected):
),
],
)
def test_convert_deps_to_pip_one_way(monkeypatch, deps, expected):
with monkeypatch.context() as m:
import pip_shims
# m.setattr(pip_shims.shims, "unpack_url", mock_unpack)
assert pipenv.utils.convert_deps_to_pip(deps, r=False) == [expected.lower()]
def test_convert_deps_to_pip_one_way(deps, expected):
assert pipenv.utils.convert_deps_to_pip(deps, r=False) == [expected.lower()]
@pytest.mark.skipif(isinstance(u"", str), reason="don't need to test if unicode is str")
@@ -218,20 +211,20 @@ class TestUtils:
@pytest.mark.windows
@pytest.mark.skipif(os.name != "nt", reason="Windows test only")
def test_windows_shellquote(self):
test_path = "C:\Program Files\Python36\python.exe"
test_path = r"C:\Program Files\Python36\python.exe"
expected_path = '"C:\\\\Program Files\\\\Python36\\\\python.exe"'
assert pipenv.utils.escape_grouped_arguments(test_path) == expected_path
@pytest.mark.utils
def test_is_valid_url(self):
url = "https://github.com/kennethreitz/requests.git"
url = "https://github.com/psf/requests.git"
not_url = "something_else"
assert pipenv.utils.is_valid_url(url)
assert pipenv.utils.is_valid_url(not_url) is False
@pytest.mark.utils
def test_download_file(self):
url = "https://github.com/kennethreitz/pipenv/blob/master/README.md"
url = "https://github.com/pypa/pipenv/blob/master/README.md"
output = "test_download.md"
pipenv.utils.download_file(url, output)
assert os.path.exists(output)