Update to py36 plus syntax

This commit is contained in:
Frost Ming
2021-07-28 10:59:00 +08:00
parent 1d8f1abaef
commit ca5d931f1f
64 changed files with 649 additions and 749 deletions
+1 -1
View File
@@ -13,4 +13,4 @@ name = "python"
enabled = true enabled = true
[analyzers.meta] [analyzers.meta]
runtime_version = "3.x.x" runtime_version = "3.x.x"
+1 -1
View File
@@ -7,7 +7,7 @@ What is the thing you want to fix? Is it associated with an issue on GitHub? Ple
Always consider opening an issue first to describe your problem, so we can discuss what is the best way to amend it. Note that if you do not describe the goal of this change or link to a related issue, the maintainers may close the PR without further review. Always consider opening an issue first to describe your problem, so we can discuss what is the best way to amend it. Note that if you do not describe the goal of this change or link to a related issue, the maintainers may close the PR without further review.
If your pull request makes a non-insignificant change to Pipenv, such as the user interface or intended functionality, please file a PEEP. If your pull request makes a non-insignificant change to Pipenv, such as the user interface or intended functionality, please file a PEEP.
https://github.com/pypa/pipenv/blob/master/peeps/PEEP-000.md https://github.com/pypa/pipenv/blob/master/peeps/PEEP-000.md
+2 -2
View File
@@ -1,5 +1,5 @@
The contents of the vendor and patched directories are subject to different licenses The contents of the vendor and patched directories are subject to different licenses
than the rest of this project. than the rest of this project.
Their respective licenses can be looked up at pypi.python.org or in their Their respective licenses can be looked up at pypi.python.org or in their
corresponding LICENSE files. corresponding LICENSE files.
+3 -3
View File
@@ -52,7 +52,7 @@ Or, if you\'re using Fedora:
Or, if you\'re using FreeBSD: Or, if you\'re using FreeBSD:
# pkg install py36-pipenv # pkg install py36-pipenv
Or, if you\'re using Windows: Or, if you\'re using Windows:
# pip install --user pipenv # pip install --user pipenv
@@ -195,8 +195,8 @@ Fish is the best shell. You should use it.
lock Generates Pipfile.lock. lock Generates Pipfile.lock.
open View a given module in your editor. open View a given module in your editor.
run Spawns a command installed into the virtualenv. run Spawns a command installed into the virtualenv.
scripts Displays the shortcuts in the (optional) [scripts] section of scripts Displays the shortcuts in the (optional) [scripts] section of
Pipfile. Pipfile.
shell Spawns a shell within the virtualenv. shell Spawns a shell within the virtualenv.
sync Installs all packages specified in Pipfile.lock. sync Installs all packages specified in Pipfile.lock.
uninstall Un-installs a provided package and removes it from Pipfile. uninstall Un-installs a provided package and removes it from Pipfile.
+1 -1
View File
@@ -17,4 +17,4 @@ help:
# Catch-all target: route all unknown targets to Sphinx using the new # Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile %: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+2 -2
View File
@@ -84,9 +84,9 @@ var Konami = function (callback) {
}, },
touchendHandler: function () { touchendHandler: function () {
konami.iphone.input.push(konami.iphone.check_direction()); konami.iphone.input.push(konami.iphone.check_direction());
if (konami.iphone.input.length > konami.iphone.keys.length) konami.iphone.input.shift(); if (konami.iphone.input.length > konami.iphone.keys.length) konami.iphone.input.shift();
if (konami.iphone.input.length === konami.iphone.keys.length) { if (konami.iphone.input.length === konami.iphone.keys.length) {
var match = true; var match = true;
for (var i = 0; i < konami.iphone.keys.length; i++) { for (var i = 0; i < konami.iphone.keys.length; i++) {
+7 -8
View File
@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# pipenv documentation build configuration file, created by # pipenv documentation build configuration file, created by
# sphinx-quickstart on Mon Jan 30 13:28:36 2017. # sphinx-quickstart on Mon Jan 30 13:28:36 2017.
@@ -56,9 +55,9 @@ source_suffix = '.rst'
master_doc = 'index' master_doc = 'index'
# General information about the project. # General information about the project.
project = u'pipenv' project = 'pipenv'
copyright = u'2020. A project founded by <a href="http://kennethreitz.com/pages/open-projects.html">Kenneth Reitz</a>' copyright = '2020. A project founded by <a href="http://kennethreitz.com/pages/open-projects.html">Kenneth Reitz</a>'
author = u'Python Packaging Authority' author = 'Python Packaging Authority'
# The version info for the project you're documenting, acts as replacement for # The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the # |version| and |release|, also used in various other places throughout the
@@ -157,8 +156,8 @@ latex_elements = {
# (source start file, target name, title, # (source start file, target name, title,
# author, documentclass [howto, manual, or own class]). # author, documentclass [howto, manual, or own class]).
latex_documents = [ latex_documents = [
(master_doc, 'pipenv.tex', u'pipenv Documentation', (master_doc, 'pipenv.tex', 'pipenv Documentation',
u'Kenneth Reitz', 'manual'), 'Kenneth Reitz', 'manual'),
] ]
@@ -167,7 +166,7 @@ latex_documents = [
# One entry per manual page. List of tuples # One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section). # (source start file, name, description, authors, manual section).
man_pages = [ man_pages = [
(master_doc, 'pipenv', u'pipenv Documentation', (master_doc, 'pipenv', 'pipenv Documentation',
[author], 1) [author], 1)
] ]
@@ -178,7 +177,7 @@ man_pages = [
# (source start file, target name, title, author, # (source start file, target name, title, author,
# dir menu entry, description, category) # dir menu entry, description, category)
texinfo_documents = [ texinfo_documents = [
(master_doc, 'pipenv', u'pipenv Documentation', (master_doc, 'pipenv', 'pipenv Documentation',
author, 'pipenv', 'One line description of project.', author, 'pipenv', 'One line description of project.',
'Miscellaneous'), 'Miscellaneous'),
] ]
+1 -1
View File
@@ -6,4 +6,4 @@ Pipenv will be governed by a board of maintainers (trusted collaborators to the
The BDFL retains his title, however, revokes himself of his powers. The BDFL retains his title, however, revokes himself of his powers.
PEEP approval will be determined by available members of the board of maintainers, in private or public channels. PEEP approval will be determined by available members of the board of maintainers, in private or public channels.
+9 -9
View File
@@ -4,18 +4,18 @@ pipenv check needs offline, ci, and other output capabilities.
Not everyone can utilize pipenv check and access the internet. Safety check knew this Not everyone can utilize pipenv check and access the internet. Safety check knew this
and that is why they created safety-db. This repository contains a json database that and that is why they created safety-db. This repository contains a json database that
is updated monthly. Safety check allows you to pass a --db flag that is a local directory is updated monthly. Safety check allows you to pass a --db flag that is a local directory
containing that database. Safety check also allows you to pass --json, --bare, and containing that database. Safety check also allows you to pass --json, --bare, and
--full-report. Pipenv check has their own way of displaying the results that is why I --full-report. Pipenv check has their own way of displaying the results that is why I
believe there should be a --output flag that allows users to specify json, bare, believe there should be a --output flag that allows users to specify json, bare,
and full-report from safety check and default for the current pipenv check output. and full-report from safety check and default for the current pipenv check output.
Currently, pipenv check has a lot of stdout messages and makes it harder to pipe Currently, pipenv check has a lot of stdout messages and makes it harder to pipe
the results into something to be checked (especially for continuous integration the results into something to be checked (especially for continuous integration
pipelines). That is why adding a --squelch switch is also important. This will be pipelines). That is why adding a --squelch switch is also important. This will be
default False (display all stdout); however, the user has the option to add the default False (display all stdout); however, the user has the option to add the
--squelch switch to make the output only come from safety check. --squelch switch to make the output only come from safety check.
## Current implementation: ## Current implementation:
### Example 1 ### Example 1
@@ -36,9 +36,9 @@ parse error: Invalid numeric literal at line 1, column 9
## Future implementation: ## Future implementation:
### Example 1 ### Example 1
``` bash ``` bash
pipenv check --db /Users/macbookpro/workspace/test/safety-db/data/ --output json --squelch pipenv check --db /Users/macbookpro/workspace/test/safety-db/data/ --output json --squelch
[ [
[ [
"insecure-package", "insecure-package",
"<0.2.0", "<0.2.0",
"0.1.0", "0.1.0",
-1
View File
@@ -1,4 +1,3 @@
# -*- coding=utf-8 -*-
# |~~\' |~~ # |~~\' |~~
# |__/||~~\|--|/~\\ / # |__/||~~\|--|/~\\ /
# | ||__/|__| |\/ # | ||__/|__| |\/
+11 -30
View File
@@ -1,4 +1,3 @@
# -*- coding=utf-8 -*-
"""A compatibility module for pipenv's backports and manipulations. """A compatibility module for pipenv's backports and manipulations.
Exposes a standard API that enables compatibility across python versions, Exposes a standard API that enables compatibility across python versions,
@@ -7,26 +6,18 @@ operating systems, etc.
import sys import sys
import warnings import warnings
import six
import vistir import vistir
from .vendor.vistir.compat import ( from .vendor.vistir.compat import (
NamedTemporaryFile, Path, ResourceWarning, TemporaryDirectory NamedTemporaryFile, Path, ResourceWarning, TemporaryDirectory
) )
# Backport required for earlier versions of Python.
if sys.version_info < (3, 3):
from .vendor.backports.shutil_get_terminal_size import get_terminal_size
else:
from shutil import get_terminal_size
warnings.filterwarnings("ignore", category=ResourceWarning) warnings.filterwarnings("ignore", category=ResourceWarning)
__all__ = [ __all__ = [
"NamedTemporaryFile", "Path", "ResourceWarning", "TemporaryDirectory", "NamedTemporaryFile", "Path", "ResourceWarning", "TemporaryDirectory",
"get_terminal_size", "getpreferredencoding", "DEFAULT_ENCODING", "canonical_encoding_name", "getpreferredencoding", "DEFAULT_ENCODING", "canonical_encoding_name",
"force_encoding", "UNICODE_TO_ASCII_TRANSLATION_MAP", "decode_output", "fix_utf8" "force_encoding", "UNICODE_TO_ASCII_TRANSLATION_MAP", "decode_output", "fix_utf8"
] ]
@@ -35,12 +26,7 @@ def getpreferredencoding():
import locale import locale
# Borrowed from Invoke # Borrowed from Invoke
# (see https://github.com/pyinvoke/invoke/blob/93af29d/invoke/runners.py#L881) # (see https://github.com/pyinvoke/invoke/blob/93af29d/invoke/runners.py#L881)
_encoding = locale.getpreferredencoding(False) return locale.getpreferredencoding(False)
if six.PY2 and sys.platform != "win32":
_default_encoding = locale.getdefaultlocale()[1]
if _default_encoding is not None:
_encoding = _default_encoding
return _encoding
DEFAULT_ENCODING = getpreferredencoding() DEFAULT_ENCODING = getpreferredencoding()
@@ -69,7 +55,7 @@ def force_encoding():
return DEFAULT_ENCODING, DEFAULT_ENCODING return DEFAULT_ENCODING, DEFAULT_ENCODING
stdout_encoding = canonical_encoding_name(sys.stdout.encoding) stdout_encoding = canonical_encoding_name(sys.stdout.encoding)
stderr_encoding = canonical_encoding_name(sys.stderr.encoding) stderr_encoding = canonical_encoding_name(sys.stderr.encoding)
if sys.platform == "win32" and sys.version_info >= (3, 1): if sys.platform == "win32":
return DEFAULT_ENCODING, DEFAULT_ENCODING return DEFAULT_ENCODING, DEFAULT_ENCODING
if stdout_encoding != "utf-8" or stderr_encoding != "utf-8": if stdout_encoding != "utf-8" or stderr_encoding != "utf-8":
@@ -110,10 +96,10 @@ OUT_ENCODING, ERR_ENCODING = force_encoding()
UNICODE_TO_ASCII_TRANSLATION_MAP = { UNICODE_TO_ASCII_TRANSLATION_MAP = {
8230: u"...", 8230: "...",
8211: u"-", 8211: "-",
10004: u"OK", 10004: "OK",
10008: u"x", 10008: "x",
} }
@@ -124,26 +110,21 @@ def decode_for_output(output, target=sys.stdout):
def decode_output(output): def decode_output(output):
if not isinstance(output, six.string_types): if not isinstance(output, str):
return output return output
try: try:
output = output.encode(DEFAULT_ENCODING) output = output.encode(DEFAULT_ENCODING)
except (AttributeError, UnicodeDecodeError, UnicodeEncodeError): except (AttributeError, UnicodeDecodeError, UnicodeEncodeError):
if six.PY2: output = output.translate(UNICODE_TO_ASCII_TRANSLATION_MAP)
output = unicode.translate(vistir.misc.to_text(output), # noqa
UNICODE_TO_ASCII_TRANSLATION_MAP)
else:
output = output.translate(UNICODE_TO_ASCII_TRANSLATION_MAP)
output = output.encode(DEFAULT_ENCODING, "replace") output = output.encode(DEFAULT_ENCODING, "replace")
return vistir.misc.to_text(output, encoding=DEFAULT_ENCODING, errors="replace") return vistir.misc.to_text(output, encoding=DEFAULT_ENCODING, errors="replace")
def fix_utf8(text): def fix_utf8(text):
if not isinstance(text, six.string_types): if not isinstance(text, str):
return text return text
try: try:
text = decode_output(text) text = decode_output(text)
except UnicodeDecodeError: except UnicodeDecodeError:
if six.PY2: pass
text = unicode.translate(vistir.misc.to_text(text), UNICODE_TO_ASCII_TRANSLATION_MAP) # noqa
return text return text
-3
View File
@@ -1,4 +1 @@
# -*- coding=utf-8 -*-
from __future__ import absolute_import
from .command import cli # noqa from .command import cli # noqa
+11 -14
View File
@@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import
import os import os
import sys import sys
@@ -81,7 +78,7 @@ def cli(
shell = shells.detect_info()[0] shell = shells.detect_info()[0]
except shells.ShellDetectionFailure: except shells.ShellDetectionFailure:
echo( echo(
"Fail to detect shell. Please provide the {0} environment " "Fail to detect shell. Please provide the {} environment "
"variable.".format(crayons.normal("PIPENV_SHELL", bold=True)), "variable.".format(crayons.normal("PIPENV_SHELL", bold=True)),
err=True, err=True,
) )
@@ -115,9 +112,9 @@ def cli(
from .. import environments from .. import environments
for key in environments.__dict__: for key in environments.__dict__:
if key.startswith("PIPENV"): if key.startswith("PIPENV"):
echo(" - {0}".format(crayons.normal(key, bold=True))) echo(f" - {crayons.normal(key, bold=True)}")
echo( echo(
"\nYou can learn more at:\n {0}".format( "\nYou can learn more at:\n {}".format(
crayons.green( crayons.green(
"https://pipenv.pypa.io/en/latest/advanced/#configuration-with-environment-variables" "https://pipenv.pypa.io/en/latest/advanced/#configuration-with-environment-variables"
) )
@@ -175,7 +172,7 @@ def cli(
loc = project.virtualenv_location loc = project.virtualenv_location
echo( echo(
crayons.normal( crayons.normal(
u"{0} ({1})...".format( "{} ({})...".format(
crayons.normal("Removing virtualenv", bold=True), crayons.normal("Removing virtualenv", bold=True),
crayons.green(loc), crayons.green(loc),
) )
@@ -413,7 +410,7 @@ def shell(
venv_name = os.environ.get("VIRTUAL_ENV", "UNKNOWN_VIRTUAL_ENVIRONMENT") venv_name = os.environ.get("VIRTUAL_ENV", "UNKNOWN_VIRTUAL_ENVIRONMENT")
if not anyway: if not anyway:
echo( echo(
"{0} {1} {2}\nNo action taken to avoid nested environments.".format( "{} {} {}\nNo action taken to avoid nested environments.".format(
crayons.normal("Shell for"), crayons.normal("Shell for"),
crayons.green(venv_name, bold=True), crayons.green(venv_name, bold=True),
crayons.normal("already activated.", bold=True), crayons.normal("already activated.", bold=True),
@@ -530,9 +527,9 @@ def check(
@cli.command(short_help="Runs lock, then sync.", context_settings=CONTEXT_SETTINGS) @cli.command(short_help="Runs lock, then sync.", context_settings=CONTEXT_SETTINGS)
@option("--bare", is_flag=True, default=False, help="Minimal output.") @option("--bare", is_flag=True, default=False, help="Minimal output.")
@option( @option(
"--outdated", is_flag=True, default=False, help=u"List out-of-date dependencies." "--outdated", is_flag=True, default=False, help="List out-of-date dependencies."
) )
@option("--dry-run", is_flag=True, default=None, help=u"List out-of-date dependencies.") @option("--dry-run", is_flag=True, default=None, help="List out-of-date dependencies.")
@install_options @install_options
@pass_state @pass_state
@pass_context @pass_context
@@ -564,7 +561,7 @@ def update(
editable = [p for p in state.installstate.editables if p] editable = [p for p in state.installstate.editables if p]
if not packages: if not packages:
echo( echo(
"{0} {1} {2} {3}{4}".format( "{} {} {} {}{}".format(
crayons.normal("Running", bold=True), crayons.normal("Running", bold=True),
crayons.yellow("$ pipenv lock", bold=True), crayons.yellow("$ pipenv lock", bold=True),
crayons.normal("then", bold=True), crayons.normal("then", bold=True),
@@ -576,7 +573,7 @@ def update(
for package in packages + editable: for package in packages + editable:
if package not in project.all_packages: if package not in project.all_packages:
echo( echo(
"{0}: {1} was not found in your Pipfile! Aborting." "{}: {} was not found in your Pipfile! Aborting."
"".format( "".format(
crayons.red("Warning", bold=True), crayons.red("Warning", bold=True),
crayons.green(package, bold=True), crayons.green(package, bold=True),
@@ -608,7 +605,7 @@ def update(
@cli.command( @cli.command(
short_help=u"Displays currently-installed dependency graph information.", short_help="Displays currently-installed dependency graph information.",
context_settings=CONTEXT_SETTINGS context_settings=CONTEXT_SETTINGS
) )
@option("--bare", is_flag=True, default=False, help="Minimal output.") @option("--bare", is_flag=True, default=False, help="Minimal output.")
@@ -656,7 +653,7 @@ def run_open(state, module, *args, **kwargs):
p = os.path.dirname(c.out.strip().rstrip("cdo")) p = os.path.dirname(c.out.strip().rstrip("cdo"))
else: else:
p = c.out.strip().rstrip("cdo") p = c.out.strip().rstrip("cdo")
echo(crayons.normal("Opening {0!r} in your EDITOR.".format(p), bold=True)) echo(crayons.normal(f"Opening {p!r} in your EDITOR.", bold=True))
inline_activate_virtual_environment() inline_activate_virtual_environment()
edit(filename=p) edit(filename=p)
return 0 return 0
+8 -11
View File
@@ -1,6 +1,3 @@
# -*- coding=utf-8 -*-
from __future__ import absolute_import
import os import os
import click.types import click.types
@@ -51,7 +48,7 @@ class PipenvGroup(DYMMixin, Group):
) )
class State(object): class State:
def __init__(self): def __init__(self):
self.index = None self.index = None
self.extra_index_urls = [] self.extra_index_urls = []
@@ -68,7 +65,7 @@ class State(object):
self.lockoptions = LockOptions() self.lockoptions = LockOptions()
class InstallState(object): class InstallState:
def __init__(self): def __init__(self):
self.dev = False self.dev = False
self.pre = False self.pre = False
@@ -84,7 +81,7 @@ class InstallState(object):
self.editables = [] self.editables = []
class LockOptions(object): class LockOptions:
def __init__(self): def __init__(self):
self.dev_only = False self.dev_only = False
self.emit_requirements = False self.emit_requirements = False
@@ -110,7 +107,7 @@ def extra_index_option(f):
state.extra_index_urls.extend(list(value)) state.extra_index_urls.extend(list(value))
return value return value
return option("--extra-index-url", multiple=True, expose_value=False, return option("--extra-index-url", multiple=True, expose_value=False,
help=u"URLs to the extra PyPI compatible indexes to query for package look-ups.", help="URLs to the extra PyPI compatible indexes to query for package look-ups.",
callback=callback, envvar="PIP_EXTRA_INDEX_URL")(f) callback=callback, envvar="PIP_EXTRA_INDEX_URL")(f)
@@ -142,7 +139,7 @@ def skip_lock_option(f):
state.installstate.skip_lock = value state.installstate.skip_lock = value
return value return value
return option("--skip-lock", is_flag=True, default=False, expose_value=False, return option("--skip-lock", is_flag=True, default=False, expose_value=False,
help=u"Skip locking mechanisms and use the Pipfile instead during operation.", help="Skip locking mechanisms and use the Pipfile instead during operation.",
envvar="PIPENV_SKIP_LOCK", callback=callback, type=click.types.BOOL, envvar="PIPENV_SKIP_LOCK", callback=callback, type=click.types.BOOL,
show_envvar=True)(f) show_envvar=True)(f)
@@ -153,7 +150,7 @@ def keep_outdated_option(f):
state.installstate.keep_outdated = value state.installstate.keep_outdated = value
return value return value
return option("--keep-outdated", is_flag=True, default=False, expose_value=False, return option("--keep-outdated", is_flag=True, default=False, expose_value=False,
help=u"Keep out-dated dependencies from being updated in Pipfile.lock.", help="Keep out-dated dependencies from being updated in Pipfile.lock.",
callback=callback, type=click.types.BOOL, show_envvar=True)(f) callback=callback, type=click.types.BOOL, show_envvar=True)(f)
@@ -204,7 +201,7 @@ def pre_option(f):
state = ctx.ensure_object(State) state = ctx.ensure_object(State)
state.installstate.pre = value state.installstate.pre = value
return value return value
return option("--pre", is_flag=True, default=False, help=u"Allow pre-releases.", return option("--pre", is_flag=True, default=False, help="Allow pre-releases.",
callback=callback, type=click.types.BOOL, expose_value=False)(f) callback=callback, type=click.types.BOOL, expose_value=False)(f)
@@ -371,7 +368,7 @@ def deploy_option(f):
state.installstate.deploy = value state.installstate.deploy = value
return value return value
return option("--deploy", is_flag=True, default=False, type=click.types.BOOL, return option("--deploy", is_flag=True, default=False, type=click.types.BOOL,
help=u"Abort if the Pipfile.lock is out-of-date, or Python version is" help="Abort if the Pipfile.lock is out-of-date, or Python version is"
" wrong.", callback=callback, expose_value=False)(f) " wrong.", callback=callback, expose_value=False)(f)
+1 -3
View File
@@ -2,8 +2,6 @@ import itertools
import re import re
import shlex import shlex
import six
class ScriptEmptyError(ValueError): class ScriptEmptyError(ValueError):
pass pass
@@ -28,7 +26,7 @@ class Script(object):
@classmethod @classmethod
def parse(cls, value): def parse(cls, value):
if isinstance(value, six.string_types): if isinstance(value, str):
value = shlex.split(value) value = shlex.split(value)
if not value: if not value:
raise ScriptEmptyError(value) raise ScriptEmptyError(value)
+187 -193
View File
File diff suppressed because it is too large Load Diff
+34 -40
View File
@@ -1,9 +1,5 @@
# -*- coding=utf-8 -*-
from __future__ import absolute_import, print_function
import contextlib import contextlib
import importlib import importlib
import io
import json import json
import operator import operator
import os import os
@@ -14,7 +10,6 @@ from sysconfig import get_paths, get_python_version
import itertools import itertools
import pkg_resources import pkg_resources
import six
import pipenv import pipenv
@@ -37,7 +32,7 @@ BASE_WORKING_SET = pkg_resources.WorkingSet(sys.path)
# TODO: Unittests for this class # TODO: Unittests for this class
class Environment(object): class Environment:
def __init__( def __init__(
self, self,
prefix=None, # type: Optional[str] prefix=None, # type: Optional[str]
@@ -48,7 +43,7 @@ class Environment(object):
sources=None, # type: Optional[List[TSource]] sources=None, # type: Optional[List[TSource]]
project=None # type: Optional[Project] project=None # type: Optional[Project]
): ):
super(Environment, self).__init__() super().__init__()
self._modules = {'pkg_resources': pkg_resources, 'pipenv': pipenv} self._modules = {'pkg_resources': pkg_resources, 'pipenv': pipenv}
self.base_working_set = base_working_set if base_working_set else BASE_WORKING_SET self.base_working_set = base_working_set if base_working_set else BASE_WORKING_SET
prefix = normalize_path(prefix) prefix = normalize_path(prefix)
@@ -89,8 +84,8 @@ class Environment(object):
module = importlib.import_module(name) module = importlib.import_module(name)
if name in sys.modules: if name in sys.modules:
try: try:
six.moves.reload_module(module) importlib.reload(module)
six.moves.reload_module(sys.modules[name]) importlib.reload(sys.modules[name])
except TypeError: except TypeError:
del sys.modules[name] del sys.modules[name]
sys.modules[name] = self._modules[name] sys.modules[name] = self._modules[name]
@@ -115,7 +110,7 @@ class Environment(object):
try: try:
reqs = dist.requires() reqs = dist.requires()
# KeyError = limited metadata can be found # KeyError = limited metadata can be found
except (KeyError, AttributeError, OSError, IOError): # The METADATA file can't be found except (KeyError, AttributeError, OSError): # The METADATA file can't be found
return deps return deps
for req in reqs: for req in reqs:
try: try:
@@ -336,20 +331,20 @@ class Environment(object):
sysconfig_line = "sysconfig.get_path('{0}')" sysconfig_line = "sysconfig.get_path('{0}')"
if python_lib: if python_lib:
for key, var, val in (("pure", "lib", "0"), ("plat", "lib", "1")): for key, var, val in (("pure", "lib", "0"), ("plat", "lib", "1")):
dist_prefix = "{0}lib".format(key) dist_prefix = f"{key}lib"
# XXX: We need to get 'stdlib' or 'platstdlib' # XXX: We need to get 'stdlib' or 'platstdlib'
sys_prefix = "{0}stdlib".format("" if key == "pure" else key) sys_prefix = "{}stdlib".format("" if key == "pure" else key)
pylib_lines.append("u'%s': u'{{0}}'.format(%s)" % (dist_prefix, distutils_line.format(var, val))) pylib_lines.append(f"u'{dist_prefix}': u'{{{{0}}}}'.format({distutils_line.format(var, val)})")
pylib_lines.append("u'%s': u'{{0}}'.format(%s)" % (sys_prefix, sysconfig_line.format(sys_prefix))) pylib_lines.append(f"u'{sys_prefix}': u'{{{{0}}}}'.format({sysconfig_line.format(sys_prefix)})")
if python_inc: if python_inc:
for key, var, val in (("include", "inc", "0"), ("platinclude", "inc", "1")): for key, var, val in (("include", "inc", "0"), ("platinclude", "inc", "1")):
pylib_lines.append("u'%s': u'{{0}}'.format(%s)" % (key, distutils_line.format(var, val))) pylib_lines.append(f"u'{key}': u'{{{{0}}}}'.format({distutils_line.format(var, val)})")
lines = pylib_lines + pyinc_lines lines = pylib_lines + pyinc_lines
if scripts: if scripts:
lines.append("u'scripts': u'{{0}}'.format(%s)" % sysconfig_line.format("scripts")) lines.append("u'scripts': u'{{0}}'.format(%s)" % sysconfig_line.format("scripts"))
if py_version: if py_version:
lines.append("u'py_version_short': u'{{0}}'.format(distutils.sysconfig.get_python_version()),") lines.append("u'py_version_short': u'{{0}}'.format(distutils.sysconfig.get_python_version()),")
lines_as_str = u",".join(lines) lines_as_str = ",".join(lines)
py_command = py_command % lines_as_str py_command = py_command % lines_as_str
return py_command return py_command
@@ -371,7 +366,7 @@ class Environment(object):
) )
if c.returncode == 0: if c.returncode == 0:
paths = {} paths = {}
with io.open(tmpfile_path, "r", encoding="utf-8") as fh: with open(tmpfile_path, "r", encoding="utf-8") as fh:
paths = json.load(fh) paths = json.load(fh)
if "purelib" in paths: if "purelib" in paths:
paths["libdir"] = paths["purelib"] = make_posix(paths["purelib"]) paths["libdir"] = paths["purelib"] = make_posix(paths["purelib"])
@@ -380,8 +375,8 @@ class Environment(object):
paths[key] = make_posix(paths[key]) paths[key] = make_posix(paths[key])
return paths return paths
else: else:
vistir.misc.echo("Failed to load paths: {0}".format(c.err), fg="yellow") vistir.misc.echo(f"Failed to load paths: {c.err}", fg="yellow")
vistir.misc.echo("Output: {0}".format(c.out), fg="yellow") vistir.misc.echo(f"Output: {c.out}", fg="yellow")
return None return None
def get_lib_paths(self): def get_lib_paths(self):
@@ -402,7 +397,7 @@ class Environment(object):
paths = None paths = None
if c.returncode == 0: if c.returncode == 0:
paths = {} paths = {}
with io.open(tmpfile_path, "r", encoding="utf-8") as fh: with open(tmpfile_path, "r", encoding="utf-8") as fh:
paths = json.load(fh) paths = json.load(fh)
if "purelib" in paths: if "purelib" in paths:
paths["libdir"] = paths["purelib"] = make_posix(paths["purelib"]) paths["libdir"] = paths["purelib"] = make_posix(paths["purelib"])
@@ -411,8 +406,8 @@ class Environment(object):
paths[key] = make_posix(paths[key]) paths[key] = make_posix(paths[key])
return paths return paths
else: else:
vistir.misc.echo("Failed to load paths: {0}".format(c.err), fg="yellow") vistir.misc.echo(f"Failed to load paths: {c.err}", fg="yellow")
vistir.misc.echo("Output: {0}".format(c.out), fg="yellow") vistir.misc.echo(f"Output: {c.out}", fg="yellow")
if not paths: if not paths:
if not self.prefix.joinpath("lib").exists(): if not self.prefix.joinpath("lib").exists():
return {} return {}
@@ -455,15 +450,15 @@ class Environment(object):
) )
if c.returncode == 0: if c.returncode == 0:
paths = [] paths = []
with io.open(tmpfile_path, "r", encoding="utf-8") as fh: with open(tmpfile_path, "r", encoding="utf-8") as fh:
paths = json.load(fh) paths = json.load(fh)
for key in ("include", "platinclude"): for key in ("include", "platinclude"):
if key in paths: if key in paths:
paths[key] = make_posix(paths[key]) paths[key] = make_posix(paths[key])
return paths return paths
else: else:
vistir.misc.echo("Failed to load paths: {0}".format(c.err), fg="yellow") vistir.misc.echo(f"Failed to load paths: {c.err}", fg="yellow")
vistir.misc.echo("Output: {0}".format(c.out), fg="yellow") vistir.misc.echo(f"Output: {c.out}", fg="yellow")
return None return None
@cached_property @cached_property
@@ -558,14 +553,13 @@ class Environment(object):
pkg_resources = self.safe_import("pkg_resources") pkg_resources = self.safe_import("pkg_resources")
libdirs = self.base_paths["libdirs"].split(os.pathsep) libdirs = self.base_paths["libdirs"].split(os.pathsep)
dists = (pkg_resources.find_distributions(libdir) for libdir in libdirs) dists = (pkg_resources.find_distributions(libdir) for libdir in libdirs)
for dist in itertools.chain.from_iterable(dists): yield from itertools.chain.from_iterable(dists)
yield dist
def find_egg(self, egg_dist): def find_egg(self, egg_dist):
# type: (pkg_resources.Distribution) -> str # type: (pkg_resources.Distribution) -> str
"""Find an egg by name in the given environment""" """Find an egg by name in the given environment"""
site_packages = self.libdir[1] site_packages = self.libdir[1]
search_filename = "{0}.egg-link".format(egg_dist.project_name) search_filename = f"{egg_dist.project_name}.egg-link"
try: try:
user_site = site.getusersitepackages() user_site = site.getusersitepackages()
except AttributeError: except AttributeError:
@@ -704,12 +698,12 @@ class Environment(object):
packages = [p for p in packages if p.key == pkg] packages = [p for p in packages if p.key == pkg]
tree = PackageDAG.from_pkgs(packages).sort() tree = PackageDAG.from_pkgs(packages).sort()
branch_keys = set(r.key for r in flatten(tree.values())) branch_keys = {r.key for r in flatten(tree.values())}
if pkg is not None: if pkg is not None:
nodes = [p for p in tree.keys() if p.key == pkg] nodes = [p for p in tree.keys() if p.key == pkg]
else: else:
nodes = [p for p in tree.keys() if p.key not in branch_keys] nodes = [p for p in tree.keys() if p.key not in branch_keys]
key_tree = dict((k.key, v) for k, v in tree.items()) key_tree = {k.key: v for k, v in tree.items()}
return [self._get_requirements_for_package(p, key_tree) for p in nodes] return [self._get_requirements_for_package(p, key_tree) for p in nodes]
@@ -751,9 +745,9 @@ class Environment(object):
for k in list(rdeps.keys()): for k in list(rdeps.keys()):
entry = rdeps[k] entry = rdeps[k]
if entry.get("parents"): if entry.get("parents"):
rdeps[k]["parents"] = set([ rdeps[k]["parents"] = {
p for p, version in chunked(2, unnest(entry["parents"])) p for p, version in chunked(2, unnest(entry["parents"]))
]) }
return rdeps return rdeps
def get_working_set(self): def get_working_set(self):
@@ -832,8 +826,8 @@ class Environment(object):
""" """
c = None c = None
if isinstance(cmd, six.string_types): if isinstance(cmd, str):
script = vistir.cmdparse.Script.parse("{0} -c {1}".format(self.python, cmd)) script = vistir.cmdparse.Script.parse(f"{self.python} -c {cmd}")
else: else:
script = vistir.cmdparse.Script.parse([self.python, "-c"] + list(cmd)) script = vistir.cmdparse.Script.parse([self.python, "-c"] + list(cmd))
with self.activated(): with self.activated():
@@ -845,8 +839,8 @@ class Environment(object):
if self.is_venv: if self.is_venv:
activate_this = os.path.join(self.scripts_dir, "activate_this.py") activate_this = os.path.join(self.scripts_dir, "activate_this.py")
if not os.path.isfile(activate_this): if not os.path.isfile(activate_this):
raise OSError("No such file: {0!s}".format(activate_this)) raise OSError(f"No such file: {activate_this!s}")
with open(activate_this, "r") as f: with open(activate_this) as f:
code = compile(f.read(), activate_this, "exec") code = compile(f.read(), activate_this, "exec")
exec(code, dict(__file__=activate_this)) exec(code, dict(__file__=activate_this))
@@ -919,7 +913,7 @@ class Environment(object):
finally: finally:
sys.path = original_path sys.path = original_path
sys.prefix = original_prefix sys.prefix = original_prefix
six.moves.reload_module(pkg_resources) importlib.reload(pkg_resources)
@cached_property @cached_property
def finders(self): def finders(self):
@@ -950,11 +944,11 @@ class Environment(object):
install_args = [ install_args = [
self.environment.python, "-u", "-c", SETUPTOOLS_SHIM % setup_path, self.environment.python, "-u", "-c", SETUPTOOLS_SHIM % setup_path,
install_arg, "--single-version-externally-managed", "--no-deps", install_arg, "--single-version-externally-managed", "--no-deps",
"--prefix={0}".format(self.base_paths["prefix"]), "--no-warn-script-location" "--prefix={}".format(self.base_paths["prefix"]), "--no-warn-script-location"
] ]
for key in install_keys: for key in install_keys:
install_args.append( install_args.append(
"--install-{0}={1}".format(key, self.base_paths[key]) f"--install-{key}={self.base_paths[key]}"
) )
return install_args return install_args
@@ -1030,7 +1024,7 @@ class Environment(object):
return return
class PatchedUninstaller(object): class PatchedUninstaller:
def _permitted(self, path): def _permitted(self, path):
return True return True
+6 -8
View File
@@ -1,5 +1,3 @@
# -*- coding=utf-8 -*-
import os import os
import sys import sys
@@ -30,7 +28,7 @@ def env_to_bool(val):
return False return False
if val.lower() in _true_values: if val.lower() in _true_values:
return True return True
raise ValueError("Value is not a valid boolean-like: {0}".format(val)) raise ValueError(f"Value is not a valid boolean-like: {val}")
def _is_env_truthy(name): def _is_env_truthy(name):
@@ -55,11 +53,11 @@ def get_from_env(arg, prefix="PIPENV", check_for_negation=True):
:return: The value from the environment if available :return: The value from the environment if available
:rtype: Optional[Union[str, bool]] :rtype: Optional[Union[str, bool]]
""" """
negative_lookup = "NO_{0}".format(arg) negative_lookup = f"NO_{arg}"
positive_lookup = arg positive_lookup = arg
if prefix: if prefix:
positive_lookup = "{0}_{1}".format(prefix, arg) positive_lookup = f"{prefix}_{arg}"
negative_lookup = "{0}_{1}".format(prefix, negative_lookup) negative_lookup = f"{prefix}_{negative_lookup}"
if positive_lookup in os.environ: if positive_lookup in os.environ:
value = os.environ[positive_lookup] value = os.environ[positive_lookup]
try: try:
@@ -391,9 +389,9 @@ def is_in_virtualenv():
return virtual_env and not (pipenv_active or ignore_virtualenvs) return virtual_env and not (pipenv_active or ignore_virtualenvs)
PIPENV_SPINNER_FAIL_TEXT = fix_utf8(u"{0}") if not PIPENV_HIDE_EMOJIS else ("{0}") PIPENV_SPINNER_FAIL_TEXT = fix_utf8("{0}") if not PIPENV_HIDE_EMOJIS else ("{0}")
PIPENV_SPINNER_OK_TEXT = fix_utf8(u"{0}") if not PIPENV_HIDE_EMOJIS else ("{0}") PIPENV_SPINNER_OK_TEXT = fix_utf8("{0}") if not PIPENV_HIDE_EMOJIS else ("{0}")
def is_type_checking(): def is_type_checking():
+47 -51
View File
@@ -1,5 +1,3 @@
# -*- coding=utf-8 -*-
import itertools import itertools
import re import re
import sys import sys
@@ -7,8 +5,6 @@ import sys
from collections import namedtuple from collections import namedtuple
from traceback import format_tb from traceback import format_tb
import six
from . import environments from . import environments
from ._compat import decode_for_output from ._compat import decode_for_output
from .patched import crayons from .patched import crayons
@@ -19,7 +15,7 @@ from .vendor.vistir.misc import echo as click_echo
import vistir import vistir
ANSI_REMOVAL_RE = re.compile(r"\033\[((?:\d|;)*)([a-zA-Z])", re.MULTILINE) ANSI_REMOVAL_RE = re.compile(r"\033\[((?:\d|;)*)([a-zA-Z])", re.MULTILINE)
STRING_TYPES = (six.string_types, crayons.ColoredString) STRING_TYPES = ((str,), crayons.ColoredString)
if sys.version_info[:2] >= (3, 7): if sys.version_info[:2] >= (3, 7):
KnownException = namedtuple( KnownException = namedtuple(
@@ -52,10 +48,10 @@ def handle_exception(exc_type, exception, traceback, hook=sys.excepthook):
for line in lines: for line in lines:
line = line.strip("'").strip('"').strip("\n").strip() line = line.strip("'").strip('"').strip("\n").strip()
if not line.startswith("File"): if not line.startswith("File"):
line = " {0}".format(line) line = f" {line}"
else: else:
line = " {0}".format(line) line = f" {line}"
line = "[{0!s}]: {1}".format( line = "[{!s}]: {}".format(
exception.__class__.__name__, line exception.__class__.__name__, line
) )
formatted_lines.append(line) formatted_lines.append(line)
@@ -86,12 +82,12 @@ class PipenvException(ClickException):
if isinstance(self.extra, STRING_TYPES): if isinstance(self.extra, STRING_TYPES):
self.extra = [self.extra] self.extra = [self.extra]
for extra in self.extra: for extra in self.extra:
extra = "[pipenv.exceptions.{0!s}]: {1}".format( extra = "[pipenv.exceptions.{!s}]: {}".format(
self.__class__.__name__, extra self.__class__.__name__, extra
) )
extra = decode_for_output(extra, file) extra = decode_for_output(extra, file)
click_echo(extra, file=file) click_echo(extra, file=file)
click_echo(decode_for_output("{0}".format(self.message), file), file=file) click_echo(decode_for_output(f"{self.message}", file), file=file)
class PipenvCmdError(PipenvException): class PipenvCmdError(PipenvException):
@@ -100,23 +96,23 @@ class PipenvCmdError(PipenvException):
self.out = out self.out = out
self.err = err self.err = err
self.exit_code = exit_code self.exit_code = exit_code
message = "Error running command: {0}".format(cmd) message = f"Error running command: {cmd}"
PipenvException.__init__(self, message) PipenvException.__init__(self, message)
def show(self, file=None): def show(self, file=None):
if file is None: if file is None:
file = vistir.misc.get_text_stderr() file = vistir.misc.get_text_stderr()
click_echo("{0} {1}".format( click_echo("{} {}".format(
crayons.red("Error running command: "), crayons.red("Error running command: "),
crayons.normal(decode_for_output("$ {0}".format(self.cmd), file), bold=True) crayons.normal(decode_for_output(f"$ {self.cmd}", file), bold=True)
), err=True) ), err=True)
if self.out: if self.out:
click_echo("{0} {1}".format( click_echo("{} {}".format(
crayons.normal("OUTPUT: "), crayons.normal("OUTPUT: "),
decode_for_output(self.out, file) decode_for_output(self.out, file)
), err=True) ), err=True)
if self.err: if self.err:
click_echo("{0} {1}".format( click_echo("{} {}".format(
crayons.normal("STDERR: "), crayons.normal("STDERR: "),
decode_for_output(self.err, file) decode_for_output(self.err, file)
), err=True) ), err=True)
@@ -130,13 +126,13 @@ class JSONParseError(PipenvException):
def show(self, file=None): def show(self, file=None):
if file is None: if file is None:
file = vistir.misc.get_text_stderr() file = vistir.misc.get_text_stderr()
message = "{0}\n{1}".format( message = "{}\n{}".format(
crayons.normal("Failed parsing JSON results:", bold=True), crayons.normal("Failed parsing JSON results:", bold=True),
decode_for_output(self.message.strip(), file) decode_for_output(self.message.strip(), file)
) )
click_echo(message, err=True) click_echo(message, err=True)
if self.error_text: if self.error_text:
click_echo("{0} {1}".format( click_echo("{} {}".format(
crayons.normal("ERROR TEXT:", bold=True), crayons.normal("ERROR TEXT:", bold=True),
decode_for_output(self.error_text, file) decode_for_output(self.error_text, file)
), err=True) ), err=True)
@@ -187,7 +183,7 @@ class PipenvFileError(FileError):
if not message: if not message:
message = crayons.normal("Please ensure that the file exists!", bold=True) message = crayons.normal("Please ensure that the file exists!", bold=True)
message = self.formatted_message.format( message = self.formatted_message.format(
crayons.normal("{0} not found!".format(filename), bold=True), crayons.normal(f"{filename} not found!", bold=True),
message message
) )
FileError.__init__(self, filename=filename, hint=decode_for_output(message), **kwargs) FileError.__init__(self, filename=filename, hint=decode_for_output(message), **kwargs)
@@ -208,7 +204,7 @@ class PipfileNotFound(PipenvFileError):
def __init__(self, filename="Pipfile", extra=None, **kwargs): def __init__(self, filename="Pipfile", extra=None, **kwargs):
extra = kwargs.pop("extra", []) extra = kwargs.pop("extra", [])
message = ( message = (
"{0} {1}".format( "{} {}".format(
crayons.red("Aborting!", bold=True), crayons.red("Aborting!", bold=True),
crayons.normal( crayons.normal(
"Please ensure that the file exists and is located in your" "Please ensure that the file exists and is located in your"
@@ -216,18 +212,18 @@ class PipfileNotFound(PipenvFileError):
) )
) )
) )
super(PipfileNotFound, self).__init__(filename, message=message, extra=extra, **kwargs) super().__init__(filename, message=message, extra=extra, **kwargs)
class LockfileNotFound(PipenvFileError): class LockfileNotFound(PipenvFileError):
def __init__(self, filename="Pipfile.lock", extra=None, **kwargs): def __init__(self, filename="Pipfile.lock", extra=None, **kwargs):
extra = kwargs.pop("extra", []) extra = kwargs.pop("extra", [])
message = "{0} {1} {2}".format( message = "{} {} {}".format(
crayons.normal("You need to run", bold=True), crayons.normal("You need to run", bold=True),
crayons.red("$ pipenv lock", bold=True), crayons.red("$ pipenv lock", bold=True),
crayons.normal("before you can continue.", bold=True) crayons.normal("before you can continue.", bold=True)
) )
super(LockfileNotFound, self).__init__(filename, message=message, extra=extra, **kwargs) super().__init__(filename, message=message, extra=extra, **kwargs)
class DeployException(PipenvUsageError): class DeployException(PipenvUsageError):
@@ -250,16 +246,16 @@ class SystemUsageError(PipenvOptionsError):
def __init__(self, option_name="system", message=None, ctx=None, **kwargs): def __init__(self, option_name="system", message=None, ctx=None, **kwargs):
extra = kwargs.pop("extra", []) extra = kwargs.pop("extra", [])
extra += [ extra += [
"{0}: --system is intended to be used for Pipfile installation, " "{}: --system is intended to be used for Pipfile installation, "
"not installation of specific packages. Aborting.".format( "not installation of specific packages. Aborting.".format(
crayons.red("Warning", bold=True) crayons.red("Warning", bold=True)
), ),
] ]
if message is None: if message is None:
message = str( message = str(
crayons.cyan("See also: {0}".format(crayons.normal("--deploy flag."))) crayons.cyan("See also: {}".format(crayons.normal("--deploy flag.")))
) )
super(SystemUsageError, self).__init__(option_name, message=message, ctx=ctx, extra=extra, **kwargs) super().__init__(option_name, message=message, ctx=ctx, extra=extra, **kwargs)
class PipfileException(PipenvFileError): class PipfileException(PipenvFileError):
@@ -267,7 +263,7 @@ class PipfileException(PipenvFileError):
from .core import project from .core import project
if not hint: if not hint:
hint = "{0} {1}".format(crayons.red("ERROR (PACKAGE NOT INSTALLED):"), hint) hint = "{} {}".format(crayons.red("ERROR (PACKAGE NOT INSTALLED):"), hint)
filename = project.pipfile_location filename = project.pipfile_location
extra = kwargs.pop("extra", []) extra = kwargs.pop("extra", [])
PipenvFileError.__init__(self, filename, hint, extra=extra, **kwargs) PipenvFileError.__init__(self, filename, hint, extra=extra, **kwargs)
@@ -310,7 +306,7 @@ class VirtualenvCreationException(VirtualenvException):
# note we need the format interpolation because ``crayons.ColoredString`` # note we need the format interpolation because ``crayons.ColoredString``
# is not an actual string type but is only a preparation for interpolation # is not an actual string type but is only a preparation for interpolation
# so replacement or parsing requires this step # so replacement or parsing requires this step
extra = ANSI_REMOVAL_RE.sub("", "{0}".format(extra)) extra = ANSI_REMOVAL_RE.sub("", f"{extra}")
if "KeyboardInterrupt" in extra: if "KeyboardInterrupt" in extra:
extra = str( extra = str(
crayons.red("Virtualenv creation interrupted by user", bold=True) crayons.red("Virtualenv creation interrupted by user", bold=True)
@@ -322,17 +318,17 @@ class VirtualenvCreationException(VirtualenvException):
class UninstallError(PipenvException): class UninstallError(PipenvException):
def __init__(self, package, command, return_values, return_code, **kwargs): def __init__(self, package, command, return_values, return_code, **kwargs):
extra = [ extra = [
"{0} {1}".format( "{} {}".format(
crayons.cyan("Attempted to run command: "), crayons.cyan("Attempted to run command: "),
crayons.yellow("$ {0!r}".format(command), bold=True) crayons.yellow(f"$ {command!r}", bold=True)
) )
] ]
extra.extend([crayons.cyan(line.strip()) for line in return_values.splitlines()]) extra.extend([crayons.cyan(line.strip()) for line in return_values.splitlines()])
if isinstance(package, (tuple, list, set)): if isinstance(package, (tuple, list, set)):
package = " ".join(package) package = " ".join(package)
message = "{0!s} {1!s}...".format( message = "{!s} {!s}...".format(
crayons.normal("Failed to uninstall package(s)"), crayons.normal("Failed to uninstall package(s)"),
crayons.yellow("{0}!s".format(package), bold=True) crayons.yellow(f"{package}!s", bold=True)
) )
self.exit_code = return_code self.exit_code = return_code
PipenvException.__init__(self, message=message, extra=extra) PipenvException.__init__(self, message=message, extra=extra)
@@ -343,11 +339,11 @@ class InstallError(PipenvException):
def __init__(self, package, **kwargs): def __init__(self, package, **kwargs):
package_message = "" package_message = ""
if package is not None: if package is not None:
package_message = "Couldn't install package: {0}\n".format( package_message = "Couldn't install package: {}\n".format(
crayons.normal("{0!s}".format(package), bold=True) crayons.normal(f"{package!s}", bold=True)
) )
message = "{0} {1}".format( message = "{} {}".format(
"{0}".format(package_message), f"{package_message}",
crayons.yellow("Package installation failed...") crayons.yellow("Package installation failed...")
) )
extra = kwargs.pop("extra", []) extra = kwargs.pop("extra", [])
@@ -356,9 +352,9 @@ class InstallError(PipenvException):
class CacheError(PipenvException): class CacheError(PipenvException):
def __init__(self, path, **kwargs): def __init__(self, path, **kwargs):
message = "{0} {1}\n{2}".format( message = "{} {}\n{}".format(
crayons.cyan("Corrupt cache file"), crayons.cyan("Corrupt cache file"),
crayons.normal("{0!s}".format(path)), crayons.normal(f"{path!s}"),
crayons.normal('Consider trying "pipenv lock --clear" to clear the cache.') crayons.normal('Consider trying "pipenv lock --clear" to clear the cache.')
) )
PipenvException.__init__(self, message=message) PipenvException.__init__(self, message=message)
@@ -366,7 +362,7 @@ class CacheError(PipenvException):
class DependencyConflict(PipenvException): class DependencyConflict(PipenvException):
def __init__(self, message): def __init__(self, message):
extra = ["{0} {1}".format( extra = ["{} {}".format(
crayons.red("The operation failed...", bold=True), crayons.red("The operation failed...", bold=True),
crayons.red("A dependency conflict was detected and could not be resolved."), crayons.red("A dependency conflict was detected and could not be resolved."),
)] )]
@@ -376,12 +372,12 @@ class DependencyConflict(PipenvException):
class ResolutionFailure(PipenvException): class ResolutionFailure(PipenvException):
def __init__(self, message, no_version_found=False): def __init__(self, message, no_version_found=False):
extra = ( extra = (
"{0}: Your dependencies could not be resolved. You likely have a " "{}: Your dependencies could not be resolved. You likely have a "
"mismatch in your sub-dependencies.\n " "mismatch in your sub-dependencies.\n "
"First try clearing your dependency cache with {1}, then try the original command again.\n " "First try clearing your dependency cache with {}, then try the original command again.\n "
"Alternatively, you can use {2} to bypass this mechanism, then run " "Alternatively, you can use {} to bypass this mechanism, then run "
"{3} to inspect the situation.\n " "{} to inspect the situation.\n "
"Hint: try {4} if it is a pre-release dependency." "Hint: try {} if it is a pre-release dependency."
"".format( "".format(
crayons.red("Warning", bold=True), crayons.red("Warning", bold=True),
crayons.yellow("$ pipenv lock --clear"), crayons.yellow("$ pipenv lock --clear"),
@@ -392,9 +388,9 @@ class ResolutionFailure(PipenvException):
) )
if "no version found at all" in message: if "no version found at all" in message:
no_version_found = True no_version_found = True
message = crayons.yellow("{0}".format(message)) message = crayons.yellow(f"{message}")
if no_version_found: if no_version_found:
message = "{0}\n{1}".format( message = "{}\n{}".format(
message, message,
crayons.cyan( crayons.cyan(
"Please check your version specifier and version number. " "Please check your version specifier and version number. "
@@ -426,18 +422,18 @@ class RequirementError(PipenvException):
if getattr(req, k, None) if getattr(req, k, None)
] ]
req_value = "\n".join([ req_value = "\n".join([
" {0}: {1}".format(k, v) for k, v in slot_vals f" {k}: {v}" for k, v in slot_vals
]) ])
elif keys_fn: elif keys_fn:
values = [(k, req.get(k)) for k in keys_fn() if req.get(k)] values = [(k, req.get(k)) for k in keys_fn() if req.get(k)]
req_value = "\n".join([ req_value = "\n".join([
" {0}: {1}".format(k, v) for k, v in values f" {k}: {v}" for k, v in values
]) ])
else: else:
req_value = getattr(req.line_instance, "line", None) req_value = getattr(req.line_instance, "line", None)
message = "{0} {1}".format( message = "{} {}".format(
crayons.normal(decode_for_output("Failed creating requirement instance")), crayons.normal(decode_for_output("Failed creating requirement instance")),
crayons.normal(decode_for_output("{0!r}".format(req_value))) crayons.normal(decode_for_output(f"{req_value!r}"))
) )
extra = [str(req)] extra = [str(req)]
PipenvException.__init__(self, message, extra=extra) PipenvException.__init__(self, message, extra=extra)
@@ -460,8 +456,8 @@ def prettify_exc(error):
_, error, info = error.rpartition(exc.prefix) _, error, info = error.rpartition(exc.prefix)
else: else:
_, error, info = error.rpartition(split_string) _, error, info = error.rpartition(split_string)
errors.append("{0} {1}".format(error, info)) errors.append(f"{error} {info}")
if not errors: if not errors:
return "{}".format(vistir.misc.decode_for_output(error)) return f"{vistir.misc.decode_for_output(error)}"
return "\n".join(errors) return "\n".join(errors)
+13 -14
View File
@@ -1,4 +1,3 @@
# coding: utf-8
import os import os
import pprint import pprint
import sys import sys
@@ -20,11 +19,11 @@ def print_utf(line):
def get_pipenv_diagnostics(): def get_pipenv_diagnostics():
print("<details><summary>$ pipenv --support</summary>") print("<details><summary>$ pipenv --support</summary>")
print("") print("")
print("Pipenv version: `{0!r}`".format(pipenv.__version__)) print(f"Pipenv version: `{pipenv.__version__!r}`")
print("") print("")
print("Pipenv location: `{0!r}`".format(os.path.dirname(pipenv.__file__))) print(f"Pipenv location: `{os.path.dirname(pipenv.__file__)!r}`")
print("") print("")
print("Python location: `{0!r}`".format(sys.executable)) print(f"Python location: `{sys.executable!r}`")
print("") print("")
print("Python installations found:") print("Python installations found:")
print("") print("")
@@ -32,7 +31,7 @@ def get_pipenv_diagnostics():
finder = pythonfinder.Finder(system=False, global_search=True) finder = pythonfinder.Finder(system=False, global_search=True)
python_paths = finder.find_all_python_versions() python_paths = finder.find_all_python_versions()
for python in python_paths: for python in python_paths:
print(" - `{}`: `{}`".format(python.py_version.version, python.path)) print(f" - `{python.py_version.version}`: `{python.path}`")
print("") print("")
print("PEP 508 Information:") print("PEP 508 Information:")
@@ -44,39 +43,39 @@ def get_pipenv_diagnostics():
print("System environment variables:") print("System environment variables:")
print("") print("")
for key in os.environ: for key in os.environ:
print(" - `{0}`".format(key)) print(f" - `{key}`")
print("") print("")
print_utf(u"Pipenvspecific environment variables:") print_utf("Pipenvspecific environment variables:")
print("") print("")
for key in os.environ: for key in os.environ:
if key.startswith("PIPENV"): if key.startswith("PIPENV"):
print(" - `{0}`: `{1}`".format(key, os.environ[key])) print(f" - `{key}`: `{os.environ[key]}`")
print("") print("")
print_utf(u"Debugspecific environment variables:") print_utf("Debugspecific environment variables:")
print("") print("")
for key in ("PATH", "SHELL", "EDITOR", "LANG", "PWD", "VIRTUAL_ENV"): for key in ("PATH", "SHELL", "EDITOR", "LANG", "PWD", "VIRTUAL_ENV"):
if key in os.environ: if key in os.environ:
print(" - `{0}`: `{1}`".format(key, os.environ[key])) print(f" - `{key}`: `{os.environ[key]}`")
print("") print("")
print("") print("")
print("---------------------------") print("---------------------------")
print("") print("")
if project.pipfile_exists: if project.pipfile_exists:
print_utf(u"Contents of `Pipfile` ({0!r}):".format(project.pipfile_location)) print_utf(f"Contents of `Pipfile` ({project.pipfile_location!r}):")
print("") print("")
print("```toml") print("```toml")
with open(project.pipfile_location, "r") as f: with open(project.pipfile_location) as f:
print(f.read()) print(f.read())
print("```") print("```")
print("") print("")
if project.lockfile_exists: if project.lockfile_exists:
print("") print("")
print_utf( print_utf(
u"Contents of `Pipfile.lock` ({0!r}):".format(project.lockfile_location) f"Contents of `Pipfile.lock` ({project.lockfile_location!r}):"
) )
print("") print("")
print("```json") print("```json")
with open(project.lockfile_location, "r") as f: with open(project.lockfile_location) as f:
print(f.read()) print(f.read())
print("```") print("```")
print("</details>") print("</details>")
+9 -11
View File
@@ -1,7 +1,6 @@
import os import os
import operator import operator
import re import re
import six
from abc import ABCMeta, abstractmethod from abc import ABCMeta, abstractmethod
@@ -11,7 +10,7 @@ from .utils import find_windows_executable
@attr.s @attr.s
class Version(object): class Version:
major = attr.ib() major = attr.ib()
minor = attr.ib() minor = attr.ib()
@@ -29,7 +28,7 @@ class Version(object):
""" """
match = re.match(r'^(\d+)\.(\d+)(?:\.(\d+))?$', name) match = re.match(r'^(\d+)\.(\d+)(?:\.(\d+))?$', name)
if not match: if not match:
raise ValueError('invalid version name {0!r}'.format(name)) raise ValueError(f'invalid version name {name!r}')
major = int(match.group(1)) major = int(match.group(1))
minor = int(match.group(2)) minor = int(match.group(2))
patch = match.group(3) patch = match.group(3)
@@ -59,17 +58,16 @@ class InstallerNotFound(RuntimeError):
class InstallerError(RuntimeError): class InstallerError(RuntimeError):
def __init__(self, desc, c): def __init__(self, desc, c):
super(InstallerError, self).__init__(desc) super().__init__(desc)
self.out = c.out self.out = c.out
self.err = c.err self.err = c.err
@six.add_metaclass(ABCMeta) class Installer(metaclass=ABCMeta):
class Installer(object):
def __init__(self): def __init__(self):
self.cmd = self._find_installer() self.cmd = self._find_installer()
super(Installer, self).__init__() super().__init__()
def __str__(self): def __str__(self):
return self.__class__.__name__ return self.__class__.__name__
@@ -109,7 +107,7 @@ class Installer(object):
# Check for explicitly set install locations (e.g. PYENV_ROOT, ASDF_DIR). # Check for explicitly set install locations (e.g. PYENV_ROOT, ASDF_DIR).
os.path.join(os.path.expanduser(os.getenv(env_var, '/dev/null')), 'bin', name), os.path.join(os.path.expanduser(os.getenv(env_var, '/dev/null')), 'bin', name),
# Check the pyenv/asdf-recommended from-source install locations # Check the pyenv/asdf-recommended from-source install locations
os.path.join(os.path.expanduser('~/.{}'.format(name)), 'bin', name), os.path.join(os.path.expanduser(f'~/.{name}'), 'bin', name),
): ):
if candidate is not None and os.path.isfile(candidate) and os.access(candidate, os.X_OK): if candidate is not None and os.path.isfile(candidate) and os.access(candidate, os.X_OK):
return candidate return candidate
@@ -119,12 +117,12 @@ class Installer(object):
timeout = kwargs.pop('timeout', delegator.TIMEOUT) timeout = kwargs.pop('timeout', delegator.TIMEOUT)
if kwargs: if kwargs:
k = list(kwargs.keys())[0] k = list(kwargs.keys())[0]
raise TypeError('unexpected keyword argument {0!r}'.format(k)) raise TypeError(f'unexpected keyword argument {k!r}')
args = (self.cmd,) + tuple(args) args = (self.cmd,) + tuple(args)
c = delegator.run(args, block=False, timeout=timeout) c = delegator.run(args, block=False, timeout=timeout)
c.block() c.block()
if c.return_code != 0: if c.return_code != 0:
raise InstallerError('failed to run {0}'.format(args), c) raise InstallerError(f'failed to run {args}', c)
return c return c
@abstractmethod @abstractmethod
@@ -149,7 +147,7 @@ class Installer(object):
), key=operator.attrgetter('cmpkey')) ), key=operator.attrgetter('cmpkey'))
except ValueError: except ValueError:
raise ValueError( raise ValueError(
'no installable version found for {0!r}'.format(name), f'no installable version found for {name!r}',
) )
return best_match return best_match
-1
View File
@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import json import json
import os import os
import platform import platform
+2 -4
View File
@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
""" """
clint.textui.progress clint.textui.progress
~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
@@ -7,7 +6,6 @@ This module provides the progressbar functionality.
""" """
from __future__ import absolute_import
import os import os
import sys import sys
@@ -37,7 +35,7 @@ else:
BAR_EMPTY_CHAR = str(crayons.black("")) BAR_EMPTY_CHAR = str(crayons.black(""))
if (sys.version_info[0] >= 3) and (os.name != "nt"): if (sys.version_info[0] >= 3) and (os.name != "nt"):
BAR_TEMPLATE = u" %s%s%s %i/%i{0}\r".format(crayons.black("%s")) BAR_TEMPLATE = " %s%s%s %i/%i{}\r".format(crayons.black("%s"))
else: else:
if os.name == "nt": if os.name == "nt":
BAR_TEMPLATE = " %s%s%s %i/%i - %s\r" BAR_TEMPLATE = " %s%s%s %i/%i - %s\r"
@@ -51,7 +49,7 @@ ETA_INTERVAL = 1
ETA_SMA_WINDOW = 9 ETA_SMA_WINDOW = 9
class Bar(object): class Bar:
def __enter__(self): def __enter__(self):
return self return self
+6 -6
View File
@@ -9,8 +9,8 @@ import operator
import os import os
import re import re
import sys import sys
import urllib.parse
import six
import toml import toml
import tomlkit import tomlkit
import vistir import vistir
@@ -89,13 +89,13 @@ class _LockFileEncoder(json.JSONEncoder):
def encode(self, obj): def encode(self, obj):
content = super(_LockFileEncoder, self).encode(obj) content = super(_LockFileEncoder, self).encode(obj)
if not isinstance(content, six.text_type): if not isinstance(content, str):
content = content.decode("utf-8") content = content.decode("utf-8")
return content return content
def preferred_newlines(f): def preferred_newlines(f):
if isinstance(f.newlines, six.text_type): if isinstance(f.newlines, str):
return f.newlines return f.newlines
return DEFAULT_NEWLINES return DEFAULT_NEWLINES
@@ -568,7 +568,7 @@ class Project(object):
_pipfile_cache.clear() _pipfile_cache.clear()
def _parse_pipfile(self, contents): def _parse_pipfile(self, contents):
# type: () -> Union[tomlkit.toml_document.TOMLDocument, TPipfile] # type: (str) -> Union[tomlkit.toml_document.TOMLDocument, TPipfile]
try: try:
return tomlkit.parse(contents) return tomlkit.parse(contents)
except Exception: except Exception:
@@ -614,7 +614,7 @@ class Project(object):
return False return False
def build_script(self, name, extra_args=None): def build_script(self, name, extra_args=None):
# type: (str, Optional[List[str]]) # type: (str, Optional[List[str]]) -> Script
try: try:
script = Script.parse(self.parsed_pipfile["scripts"][name]) script = Script.parse(self.parsed_pipfile["scripts"][name])
except KeyError: except KeyError:
@@ -1011,7 +1011,7 @@ class Project(object):
self.write_toml(p) self.write_toml(p)
def src_name_from_url(self, index_url): def src_name_from_url(self, index_url):
name, _, tld_guess = six.moves.urllib.parse.urlsplit(index_url).netloc.rpartition( name, _, tld_guess = urllib.parse.urlsplit(index_url).netloc.rpartition(
"." "."
) )
src_name = name.replace(".", "") src_name = name.replace(".", "")
+22 -26
View File
@@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function
import json import json
import logging import logging
import os import os
@@ -20,12 +17,12 @@ def find_site_path(pkg, site_dir=None):
base_name = dist.project_name if dist.project_name else dist.key base_name = dist.project_name if dist.project_name else dist.key
name = None name = None
if "top_level.txt" in dist.metadata_listdir(""): if "top_level.txt" in dist.metadata_listdir(""):
name = next(iter([l.strip() for l in dist.get_metadata_lines("top_level.txt") if l is not None]), None) name = next(iter([line.strip() for line in dist.get_metadata_lines("top_level.txt") if line is not None]), None)
if name is None: if name is None:
name = pkg_resources.safe_name(base_name).replace("-", "_") name = pkg_resources.safe_name(base_name).replace("-", "_")
if not any(pkg == _ for _ in [base_name, name]): if not any(pkg == _ for _ in [base_name, name]):
continue continue
path_options = [name, "{0}.py".format(name)] path_options = [name, f"{name}.py"]
path_options = [os.path.join(root, p) for p in path_options if p is not None] path_options = [os.path.join(root, p) for p in path_options if p is not None]
path = next(iter(p for p in path_options if os.path.exists(p)), None) path = next(iter(p for p in path_options if os.path.exists(p)), None)
if path is not None: if path is not None:
@@ -92,11 +89,11 @@ def handle_parsed_args(parsed):
return parsed return parsed
class Entry(object): class Entry:
"""A resolved entry from a resolver run""" """A resolved entry from a resolver run"""
def __init__(self, name, entry_dict, project, resolver, reverse_deps=None, dev=False): def __init__(self, name, entry_dict, project, resolver, reverse_deps=None, dev=False):
super(Entry, self).__init__() super().__init__()
from pipenv.vendor.requirementslib.models.utils import tomlkit_value_to_python from pipenv.vendor.requirementslib.models.utils import tomlkit_value_to_python
self.name = name self.name = name
if isinstance(entry_dict, dict): if isinstance(entry_dict, dict):
@@ -173,7 +170,7 @@ class Entry(object):
markers = set() markers = set()
keys_in_dict = [k for k in marker_keys if k in entry_dict] keys_in_dict = [k for k in marker_keys if k in entry_dict]
markers = { markers = {
normalize_marker_str("{k} {v}".format(k=k, v=entry_dict.pop(k))) normalize_marker_str(f"{k} {entry_dict.pop(k)}")
for k in keys_in_dict for k in keys_in_dict
} }
if "markers" in entry_dict: if "markers" in entry_dict:
@@ -216,18 +213,17 @@ class Entry(object):
from pipenv.vendor.requirementslib.models.markers import normalize_marker_str from pipenv.vendor.requirementslib.models.markers import normalize_marker_str
if not marker: if not marker:
return None return None
from pipenv.vendor import six
from pipenv.vendor.vistir.compat import Mapping from pipenv.vendor.vistir.compat import Mapping
marker_str = None marker_str = None
if isinstance(marker, Mapping): if isinstance(marker, Mapping):
marker_dict, _ = Entry.get_markers_from_dict(marker) marker_dict, _ = Entry.get_markers_from_dict(marker)
if marker_dict: if marker_dict:
marker_str = "{0}".format(marker_dict.popitem()[1]) marker_str = f"{marker_dict.popitem()[1]}"
elif isinstance(marker, (list, set, tuple)): elif isinstance(marker, (list, set, tuple)):
marker_str = " and ".join([normalize_marker_str(m) for m in marker if m]) marker_str = " and ".join([normalize_marker_str(m) for m in marker if m])
elif isinstance(marker, six.string_types): elif isinstance(marker, str):
marker_str = "{0}".format(normalize_marker_str(marker)) marker_str = f"{normalize_marker_str(marker)}"
if isinstance(marker_str, six.string_types): if isinstance(marker_str, str):
return marker_str return marker_str
return None return None
@@ -317,9 +313,9 @@ class Entry(object):
if not any(specifier.startswith(k) for k in Specifier._operators.keys()): if not any(specifier.startswith(k) for k in Specifier._operators.keys()):
if specifier.strip().lower() in ["any", "<any>", "*"]: if specifier.strip().lower() in ["any", "<any>", "*"]:
return "*" return "*"
specifier = "=={0}".format(specifier) specifier = f"=={specifier}"
elif specifier.startswith("==") and specifier.count("=") > 3: elif specifier.startswith("==") and specifier.count("=") > 3:
specifier = "=={0}".format(specifier.lstrip("=")) specifier = "=={}".format(specifier.lstrip("="))
return specifier return specifier
@staticmethod @staticmethod
@@ -448,7 +444,7 @@ class Entry(object):
self.can_use_updated = False self.can_use_updated = False
satisfied_by_value = getattr(constraint, "satisfied_by", None) satisfied_by_value = getattr(constraint, "satisfied_by", None)
if satisfied_by_value: if satisfied_by_value:
satisfied_by = "{0}".format( satisfied_by = "{}".format(
self.clean_specifier(str(satisfied_by_value.version)) self.clean_specifier(str(satisfied_by_value.version))
) )
satisfied_by_versions.add(satisfied_by) satisfied_by_versions.add(satisfied_by)
@@ -525,9 +521,9 @@ class Entry(object):
str(pinned_version), prereleases=True str(pinned_version), prereleases=True
): ):
if is_verbose(): if is_verbose():
print("Tried constraint: {0!r}".format(constraint), file=sys.stderr) print(f"Tried constraint: {constraint!r}", file=sys.stderr)
msg = ( msg = (
"Cannot resolve conflicting version {0}{1} while {2}{3} is " "Cannot resolve conflicting version {}{} while {}{} is "
"locked.".format( "locked.".format(
self.name, constraint.req.specifier, self.name, constraint.req.specifier,
self.name, self.updated_specifier self.name, self.updated_specifier
@@ -543,8 +539,8 @@ class Entry(object):
if not parent.validate_specifiers(): if not parent.validate_specifiers():
from pipenv.exceptions import DependencyConflict from pipenv.exceptions import DependencyConflict
msg = ( msg = (
"Cannot resolve conflicting versions: (Root: {0}) {1}{2} (Pipfile) " "Cannot resolve conflicting versions: (Root: {}) {}{} (Pipfile) "
"Incompatible with {3}{4} (resolved)\n".format( "Incompatible with {}{} (resolved)\n".format(
self.name, parent.pipfile_name, self.name, parent.pipfile_name,
parent.pipfile_entry.requirement.specifiers, parent.name, parent.pipfile_entry.requirement.specifiers, parent.name,
parent.updated_specifiers parent.updated_specifiers
@@ -565,7 +561,7 @@ class Entry(object):
except AttributeError: except AttributeError:
result = getattr(entry, key) result = getattr(entry, key)
except AttributeError: except AttributeError:
result = super(Entry, self).__getattribute__(key) result = super().__getattribute__(key)
return result return result
if any(key.startswith(v) for v in old_version): if any(key.startswith(v) for v in old_version):
lockfile_entry = Entry.__getattribute__(self, "lockfile_entry") lockfile_entry = Entry.__getattribute__(self, "lockfile_entry")
@@ -576,9 +572,9 @@ class Entry(object):
except AttributeError: except AttributeError:
result = getattr(lockfile_entry, key) result = getattr(lockfile_entry, key)
except AttributeError: except AttributeError:
result = super(Entry, self).__getattribute__(key) result = super().__getattribute__(key)
return result return result
return super(Entry, self).__getattribute__(key) return super().__getattribute__(key)
def clean_results(results, resolver, project, dev=False): def clean_results(results, resolver, project, dev=False):
@@ -751,9 +747,9 @@ def main():
warnings.simplefilter("ignore", category=ResourceWarning) warnings.simplefilter("ignore", category=ResourceWarning)
replace_with_text_stream("stdout") replace_with_text_stream("stdout")
replace_with_text_stream("stderr") replace_with_text_stream("stderr")
os.environ["PIP_DISABLE_PIP_VERSION_CHECK"] = str("1") os.environ["PIP_DISABLE_PIP_VERSION_CHECK"] = "1"
os.environ["PYTHONIOENCODING"] = str("utf-8") os.environ["PYTHONIOENCODING"] = "utf-8"
os.environ["PYTHONUNBUFFERED"] = str("1") os.environ["PYTHONUNBUFFERED"] = "1"
parsed = handle_parsed_args(parsed) parsed = handle_parsed_args(parsed)
_main(parsed.pre, parsed.clear, parsed.verbose, parsed.system, parsed.write, _main(parsed.pre, parsed.clear, parsed.verbose, parsed.system, parsed.write,
parsed.requirements_dir, parsed.packages, parse_only=parsed.parse_only, parsed.requirements_dir, parsed.packages, parse_only=parsed.parse_only,
+13 -13
View File
@@ -52,7 +52,7 @@ def _get_activate_script(cmd, venv):
# for proper activation. # for proper activation.
venv_location = re.sub(r'([ &$()\[\]])', r"\\\1", str(venv)) venv_location = re.sub(r'([ &$()\[\]])', r"\\\1", str(venv))
# The leading space can make history cleaner in some shells. # The leading space can make history cleaner in some shells.
return " {2} {0}/bin/activate{1}".format(venv_location, suffix, command) return f" {command} {venv_location}/bin/activate{suffix}"
def _handover(cmd, args): def _handover(cmd, args):
@@ -63,7 +63,7 @@ def _handover(cmd, args):
sys.exit(subprocess.call(args, shell=True, universal_newlines=True)) sys.exit(subprocess.call(args, shell=True, universal_newlines=True))
class Shell(object): class Shell:
def __init__(self, cmd): def __init__(self, cmd):
self.cmd = cmd self.cmd = cmd
self.args = [] self.args = []
@@ -77,7 +77,7 @@ class Shell(object):
@contextlib.contextmanager @contextlib.contextmanager
def inject_path(self, venv): def inject_path(self, venv):
with temp_environ(): with temp_environ():
os.environ["PATH"] = "{0}{1}{2}".format( os.environ["PATH"] = "{}{}{}".format(
os.pathsep.join(str(p.parent) for p in _iter_python(venv)), os.pathsep.join(str(p.parent) for p in _iter_python(venv)),
os.pathsep, os.pathsep,
os.environ["PATH"], os.environ["PATH"],
@@ -90,9 +90,9 @@ class Shell(object):
name = os.path.basename(venv) name = os.path.basename(venv)
os.environ["VIRTUAL_ENV"] = str(venv) os.environ["VIRTUAL_ENV"] = str(venv)
if "PROMPT" in os.environ: if "PROMPT" in os.environ:
os.environ["PROMPT"] = "({0}) {1}".format(name, os.environ["PROMPT"]) os.environ["PROMPT"] = "({}) {}".format(name, os.environ["PROMPT"])
if "PS1" in os.environ: if "PS1" in os.environ:
os.environ["PS1"] = "({0}) {1}".format(name, os.environ["PS1"]) os.environ["PS1"] = "({}) {}".format(name, os.environ["PS1"])
with self.inject_path(venv): with self.inject_path(venv):
os.chdir(cwd) os.chdir(cwd)
_handover(self.cmd, self.args + list(args)) _handover(self.cmd, self.args + list(args))
@@ -147,10 +147,10 @@ class Bash(Shell):
bashrc_path = Path.home().joinpath(".bashrc") bashrc_path = Path.home().joinpath(".bashrc")
with NamedTemporaryFile("w+") as rcfile: with NamedTemporaryFile("w+") as rcfile:
if bashrc_path.is_file(): if bashrc_path.is_file():
base_rc_src = 'source "{0}"\n'.format(bashrc_path.as_posix()) base_rc_src = f'source "{bashrc_path.as_posix()}"\n'
rcfile.write(base_rc_src) rcfile.write(base_rc_src)
export_path = 'export PATH="{0}:$PATH"\n'.format(":".join( export_path = 'export PATH="{}:$PATH"\n'.format(":".join(
self._format_path(python) self._format_path(python)
for python in _iter_python(venv) for python in _iter_python(venv)
)) ))
@@ -162,18 +162,18 @@ class Bash(Shell):
class MsysBash(Bash): class MsysBash(Bash):
def _format_path(self, python): def _format_path(self, python):
s = super(MsysBash, self)._format_path(python) s = super()._format_path(python)
if not python.drive: if not python.drive:
return s return s
# Convert "C:/something" to "/c/something". # Convert "C:/something" to "/c/something".
return '/{drive}{path}'.format(drive=s[0].lower(), path=s[2:]) return f'/{s[0].lower()}{s[2:]}'
class CmderEmulatedShell(Shell): class CmderEmulatedShell(Shell):
def fork(self, venv, cwd, args): def fork(self, venv, cwd, args):
if cwd: if cwd:
os.environ["CMDER_START"] = cwd os.environ["CMDER_START"] = cwd
super(CmderEmulatedShell, self).fork(venv, cwd, args) super().fork(venv, cwd, args)
class CmderCommandPrompt(CmderEmulatedShell): class CmderCommandPrompt(CmderEmulatedShell):
@@ -181,7 +181,7 @@ class CmderCommandPrompt(CmderEmulatedShell):
rc = os.path.expandvars("%CMDER_ROOT%\\vendor\\init.bat") rc = os.path.expandvars("%CMDER_ROOT%\\vendor\\init.bat")
if os.path.exists(rc): if os.path.exists(rc):
self.args.extend(["/k", rc]) self.args.extend(["/k", rc])
super(CmderCommandPrompt, self).fork(venv, cwd, args) super().fork(venv, cwd, args)
class CmderPowershell(Shell): class CmderPowershell(Shell):
@@ -196,10 +196,10 @@ class CmderPowershell(Shell):
"-NoProfile", "-NoProfile",
"-NoExit", "-NoExit",
"-Command", "-Command",
"Invoke-Expression '. ''{0}'''".format(rc), f"Invoke-Expression '. ''{rc}'''",
] ]
) )
super(CmderPowershell, self).fork(venv, cwd, args) super().fork(venv, cwd, args)
# Two dimensional dict. First is the shell type, second is the emulator type. # Two dimensional dict. First is the shell type, second is the emulator type.
+69 -74
View File
@@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import print_function
import contextlib import contextlib
import errno import errno
import logging import logging
@@ -14,11 +11,10 @@ import sys
import warnings import warnings
from contextlib import contextmanager from contextlib import contextmanager
from distutils.spawn import find_executable from distutils.spawn import find_executable
from urllib.parse import urlparse
import six
import toml import toml
from click import echo as click_echo from click import echo as click_echo
from six.moves.urllib.parse import urlparse
import crayons import crayons
import parse import parse
@@ -137,7 +133,7 @@ def run_command(cmd, *args, **kwargs):
from ._compat import decode_for_output from ._compat import decode_for_output
from .cmdparse import Script from .cmdparse import Script
catch_exceptions = kwargs.pop("catch_exceptions", True) catch_exceptions = kwargs.pop("catch_exceptions", True)
if isinstance(cmd, (six.string_types, list, tuple)): if isinstance(cmd, ((str,), list, tuple)):
cmd = Script.parse(cmd) cmd = Script.parse(cmd)
if not isinstance(cmd, Script): if not isinstance(cmd, Script):
raise TypeError("Command input must be a string, list or tuple") raise TypeError("Command input must be a string, list or tuple")
@@ -147,14 +143,14 @@ def run_command(cmd, *args, **kwargs):
try: try:
cmd_string = cmd.cmdify() cmd_string = cmd.cmdify()
except TypeError: except TypeError:
click_echo("Error turning command into string: {0}".format(cmd), err=True) click_echo(f"Error turning command into string: {cmd}", err=True)
sys.exit(1) sys.exit(1)
if environments.is_verbose(): if environments.is_verbose():
click_echo("Running command: $ {0}".format(cmd_string, err=True)) click_echo(f"Running command: $ {cmd_string}")
c = delegator.run(cmd_string, *args, **kwargs) c = delegator.run(cmd_string, *args, **kwargs)
return_code = c.return_code return_code = c.return_code
if environments.is_verbose(): if environments.is_verbose():
click_echo("Command output: {0}".format( click_echo("Command output: {}".format(
crayons.cyan(decode_for_output(c.out)) crayons.cyan(decode_for_output(c.out))
), err=True) ), err=True)
if not c.ok and catch_exceptions: if not c.ok and catch_exceptions:
@@ -223,10 +219,10 @@ def escape_grouped_arguments(s):
def clean_pkg_version(version): def clean_pkg_version(version):
"""Uses pip to prepare a package version string, from our internal version.""" """Uses pip to prepare a package version string, from our internal version."""
return six.u(pep440_version(str(version).replace("==", ""))) return pep440_version(str(version).replace("==", ""))
class HackedPythonVersion(object): class HackedPythonVersion:
"""A Beautiful hack, which allows us to tell pip which version of Python we're using.""" """A Beautiful hack, which allows us to tell pip which version of Python we're using."""
def __init__(self, python_version, python_path): def __init__(self, python_version, python_path):
@@ -260,9 +256,9 @@ def prepare_pip_source_args(sources, pip_args=None):
# Trust the host if it's not verified. # Trust the host if it's not verified.
if not sources[0].get("verify_ssl", True): if not sources[0].get("verify_ssl", True):
url_parts = urllib3_util.parse_url(package_url) url_parts = urllib3_util.parse_url(package_url)
url_port = ":{0}".format(url_parts.port) if url_parts.port else "" url_port = f":{url_parts.port}" if url_parts.port else ""
pip_args.extend( pip_args.extend(
["--trusted-host", "{0}{1}".format(url_parts.host, url_port)] ["--trusted-host", f"{url_parts.host}{url_port}"]
) )
# Add additional sources as extra indexes. # Add additional sources as extra indexes.
if len(sources) > 1: if len(sources) > 1:
@@ -274,9 +270,9 @@ def prepare_pip_source_args(sources, pip_args=None):
# Trust the host if it's not verified. # Trust the host if it's not verified.
if not source.get("verify_ssl", True): if not source.get("verify_ssl", True):
url_parts = urllib3_util.parse_url(url) url_parts = urllib3_util.parse_url(url)
url_port = ":{0}".format(url_parts.port) if url_parts.port else "" url_port = f":{url_parts.port}" if url_parts.port else ""
pip_args.extend( pip_args.extend(
["--trusted-host", "{0}{1}".format(url_parts.host, url_port)] ["--trusted-host", f"{url_parts.host}{url_port}"]
) )
return pip_args return pip_args
@@ -314,7 +310,7 @@ def get_source_list(
if index: if index:
sources.append(get_project_index(index)) sources.append(get_project_index(index))
if extra_indexes: if extra_indexes:
if isinstance(extra_indexes, six.string_types): if isinstance(extra_indexes, str):
extra_indexes = [extra_indexes] extra_indexes = [extra_indexes]
for source in extra_indexes: for source in extra_indexes:
extra_src = get_project_index(source) extra_src = get_project_index(source)
@@ -375,7 +371,7 @@ def get_pipenv_sitedir():
return None return None
class Resolver(object): class Resolver:
def __init__( def __init__(
self, constraints, req_dir, project, sources, index_lookup=None, self, constraints, req_dir, project, sources, index_lookup=None,
markers_lookup=None, skipped=None, clear=False, pre=False markers_lookup=None, skipped=None, clear=False, pre=False
@@ -495,13 +491,13 @@ class Resolver(object):
except ValueError: except ValueError:
direct_url = DIRECT_URL_RE.match(line) direct_url = DIRECT_URL_RE.match(line)
if direct_url: if direct_url:
line = "{0}#egg={1}".format(line, direct_url.groupdict()["name"]) line = "{}#egg={}".format(line, direct_url.groupdict()["name"])
try: try:
req = Requirement.from_line(line) req = Requirement.from_line(line)
except ValueError: except ValueError:
raise ResolutionFailure("Failed to resolve requirement from line: {0!s}".format(line)) raise ResolutionFailure(f"Failed to resolve requirement from line: {line!s}")
else: else:
raise ResolutionFailure("Failed to resolve requirement from line: {0!s}".format(line)) raise ResolutionFailure(f"Failed to resolve requirement from line: {line!s}")
if url: if url:
try: try:
index_lookup[req.normalized_name] = project.get_source( index_lookup[req.normalized_name] = project.get_source(
@@ -680,8 +676,8 @@ class Resolver(object):
index_lookup, markers_lookup = {}, {} index_lookup, markers_lookup = {}, {}
deps = set() deps = set()
if dev: if dev:
deps.update(set([req.as_line() for req in pipfile.dev_packages])) deps.update({req.as_line() for req in pipfile.dev_packages})
deps.update(set([req.as_line() for req in pipfile.packages])) deps.update({req.as_line() for req in pipfile.packages})
constraints, skipped, index_lookup, markers_lookup = cls.get_metadata( constraints, skipped, index_lookup, markers_lookup = cls.get_metadata(
list(deps), index_lookup, markers_lookup, project, project.sources, list(deps), index_lookup, markers_lookup, project, project.sources,
req_dir=req_dir, pre=pre, clear=clear req_dir=req_dir, pre=pre, clear=clear
@@ -737,9 +733,9 @@ class Resolver(object):
if self.sources: if self.sources:
requirementstxt_sources = " ".join(args_to_add) if args_to_add else "" requirementstxt_sources = " ".join(args_to_add) if args_to_add else ""
requirementstxt_sources = requirementstxt_sources.replace(" --", "\n--") requirementstxt_sources = requirementstxt_sources.replace(" --", "\n--")
constraints_file.write(u"{0}\n".format(requirementstxt_sources)) constraints_file.write(f"{requirementstxt_sources}\n")
constraints = self.initial_constraints constraints = self.initial_constraints
constraints_file.write(u"\n".join([c for c in constraints])) constraints_file.write("\n".join([c for c in constraints]))
constraints_file.close() constraints_file.close()
return constraints_file.name return constraints_file.name
@@ -820,7 +816,7 @@ class Resolver(object):
from pipenv.patched.piptools.cache import CorruptCacheError from pipenv.patched.piptools.cache import CorruptCacheError
from .exceptions import CacheError, ResolutionFailure from .exceptions import CacheError, ResolutionFailure
with temp_environ(): with temp_environ():
os.environ["PIP_NO_USE_PEP517"] = str("") os.environ["PIP_NO_USE_PEP517"] = ""
try: try:
results = self.resolver.resolve(max_rounds=environments.PIPENV_MAX_ROUNDS) results = self.resolver.resolve(max_rounds=environments.PIPENV_MAX_ROUNDS)
except CorruptCacheError as e: except CorruptCacheError as e:
@@ -876,7 +872,7 @@ class Resolver(object):
if not checksum: if not checksum:
continue continue
if not checksum.startswith("sha256:"): if not checksum.startswith("sha256:"):
checksum = "sha256:{0}".format(checksum) checksum = f"sha256:{checksum}"
cleaned_checksums.append(checksum) cleaned_checksums.append(checksum)
return cleaned_checksums return cleaned_checksums
@@ -895,7 +891,7 @@ class Resolver(object):
"python.org" in source["url"] or "pypi.org" in source["url"] "python.org" in source["url"] or "pypi.org" in source["url"]
for source in self.sources for source in self.sources
): ):
pkg_url = "https://pypi.org/pypi/{0}/json".format(ireq.name) pkg_url = f"https://pypi.org/pypi/{ireq.name}/json"
session = _get_requests_session() session = _get_requests_session()
try: try:
# Grab the hashes from the new warehouse API. # Grab the hashes from the new warehouse API.
@@ -916,7 +912,7 @@ class Resolver(object):
except (ValueError, KeyError, ConnectionError): except (ValueError, KeyError, ConnectionError):
if environments.is_verbose(): if environments.is_verbose():
click_echo( click_echo(
"{0}: Error generating hash for {1}".format( "{}: Error generating hash for {}".format(
crayons.red("Warning", bold=True), ireq.name crayons.red("Warning", bold=True), ireq.name
), err=True ), err=True
) )
@@ -1056,7 +1052,7 @@ def format_requirement_for_lockfile(req, markers_lookup, index_lookup, hashes=No
name, pf_entry = req.pipfile_entry name, pf_entry = req.pipfile_entry
name = pep423_name(req.name) name = pep423_name(req.name)
entry = {} entry = {}
if isinstance(pf_entry, six.string_types): if isinstance(pf_entry, str):
entry["version"] = pf_entry.lstrip("=") entry["version"] = pf_entry.lstrip("=")
else: else:
entry.update(pf_entry) entry.update(pf_entry)
@@ -1150,7 +1146,7 @@ def resolve(cmd, sp):
while True: while True:
result = None result = None
try: try:
result = c.expect(u"\n", timeout=environments.PIPENV_INSTALL_TIMEOUT) result = c.expect("\n", timeout=environments.PIPENV_INSTALL_TIMEOUT)
except TIMEOUT: except TIMEOUT:
pass pass
except EOF: except EOF:
@@ -1160,7 +1156,7 @@ def resolve(cmd, sp):
break break
if result: if result:
_out = c.subprocess.before _out = c.subprocess.before
_out = decode_output("{0}".format(_out)) _out = decode_output(f"{_out}")
out += _out out += _out
# sp.text = to_native_string("{0}".format(_out[:100])) # sp.text = to_native_string("{0}".format(_out[:100]))
if environments.is_verbose(): if environments.is_verbose():
@@ -1342,13 +1338,13 @@ def venv_resolve_deps(
if c.ok: if c.ok:
sp.green.ok(environments.PIPENV_SPINNER_OK_TEXT.format("Success!")) sp.green.ok(environments.PIPENV_SPINNER_OK_TEXT.format("Success!"))
if not environments.is_verbose() and c.out.strip(): if not environments.is_verbose() and c.out.strip():
click_echo(crayons.yellow("Warning: {0}".format(c.out.strip())), err=True) click_echo(crayons.yellow(f"Warning: {c.out.strip()}"), err=True)
else: else:
sp.red.fail(environments.PIPENV_SPINNER_FAIL_TEXT.format("Locking Failed!")) sp.red.fail(environments.PIPENV_SPINNER_FAIL_TEXT.format("Locking Failed!"))
click_echo("Output: {0}".format(c.out.strip()), err=True) click_echo(f"Output: {c.out.strip()}", err=True)
click_echo("Error: {0}".format(c.err.strip()), err=True) click_echo(f"Error: {c.err.strip()}", err=True)
try: try:
with open(target_file.name, "r") as fh: with open(target_file.name) as fh:
results = json.load(fh) results = json.load(fh)
except (IndexError, JSONDecodeError): except (IndexError, JSONDecodeError):
click_echo(c.out.strip(), err=True) click_echo(c.out.strip(), err=True)
@@ -1432,13 +1428,13 @@ def resolve_deps(
def is_star(val): def is_star(val):
return isinstance(val, six.string_types) and val == "*" return isinstance(val, str) and val == "*"
def is_pinned(val): def is_pinned(val):
if isinstance(val, Mapping): if isinstance(val, Mapping):
val = val.get("version") val = val.get("version")
return isinstance(val, six.string_types) and val.startswith("==") return isinstance(val, str) and val.startswith("==")
def convert_deps_to_pip(deps, project=None, r=True, include_index=True): def convert_deps_to_pip(deps, project=None, r=True, include_index=True):
@@ -1477,7 +1473,7 @@ def mkdir_p(newdir):
pass pass
elif os.path.isfile(newdir): elif os.path.isfile(newdir):
raise OSError( raise OSError(
"a file with the same name as the desired dir, '{0}', already exists.".format( "a file with the same name as the desired dir, '{}', already exists.".format(
newdir newdir
) )
) )
@@ -1530,7 +1526,7 @@ def is_installable_file(path):
key for key in path.keys() if key in ["file", "path"] key for key in path.keys() if key in ["file", "path"]
): ):
path = urlparse(path["file"]).path if "file" in path else path["path"] path = urlparse(path["file"]).path if "file" in path else path["path"]
if not isinstance(path, six.string_types) or path == "*": if not isinstance(path, str) or path == "*":
return False return False
# If the string starts with a valid specifier operator, test if it is a valid # If the string starts with a valid specifier operator, test if it is a valid
@@ -1548,7 +1544,7 @@ def is_installable_file(path):
return False return False
lookup_path = Path(path) lookup_path = Path(path)
absolute_path = "{0}".format(lookup_path.absolute()) absolute_path = f"{lookup_path.absolute()}"
if lookup_path.is_dir() and is_installable_dir(absolute_path): if lookup_path.is_dir() and is_installable_dir(absolute_path):
return True return True
@@ -1595,11 +1591,11 @@ def proper_case(package_name):
"""Properly case project name from pypi.org.""" """Properly case project name from pypi.org."""
# Hit the simple API. # Hit the simple API.
r = _get_requests_session().get( r = _get_requests_session().get(
"https://pypi.org/pypi/{0}/json".format(package_name), timeout=0.3, stream=True f"https://pypi.org/pypi/{package_name}/json", timeout=0.3, stream=True
) )
if not r.ok: if not r.ok:
raise IOError( raise OSError(
"Unable to find package {0} in PyPI repository.".format(package_name) f"Unable to find package {package_name} in PyPI repository."
) )
r = parse.parse("https://pypi.org/pypi/{name}/json", r.url) r = parse.parse("https://pypi.org/pypi/{name}/json", r.url)
@@ -1646,7 +1642,7 @@ def normalize_path(path):
def get_url_name(url): def get_url_name(url):
if not isinstance(url, six.string_types): if not isinstance(url, str):
return return
return urllib3_util.parse_url(url).host return urllib3_util.parse_url(url).host
@@ -1656,10 +1652,10 @@ def get_canonical_names(packages):
from .vendor.packaging.utils import canonicalize_name from .vendor.packaging.utils import canonicalize_name
if not isinstance(packages, Sequence): if not isinstance(packages, Sequence):
if not isinstance(packages, six.string_types): if not isinstance(packages, str):
return packages return packages
packages = [packages] packages = [packages]
return set([canonicalize_name(pkg) for pkg in packages if pkg]) return {canonicalize_name(pkg) for pkg in packages if pkg}
def walk_up(bottom): def walk_up(bottom):
@@ -1686,8 +1682,7 @@ def walk_up(bottom):
if new_path == bottom: if new_path == bottom:
return return
for x in walk_up(new_path): yield from walk_up(new_path)
yield x
def find_requirements(max_depth=3): def find_requirements(max_depth=3):
@@ -1733,7 +1728,7 @@ def load_path(python):
import json import json
python = Path(python).as_posix() python = Path(python).as_posix()
json_dump_commmand = '"import json, sys; print(json.dumps(sys.path));"' json_dump_commmand = '"import json, sys; print(json.dumps(sys.path));"'
c = delegator.run('"{0}" -c {1}'.format(python, json_dump_commmand)) c = delegator.run(f'"{python}" -c {json_dump_commmand}')
if c.return_code == 0: if c.return_code == 0:
return json.loads(c.out.strip()) return json.loads(c.out.strip())
else: else:
@@ -1768,7 +1763,7 @@ def download_file(url, filename):
"""Downloads file from url to a path with filename""" """Downloads file from url to a path with filename"""
r = _get_requests_session().get(url, stream=True) r = _get_requests_session().get(url, stream=True)
if not r.ok: if not r.ok:
raise IOError("Unable to download file") raise OSError("Unable to download file")
with open(filename, "wb") as f: with open(filename, "wb") as f:
f.write(r.content) f.write(r.content)
@@ -1783,13 +1778,13 @@ def normalize_drive(path):
See: <https://github.com/pypa/pipenv/issues/1218> See: <https://github.com/pypa/pipenv/issues/1218>
""" """
if os.name != "nt" or not isinstance(path, six.string_types): if os.name != "nt" or not isinstance(path, str):
return path return path
drive, tail = os.path.splitdrive(path) drive, tail = os.path.splitdrive(path)
# Only match (lower cased) local drives (e.g. 'c:'), not UNC mounts. # Only match (lower cased) local drives (e.g. 'c:'), not UNC mounts.
if drive.islower() and len(drive) == 2 and drive[1] == ":": if drive.islower() and len(drive) == 2 and drive[1] == ":":
return "{}{}".format(drive.upper(), tail) return f"{drive.upper()}{tail}"
return path return path
@@ -1806,7 +1801,7 @@ def is_readonly_path(fn):
def set_write_bit(fn): def set_write_bit(fn):
if isinstance(fn, six.string_types) and not os.path.exists(fn): if isinstance(fn, str) and not os.path.exists(fn):
return return
os.chmod(fn, stat.S_IWRITE | stat.S_IWUSR | stat.S_IRUSR) os.chmod(fn, stat.S_IWRITE | stat.S_IWUSR | stat.S_IRUSR)
return return
@@ -1834,7 +1829,7 @@ def handle_remove_readonly(func, path, exc):
set_write_bit(path) set_write_bit(path)
try: try:
func(path) func(path)
except (OSError, IOError) as e: except OSError as e:
if e.errno in [errno.EACCES, errno.EPERM]: if e.errno in [errno.EACCES, errno.EPERM]:
warnings.warn(default_warning_message.format(path), ResourceWarning) warnings.warn(default_warning_message.format(path), ResourceWarning)
return return
@@ -1848,14 +1843,14 @@ def handle_remove_readonly(func, path, exc):
def escape_cmd(cmd): def escape_cmd(cmd):
if any(special_char in cmd for special_char in ["<", ">", "&", ".", "^", "|", "?"]): if any(special_char in cmd for special_char in ["<", ">", "&", ".", "^", "|", "?"]):
cmd = '\"{0}\"'.format(cmd) cmd = f'\"{cmd}\"'
return cmd return cmd
def safe_expandvars(value): def safe_expandvars(value):
"""Call os.path.expandvars if value is a string, otherwise do nothing. """Call os.path.expandvars if value is a string, otherwise do nothing.
""" """
if isinstance(value, six.string_types): if isinstance(value, str):
return os.path.expandvars(value) return os.path.expandvars(value)
return value return value
@@ -1932,13 +1927,13 @@ def translate_markers(pipfile_entry):
if 'extra' not in marker: if 'extra' not in marker:
marker_set.add(marker) marker_set.add(marker)
for m in pipfile_markers: for m in pipfile_markers:
entry = "{0}".format(pipfile_entry[m]) entry = f"{pipfile_entry[m]}"
if m != "markers": if m != "markers":
marker_set.add(str(Marker("{0} {1}".format(m, entry)))) marker_set.add(str(Marker(f"{m} {entry}")))
new_pipfile.pop(m) new_pipfile.pop(m)
if marker_set: if marker_set:
new_pipfile["markers"] = str(Marker(" or ".join( new_pipfile["markers"] = str(Marker(" or ".join(
"{0}".format(s) if " and " in s else s f"{s}" if " and " in s else s
for s in sorted(dedup(marker_set)) for s in sorted(dedup(marker_set))
))).replace('"', "'") ))).replace('"', "'")
return new_pipfile return new_pipfile
@@ -1951,9 +1946,9 @@ def clean_resolved_dep(dep, is_top_level=False, pipfile_entry=None):
# We use this to determine if there are any markers on top level packages # We use this to determine if there are any markers on top level packages
# So we can make sure those win out during resolution if the packages reoccur # So we can make sure those win out during resolution if the packages reoccur
if "version" in dep and dep["version"] and not dep.get("editable", False): if "version" in dep and dep["version"] and not dep.get("editable", False):
version = "{0}".format(dep["version"]) version = "{}".format(dep["version"])
if not version.startswith("=="): if not version.startswith("=="):
version = "=={0}".format(version) version = f"=={version}"
lockfile["version"] = version lockfile["version"] = version
if is_vcs(dep): if is_vcs(dep):
ref = dep.get("ref", None) ref = dep.get("ref", None)
@@ -2139,10 +2134,10 @@ def is_url_equal(url, other_url):
"https://mydomain.com/some?some_query") "https://mydomain.com/some?some_query")
False False
""" """
if not isinstance(url, six.string_types): if not isinstance(url, str):
raise TypeError("Expected string for url, received {0!r}".format(url)) raise TypeError(f"Expected string for url, received {url!r}")
if not isinstance(other_url, six.string_types): if not isinstance(other_url, str):
raise TypeError("Expected string for url, received {0!r}".format(other_url)) raise TypeError(f"Expected string for url, received {other_url!r}")
parsed_url = urllib3_util.parse_url(url) parsed_url = urllib3_util.parse_url(url)
parsed_other_url = urllib3_util.parse_url(other_url) parsed_other_url = urllib3_util.parse_url(other_url)
unparsed = parsed_url._replace(auth=None, query=None, fragment=None).url unparsed = parsed_url._replace(auth=None, query=None, fragment=None).url
@@ -2167,14 +2162,14 @@ def make_posix(path):
>>> make_posix("c:\\users\\user\\venvs\\some_venv") >>> make_posix("c:\\users\\user\\venvs\\some_venv")
"c:/users/user/venvs/some_venv" "c:/users/user/venvs/some_venv"
""" """
if not isinstance(path, six.string_types): if not isinstance(path, str):
raise TypeError("Expected a string for path, received {0!r}...".format(path)) raise TypeError(f"Expected a string for path, received {path!r}...")
starts_with_sep = path.startswith(os.path.sep) starts_with_sep = path.startswith(os.path.sep)
separated = normalize_path(path).split(os.path.sep) separated = normalize_path(path).split(os.path.sep)
if isinstance(separated, (list, tuple)): if isinstance(separated, (list, tuple)):
path = posixpath.join(*separated) path = posixpath.join(*separated)
if starts_with_sep: if starts_with_sep:
path = "/{0}".format(path) path = f"/{path}"
return path return path
@@ -2198,9 +2193,9 @@ def find_python(finder, line=None):
:rtype: str :rtype: str
""" """
if line and not isinstance(line, six.string_types): if line and not isinstance(line, str):
raise TypeError( raise TypeError(
"Invalid python search type: expected string, received {0!r}".format(line) f"Invalid python search type: expected string, received {line!r}"
) )
if line and os.path.isabs(line): if line and os.path.isabs(line):
if os.name == "nt": if os.name == "nt":
@@ -2218,11 +2213,11 @@ def find_python(finder, line=None):
if not result: if not result:
result = finder.which(line) result = finder.which(line)
if not result and not line.startswith("python"): if not result and not line.startswith("python"):
line = "python{0}".format(line) line = f"python{line}"
result = find_python(finder, line) result = find_python(finder, line)
if result: if result:
if not isinstance(result, six.string_types): if not isinstance(result, str):
return result.path.as_posix() return result.path.as_posix()
return result return result
return return
@@ -2239,8 +2234,8 @@ def is_python_command(line):
:rtype: bool :rtype: bool
""" """
if not isinstance(line, six.string_types): if not isinstance(line, str):
raise TypeError("Not a valid command to check: {0!r}".format(line)) raise TypeError(f"Not a valid command to check: {line!r}")
from pipenv.vendor.pythonfinder.utils import PYTHON_IMPLEMENTATIONS from pipenv.vendor.pythonfinder.utils import PYTHON_IMPLEMENTATIONS
is_version = re.match(r'\d+(\.\d+)*', line) is_version = re.match(r'\d+(\.\d+)*', line)
+8 -3
View File
@@ -4,9 +4,14 @@ license = MIT
license_file = LICENSE license_file = LICENSE
[flake8] [flake8]
exclude = extend-exclude =
.git,__pycache__,docs/,pipenv/vendor/,pipenv/patched,get-pipenv.py, docs/,
.eggs/,setup.py,tests/fixtures/ pipenv/vendor/,
pipenv/patched/,
get-pipenv.py,
setup.py,
tests/fixtures/,
tests/test_artifacts/
ignore = ignore =
# The default ignore list: # The default ignore list:
E121,E123,E126,E226,E24,E704, E121,E123,E126,E226,E24,E704,
+7 -8
View File
@@ -1,5 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*-
import codecs import codecs
import os import os
import sys import sys
@@ -53,7 +52,7 @@ class DebCommand(Command):
@staticmethod @staticmethod
def status(s): def status(s):
"""Prints things in bold.""" """Prints things in bold."""
print("\033[1m{0}\033[0m".format(s)) print(f"\033[1m{s}\033[0m")
def initialize_options(self): def initialize_options(self):
pass pass
@@ -67,12 +66,12 @@ class DebCommand(Command):
rmtree(os.path.join(here, "deb_dist")) rmtree(os.path.join(here, "deb_dist"))
except FileNotFoundError: except FileNotFoundError:
pass pass
self.status(u"Creating debian mainfest...") self.status("Creating debian mainfest...")
os.system( os.system(
"python setup.py --command-packages=stdeb.command sdist_dsc -z artful --package3=pipenv --depends3=python3-virtualenv-clone" "python setup.py --command-packages=stdeb.command sdist_dsc -z artful --package3=pipenv --depends3=python3-virtualenv-clone"
) )
self.status(u"Building .deb...") self.status("Building .deb...")
os.chdir("deb_dist/pipenv-{0}".format(about["__version__"])) os.chdir("deb_dist/pipenv-{}".format(about["__version__"]))
os.system("dpkg-buildpackage -rfakeroot -uc -us") os.system("dpkg-buildpackage -rfakeroot -uc -us")
@@ -85,7 +84,7 @@ class UploadCommand(Command):
@staticmethod @staticmethod
def status(s): def status(s):
"""Prints things in bold.""" """Prints things in bold."""
print("\033[1m{0}\033[0m".format(s)) print(f"\033[1m{s}\033[0m")
def initialize_options(self): def initialize_options(self):
pass pass
@@ -100,11 +99,11 @@ class UploadCommand(Command):
except FileNotFoundError: except FileNotFoundError:
pass pass
self.status("Building Source distribution...") self.status("Building Source distribution...")
os.system("{0} setup.py sdist bdist_wheel".format(sys.executable)) os.system(f"{sys.executable} setup.py sdist bdist_wheel")
self.status("Uploading the package to PyPI via Twine...") self.status("Uploading the package to PyPI via Twine...")
os.system("twine upload dist/*") os.system("twine upload dist/*")
self.status("Pushing git tags...") self.status("Pushing git tags...")
os.system("git tag v{0}".format(about["__version__"])) os.system("git tag v{}".format(about["__version__"]))
os.system("git push --tags") os.system("git push --tags")
sys.exit() sys.exit()
-1
View File
@@ -1,4 +1,3 @@
# -*- coding=utf-8 -*-
# Copied from pip's vendoring process # Copied from pip's vendoring process
# see https://github.com/pypa/pip/blob/95bcf8c5f6394298035a7332c441868f3b0169f4/tasks/__init__.py # see https://github.com/pypa/pip/blob/95bcf8c5f6394298035a7332c441868f3b0169f4/tasks/__init__.py
from pathlib import Path from pathlib import Path
+7 -8
View File
@@ -1,4 +1,3 @@
# -*- coding=utf-8 -*-
import datetime import datetime
import os import os
import pathlib import pathlib
@@ -107,11 +106,11 @@ def release(ctx, manual=False, local=False, dry_run=False, pre=False, tag=None,
if pre: if pre:
log("generating towncrier draft...") log("generating towncrier draft...")
ctx.run("towncrier --draft > CHANGELOG.draft.rst") ctx.run("towncrier --draft > CHANGELOG.draft.rst")
ctx.run("git add {0}".format(get_version_file(ctx).as_posix())) ctx.run(f"git add {get_version_file(ctx).as_posix()}")
else: else:
ctx.run("towncrier") ctx.run("towncrier")
ctx.run( ctx.run(
"git add CHANGELOG.rst news/ {0}".format(get_version_file(ctx).as_posix()) f"git add CHANGELOG.rst news/ {get_version_file(ctx).as_posix()}"
) )
log("removing changelog draft if present") log("removing changelog draft if present")
draft_changelog = pathlib.Path("CHANGELOG.draft.rst") draft_changelog = pathlib.Path("CHANGELOG.draft.rst")
@@ -283,12 +282,12 @@ def date_offset(dt, month_offset=0, day_offset=0, truncate=False):
"month": dt.month + month_offset, "month": dt.month + month_offset,
"year": dt.year + year_offset, "year": dt.year + year_offset,
} }
log("Getting updated date from date: {0} using month offset: {1} and year offset {2}".format( log("Getting updated date from date: {} using month offset: {} and year offset {}".format(
dt, new_month, replace_args["year"] dt, new_month, replace_args["year"]
)) ))
if day_offset: if day_offset:
dt = dt + datetime.timedelta(days=day_offset) dt = dt + datetime.timedelta(days=day_offset)
log("updated date using day offset: {0} => {1}".format(day_offset, dt)) log(f"updated date using day offset: {day_offset} => {dt}")
if truncate: if truncate:
log("Truncating...") log("Truncating...")
replace_args["day"] = 1 replace_args["day"] = 1
@@ -317,7 +316,7 @@ def bump_version(ctx, dry_run=False, dev=False, pre=False, tag=None, commit=Fals
day_offset=day_offset, day_offset=day_offset,
truncate=trunc_month truncate=trunc_month
) )
log("target_day: {0}".format(target_day)) log(f"target_day: {target_day}")
target_timetuple = target_day.timetuple()[:3] target_timetuple = target_day.timetuple()[:3]
new_version = current_version.replace(release=target_timetuple) new_version = current_version.replace(release=target_timetuple)
if pre and dev: if pre and dev:
@@ -338,7 +337,7 @@ def bump_version(ctx, dry_run=False, dev=False, pre=False, tag=None, commit=Fals
new_version = new_version.replace(dev=None) new_version = new_version.replace(dev=None)
if new_version.pre_tag: if new_version.pre_tag:
if new_version.pre_tag != tag: if new_version.pre_tag != tag:
log("Swapping prerelease tag: {0} for {1}".format(new_version.pre_tag, tag)) log(f"Swapping prerelease tag: {new_version.pre_tag} for {tag}")
new_version = new_version.replace(pre_tag=tag, pre=tag_version) new_version = new_version.replace(pre_tag=tag, pre=tag_version)
else: else:
new_version = new_version.replace(pre_tag=tag, pre=tag_version) new_version = new_version.replace(pre_tag=tag, pre=tag_version)
@@ -359,7 +358,7 @@ def bump_version(ctx, dry_run=False, dev=False, pre=False, tag=None, commit=Fals
file_contents.replace(version, str(new_version.normalize())) file_contents.replace(version, str(new_version.normalize()))
) )
if commit: if commit:
ctx.run("git add {0}".format(version_file.as_posix())) ctx.run(f"git add {version_file.as_posix()}")
log("Committing...") log("Committing...")
ctx.run('git commit -s -m "Bumped version."') ctx.run('git commit -s -m "Bumped version."')
return str(new_version) return str(new_version)
+56 -57
View File
@@ -1,4 +1,3 @@
# -*- coding=utf-8 -*-
# Taken from pip # Taken from pip
# see https://github.com/pypa/pip/blob/95bcf8c5f6394298035a7332c441868f3b0169f4/tasks/vendoring/__init__.py # see https://github.com/pypa/pip/blob/95bcf8c5f6394298035a7332c441868f3b0169f4/tasks/vendoring/__init__.py
""""Vendoring script, python 3.5 needed""" """"Vendoring script, python 3.5 needed"""
@@ -102,7 +101,7 @@ def remove_all(paths):
def log(msg): def log(msg):
print("[vendoring.%s] %s" % (TASK_NAME, msg)) print(f"[vendoring.{TASK_NAME}] {msg}")
def _get_git_root(ctx): def _get_git_root(ctx):
@@ -222,8 +221,8 @@ def update_safety(ctx):
log("generating lockfile...") log("generating lockfile...")
packages = "\n".join(["safety", "requests[security]"]) packages = "\n".join(["safety", "requests[security]"])
env = {"PIPENV_PACKAGES": packages} env = {"PIPENV_PACKAGES": packages}
resolve_cmd = "python {0}".format(root.joinpath("pipenv/resolver.py").as_posix()) resolve_cmd = "python {}".format(root.joinpath("pipenv/resolver.py").as_posix())
py27_resolve_cmd = "python2.7 {0}".format(root.joinpath("pipenv/resolver.py").as_posix()) py27_resolve_cmd = "python2.7 {}".format(root.joinpath("pipenv/resolver.py").as_posix())
_, _, resolved = ctx.run(resolve_cmd, hide=True, env=env).stdout.partition("RESULTS:") _, _, resolved = ctx.run(resolve_cmd, hide=True, env=env).stdout.partition("RESULTS:")
_, _, resolved_py2 = ctx.run(py27_resolve_cmd, hide=True, env=env).stdout.partition("RESULTS:") _, _, resolved_py2 = ctx.run(py27_resolve_cmd, hide=True, env=env).stdout.partition("RESULTS:")
resolved = json.loads(resolved.strip()) resolved = json.loads(resolved.strip())
@@ -231,11 +230,11 @@ def update_safety(ctx):
pkg_dict, pkg_dict_py2 = {}, {} pkg_dict, pkg_dict_py2 = {}, {}
for pkg in resolved: for pkg in resolved:
name = pkg.pop("name") name = pkg.pop("name")
pkg["version"] = "=={0}".format(pkg["version"]) pkg["version"] = "=={}".format(pkg["version"])
pkg_dict[name] = pkg pkg_dict[name] = pkg
for pkg in resolved_py2: for pkg in resolved_py2:
name = pkg.pop("name") name = pkg.pop("name")
pkg["version"] = "=={0}".format(pkg["version"]) pkg["version"] = "=={}".format(pkg["version"])
pkg_dict_py2[name] = pkg pkg_dict_py2[name] = pkg
merged = merge_items([pkg_dict, pkg_dict_py2]) merged = merge_items([pkg_dict, pkg_dict_py2])
lf = Lockfile.create(safety_dir.as_posix()) lf = Lockfile.create(safety_dir.as_posix())
@@ -255,12 +254,12 @@ def update_safety(ctx):
] ]
safety_dir.joinpath("requirements.txt").write_text("\n".join(requirements)) safety_dir.joinpath("requirements.txt").write_text("\n".join(requirements))
if build_dir.exists() and build_dir.is_dir(): if build_dir.exists() and build_dir.is_dir():
log("dropping pre-existing build dir at {0}".format(build_dir.as_posix())) log(f"dropping pre-existing build dir at {build_dir.as_posix()}")
drop_dir(build_dir) drop_dir(build_dir)
pip_command = "pip download -b {0} --no-binary=:all: --no-clean --no-deps -d {1} pyyaml safety".format( pip_command = "pip download -b {} --no-binary=:all: --no-clean --no-deps -d {} pyyaml safety".format(
build_dir.absolute().as_posix(), str(download_dir.name), build_dir.absolute().as_posix(), str(download_dir.name),
) )
log("downloading deps via pip: {0}".format(pip_command)) log(f"downloading deps via pip: {pip_command}")
ctx.run(pip_command) ctx.run(pip_command)
yaml_build_dir = build_dir / "pyyaml" yaml_build_dir = build_dir / "pyyaml"
@@ -268,8 +267,8 @@ def update_safety(ctx):
with ctx.cd(str(safety_dir)): with ctx.cd(str(safety_dir)):
lib_dir.mkdir(exist_ok=True) lib_dir.mkdir(exist_ok=True)
install_cmd = "python2.7 -m pip install --ignore-requires-python -t {0} -r {1}".format(lib_dir.as_posix(), safety_dir.joinpath("requirements.txt").as_posix()) install_cmd = "python2.7 -m pip install --ignore-requires-python -t {} -r {}".format(lib_dir.as_posix(), safety_dir.joinpath("requirements.txt").as_posix())
log("installing dependencies: {0}".format(install_cmd)) log(f"installing dependencies: {install_cmd}")
ctx.run(install_cmd) ctx.run(install_cmd)
safety_dir = safety_dir.absolute() safety_dir = safety_dir.absolute()
yaml_dir = lib_dir / "yaml" yaml_dir = lib_dir / "yaml"
@@ -299,23 +298,23 @@ def update_safety(ctx):
log("dropping ignored files...") log("dropping ignored files...")
for pattern in ignore_patterns: for pattern in ignore_patterns:
for path in lib_dir.rglob(pattern): for path in lib_dir.rglob(pattern):
log("removing {0!s}".format(path)) log(f"removing {path!s}")
path.unlink() path.unlink()
for dep in ignore_subdeps: for dep in ignore_subdeps:
if lib_dir.joinpath(dep).exists(): if lib_dir.joinpath(dep).exists():
log("cleaning up {0}".format(dep)) log(f"cleaning up {dep}")
drop_dir(lib_dir.joinpath(dep)) drop_dir(lib_dir.joinpath(dep))
for path in itertools.chain.from_iterable(( for path in itertools.chain.from_iterable((
lib_dir.rglob("{0}*.egg-info".format(dep)), lib_dir.rglob(f"{dep}*.egg-info"),
lib_dir.rglob("{0}*.dist-info".format(dep)) lib_dir.rglob(f"{dep}*.dist-info")
)): )):
log("cleaning up {0}".format(path)) log(f"cleaning up {path}")
drop_dir(path) drop_dir(path)
for fn in ignore_files: for fn in ignore_files:
for path in lib_dir.rglob(fn): for path in lib_dir.rglob(fn):
log("cleaning up {0}".format(path)) log(f"cleaning up {path}")
path.unlink() path.unlink()
zip_name = "{0}/safety.zip".format(str(patched_dir)) zip_name = f"{str(patched_dir)}/safety.zip"
log("writing zipfile...") log("writing zipfile...")
with zipfile.ZipFile(zip_name, 'w', compression=zipfile.ZIP_DEFLATED, compresslevel=6) as zf: with zipfile.ZipFile(zip_name, 'w', compression=zipfile.ZIP_DEFLATED, compresslevel=6) as zf:
_recursive_write_to_zip(zf, safety_dir) _recursive_write_to_zip(zf, safety_dir)
@@ -329,7 +328,7 @@ def rename_if_needed(ctx, vendor_dir, item):
if item.name in rename_dict or item.name in LIBRARY_DIRNAMES: if item.name in rename_dict or item.name in LIBRARY_DIRNAMES:
new_name = rename_dict.get(item.name, LIBRARY_DIRNAMES.get(item.name)) new_name = rename_dict.get(item.name, LIBRARY_DIRNAMES.get(item.name))
new_path = item.parent / new_name new_path = item.parent / new_name
log("Renaming %s => %s" % (item.name, new_path)) log(f"Renaming {item.name} => {new_path}")
# handle existing directories # handle existing directories
try: try:
item.rename(str(new_path)) item.rename(str(new_path))
@@ -346,7 +345,7 @@ def write_backport_imports(ctx, vendor_dir):
backport_libs = detect_vendored_libs(backport_dir) backport_libs = detect_vendored_libs(backport_dir)
init_py_lines = backport_init.read_text().splitlines() init_py_lines = backport_init.read_text().splitlines()
for lib in backport_libs: for lib in backport_libs:
lib_line = "from . import {0}".format(lib) lib_line = f"from . import {lib}"
if lib_line not in init_py_lines: if lib_line not in init_py_lines:
log("Adding backport %s to __init__.py exports" % lib) log("Adding backport %s to __init__.py exports" % lib)
init_py_lines.append(lib_line) init_py_lines.append(lib_line)
@@ -366,29 +365,29 @@ def _ensure_package_in_requirements(ctx, requirements_file, package):
if m.lower() == package or ( if m.lower() == package or (
specifiers and m[: min(specifiers)].lower() == package specifiers and m[: min(specifiers)].lower() == package
): ):
matched_req = "{0}".format(m) matched_req = f"{m}"
requirement = matched_req requirement = matched_req
log("Matched req: %r" % matched_req) log("Matched req: %r" % matched_req)
if not matched_req: if not matched_req:
req_file_lines.append("{0}".format(package)) req_file_lines.append(f"{package}")
log("Writing requirements file: %s" % requirements_file) log("Writing requirements file: %s" % requirements_file)
requirements_file.write_text("\n".join(req_file_lines)) requirements_file.write_text("\n".join(req_file_lines))
requirement = "{0}".format(package) requirement = f"{package}"
return requirement return requirement
def install_pyyaml(ctx, vendor_dir): def install_pyyaml(ctx, vendor_dir):
build_dir = vendor_dir / "build" build_dir = vendor_dir / "build"
if build_dir.exists() and build_dir.is_dir(): if build_dir.exists() and build_dir.is_dir():
log("dropping pre-existing build dir at {0}".format(build_dir.as_posix())) log(f"dropping pre-existing build dir at {build_dir.as_posix()}")
drop_dir(build_dir) drop_dir(build_dir)
build_dir.mkdir() build_dir.mkdir()
with TemporaryDirectory(prefix="pipenv-", suffix="-safety") as download_dir: with TemporaryDirectory(prefix="pipenv-", suffix="-safety") as download_dir:
pip_command = "pip download -b {0} --no-binary=:all: --no-clean --no-deps -d {1} pyyaml safety".format( pip_command = "pip download -b {} --no-binary=:all: --no-clean --no-deps -d {} pyyaml safety".format(
build_dir.absolute().as_posix(), str(download_dir.name), build_dir.absolute().as_posix(), str(download_dir.name),
) )
temp_env = "TEMP" if os.name == "nt" else "TMPDIR" temp_env = "TEMP" if os.name == "nt" else "TMPDIR"
log("downloading deps via pip: {0}".format(pip_command)) log(f"downloading deps via pip: {pip_command}")
ctx.run(pip_command, env={temp_env: str(build_dir)}) ctx.run(pip_command, env={temp_env: str(build_dir)})
yaml_build_dir = next(build_dir.glob('pip-download-*/pyyaml_*')) yaml_build_dir = next(build_dir.glob('pip-download-*/pyyaml_*'))
yaml_dir = vendor_dir / "yaml" yaml_dir = vendor_dir / "yaml"
@@ -404,8 +403,8 @@ def install_pyyaml(ctx, vendor_dir):
def install(ctx, vendor_dir, package=None): def install(ctx, vendor_dir, package=None):
requirements_file = vendor_dir / "{0}.txt".format(vendor_dir.name) requirements_file = vendor_dir / f"{vendor_dir.name}.txt"
requirement = "-r {0}".format(requirements_file.as_posix()) requirement = f"-r {requirements_file.as_posix()}"
log("Using requirements file: %s" % requirement) log("Using requirements file: %s" % requirement)
if package: if package:
requirement = _ensure_package_in_requirements(ctx, requirements_file, package) requirement = _ensure_package_in_requirements(ctx, requirements_file, package)
@@ -413,7 +412,7 @@ def install(ctx, vendor_dir, package=None):
# are added to vendor.txt, this includes all dependencies recursively up # are added to vendor.txt, this includes all dependencies recursively up
# the chain. # the chain.
ctx.run( ctx.run(
"pip install -t {0} --no-compile --no-deps --upgrade {1}".format( "pip install -t {} --no-compile --no-deps --upgrade {}".format(
vendor_dir.as_posix(), requirement, vendor_dir.as_posix(), requirement,
) )
) )
@@ -427,20 +426,20 @@ def install(ctx, vendor_dir, package=None):
vendor_dir.joinpath(pkg).joinpath("LICENSE").write_text( vendor_dir.joinpath(pkg).joinpath("LICENSE").write_text(
license_file.read_text() license_file.read_text()
) )
elif vendor_dir.joinpath("{0}.py".format(pkg)).exists(): elif vendor_dir.joinpath(f"{pkg}.py").exists():
vendor_dir.joinpath("{0}.LICENSE".format(pkg)).write_text( vendor_dir.joinpath(f"{pkg}.LICENSE").write_text(
license_file.read_text() license_file.read_text()
) )
else: else:
pkg = pkg.replace("-", "?").replace("_", "?") pkg = pkg.replace("-", "?").replace("_", "?")
matched_path = next( matched_path = next(
iter(pth for pth in vendor_dir.glob("{0}*".format(pkg))), None iter(pth for pth in vendor_dir.glob(f"{pkg}*")), None
) )
if matched_path is not None: if matched_path is not None:
if matched_path.is_dir(): if matched_path.is_dir():
target = vendor_dir.joinpath(matched_path).joinpath("LICENSE") target = vendor_dir.joinpath(matched_path).joinpath("LICENSE")
else: else:
target = vendor_dir.joinpath("{0}.LICENSE".format(matched_path)) target = vendor_dir.joinpath(f"{matched_path}.LICENSE")
target.write_text( target.write_text(
license_file.read_text() license_file.read_text()
) )
@@ -529,7 +528,7 @@ def redo_imports(ctx, library, vendor_dir=None):
log("Using vendor dir: %s" % vendor_dir) log("Using vendor dir: %s" % vendor_dir)
vendored_libs = detect_vendored_libs(vendor_dir) vendored_libs = detect_vendored_libs(vendor_dir)
item = vendor_dir / library item = vendor_dir / library
library_name = vendor_dir / "{0}.py".format(library) library_name = vendor_dir / f"{library}.py"
log("Detected vendored libraries: %s" % ", ".join(vendored_libs)) log("Detected vendored libraries: %s" % ", ".join(vendored_libs))
log("Rewriting imports for %s..." % item) log("Rewriting imports for %s..." % item)
if item.is_dir(): if item.is_dir():
@@ -581,7 +580,7 @@ def packages_missing_licenses(
possible_pkgs.append(LIBRARY_DIRNAMES[pkg]) possible_pkgs.append(LIBRARY_DIRNAMES[pkg])
for pkgpath in possible_pkgs: for pkgpath in possible_pkgs:
pkgpath = vendor_dir.joinpath(pkgpath) pkgpath = vendor_dir.joinpath(pkgpath)
py_path = pkgpath.parent / "{0}.py".format(pkgpath.stem) py_path = pkgpath.parent / f"{pkgpath.stem}.py"
if pkgpath.exists() and pkgpath.is_dir(): if pkgpath.exists() and pkgpath.is_dir():
for license_path in LICENSES: for license_path in LICENSES:
license_path = pkgpath.joinpath(license_path) license_path = pkgpath.joinpath(license_path)
@@ -591,7 +590,7 @@ def packages_missing_licenses(
break break
elif pkgpath.exists() or py_path.exists(): elif pkgpath.exists() or py_path.exists():
for license_path in LICENSES: for license_path in LICENSES:
license_name = "{0}.{1}".format(pkgpath.stem, license_path) license_name = f"{pkgpath.stem}.{license_path}"
license_path = pkgpath.parent / license_name license_path = pkgpath.parent / license_name
if license_path.exists(): if license_path.exists():
match_found = True match_found = True
@@ -635,16 +634,16 @@ def download_licenses(
ctx.run("pip install flit") # needed for the next step ctx.run("pip install flit") # needed for the next step
for req in requirements: for req in requirements:
if req.startswith("enum34"): if req.startswith("enum34"):
exe_cmd = "{0} -d {1} {2}".format(enum_cmd, tmp_dir.as_posix(), req) exe_cmd = f"{enum_cmd} -d {tmp_dir.as_posix()} {req}"
else: else:
exe_cmd = "{0} --no-build-isolation -d {1} {2}".format( exe_cmd = "{} --no-build-isolation -d {} {}".format(
cmd, tmp_dir.as_posix(), req cmd, tmp_dir.as_posix(), req
) )
try: try:
ctx.run(exe_cmd) ctx.run(exe_cmd)
except invoke.exceptions.UnexpectedExit as e: except invoke.exceptions.UnexpectedExit as e:
if "Disabling PEP 517 processing is invalid" not in e.result.stderr: if "Disabling PEP 517 processing is invalid" not in e.result.stderr:
log("WARNING: Failed to download license for {0}".format(req)) log(f"WARNING: Failed to download license for {req}")
continue continue
parse_target = ( parse_target = (
"Disabling PEP 517 processing is invalid: project specifies a build " "Disabling PEP 517 processing is invalid: project specifies a build "
@@ -655,9 +654,9 @@ def download_licenses(
if backend is not None: if backend is not None:
if "." in backend: if "." in backend:
backend, _, _ = backend.partition(".") backend, _, _ = backend.partition(".")
ctx.run("pip install {0}".format(backend)) ctx.run(f"pip install {backend}")
ctx.run( ctx.run(
"{0} --no-build-isolation -d {1} {2}".format(cmd, tmp_dir.as_posix(), req) f"{cmd} --no-build-isolation -d {tmp_dir.as_posix()} {req}"
) )
for sdist in tmp_dir.iterdir(): for sdist in tmp_dir.iterdir():
extract_license(vendor_dir, sdist) extract_license(vendor_dir, sdist)
@@ -667,7 +666,7 @@ def download_licenses(
def extract_license(vendor_dir, sdist): def extract_license(vendor_dir, sdist):
if sdist.stem.endswith(".tar"): if sdist.stem.endswith(".tar"):
ext = sdist.suffix[1:] ext = sdist.suffix[1:]
with tarfile.open(sdist, mode="r:{}".format(ext)) as tar: with tarfile.open(sdist, mode=f"r:{ext}") as tar:
found = find_and_extract_license(vendor_dir, tar, tar.getmembers()) found = find_and_extract_license(vendor_dir, tar, tar.getmembers())
elif sdist.suffix in (".zip", ".whl"): elif sdist.suffix in (".zip", ".whl"):
with zipfile.ZipFile(sdist) as zip: with zipfile.ZipFile(sdist) as zip:
@@ -676,7 +675,7 @@ def extract_license(vendor_dir, sdist):
raise NotImplementedError("new sdist type!") raise NotImplementedError("new sdist type!")
if not found: if not found:
log("License not found in {}, will download".format(sdist.name)) log(f"License not found in {sdist.name}, will download")
license_fallback(vendor_dir, sdist.name) license_fallback(vendor_dir, sdist.name)
@@ -690,7 +689,7 @@ def find_and_extract_license(vendor_dir, tar, members):
if "LICENSE" in name or "COPYING" in name: if "LICENSE" in name or "COPYING" in name:
if "/test" in name: if "/test" in name:
# some testing licenses in hml5lib and distlib # some testing licenses in hml5lib and distlib
log("Ignoring {}".format(name)) log(f"Ignoring {name}")
continue continue
found = True found = True
extract_license_member(vendor_dir, tar, member, name) extract_license_member(vendor_dir, tar, member, name)
@@ -701,13 +700,13 @@ def license_fallback(vendor_dir, sdist_name):
"""Hardcoded license URLs. Check when updating if those are still needed""" """Hardcoded license URLs. Check when updating if those are still needed"""
libname = libname_from_dir(sdist_name) libname = libname_from_dir(sdist_name)
if libname not in HARDCODED_LICENSE_URLS: if libname not in HARDCODED_LICENSE_URLS:
raise ValueError("No hardcoded URL for {} license".format(libname)) raise ValueError(f"No hardcoded URL for {libname} license")
url = HARDCODED_LICENSE_URLS[libname] url = HARDCODED_LICENSE_URLS[libname]
_, _, name = url.rpartition("/") _, _, name = url.rpartition("/")
dest = license_destination(vendor_dir, libname, name) dest = license_destination(vendor_dir, libname, name)
r = requests.get(url, allow_redirects=True) r = requests.get(url, allow_redirects=True)
log("Downloading {}".format(url)) log(f"Downloading {url}")
r.raise_for_status() r.raise_for_status()
dest.write_bytes(r.content) dest.write_bytes(r.content)
@@ -738,7 +737,7 @@ def license_destination(vendor_dir, libname, filename):
override = vendor_dir / LIBRARY_DIRNAMES[libname] override = vendor_dir / LIBRARY_DIRNAMES[libname]
if not override.exists() and override.parent.exists(): if not override.exists() and override.parent.exists():
# for flattened subdeps, specifically backports/weakref.py # for flattened subdeps, specifically backports/weakref.py
return (vendor_dir / override.parent) / "{0}.{1}".format( return (vendor_dir / override.parent) / "{}.{}".format(
override.name, filename override.name, filename
) )
license_path = Path(LIBRARY_DIRNAMES[libname]) / filename license_path = Path(LIBRARY_DIRNAMES[libname]) / filename
@@ -746,7 +745,7 @@ def license_destination(vendor_dir, libname, filename):
return vendor_dir / LICENSE_RENAMES[license_path.as_posix()] return vendor_dir / LICENSE_RENAMES[license_path.as_posix()]
return vendor_dir / LIBRARY_DIRNAMES[libname] / filename return vendor_dir / LIBRARY_DIRNAMES[libname] / filename
# fallback to libname.LICENSE (used for nondirs) # fallback to libname.LICENSE (used for nondirs)
return vendor_dir / "{}.{}".format(libname, filename) return vendor_dir / f"{libname}.{filename}"
def extract_license_member(vendor_dir, tar, member, name): def extract_license_member(vendor_dir, tar, member, name):
@@ -754,7 +753,7 @@ def extract_license_member(vendor_dir, tar, member, name):
dirname = list(mpath.parents)[-2].name # -1 is . dirname = list(mpath.parents)[-2].name # -1 is .
libname = libname_from_dir(dirname) libname = libname_from_dir(dirname)
dest = license_destination(vendor_dir, libname, mpath.name) dest = license_destination(vendor_dir, libname, mpath.name)
log("Extracting {} into {}".format(name, dest)) log(f"Extracting {name} into {dest}")
try: try:
fileobj = tar.extractfile(member) fileobj = tar.extractfile(member)
dest.write_bytes(fileobj.read()) dest.write_bytes(fileobj.read())
@@ -770,9 +769,9 @@ def generate_patch(ctx, package_path, patch_description, base="HEAD"):
"example usage: generate-patch patched/piptools some-description" "example usage: generate-patch patched/piptools some-description"
) )
if patch_description: if patch_description:
patch_fn = "{0}-{1}.patch".format(pkg.parts[1], patch_description) patch_fn = f"{pkg.parts[1]}-{patch_description}.patch"
else: else:
patch_fn = "{0}.patch".format(pkg.parts[1]) patch_fn = f"{pkg.parts[1]}.patch"
command = "git diff {base} -p {root} > {out}".format( command = "git diff {base} -p {root} > {out}".format(
base=base, base=base,
root=Path("pipenv").joinpath(pkg), root=Path("pipenv").joinpath(pkg),
@@ -826,13 +825,13 @@ def unpin_and_copy_requirements(ctx, requirement_file, name="requirements.txt"):
"PIPENV_PYTHON": "3.6", "PIPENV_PYTHON": "3.6",
} }
with ctx.cd(tempdir.name): with ctx.cd(tempdir.name):
ctx.run("pipenv install -r {0}".format(target.as_posix()), env=env, hide=True) ctx.run(f"pipenv install -r {target.as_posix()}", env=env, hide=True)
result = ctx.run("pipenv lock -r", env=env, hide=True).stdout.strip() result = ctx.run("pipenv lock -r", env=env, hide=True).stdout.strip()
ctx.run("pipenv --rm", env=env, hide=True) ctx.run("pipenv --rm", env=env, hide=True)
result = list(sorted([line.strip() for line in result.splitlines()[1:]])) result = list(sorted(line.strip() for line in result.splitlines()[1:]))
new_requirements = requirement_file.parent.joinpath(name) new_requirements = requirement_file.parent.joinpath(name)
requirement_file.rename( requirement_file.rename(
requirement_file.parent.joinpath("{}.bak".format(name)) requirement_file.parent.joinpath(f"{name}.bak")
) )
new_requirements.write_text("\n".join(result)) new_requirements.write_text("\n".join(result))
return result return result
@@ -886,8 +885,8 @@ def install_yaml(ctx):
@invoke.task @invoke.task
def vendor_artifact(ctx, package, version=None): def vendor_artifact(ctx, package, version=None):
simple = requests.get("https://pypi.org/simple/{0}/".format(package)) simple = requests.get(f"https://pypi.org/simple/{package}/")
pkg_str = "{0}-{1}".format(package, version) pkg_str = f"{package}-{version}"
soup = bs4.BeautifulSoup(simple.content) soup = bs4.BeautifulSoup(simple.content)
links = [ links = [
a.attrs["href"] for a in soup.find_all("a") if a.getText().startswith(pkg_str) a.attrs["href"] for a in soup.find_all("a") if a.getText().startswith(pkg_str)
@@ -898,6 +897,6 @@ def vendor_artifact(ctx, package, version=None):
dest_dir.mkdir() dest_dir.mkdir()
_, _, dest_path = urllib3_parse(link).path.rpartition("/") _, _, dest_path = urllib3_parse(link).path.rpartition("/")
dest_file = dest_dir / dest_path dest_file = dest_dir / dest_path
with io.open(dest_file.as_posix(), "wb") as target_handle: with open(dest_file.as_posix(), "wb") as target_handle:
with open_file(link) as fp: with open_file(link) as fp:
shutil.copyfileobj(fp, target_handle) shutil.copyfileobj(fp, target_handle)
+1 -2
View File
@@ -1,5 +1,4 @@
"""Allow safety to be executable through `python -m safety`.""" """Allow safety to be executable through `python -m safety`."""
from __future__ import absolute_import
import os import os
import sys import sys
@@ -38,7 +37,7 @@ def insert_before_site_packages(*paths):
if __name__ == "__main__": if __name__ == "__main__":
insert_before_site_packages(LIBPATH) insert_before_site_packages(LIBPATH)
yaml_lib = 'yaml{0}'.format(sys.version_info[0]) yaml_lib = f'yaml{sys.version_info[0]}'
locals()[yaml_lib] = __import__(yaml_lib) locals()[yaml_lib] = __import__(yaml_lib)
sys.modules['yaml'] = sys.modules[yaml_lib] sys.modules['yaml'] = sys.modules[yaml_lib]
from safety.cli import cli from safety.cli import cli
+1 -1
View File
@@ -26,4 +26,4 @@ importlib-resources==1.4.0
zipp==1.2.0 zipp==1.2.0
contextlib2==0.6.0.post1 contextlib2==0.6.0.post1
enum34==1.1.10 enum34==1.1.10
scandir==1.10.0 scandir==1.10.0
+1 -2
View File
@@ -53,6 +53,5 @@ install_requires =
universal = 1 universal = 1
[egg_info] [egg_info]
tag_build = tag_build =
tag_date = 0 tag_date = 0
+1 -1
View File
@@ -23,7 +23,7 @@ with open(os.path.join(ROOT, 'src', PACKAGE_NAME.replace("-", "_"), '__init__.py
VERSION = ast.literal_eval(line[len('__version__ = '):].strip()) VERSION = ast.literal_eval(line[len('__version__ = '):].strip())
break break
if VERSION is None: if VERSION is None:
raise EnvironmentError('failed to read version') raise OSError('failed to read version')
# Put everything in setup.cfg, except those that don't actually work? # Put everything in setup.cfg, except those that don't actually work?
-1
View File
@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# Configuration file for the Sphinx documentation builder. # Configuration file for the Sphinx documentation builder.
# #
+1 -1
View File
@@ -16,7 +16,7 @@ with open(os.path.join(ROOT, 'src', PACKAGE_NAME.replace("-", "_"), '__init__.py
VERSION = ast.literal_eval(line[len('__version__ = '):].strip()) VERSION = ast.literal_eval(line[len('__version__ = '):].strip())
break break
if VERSION is None: if VERSION is None:
raise EnvironmentError('failed to read version') raise OSError('failed to read version')
# Put everything in setup.cfg, except those that don't actually work? # Put everything in setup.cfg, except those that don't actually work?
+2 -2
View File
@@ -152,14 +152,14 @@ def build_docs(ctx):
minor = [str(i) for i in _current_version.release[:2]] minor = [str(i) for i in _current_version.release[:2]]
docs_folder = (ROOT / 'docs').as_posix() docs_folder = (ROOT / 'docs').as_posix()
if not docs_folder.endswith('/'): if not docs_folder.endswith('/'):
docs_folder = '{0}/'.format(docs_folder) docs_folder = f'{docs_folder}/'
args = ["--ext-autodoc", "--ext-viewcode", "-o", docs_folder] args = ["--ext-autodoc", "--ext-viewcode", "-o", docs_folder]
args.extend(["-A", "'Dan Ryan <dan@danryan.co>'"]) args.extend(["-A", "'Dan Ryan <dan@danryan.co>'"])
args.extend(["-R", str(_current_version)]) args.extend(["-R", str(_current_version)])
args.extend(["-V", ".".join(minor)]) args.extend(["-V", ".".join(minor)])
args.extend(["-e", "-M", "-F", f"src/{PACKAGE_NAME}"]) args.extend(["-e", "-M", "-F", f"src/{PACKAGE_NAME}"])
print("Building docs...") print("Building docs...")
ctx.run("sphinx-apidoc {0}".format(" ".join(args))) ctx.run("sphinx-apidoc {}".format(" ".join(args)))
@invoke.task @invoke.task
+2 -2
View File
@@ -45,7 +45,7 @@ dev =
[options] [options]
zip_safe = true zip_safe = true
python_requires = >=2.6,!=3.0,!=3.1,!=3.2,!=3.3 python_requires = >=2.6,!=3.0,!=3.1,!=3.2,!=3.3
setup_requires = setup_requires =
setuptools_scm>=3.3.1 setuptools_scm>=3.3.1
install_requires = install_requires =
attrs attrs
@@ -55,7 +55,7 @@ install_requires =
universal = 1 universal = 1
[egg_info] [egg_info]
tag_build = tag_build =
tag_date = 0 tag_date = 0
+1 -1
View File
@@ -16,7 +16,7 @@ with open(os.path.join(ROOT, 'src', PACKAGE_NAME.replace("-", "_"), '__init__.py
VERSION = ast.literal_eval(line[len('__version__ = '):].strip()) VERSION = ast.literal_eval(line[len('__version__ = '):].strip())
break break
if VERSION is None: if VERSION is None:
raise EnvironmentError('failed to read version') raise OSError('failed to read version')
# Put everything in setup.cfg, except those that don't actually work? # Put everything in setup.cfg, except those that don't actually work?
+16 -19
View File
@@ -1,6 +1,3 @@
# -*- coding=utf-8 -*-
from __future__ import absolute_import, print_function
import errno import errno
import json import json
import logging import logging
@@ -49,11 +46,11 @@ def check_internet():
try_internet(url) try_internet(url)
except KeyboardInterrupt: except KeyboardInterrupt:
warnings.warn( warnings.warn(
"Skipped connecting to internet: {0}".format(url), RuntimeWarning f"Skipped connecting to internet: {url}", RuntimeWarning
) )
except Exception: except Exception:
warnings.warn( warnings.warn(
"Failed connecting to internet: {0}".format(url), RuntimeWarning f"Failed connecting to internet: {url}", RuntimeWarning
) )
else: else:
has_internet = True has_internet = True
@@ -223,7 +220,7 @@ WE_HAVE_INTERNET = check_internet()
WE_HAVE_GITHUB_SSH_KEYS = False WE_HAVE_GITHUB_SSH_KEYS = False
class _Pipfile(object): class _Pipfile:
def __init__(self, path): def __init__(self, path):
self.path = path self.path = path
if self.path.exists(): if self.path.exists():
@@ -234,7 +231,7 @@ class _Pipfile(object):
self.document["requires"] = self.document.get("requires", tomlkit.table()) self.document["requires"] = self.document.get("requires", tomlkit.table())
self.document["packages"] = self.document.get("packages", tomlkit.table()) self.document["packages"] = self.document.get("packages", tomlkit.table())
self.document["dev_packages"] = self.document.get("dev_packages", tomlkit.table()) self.document["dev_packages"] = self.document.get("dev_packages", tomlkit.table())
super(_Pipfile, self).__init__() super().__init__()
def install(self, package, value, dev=False): def install(self, package, value, dev=False):
section = "packages" if not dev else "dev_packages" section = "packages" if not dev else "dev_packages"
@@ -292,15 +289,15 @@ class _Pipfile(object):
fixture_pypi = os.getenv("ARTIFACT_PYPI_URL") fixture_pypi = os.getenv("ARTIFACT_PYPI_URL")
if fixture_pypi: if fixture_pypi:
if pkg and not filename: if pkg and not filename:
url = "{0}/artifacts/{1}".format(fixture_pypi, pkg) url = f"{fixture_pypi}/artifacts/{pkg}"
else: else:
url = "{0}/artifacts/{1}/{2}".format(fixture_pypi, pkg, filename) url = f"{fixture_pypi}/artifacts/{pkg}/{filename}"
return url return url
if pkg and not filename: if pkg and not filename:
return cls.get_fixture_path(file_path).as_uri() return cls.get_fixture_path(file_path).as_uri()
class _PipenvInstance(object): class _PipenvInstance:
"""An instance of a Pipenv Project...""" """An instance of a Pipenv Project..."""
def __init__( def __init__(
self, pypi=None, pipfile=True, chdir=False, path=None, home_dir=None, self, pypi=None, pipfile=True, chdir=False, path=None, home_dir=None,
@@ -351,7 +348,7 @@ class _PipenvInstance(object):
self.chdir = chdir self.chdir = chdir
if self.pypi and "PIPENV_PYPI_URL" not in os.environ: if self.pypi and "PIPENV_PYPI_URL" not in os.environ:
os.environ['PIPENV_PYPI_URL'] = fs_str('{0}'.format(self.pypi)) os.environ['PIPENV_PYPI_URL'] = fs_str(f'{self.pypi}')
# os.environ['PIPENV_PYPI_URL'] = fs_str('{0}'.format(self.pypi.url)) # os.environ['PIPENV_PYPI_URL'] = fs_str('{0}'.format(self.pypi.url))
# os.environ['PIPENV_TEST_INDEX'] = fs_str('{0}/simple'.format(self.pypi.url)) # os.environ['PIPENV_TEST_INDEX'] = fs_str('{0}/simple'.format(self.pypi.url))
@@ -389,7 +386,7 @@ class _PipenvInstance(object):
with TemporaryDirectory(prefix='pipenv-', suffix='-cache') as tempdir: with TemporaryDirectory(prefix='pipenv-', suffix='-cache') as tempdir:
os.environ['PIPENV_CACHE_DIR'] = fs_str(tempdir.name) os.environ['PIPENV_CACHE_DIR'] = fs_str(tempdir.name)
c = delegator.run( c = delegator.run(
'pipenv {0}'.format(cmd), block=block, f'pipenv {cmd}', block=block,
cwd=os.path.abspath(self.path), env=os.environ.copy() cwd=os.path.abspath(self.path), env=os.environ.copy()
) )
if 'PIPENV_CACHE_DIR' in os.environ: if 'PIPENV_CACHE_DIR' in os.environ:
@@ -400,7 +397,7 @@ class _PipenvInstance(object):
# Pretty output for failing tests. # Pretty output for failing tests.
if block: if block:
print('$ pipenv {0}'.format(cmd)) print(f'$ pipenv {cmd}')
print(c.out) print(c.out)
print(c.err, file=sys.stderr) print(c.err, file=sys.stderr)
if c.return_code != 0: if c.return_code != 0:
@@ -412,13 +409,13 @@ class _PipenvInstance(object):
@property @property
def pipfile(self): def pipfile(self):
p_path = os.sep.join([self.path, 'Pipfile']) p_path = os.sep.join([self.path, 'Pipfile'])
with open(p_path, 'r') as f: with open(p_path) as f:
return toml.loads(f.read()) return toml.loads(f.read())
@property @property
def lockfile(self): def lockfile(self):
p_path = self.lockfile_path p_path = self.lockfile_path
with open(p_path, 'r') as f: with open(p_path) as f:
return json.loads(f.read()) return json.loads(f.read())
@property @property
@@ -433,7 +430,7 @@ def _rmtree_func(path, ignore_errors=True, onerror=None):
onerror = handle_remove_readonly onerror = handle_remove_readonly
try: try:
shutil_rmtree(directory, ignore_errors=ignore_errors, onerror=onerror) shutil_rmtree(directory, ignore_errors=ignore_errors, onerror=onerror)
except (IOError, OSError, FileNotFoundError, PermissionError) as exc: except (OSError, FileNotFoundError, PermissionError) as exc:
# Ignore removal failures where the file doesn't exist # Ignore removal failures where the file doesn't exist
if exc.errno != errno.ENOENT: if exc.errno != errno.ENOENT:
raise raise
@@ -459,7 +456,7 @@ def PipenvInstance(pip_src_dir, monkeypatch, pypi):
m.setenv("PIPENV_NOSPIN", fs_str("1")) m.setenv("PIPENV_NOSPIN", fs_str("1"))
m.setenv("CI", fs_str("1")) m.setenv("CI", fs_str("1"))
m.setenv('PIPENV_DONT_USE_PYENV', fs_str('1')) m.setenv('PIPENV_DONT_USE_PYENV', fs_str('1'))
m.setenv("PIPENV_TEST_INDEX", "{0}/simple".format(pypi.url)) m.setenv("PIPENV_TEST_INDEX", f"{pypi.url}/simple")
m.setenv("PIPENV_PYPI_INDEX", "simple") m.setenv("PIPENV_PYPI_INDEX", "simple")
m.setenv("ARTIFACT_PYPI_URL", pypi.url) m.setenv("ARTIFACT_PYPI_URL", pypi.url)
m.setenv("PIPENV_PYPI_URL", pypi.url) m.setenv("PIPENV_PYPI_URL", pypi.url)
@@ -479,7 +476,7 @@ def PipenvInstance_NoPyPI(monkeypatch, pip_src_dir, pypi):
m.setenv("PIPENV_NOSPIN", fs_str("1")) m.setenv("PIPENV_NOSPIN", fs_str("1"))
m.setenv("CI", fs_str("1")) m.setenv("CI", fs_str("1"))
m.setenv('PIPENV_DONT_USE_PYENV', fs_str('1')) m.setenv('PIPENV_DONT_USE_PYENV', fs_str('1'))
m.setenv("PIPENV_TEST_INDEX", "{0}/simple".format(pypi.url)) m.setenv("PIPENV_TEST_INDEX", f"{pypi.url}/simple")
m.setenv("ARTIFACT_PYPI_URL", pypi.url) m.setenv("ARTIFACT_PYPI_URL", pypi.url)
warnings.simplefilter("ignore", category=ResourceWarning) warnings.simplefilter("ignore", category=ResourceWarning)
warnings.filterwarnings("ignore", category=ResourceWarning, message="unclosed.*<ssl.SSLSocket.*>") warnings.filterwarnings("ignore", category=ResourceWarning, message="unclosed.*<ssl.SSLSocket.*>")
@@ -494,7 +491,7 @@ def testsroot():
return TESTS_ROOT return TESTS_ROOT
class VirtualEnv(object): class VirtualEnv:
def __init__(self, name="venv", base_dir=None): def __init__(self, name="venv", base_dir=None):
if base_dir is None: if base_dir is None:
base_dir = Path(_create_tracked_dir()) base_dir = Path(_create_tracked_dir())
+10 -12
View File
@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function
"""Tests to ensure `pipenv --option` works. """Tests to ensure `pipenv --option` works.
""" """
@@ -120,22 +118,22 @@ def test_pipenv_graph_reverse(PipenvInstance):
] ]
for dep_name, dep_constraint in requests_dependency: for dep_name, dep_constraint in requests_dependency:
pat = r'^[ -]*{}==[\d.]+'.format(dep_name) pat = fr'^[ -]*{dep_name}==[\d.]+'
dep_match = re.search(pat, output, flags=re.MULTILINE) dep_match = re.search(pat, output, flags=re.MULTILINE)
assert dep_match is not None, '{} not found in {}'.format(pat, output) assert dep_match is not None, f'{pat} not found in {output}'
# openpyxl should be indented # openpyxl should be indented
if dep_name == 'openpyxl': if dep_name == 'openpyxl':
openpyxl_dep = re.search(r'^openpyxl', output, flags=re.MULTILINE) openpyxl_dep = re.search(r'^openpyxl', output, flags=re.MULTILINE)
assert openpyxl_dep is None, 'openpyxl should not appear at begining of lines in {}'.format(output) assert openpyxl_dep is None, f'openpyxl should not appear at begining of lines in {output}'
assert ' - openpyxl==2.5.4 [requires: et-xmlfile]' in output assert ' - openpyxl==2.5.4 [requires: et-xmlfile]' in output
else: else:
dep_match = re.search(r'^[ -]*{}==[\d.]+$'.format(dep_name), output, flags=re.MULTILINE) dep_match = re.search(fr'^[ -]*{dep_name}==[\d.]+$', output, flags=re.MULTILINE)
assert dep_match is not None, '{} not found at beginning of line in {}'.format(dep_name, output) assert dep_match is not None, f'{dep_name} not found at beginning of line in {output}'
dep_requests_match = re.search(r'^ +- tablib==0.13.0 \[requires: {}\]$'.format(dep_constraint), output, flags=re.MULTILINE) dep_requests_match = re.search(fr'^ +- tablib==0.13.0 \[requires: {dep_constraint}\]$', output, flags=re.MULTILINE)
assert dep_requests_match is not None, 'constraint {} not found in {}'.format(dep_constraint, output) assert dep_requests_match is not None, f'constraint {dep_constraint} not found in {output}'
assert dep_requests_match.start() > dep_match.start() assert dep_requests_match.start() > dep_match.start()
@@ -164,11 +162,11 @@ def test_pipenv_clean_pip_no_warnings(PipenvInstance):
f.write('from setuptools import setup; setup(name="empty")') f.write('from setuptools import setup; setup(name="empty")')
c = p.pipenv('install -e .') c = p.pipenv('install -e .')
assert c.return_code == 0 assert c.return_code == 0
c = p.pipenv('run pip install -i {} pytz'.format(p.index_url)) c = p.pipenv(f'run pip install -i {p.index_url} pytz')
assert c.return_code == 0 assert c.return_code == 0
c = p.pipenv('clean') c = p.pipenv('clean')
assert c.return_code == 0 assert c.return_code == 0
assert c.out, "{0} -- STDERR: {1}".format(c.out, c.err) assert c.out, f"{c.out} -- STDERR: {c.err}"
@pytest.mark.cli @pytest.mark.cli
@@ -178,7 +176,7 @@ def test_pipenv_clean_pip_warnings(PipenvInstance):
f.write('from setuptools import setup; setup(name="empty")') f.write('from setuptools import setup; setup(name="empty")')
# create a fake git repo to trigger a pip freeze warning # create a fake git repo to trigger a pip freeze warning
os.mkdir('.git') os.mkdir('.git')
c = p.pipenv("run pip install -i {} -e .".format(p.index_url)) c = p.pipenv(f"run pip install -i {p.index_url} -e .")
assert c.return_code == 0 assert c.return_code == 0
c = p.pipenv('clean') c = p.pipenv('clean')
assert c.return_code == 0 assert c.return_code == 0
+5 -7
View File
@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function
import os import os
import pytest import pytest
@@ -55,7 +53,7 @@ def test_mirror_install(PipenvInstance):
assert "pypi.org" not in mirror_url assert "pypi.org" not in mirror_url
# This should sufficiently demonstrate the mirror functionality # This should sufficiently demonstrate the mirror functionality
# since pypi.org is the default when PIPENV_TEST_INDEX is unset. # since pypi.org is the default when PIPENV_TEST_INDEX is unset.
c = p.pipenv("install requests --pypi-mirror {0}".format(mirror_url)) c = p.pipenv(f"install requests --pypi-mirror {mirror_url}")
assert c.return_code == 0 assert c.return_code == 0
# Ensure the --pypi-mirror parameter hasn't altered the Pipfile or Pipfile.lock sources # Ensure the --pypi-mirror parameter hasn't altered the Pipfile or Pipfile.lock sources
assert len(p.pipfile["source"]) == 1 assert len(p.pipfile["source"]) == 1
@@ -91,8 +89,8 @@ def test_complex_lock(PipenvInstance):
c = p.pipenv("install apscheduler") c = p.pipenv("install apscheduler")
assert c.return_code == 0 assert c.return_code == 0
assert "apscheduler" in p.pipfile["packages"] assert "apscheduler" in p.pipfile["packages"]
assert "funcsigs" in p.lockfile[u"default"] assert "funcsigs" in p.lockfile["default"]
assert "futures" in p.lockfile[u"default"] assert "futures" in p.lockfile["default"]
@flaky @flaky
@@ -286,7 +284,7 @@ def test_requirements_to_pipfile(PipenvInstance, pypi):
# Write a requirements file # Write a requirements file
with open("requirements.txt", "w") as f: with open("requirements.txt", "w") as f:
f.write("-i {}\nrequests[socks]==2.19.1\n".format(pypi.url)) f.write(f"-i {pypi.url}\nrequests[socks]==2.19.1\n")
c = p.pipenv("install") c = p.pipenv("install")
assert c.return_code == 0 assert c.return_code == 0
@@ -430,7 +428,7 @@ def test_system_and_deploy_work(PipenvInstance):
c = p.pipenv("--rm") c = p.pipenv("--rm")
assert c.return_code == 0 assert c.return_code == 0
Path(p.pipfile_path).write_text( Path(p.pipfile_path).write_text(
u""" """
[packages] [packages]
tablib = "*" tablib = "*"
""".strip() """.strip()
@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function
import os import os
import sys import sys
+9 -11
View File
@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function
import os import os
import shutil import shutil
import sys import sys
@@ -54,8 +52,8 @@ testpipenv = {path = ".", editable = true, extras = ["dev"]}
assert "six" in p.lockfile["default"] assert "six" in p.lockfile["default"]
c = p.pipenv("uninstall --all") c = p.pipenv("uninstall --all")
assert c.return_code == 0 assert c.return_code == 0
print("Current directory: {0}".format(os.getcwd()), file=sys.stderr) print(f"Current directory: {os.getcwd()}", file=sys.stderr)
c = p.pipenv("install {0}".format(line)) c = p.pipenv(f"install {line}")
assert c.return_code == 0 assert c.return_code == 0
assert "testpipenv" in p.pipfile["packages"] assert "testpipenv" in p.pipfile["packages"]
assert p.pipfile["packages"]["testpipenv"]["path"] == "." assert p.pipfile["packages"]["testpipenv"]["path"] == "."
@@ -67,7 +65,7 @@ testpipenv = {path = ".", editable = true, extras = ["dev"]}
@pytest.mark.install @pytest.mark.install
@pytest.mark.needs_internet @pytest.mark.needs_internet
@flaky @flaky
class TestDirectDependencies(object): class TestDirectDependencies:
"""Ensure dependency_links are parsed and installed. """Ensure dependency_links are parsed and installed.
This is needed for private repo dependencies. This is needed for private repo dependencies.
@@ -126,7 +124,7 @@ setup(
def test_e_dot(PipenvInstance, pip_src_dir): def test_e_dot(PipenvInstance, pip_src_dir):
with PipenvInstance() as p: with PipenvInstance() as p:
path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
c = p.pipenv("install -e '{0}' --dev".format(path)) c = p.pipenv(f"install -e '{path}' --dev")
assert c.return_code == 0 assert c.return_code == 0
@@ -239,7 +237,7 @@ def test_local_package(PipenvInstance, pip_src_dir, testsroot):
with tarfile.open(copy_to, "r:gz") as tgz: with tarfile.open(copy_to, "r:gz") as tgz:
tgz.extractall(path=p.path) tgz.extractall(path=p.path)
c = p.pipenv("install -e {0}".format(package)) c = p.pipenv(f"install -e {package}")
assert c.return_code == 0 assert c.return_code == 0
assert all( assert all(
pkg in p.lockfile["default"] pkg in p.lockfile["default"]
@@ -259,7 +257,7 @@ def test_local_zipfiles(PipenvInstance, testsroot):
# This tests for a bug when installing a zipfile in the current dir # This tests for a bug when installing a zipfile in the current dir
shutil.copy(source_path, os.path.join(p.path, file_name)) shutil.copy(source_path, os.path.join(p.path, file_name))
c = p.pipenv("install {}".format(file_name)) c = p.pipenv(f"install {file_name}")
assert c.return_code == 0 assert c.return_code == 0
key = [k for k in p.pipfile["packages"].keys()][0] key = [k for k in p.pipfile["packages"].keys()][0]
dep = p.pipfile["packages"][key] dep = p.pipfile["packages"][key]
@@ -286,7 +284,7 @@ def test_relative_paths(PipenvInstance, testsroot):
mkdir_p(artifact_path) mkdir_p(artifact_path)
shutil.copy(source_path, os.path.join(artifact_path, file_name)) shutil.copy(source_path, os.path.join(artifact_path, file_name))
# Test installing a relative path in a subdirectory # Test installing a relative path in a subdirectory
c = p.pipenv("install {}/{}".format(artifact_dir, file_name)) c = p.pipenv(f"install {artifact_dir}/{file_name}")
assert c.return_code == 0 assert c.return_code == 0
key = next(k for k in p.pipfile["packages"].keys()) key = next(k for k in p.pipfile["packages"].keys())
dep = p.pipfile["packages"][key] dep = p.pipfile["packages"][key]
@@ -306,7 +304,7 @@ def test_install_local_file_collision(PipenvInstance):
fake_file = os.path.join(p.path, target_package) fake_file = os.path.join(p.path, target_package)
with open(fake_file, "w") as f: with open(fake_file, "w") as f:
f.write("") f.write("")
c = p.pipenv("install {}".format(target_package)) c = p.pipenv(f"install {target_package}")
assert c.return_code == 0 assert c.return_code == 0
assert target_package in p.pipfile["packages"] assert target_package in p.pipfile["packages"]
assert p.pipfile["packages"][target_package] == "*" assert p.pipfile["packages"][target_package] == "*"
@@ -359,7 +357,7 @@ def test_multiple_editable_packages_should_not_race(PipenvInstance, testsroot):
with PipenvInstance(chdir=True) as p: with PipenvInstance(chdir=True) as p:
for pkg_name in pkgs: for pkg_name in pkgs:
source_path = p._pipfile.get_fixture_path("git/{0}/".format(pkg_name)).as_posix() source_path = p._pipfile.get_fixture_path(f"git/{pkg_name}/").as_posix()
shutil.copytree(source_path, pkg_name) shutil.copytree(source_path, pkg_name)
pipfile_string += '"{0}" = {{path = "./{0}", editable = true}}\n'.format(pkg_name) pipfile_string += '"{0}" = {{path = "./{0}", editable = true}}\n'.format(pkg_name)
+7 -9
View File
@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
import json import json
import os import os
import sys import sys
@@ -389,13 +387,13 @@ six = {version = "*", index = "testpypi"}
fake-package = "*" fake-package = "*"
""".strip() """.strip()
f.write(contents) f.write(contents)
c = p.pipenv('install --pypi-mirror {0}'.format(mirror_url)) c = p.pipenv(f'install --pypi-mirror {mirror_url}')
assert c.return_code == 0 assert c.return_code == 0
c = p.pipenv('lock -r --pypi-mirror {0}'.format(mirror_url)) c = p.pipenv(f'lock -r --pypi-mirror {mirror_url}')
assert c.return_code == 0 assert c.return_code == 0
assert '-i {0}'.format(mirror_url) in c.out.strip() assert f'-i {mirror_url}' in c.out.strip()
assert '--extra-index-url https://test.pypi.org/simple' in c.out.strip() assert '--extra-index-url https://test.pypi.org/simple' in c.out.strip()
assert '--extra-index-url {}'.format(mirror_url) not in c.out.strip() assert f'--extra-index-url {mirror_url}' not in c.out.strip()
@pytest.mark.lock @pytest.mark.lock
@@ -650,7 +648,7 @@ requests = "*"
@pytest.mark.install @pytest.mark.install
def test_lock_no_warnings(PipenvInstance): def test_lock_no_warnings(PipenvInstance):
with PipenvInstance(chdir=True) as p: with PipenvInstance(chdir=True) as p:
os.environ["PYTHONWARNINGS"] = str("once") os.environ["PYTHONWARNINGS"] = "once"
c = p.pipenv("install six") c = p.pipenv("install six")
assert c.return_code == 0 assert c.return_code == 0
c = p.pipenv('run python -c "import warnings; warnings.warn(\\"This is a warning\\", DeprecationWarning); print(\\"hello\\")"') c = p.pipenv('run python -c "import warnings; warnings.warn(\\"This is a warning\\", DeprecationWarning); print(\\"hello\\")"')
@@ -675,7 +673,7 @@ def test_lock_missing_cache_entries_gets_all_hashes(PipenvInstance, tmpdir):
p._pipfile.add("pathlib2", "*") p._pipfile.add("pathlib2", "*")
assert "pathlib2" in p.pipfile["packages"] assert "pathlib2" in p.pipfile["packages"]
c = p.pipenv("install") c = p.pipenv("install")
assert c.return_code == 0, (c.err, ("\n".join(["{0}: {1}\n".format(k, v) for k, v in os.environ.items()]))) assert c.return_code == 0, (c.err, ("\n".join([f"{k}: {v}\n" for k, v in os.environ.items()])))
c = p.pipenv("lock --clear") c = p.pipenv("lock --clear")
assert c.return_code == 0, c.err assert c.return_code == 0, c.err
assert "pathlib2" in p.lockfile["default"] assert "pathlib2" in p.lockfile["default"]
@@ -692,7 +690,7 @@ def test_vcs_lock_respects_top_level_pins(PipenvInstance):
with PipenvInstance(chdir=True) as p: with PipenvInstance(chdir=True) as p:
requests_uri = p._pipfile.get_fixture_path("git/requests").as_uri() requests_uri = p._pipfile.get_fixture_path("git/requests").as_uri()
p._pipfile.add("requests", { p._pipfile.add("requests", {
"editable": True, "git": "{0}".format(requests_uri), "editable": True, "git": f"{requests_uri}",
"ref": "v2.18.4" "ref": "v2.18.4"
}) })
p._pipfile.add("urllib3", "==1.21.1") p._pipfile.add("urllib3", "==1.21.1")
+1 -3
View File
@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function
"""Misc. tests that don't fit anywhere. """Misc. tests that don't fit anywhere.
XXX: Try our best to reduce tests in this file. XXX: Try our best to reduce tests in this file.
@@ -65,7 +63,7 @@ def test_update_locks(PipenvInstance):
c = p.pipenv('install jdcal==1.3') c = p.pipenv('install jdcal==1.3')
assert c.return_code == 0 assert c.return_code == 0
assert p.lockfile['default']['jdcal']['version'] == '==1.3' assert p.lockfile['default']['jdcal']['version'] == '==1.3'
with open(p.pipfile_path, 'r') as fh: with open(p.pipfile_path) as fh:
pipfile_contents = fh.read() pipfile_contents = fh.read()
assert '==1.3' in pipfile_contents assert '==1.3' in pipfile_contents
pipfile_contents = pipfile_contents.replace('==1.3', '*') pipfile_contents = pipfile_contents.replace('==1.3', '*')
+10 -13
View File
@@ -1,5 +1,3 @@
# -*- coding=utf-8 -*-
from __future__ import absolute_import, print_function
import io import io
import os import os
import tarfile import tarfile
@@ -84,7 +82,7 @@ six = {{version = "*", index = "pypi"}}
@pytest.mark.install @pytest.mark.install
@pytest.mark.project @pytest.mark.project
@pytest.mark.parametrize('newlines', [u'\n', u'\r\n']) @pytest.mark.parametrize('newlines', ['\n', '\r\n'])
def test_maintain_file_line_endings(PipenvInstance, newlines): def test_maintain_file_line_endings(PipenvInstance, newlines):
with PipenvInstance(chdir=True) as p: with PipenvInstance(chdir=True) as p:
# Initial pipfile + lockfile generation # Initial pipfile + lockfile generation
@@ -93,15 +91,15 @@ def test_maintain_file_line_endings(PipenvInstance, newlines):
# Rewrite each file with parameterized newlines # Rewrite each file with parameterized newlines
for fn in [p.pipfile_path, p.lockfile_path]: for fn in [p.pipfile_path, p.lockfile_path]:
with io.open(fn) as f: with open(fn) as f:
contents = f.read() contents = f.read()
written_newlines = f.newlines written_newlines = f.newlines
assert written_newlines == u'\n', '{0!r} != {1!r} for {2}'.format( assert written_newlines == '\n', '{!r} != {!r} for {}'.format(
written_newlines, u'\n', fn, written_newlines, '\n', fn,
) )
# message because of https://github.com/pytest-dev/pytest/issues/3443 # message because of https://github.com/pytest-dev/pytest/issues/3443
with io.open(fn, 'w', newline=newlines) as f: with open(fn, 'w', newline=newlines) as f:
f.write(contents) f.write(contents)
# Run pipenv install to programatically rewrite # Run pipenv install to programatically rewrite
@@ -110,10 +108,10 @@ def test_maintain_file_line_endings(PipenvInstance, newlines):
# Make sure we kept the right newlines # Make sure we kept the right newlines
for fn in [p.pipfile_path, p.lockfile_path]: for fn in [p.pipfile_path, p.lockfile_path]:
with io.open(fn) as f: with open(fn) as f:
f.read() # Consumes the content to detect newlines. f.read() # Consumes the content to detect newlines.
actual_newlines = f.newlines actual_newlines = f.newlines
assert actual_newlines == newlines, '{0!r} != {1!r} for {2}'.format( assert actual_newlines == newlines, '{!r} != {!r} for {}'.format(
actual_newlines, newlines, fn, actual_newlines, newlines, fn,
) )
# message because of https://github.com/pytest-dev/pytest/issues/3443 # message because of https://github.com/pytest-dev/pytest/issues/3443
@@ -161,7 +159,7 @@ def test_include_editable_packages(PipenvInstance, testsroot, pathlib_tmpdir):
with PipenvInstance(chdir=True) as p: with PipenvInstance(chdir=True) as p:
with tarfile.open(source_path, "r:gz") as tarinfo: with tarfile.open(source_path, "r:gz") as tarinfo:
tarinfo.extractall(path=str(pathlib_tmpdir)) tarinfo.extractall(path=str(pathlib_tmpdir))
c = p.pipenv('install -e {0}'.format(package.as_posix())) c = p.pipenv(f'install -e {package.as_posix()}')
assert c.return_code == 0 assert c.return_code == 0
project = Project() project = Project()
assert "tablib" in [ assert "tablib" in [
@@ -185,14 +183,14 @@ def test_run_in_virtualenv_with_global_context(PipenvInstance, virtualenv):
project.virtualenv_location, virtualenv.as_posix() project.virtualenv_location, virtualenv.as_posix()
) )
c = delegator_run( c = delegator_run(
"pipenv run pip install -i {} click".format(p.index_url), f"pipenv run pip install -i {p.index_url} click",
cwd=os.path.abspath(p.path), cwd=os.path.abspath(p.path),
env=os.environ.copy() env=os.environ.copy()
) )
assert c.return_code == 0, (c.out, c.err) assert c.return_code == 0, (c.out, c.err)
assert "Courtesy Notice" in c.err, (c.out, c.err) assert "Courtesy Notice" in c.err, (c.out, c.err)
c = delegator_run( c = delegator_run(
"pipenv install -i {} six".format(p.index_url), f"pipenv install -i {p.index_url} six",
cwd=os.path.abspath(p.path), env=os.environ.copy() cwd=os.path.abspath(p.path), env=os.environ.copy()
) )
assert c.return_code == 0, (c.out, c.err) assert c.return_code == 0, (c.out, c.err)
@@ -243,4 +241,3 @@ pytest = "*"
f.write(contents) f.write(contents)
c = p.pipenv('install --skip-lock') c = p.pipenv('install --skip-lock')
assert c.return_code == 0 assert c.return_code == 0
-2
View File
@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function
import os import os
import pytest import pytest
+3 -5
View File
@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function
import json import json
import os import os
@@ -38,9 +36,9 @@ verify_ssl = true
[packages] [packages]
six = "*" six = "*"
""".strip()) """.strip())
c = p.pipenv('lock --pypi-mirror {0}'.format(mirror_url)) c = p.pipenv(f'lock --pypi-mirror {mirror_url}')
assert c.return_code == 0 assert c.return_code == 0
c = p.pipenv('sync --pypi-mirror {0}'.format(mirror_url)) c = p.pipenv(f'sync --pypi-mirror {mirror_url}')
assert c.return_code == 0 assert c.return_code == 0
@@ -112,4 +110,4 @@ requests = "*"
c = p.pipenv('sync --sequential --verbose') c = p.pipenv('sync --sequential --verbose')
for package in p.lockfile['default']: for package in p.lockfile['default']:
assert 'Successfully installed {}'.format(package) in c.out assert f'Successfully installed {package}' in c.out
+3 -5
View File
@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function
import os import os
import shutil import shutil
@@ -63,7 +61,7 @@ def test_mirror_uninstall(PipenvInstance):
) )
assert "pypi.org" not in mirror_url assert "pypi.org" not in mirror_url
c = p.pipenv("install Django==1.11.13 --pypi-mirror {0}".format(mirror_url)) c = p.pipenv(f"install Django==1.11.13 --pypi-mirror {mirror_url}")
assert c.return_code == 0 assert c.return_code == 0
assert "django" in p.pipfile["packages"] assert "django" in p.pipfile["packages"]
assert "django" in p.lockfile["default"] assert "django" in p.lockfile["default"]
@@ -77,7 +75,7 @@ def test_mirror_uninstall(PipenvInstance):
c = p.pipenv("run python -m django --version") c = p.pipenv("run python -m django --version")
assert c.return_code == 0 assert c.return_code == 0
c = p.pipenv("uninstall Django --pypi-mirror {0}".format(mirror_url)) c = p.pipenv(f"uninstall Django --pypi-mirror {mirror_url}")
assert c.return_code == 0 assert c.return_code == 0
assert "django" not in p.pipfile["dev-packages"] assert "django" not in p.pipfile["dev-packages"]
assert "django" not in p.lockfile["develop"] assert "django" not in p.lockfile["develop"]
@@ -103,7 +101,7 @@ def test_uninstall_all_local_files(PipenvInstance, testsroot):
with PipenvInstance(chdir=True) as p: with PipenvInstance(chdir=True) as p:
shutil.copy(source_path, os.path.join(p.path, file_name)) shutil.copy(source_path, os.path.join(p.path, file_name))
os.mkdir(os.path.join(p.path, "tablib")) os.mkdir(os.path.join(p.path, "tablib"))
c = p.pipenv("install {}".format(file_name)) c = p.pipenv(f"install {file_name}")
assert c.return_code == 0 assert c.return_code == 0
c = p.pipenv("uninstall --all") c = p.pipenv("uninstall --all")
assert c.return_code == 0 assert c.return_code == 0
+3 -5
View File
@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function
import os import os
import pytest import pytest
@@ -50,7 +48,7 @@ def test_local_path_windows(PipenvInstance):
except OSError: except OSError:
whl = whl.absolute() whl = whl.absolute()
with PipenvInstance(chdir=True) as p: with PipenvInstance(chdir=True) as p:
c = p.pipenv('install "{0}"'.format(whl)) c = p.pipenv(f'install "{whl}"')
assert c.return_code == 0 assert c.return_code == 0
@@ -66,7 +64,7 @@ def test_local_path_windows_forward_slash(PipenvInstance):
except OSError: except OSError:
whl = whl.absolute() whl = whl.absolute()
with PipenvInstance(chdir=True) as p: with PipenvInstance(chdir=True) as p:
c = p.pipenv('install "{0}"'.format(whl.as_posix())) c = p.pipenv(f'install "{whl.as_posix()}"')
assert c.return_code == 0 assert c.return_code == 0
@@ -75,7 +73,7 @@ def test_pipenv_clean_windows(PipenvInstance):
with PipenvInstance(chdir=True) as p: with PipenvInstance(chdir=True) as p:
c = p.pipenv('install requests') c = p.pipenv('install requests')
assert c.return_code == 0 assert c.return_code == 0
c = p.pipenv('run pip install -i {} click'.format(p.index_url)) c = p.pipenv(f'run pip install -i {p.index_url} click')
assert c.return_code == 0 assert c.return_code == 0
c = p.pipenv('clean --dry-run') c = p.pipenv('clean --dry-run')
+1 -1
View File
@@ -1,3 +1,3 @@
[build-system] [build-system]
requires = ["setuptools", "wheel"] requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta:__legacy__" build-backend = "setuptools.build_meta:__legacy__"
+11 -13
View File
@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function
import collections import collections
import contextlib import contextlib
import io import io
@@ -42,11 +40,11 @@ def get_pypi_package_names():
return pypi_packages return pypi_packages
class Package(object): class Package:
"""Package represents a collection of releases from one or more directories""" """Package represents a collection of releases from one or more directories"""
def __init__(self, name): def __init__(self, name):
super(Package, self).__init__() super().__init__()
self.name = name self.name = name
self.releases = {} self.releases = {}
self._package_dirs = set() self._package_dirs = set()
@@ -58,7 +56,7 @@ class Package(object):
with open(os.path.join(path, 'api.json')) as f: with open(os.path.join(path, 'api.json')) as f:
return json.load(f) return json.load(f)
except FileNotFoundError: except FileNotFoundError:
r = session.get('https://pypi.org/pypi/{0}/json'.format(self.name)) r = session.get(f'https://pypi.org/pypi/{self.name}/json')
response = r.json() response = r.json()
releases = response["releases"] releases = response["releases"]
files = { files = {
@@ -75,12 +73,12 @@ class Package(object):
else: else:
del releases[release] del releases[release]
response["releases"] = releases response["releases"] = releases
with io.open(os.path.join(path, "api.json"), "w") as fh: with open(os.path.join(path, "api.json"), "w") as fh:
json.dump(response, fh, indent=4) json.dump(response, fh, indent=4)
return response return response
def __repr__(self): def __repr__(self):
return "<Package name={0!r} releases={1!r}".format(self.name, len(self.releases)) return f"<Package name={self.name!r} releases={len(self.releases)!r}"
def add_release(self, path_to_binary): def add_release(self, path_to_binary):
path_to_binary = os.path.abspath(path_to_binary) path_to_binary = os.path.abspath(path_to_binary)
@@ -100,17 +98,17 @@ class Package(object):
self._package_dirs.add(ReleaseTuple(path, requires_python, hash_value)) self._package_dirs.add(ReleaseTuple(path, requires_python, hash_value))
class Artifact(object): class Artifact:
"""Represents an artifact for download""" """Represents an artifact for download"""
def __init__(self, name): def __init__(self, name):
super(Artifact, self).__init__() super().__init__()
self.name = name self.name = name
self.files = {} self.files = {}
self._artifact_dirs = set() self._artifact_dirs = set()
def __repr__(self): def __repr__(self):
return "<Artifact name={0!r} files={1!r}".format(self.name, len(self.files)) return f"<Artifact name={self.name!r} files={len(self.files)!r}"
def add_file(self, path): def add_file(self, path):
path = os.path.abspath(path) path = os.path.abspath(path)
@@ -122,7 +120,7 @@ class Artifact(object):
def prepare_fixtures(path): def prepare_fixtures(path):
path = os.path.abspath(path) path = os.path.abspath(path)
if not (os.path.exists(path) and os.path.isdir(path)): if not (os.path.exists(path) and os.path.isdir(path)):
raise ValueError("{} is not a directory!".format(path)) raise ValueError(f"{path} is not a directory!")
for root, dirs, files in os.walk(path): for root, dirs, files in os.walk(path):
package_name, _, _ = os.path.relpath(root, start=path).partition(os.path.sep) package_name, _, _ = os.path.relpath(root, start=path).partition(os.path.sep)
if package_name not in ARTIFACTS: if package_name not in ARTIFACTS:
@@ -144,7 +142,7 @@ def prepare_packages(path):
"""Add packages in path to the registry.""" """Add packages in path to the registry."""
path = os.path.abspath(path) path = os.path.abspath(path)
if not (os.path.exists(path) and os.path.isdir(path)): if not (os.path.exists(path) and os.path.isdir(path)):
raise ValueError("{} is not a directory!".format(path)) raise ValueError(f"{path} is not a directory!")
for root, dirs, files in os.walk(path): for root, dirs, files in os.walk(path):
if all([setup_file in list(files) for setup_file in ("setup.py", "setup.cfg")]): if all([setup_file in list(files) for setup_file in ("setup.py", "setup.cfg")]):
continue continue
@@ -185,7 +183,7 @@ def simple_package(package):
return render_template('package.html', package=packages[package]) return render_template('package.html', package=packages[package])
else: else:
try: try:
r = requests.get("https://pypi.org/simple/{0}".format(package)) r = requests.get(f"https://pypi.org/simple/{package}")
r.raise_for_status() r.raise_for_status()
except Exception: except Exception:
abort(404) abort(404)
-1
View File
@@ -1,4 +1,3 @@
from __future__ import absolute_import
import pytest import pytest
from .app import app as pypi_app from .app import app as pypi_app
from . import serve, certs from . import serve, certs
+3 -3
View File
@@ -77,7 +77,7 @@ class SecureWSGIServer(WSGIServer):
# Thanks, WSGIRequestHandler!! # Thanks, WSGIRequestHandler!!
class Server(object): class Server:
""" """
HTTP server running a WSGI application in its own thread. HTTP server running a WSGI application in its own thread.
""" """
@@ -119,7 +119,7 @@ class Server(object):
@property @property
def url(self): def url(self):
return '{0}://{1}:{2}'.format(self.protocol, self.host, self.port) return f'{self.protocol}://{self.host}:{self.port}'
def join(self, url, allow_fragments=True): def join(self, url, allow_fragments=True):
return urljoin(self.url, url, allow_fragments=allow_fragments) return urljoin(self.url, url, allow_fragments=allow_fragments)
@@ -130,5 +130,5 @@ class SecureServer(Server):
def __init__(self, host='127.0.0.1', port=0, application=None, **kwargs): def __init__(self, host='127.0.0.1', port=0, application=None, **kwargs):
kwargs['server_class'] = SecureWSGIServer kwargs['server_class'] = SecureWSGIServer
super(SecureServer, self).__init__(host, port, application, **kwargs) super().__init__(host, port, application, **kwargs)
self.protocol = 'https' self.protocol = 'https'
@@ -10,4 +10,4 @@
<br> <br>
{% endfor %} {% endfor %}
</body> </body>
</html> </html>
+3 -3
View File
@@ -24,7 +24,7 @@ class UploadCommand(Command):
@staticmethod @staticmethod
def status(s): def status(s):
"""Prints things in bold.""" """Prints things in bold."""
print('\033[1m{0}\033[0m'.format(s)) print(f'\033[1m{s}\033[0m')
def initialize_options(self): def initialize_options(self):
pass pass
@@ -40,13 +40,13 @@ class UploadCommand(Command):
pass pass
self.status('Building Source and Wheel (universal) distribution...') self.status('Building Source and Wheel (universal) distribution...')
os.system('{0} setup.py sdist bdist_wheel --universal'.format(sys.executable)) os.system(f'{sys.executable} setup.py sdist bdist_wheel --universal')
self.status('Uploading the package to PyPI via Twine...') self.status('Uploading the package to PyPI via Twine...')
os.system('twine upload dist/*') os.system('twine upload dist/*')
self.status('Pushing git tags...') self.status('Pushing git tags...')
os.system('git tag v{0}'.format(__version__)) os.system(f'git tag v{__version__}')
os.system('git push --tags') os.system('git push --tags')
sys.exit() sys.exit()
+3 -3
View File
@@ -1,6 +1,6 @@
import os import os
import mock from unittest import mock
import pytest import pytest
from pipenv._compat import TemporaryDirectory from pipenv._compat import TemporaryDirectory
@@ -29,7 +29,7 @@ def test_load_dot_env_from_environment_variable_location(monkeypatch, capsys):
dotenv_path = os.path.join(tempdir.name, 'test.env') dotenv_path = os.path.join(tempdir.name, 'test.env')
key, val = 'SOME_KEY', 'some_value' key, val = 'SOME_KEY', 'some_value'
with open(dotenv_path, 'w') as f: with open(dotenv_path, 'w') as f:
f.write('{}={}'.format(key, val)) f.write(f'{key}={val}')
m.setenv("PIPENV_DOTENV_LOCATION", str(dotenv_path)) m.setenv("PIPENV_DOTENV_LOCATION", str(dotenv_path))
m.setattr("pipenv.environments.PIPENV_DOTENV_LOCATION", str(dotenv_path)) m.setattr("pipenv.environments.PIPENV_DOTENV_LOCATION", str(dotenv_path))
@@ -47,7 +47,7 @@ def test_doesnt_load_dot_env_if_disabled(monkeypatch, capsys):
dotenv_path = os.path.join(tempdir.name, 'test.env') dotenv_path = os.path.join(tempdir.name, 'test.env')
key, val = 'SOME_KEY', 'some_value' key, val = 'SOME_KEY', 'some_value'
with open(dotenv_path, 'w') as f: with open(dotenv_path, 'w') as f:
f.write('{}={}'.format(key, val)) f.write(f'{key}={val}')
m.setenv("PIPENV_DOTENV_LOCATION", str(dotenv_path)) m.setenv("PIPENV_DOTENV_LOCATION", str(dotenv_path))
m.setattr("pipenv.environments.PIPENV_DOTENV_LOCATION", str(dotenv_path)) m.setattr("pipenv.environments.PIPENV_DOTENV_LOCATION", str(dotenv_path))
+3 -3
View File
@@ -11,12 +11,12 @@ from pipenv.utils import temp_environ
list(itertools.product(("ENABLE_SOMETHING",), ("FAKEPREFIX", None), (True, False))), list(itertools.product(("ENABLE_SOMETHING",), ("FAKEPREFIX", None), (True, False))),
) )
def test_get_from_env(arg, prefix, use_negation): def test_get_from_env(arg, prefix, use_negation):
negated_arg = "NO_{0}".format(arg) negated_arg = f"NO_{arg}"
positive_var = arg positive_var = arg
negative_var = negated_arg negative_var = negated_arg
if prefix: if prefix:
negative_var = "{0}_{1}".format(prefix, negative_var) negative_var = f"{prefix}_{negative_var}"
positive_var = "{0}_{1}".format(prefix, positive_var) positive_var = f"{prefix}_{positive_var}"
# set the positive first # set the positive first
for var_to_set, opposite_var in ((arg, negated_arg), (negated_arg, arg)): for var_to_set, opposite_var in ((arg, negated_arg), (negated_arg, arg)):
os.environ.pop(var_to_set, None) os.environ.pop(var_to_set, None)
-2
View File
@@ -1,5 +1,3 @@
from __future__ import absolute_import
import pytest import pytest
from notpip._internal.index.package_finder import PackageFinder from notpip._internal.index.package_finder import PackageFinder
+2 -3
View File
@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import os import os
import pytest import pytest
@@ -130,10 +129,10 @@ def test_convert_deps_to_pip_one_way(deps, expected):
assert pipenv.utils.convert_deps_to_pip(deps, r=False) == [expected.lower()] 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") @pytest.mark.skipif(isinstance("", str), reason="don't need to test if unicode is str")
@pytest.mark.utils @pytest.mark.utils
def test_convert_deps_to_pip_unicode(): def test_convert_deps_to_pip_unicode():
deps = {u"django": u"==1.10"} deps = {"django": "==1.10"}
deps = pipenv.utils.convert_deps_to_pip(deps, r=False) deps = pipenv.utils.convert_deps_to_pip(deps, r=False)
assert deps[0] == "django==1.10" assert deps[0] == "django==1.10"
+1 -2
View File
@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# We need to import the patched packages directly from sys.path, so the # We need to import the patched packages directly from sys.path, so the
# identity checks can pass. # identity checks can pass.
import pipenv # noqa import pipenv # noqa
@@ -82,6 +81,6 @@ def test_token_date(dt, content):
def test_dump_nonascii_string(): def test_dump_nonascii_string():
content = u'name = "Stažené"\n' content = 'name = "Stažené"\n'
toml_content = tomlkit.dumps(tomlkit.loads(content)) toml_content = tomlkit.dumps(tomlkit.loads(content))
assert toml_content == content assert toml_content == content