diff --git a/docs/_templates/sidebarintro.html b/docs/_templates/sidebarintro.html
index 216eb345..cbf7e5f8 100644
--- a/docs/_templates/sidebarintro.html
+++ b/docs/_templates/sidebarintro.html
@@ -37,9 +37,8 @@
Stay Informed
Receive updates on new releases and upcoming projects.
-
-Say Thanks!
-Join Mailing List .
+
+Join Mailing List .
Other Projects
@@ -47,7 +46,7 @@
Pipenv-Pipes
-More Kenneth Reitz projects:
+More projects founded by Kenneth Reitz :
@@ -75,4 +74,3 @@
日本語
Español
-
diff --git a/docs/_templates/sidebarlogo.html b/docs/_templates/sidebarlogo.html
index 00fb20c4..59e8641e 100644
--- a/docs/_templates/sidebarlogo.html
+++ b/docs/_templates/sidebarlogo.html
@@ -38,12 +38,11 @@
Stay Informed
Receive updates on new releases and upcoming projects.
-
-
-Say Thanks!
-Join Mailing List .
+
+Join Mailing List .
Other Projects
@@ -51,7 +50,7 @@
Pipenv-Pipes
-More Kenneth Reitz projects:
+More projects founded by Kenneth Reitz :
@@ -72,11 +71,10 @@
Pipenv @ GitHub
- Pipenv @ PyPI
+ Pipenv @ PyPI
Pipenv PPA (PyPA)
- Issue Tracker
+ Issue Tracker
日本語
Español
-
diff --git a/docs/advanced.rst b/docs/advanced.rst
index 9efb798e..e6e31f62 100644
--- a/docs/advanced.rst
+++ b/docs/advanced.rst
@@ -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 `_ 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/
diff --git a/docs/basics.rst b/docs/basics.rst
index a78df254..fa02fb16 100644
--- a/docs/basics.rst
+++ b/docs/basics.rst
@@ -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 `_.
- Note that the ``Pipfile`` uses the `TOML Spec `_.
@@ -188,7 +194,7 @@ You can specify versions of a package using the `Semantic Versioning scheme
+.. _`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``.
diff --git a/docs/cli.rst b/docs/cli.rst
new file mode 100644
index 00000000..873c67d7
--- /dev/null
+++ b/docs/cli.rst
@@ -0,0 +1,8 @@
+.. _cli:
+
+Pipenv CLI Reference
+======================================
+
+.. click:: pipenv:cli
+ :prog: pipenv
+ :show-nested:
diff --git a/docs/conf.py b/docs/conf.py
index c5d6fbe0..90e16afe 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -57,8 +57,8 @@ master_doc = 'index'
# General information about the project.
project = u'pipenv'
-copyright = u'2017. A Kenneth Reitz Project'
-author = u'Kenneth Reitz'
+copyright = u'2020. A project founded by Kenneth Reitz '
+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
diff --git a/docs/dev/philosophy.rst b/docs/dev/philosophy.rst
index 9d364e84..3f4c0bd0 100644
--- a/docs/dev/philosophy.rst
+++ b/docs/dev/philosophy.rst
@@ -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 `__ 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 `__, `Tzu-ping Chung `__, and `Nate Prewitt `__ are the core contributors.
diff --git a/docs/index.rst b/docs/index.rst
index 5d78ecc7..26bfde19 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -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
==================
diff --git a/docs/install.rst b/docs/install.rst
index b5acd312..6aceba0c 100644
--- a/docs/install.rst
+++ b/docs/install.rst
@@ -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
diff --git a/news/3346.doc.rst b/news/3346.doc.rst
new file mode 100644
index 00000000..c985f001
--- /dev/null
+++ b/news/3346.doc.rst
@@ -0,0 +1 @@
+Move CLI docs to its own page.
diff --git a/news/3879.bugfix.rst b/news/3879.bugfix.rst
new file mode 100644
index 00000000..95413ca5
--- /dev/null
+++ b/news/3879.bugfix.rst
@@ -0,0 +1 @@
+Pass ``--pre`` and ``--clear`` options to ``pipenv update --outdated``.
diff --git a/news/3885.trivial.rst b/news/3885.trivial.rst
new file mode 100644
index 00000000..7782e0c9
--- /dev/null
+++ b/news/3885.trivial.rst
@@ -0,0 +1 @@
+Remove a misleading code comment from Specifying Versions documentation.
diff --git a/news/3911.doc.rst b/news/3911.doc.rst
new file mode 100644
index 00000000..a5ab134f
--- /dev/null
+++ b/news/3911.doc.rst
@@ -0,0 +1 @@
+Fix link to GIF in README.md demonstrating Pipenv's usage, and add descriptive alt text.
diff --git a/news/3912.doc.rst b/news/3912.doc.rst
new file mode 100644
index 00000000..24598d19
--- /dev/null
+++ b/news/3912.doc.rst
@@ -0,0 +1 @@
+Added a line describing potential issues in fancy extension.
diff --git a/news/3913.doc.rst b/news/3913.doc.rst
new file mode 100644
index 00000000..54fbbfe8
--- /dev/null
+++ b/news/3913.doc.rst
@@ -0,0 +1 @@
+Documental description of how Pipfile works and association with Pipenv.
diff --git a/news/3914.doc.rst b/news/3914.doc.rst
new file mode 100644
index 00000000..ae37d61d
--- /dev/null
+++ b/news/3914.doc.rst
@@ -0,0 +1 @@
+Clarify the proper value of `python_version` and `python_full_version`.
diff --git a/news/3915.doc.rst b/news/3915.doc.rst
new file mode 100644
index 00000000..2cc94a20
--- /dev/null
+++ b/news/3915.doc.rst
@@ -0,0 +1 @@
+Write description for --deploy extension and few extensions differences.
diff --git a/news/4018.feature.rst b/news/4018.feature.rst
new file mode 100644
index 00000000..fcd6a2a9
--- /dev/null
+++ b/news/4018.feature.rst
@@ -0,0 +1 @@
+Added support for automatic python installs via ``asdf`` and associated ``PIPENV_DONT_USE_ASDF`` environment variable.
diff --git a/news/4045.bugfix.rst b/news/4045.bugfix.rst
new file mode 100644
index 00000000..6558018c
--- /dev/null
+++ b/news/4045.bugfix.rst
@@ -0,0 +1 @@
+Honor PIPENV_SPINNER environment variable
diff --git a/news/4100.doc.rst b/news/4100.doc.rst
new file mode 100644
index 00000000..050bdcca
--- /dev/null
+++ b/news/4100.doc.rst
@@ -0,0 +1 @@
+More documentation for ``.env`` files
diff --git a/news/4137.doc b/news/4137.doc
new file mode 100644
index 00000000..45de74d2
--- /dev/null
+++ b/news/4137.doc
@@ -0,0 +1 @@
+Updated documentation to point to working links.
\ No newline at end of file
diff --git a/pipenv/__init__.py b/pipenv/__init__.py
index 31d49fc1..624397c5 100644
--- a/pipenv/__init__.py
+++ b/pipenv/__init__.py
@@ -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()
diff --git a/pipenv/_compat.py b/pipenv/_compat.py
index caba80fe..fdcca7f5 100644
--- a/pipenv/_compat.py
+++ b/pipenv/_compat.py
@@ -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
diff --git a/pipenv/cli/__init__.py b/pipenv/cli/__init__.py
index d1819953..0f57e306 100644
--- a/pipenv/cli/__init__.py
+++ b/pipenv/cli/__init__.py
@@ -1,4 +1,4 @@
# -*- coding=utf-8 -*-
from __future__ import absolute_import
-from .command import cli
+from .command import cli # noqa
diff --git a/pipenv/cli/command.py b/pipenv/cli/command.py
index c2cd2e49..9d3ce9bf 100644
--- a/pipenv/cli/command.py
+++ b/pipenv/cli/command.py
@@ -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:
diff --git a/pipenv/core.py b/pipenv/core.py
index 0637c225..74b72359 100644
--- a/pipenv/core.py
+++ b/pipenv/core.py
@@ -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:
diff --git a/pipenv/environment.py b/pipenv/environment.py
index 4a694019..b57a858a 100644
--- a/pipenv/environment.py
+++ b/pipenv/environment.py
@@ -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:
diff --git a/pipenv/environments.py b/pipenv/environments.py
index e59ed63a..622b76ff 100644
--- a/pipenv/environments.py
+++ b/pipenv/environments.py
@@ -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
diff --git a/pipenv/exceptions.py b/pipenv/exceptions.py
index c8ca0dc8..6e0032ad 100644
--- a/pipenv/exceptions.py
+++ b/pipenv/exceptions.py
@@ -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)
diff --git a/pipenv/pyenv.py b/pipenv/installers.py
similarity index 61%
rename from pipenv/pyenv.py
rename to pipenv/installers.py
index 941e5991..cd8e49a2 100644
--- a/pipenv/pyenv.py
+++ b/pipenv/installers.py
@@ -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
diff --git a/pipenv/pipenv.1 b/pipenv/pipenv.1
index 6cd64a4c..7dd63f58 100644
--- a/pipenv/pipenv.1
+++ b/pipenv/pipenv.1
@@ -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 Kenneth Reitz Project
+2017. A project founded by Kenneth Reitz
.\" Generated by docutils manpage writer.
.
diff --git a/pipenv/project.py b/pipenv/project.py
index c4b0c941..5b14106e 100644
--- a/pipenv/project.py
+++ b/pipenv/project.py
@@ -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,
diff --git a/pipenv/resolver.py b/pipenv/resolver.py
index 1219cc24..cd04fccb 100644
--- a/pipenv/resolver.py
+++ b/pipenv/resolver.py
@@ -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")
diff --git a/pipenv/utils.py b/pipenv/utils.py
index 2b0a8cdb..32f4491c 100644
--- a/pipenv/utils.py
+++ b/pipenv/utils.py
@@ -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"):
diff --git a/pytest.ini b/pytest.ini
deleted file mode 100644
index da966ec9..00000000
--- a/pytest.ini
+++ /dev/null
@@ -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
diff --git a/setup.cfg b/setup.cfg
index 896a5a91..fbc691d4 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -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
diff --git a/setup.py b/setup.py
index d86d85e0..c3ee913b 100644
--- a/setup.py
+++ b/setup.py
@@ -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={
diff --git a/tasks/__init__.py b/tasks/__init__.py
index 63fe1388..d81d101d 100644
--- a/tasks/__init__.py
+++ b/tasks/__init__.py
@@ -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
diff --git a/tasks/release.py b/tasks/release.py
index 610a36a9..c43a7c85 100644
--- a/tasks/release.py
+++ b/tasks/release.py
@@ -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
diff --git a/tasks/vendoring/__init__.py b/tasks/vendoring/__init__.py
index 69398450..8329ba4e 100644
--- a/tasks/vendoring/__init__.py
+++ b/tasks/vendoring/__init__.py
@@ -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"
diff --git a/tasks/vendoring/vendor_passa.py b/tasks/vendoring/vendor_passa.py
index f2c58745..2da91259 100644
--- a/tasks/vendoring/vendor_passa.py
+++ b/tasks/vendoring/vendor_passa.py
@@ -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
diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py
index b05eacfa..53973d34 100644
--- a/tests/integration/conftest.py
+++ b/tests/integration/conftest.py
@@ -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
diff --git a/tests/integration/test_cli.py b/tests/integration/test_cli.py
index 1ee9f64a..04253fc5 100644
--- a/tests/integration/test_cli.py
+++ b/tests/integration/test_cli.py
@@ -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
diff --git a/tests/integration/test_dot_venv.py b/tests/integration/test_dot_venv.py
index aa52dd5e..3cbc88db 100644
--- a/tests/integration/test_dot_venv.py
+++ b/tests/integration/test_dot_venv.py
@@ -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
diff --git a/tests/integration/test_install_basic.py b/tests/integration/test_install_basic.py
index 80ccdf0e..a6beb21d 100644
--- a/tests/integration/test_install_basic.py
+++ b/tests/integration/test_install_basic.py
@@ -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
diff --git a/tests/integration/test_install_markers.py b/tests/integration/test_install_markers.py
index 00f9c789..de3ba193 100644
--- a/tests/integration/test_install_markers.py
+++ b/tests/integration/test_install_markers.py
@@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function
import os
-import sys
import pytest
diff --git a/tests/integration/test_install_twists.py b/tests/integration/test_install_twists.py
index 44973df5..4fcbd4c5 100644
--- a/tests/integration/test_install_twists.py
+++ b/tests/integration/test_install_twists.py
@@ -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]
diff --git a/tests/integration/test_lock.py b/tests/integration/test_lock.py
index 4c227395..7d207cca 100644
--- a/tests/integration/test_lock.py
+++ b/tests/integration/test_lock.py
@@ -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"]
diff --git a/tests/integration/test_project.py b/tests/integration/test_project.py
index f7b0e460..bef9912f 100644
--- a/tests/integration/test_project.py
+++ b/tests/integration/test_project.py
@@ -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
diff --git a/tests/integration/test_windows.py b/tests/integration/test_windows.py
index b303d0ab..a74be386 100644
--- a/tests/integration/test_windows.py
+++ b/tests/integration/test_windows.py
@@ -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.
diff --git a/tests/pytest-pypi/pytest_pypi/app.py b/tests/pytest-pypi/pytest_pypi/app.py
index 95dbd076..5484eeb7 100644
--- a/tests/pytest-pypi/pytest_pypi/app.py
+++ b/tests/pytest-pypi/pytest_pypi/app.py
@@ -4,7 +4,6 @@ import contextlib
import io
import json
import os
-import sys
from tarfile import is_tarfile
from zipfile import is_zipfile
diff --git a/tests/pytest-pypi/pytest_pypi/certs.py b/tests/pytest-pypi/pytest_pypi/certs.py
index f9e33870..b73fc63a 100644
--- a/tests/pytest-pypi/pytest_pypi/certs.py
+++ b/tests/pytest-pypi/pytest_pypi/certs.py
@@ -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())
diff --git a/tests/pytest-pypi/pytest_pypi/plugin.py b/tests/pytest-pypi/pytest_pypi/plugin.py
index a17fcb24..83cd73fb 100644
--- a/tests/pytest-pypi/pytest_pypi/plugin.py
+++ b/tests/pytest-pypi/pytest_pypi/plugin.py
@@ -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
diff --git a/tests/unit/test_patched.py b/tests/unit/test_patched.py
index 249292b4..03e1c039 100644
--- a/tests/unit/test_patched.py
+++ b/tests/unit/test_patched.py
@@ -122,6 +122,7 @@ get_extras_links_scenarios = {
),
}
+
@pytest.mark.parametrize(
'scenarios,expected',
list(get_extras_links_scenarios.values()),
diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py
index 18cb94a8..d3363037 100644
--- a/tests/unit/test_utils.py
+++ b/tests/unit/test_utils.py
@@ -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)