From ca5d931f1f9898551c6685fa5c4061d5411d59ee Mon Sep 17 00:00:00 2001 From: Frost Ming Date: Wed, 28 Jul 2021 10:59:00 +0800 Subject: [PATCH] Update to py36 plus syntax --- .deepsource.toml | 2 +- .github/PULL_REQUEST_TEMPLATE.md | 2 +- NOTICES | 4 +- README.md | 6 +- docs/Makefile | 2 +- docs/_static/konami.js | 4 +- docs/conf.py | 15 +- peeps/PEEP-003.md | 2 +- peeps/PEEP-044.md | 18 +- pipenv/__init__.py | 1 - pipenv/_compat.py | 41 +- pipenv/cli/__init__.py | 3 - pipenv/cli/command.py | 25 +- pipenv/cli/options.py | 19 +- pipenv/cmdparse.py | 4 +- pipenv/core.py | 380 +++++++++--------- pipenv/environment.py | 74 ++-- pipenv/environments.py | 14 +- pipenv/exceptions.py | 98 +++-- pipenv/help.py | 27 +- pipenv/installers.py | 20 +- pipenv/pep508checker.py | 1 - pipenv/progress.py | 6 +- pipenv/project.py | 12 +- pipenv/resolver.py | 48 +-- pipenv/shells.py | 26 +- pipenv/utils.py | 143 ++++--- setup.cfg | 11 +- setup.py | 15 +- tasks/__init__.py | 1 - tasks/release.py | 15 +- tasks/vendoring/__init__.py | 113 +++--- tasks/vendoring/safety/__main__.py | 3 +- tasks/vendoring/safety/requirements.txt | 2 +- .../fixtures/cython-import-package/setup.cfg | 3 +- tests/fixtures/cython-import-package/setup.py | 2 +- tests/fixtures/fake-package/docs/conf.py | 1 - tests/fixtures/fake-package/setup.py | 2 +- tests/fixtures/fake-package/tasks/__init__.py | 4 +- .../fixtures/legacy-backend-package/setup.cfg | 4 +- .../fixtures/legacy-backend-package/setup.py | 2 +- tests/integration/conftest.py | 35 +- tests/integration/test_cli.py | 22 +- tests/integration/test_install_basic.py | 12 +- tests/integration/test_install_markers.py | 2 - tests/integration/test_install_twists.py | 20 +- tests/integration/test_lock.py | 16 +- tests/integration/test_pipenv.py | 4 +- tests/integration/test_project.py | 23 +- tests/integration/test_run.py | 2 - tests/integration/test_sync.py | 8 +- tests/integration/test_uninstall.py | 8 +- tests/integration/test_windows.py | 8 +- tests/pytest-pypi/pyproject.toml | 2 +- tests/pytest-pypi/pytest_pypi/app.py | 24 +- tests/pytest-pypi/pytest_pypi/plugin.py | 1 - tests/pytest-pypi/pytest_pypi/serve.py | 6 +- .../pytest_pypi/templates/simple.html | 2 +- tests/pytest-pypi/setup.py | 6 +- tests/unit/test_core.py | 6 +- tests/unit/test_environments.py | 6 +- tests/unit/test_patched.py | 2 - tests/unit/test_utils.py | 5 +- tests/unit/test_vendor.py | 3 +- 64 files changed, 649 insertions(+), 749 deletions(-) diff --git a/.deepsource.toml b/.deepsource.toml index 1cd8dcda..902f3dc2 100644 --- a/.deepsource.toml +++ b/.deepsource.toml @@ -13,4 +13,4 @@ name = "python" enabled = true [analyzers.meta] - runtime_version = "3.x.x" + runtime_version = "3.x.x" diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index c80b5eef..325d14db 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -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. -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 diff --git a/NOTICES b/NOTICES index e237e5b6..8ba4ddc1 100644 --- a/NOTICES +++ b/NOTICES @@ -1,5 +1,5 @@ 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. diff --git a/README.md b/README.md index 2e9c9a73..f0584423 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ Or, if you\'re using Fedora: Or, if you\'re using FreeBSD: # pkg install py36-pipenv - + Or, if you\'re using Windows: # pip install --user pipenv @@ -195,8 +195,8 @@ Fish is the best shell. You should use it. lock Generates Pipfile.lock. open View a given module in your editor. run Spawns a command installed into the virtualenv. - scripts Displays the shortcuts in the (optional) [scripts] section of - Pipfile. + scripts Displays the shortcuts in the (optional) [scripts] section of + Pipfile. shell Spawns a shell within the virtualenv. sync Installs all packages specified in Pipfile.lock. uninstall Un-installs a provided package and removes it from Pipfile. diff --git a/docs/Makefile b/docs/Makefile index 6b4a9de9..2d91525a 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -17,4 +17,4 @@ help: # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/_static/konami.js b/docs/_static/konami.js index e0028445..41672442 100644 --- a/docs/_static/konami.js +++ b/docs/_static/konami.js @@ -84,9 +84,9 @@ var Konami = function (callback) { }, touchendHandler: function () { 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) { var match = true; for (var i = 0; i < konami.iphone.keys.length; i++) { diff --git a/docs/conf.py b/docs/conf.py index 4031c337..96c43ad1 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # # pipenv documentation build configuration file, created by # sphinx-quickstart on Mon Jan 30 13:28:36 2017. @@ -56,9 +55,9 @@ source_suffix = '.rst' master_doc = 'index' # General information about the project. -project = u'pipenv' -copyright = u'2020. A project founded by Kenneth Reitz' -author = u'Python Packaging Authority' +project = 'pipenv' +copyright = '2020. A project founded by Kenneth Reitz' +author = 'Python Packaging Authority' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -157,8 +156,8 @@ latex_elements = { # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, 'pipenv.tex', u'pipenv Documentation', - u'Kenneth Reitz', 'manual'), + (master_doc, 'pipenv.tex', 'pipenv Documentation', + 'Kenneth Reitz', 'manual'), ] @@ -167,7 +166,7 @@ latex_documents = [ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - (master_doc, 'pipenv', u'pipenv Documentation', + (master_doc, 'pipenv', 'pipenv Documentation', [author], 1) ] @@ -178,7 +177,7 @@ man_pages = [ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - (master_doc, 'pipenv', u'pipenv Documentation', + (master_doc, 'pipenv', 'pipenv Documentation', author, 'pipenv', 'One line description of project.', 'Miscellaneous'), ] diff --git a/peeps/PEEP-003.md b/peeps/PEEP-003.md index d0493eaa..7744e728 100644 --- a/peeps/PEEP-003.md +++ b/peeps/PEEP-003.md @@ -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. -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. diff --git a/peeps/PEEP-044.md b/peeps/PEEP-044.md index 5b04ab55..38d60dd3 100644 --- a/peeps/PEEP-044.md +++ b/peeps/PEEP-044.md @@ -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 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 -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. 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 -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 ---squelch switch to make the output only come from safety check. +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 +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. ## Current implementation: ### Example 1 @@ -36,9 +36,9 @@ parse error: Invalid numeric literal at line 1, column 9 ## Future implementation: ### Example 1 ``` 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", "<0.2.0", "0.1.0", diff --git a/pipenv/__init__.py b/pipenv/__init__.py index 624397c5..a3c188a7 100644 --- a/pipenv/__init__.py +++ b/pipenv/__init__.py @@ -1,4 +1,3 @@ -# -*- coding=utf-8 -*- # |~~\' |~~ # |__/||~~\|--|/~\\ / # | ||__/|__| |\/ diff --git a/pipenv/_compat.py b/pipenv/_compat.py index 04040c74..b97feb20 100644 --- a/pipenv/_compat.py +++ b/pipenv/_compat.py @@ -1,4 +1,3 @@ -# -*- coding=utf-8 -*- """A compatibility module for pipenv's backports and manipulations. Exposes a standard API that enables compatibility across python versions, @@ -7,26 +6,18 @@ operating systems, etc. import sys import warnings -import six import vistir from .vendor.vistir.compat import ( 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) __all__ = [ "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" ] @@ -35,12 +26,7 @@ def getpreferredencoding(): import locale # Borrowed from Invoke # (see https://github.com/pyinvoke/invoke/blob/93af29d/invoke/runners.py#L881) - _encoding = 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 + return locale.getpreferredencoding(False) DEFAULT_ENCODING = getpreferredencoding() @@ -69,7 +55,7 @@ def force_encoding(): return DEFAULT_ENCODING, DEFAULT_ENCODING stdout_encoding = canonical_encoding_name(sys.stdout.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 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 = { - 8230: u"...", - 8211: u"-", - 10004: u"OK", - 10008: u"x", + 8230: "...", + 8211: "-", + 10004: "OK", + 10008: "x", } @@ -124,26 +110,21 @@ def decode_for_output(output, target=sys.stdout): def decode_output(output): - if not isinstance(output, six.string_types): + if not isinstance(output, str): return output try: output = output.encode(DEFAULT_ENCODING) except (AttributeError, UnicodeDecodeError, UnicodeEncodeError): - if six.PY2: - 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.translate(UNICODE_TO_ASCII_TRANSLATION_MAP) output = output.encode(DEFAULT_ENCODING, "replace") return vistir.misc.to_text(output, encoding=DEFAULT_ENCODING, errors="replace") def fix_utf8(text): - if not isinstance(text, six.string_types): + if not isinstance(text, str): return text try: text = decode_output(text) except UnicodeDecodeError: - if six.PY2: - text = unicode.translate(vistir.misc.to_text(text), UNICODE_TO_ASCII_TRANSLATION_MAP) # noqa + pass return text diff --git a/pipenv/cli/__init__.py b/pipenv/cli/__init__.py index 0f57e306..9d53abf8 100644 --- a/pipenv/cli/__init__.py +++ b/pipenv/cli/__init__.py @@ -1,4 +1 @@ -# -*- coding=utf-8 -*- -from __future__ import absolute_import - from .command import cli # noqa diff --git a/pipenv/cli/command.py b/pipenv/cli/command.py index 2d4d2892..8538abf6 100644 --- a/pipenv/cli/command.py +++ b/pipenv/cli/command.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import absolute_import - import os import sys @@ -81,7 +78,7 @@ def cli( shell = shells.detect_info()[0] except shells.ShellDetectionFailure: 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)), err=True, ) @@ -115,9 +112,9 @@ def cli( from .. import environments for key in environments.__dict__: if key.startswith("PIPENV"): - echo(" - {0}".format(crayons.normal(key, bold=True))) + echo(f" - {crayons.normal(key, bold=True)}") echo( - "\nYou can learn more at:\n {0}".format( + "\nYou can learn more at:\n {}".format( crayons.green( "https://pipenv.pypa.io/en/latest/advanced/#configuration-with-environment-variables" ) @@ -175,7 +172,7 @@ def cli( loc = project.virtualenv_location echo( crayons.normal( - u"{0} ({1})...".format( + "{} ({})...".format( crayons.normal("Removing virtualenv", bold=True), crayons.green(loc), ) @@ -413,7 +410,7 @@ def shell( venv_name = os.environ.get("VIRTUAL_ENV", "UNKNOWN_VIRTUAL_ENVIRONMENT") if not anyway: 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.green(venv_name, 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) @option("--bare", is_flag=True, default=False, help="Minimal output.") @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 @pass_state @pass_context @@ -564,7 +561,7 @@ def update( editable = [p for p in state.installstate.editables if p] if not packages: echo( - "{0} {1} {2} {3}{4}".format( + "{} {} {} {}{}".format( crayons.normal("Running", bold=True), crayons.yellow("$ pipenv lock", bold=True), crayons.normal("then", bold=True), @@ -576,7 +573,7 @@ def update( for package in packages + editable: if package not in project.all_packages: echo( - "{0}: {1} was not found in your Pipfile! Aborting." + "{}: {} was not found in your Pipfile! Aborting." "".format( crayons.red("Warning", bold=True), crayons.green(package, bold=True), @@ -608,7 +605,7 @@ def update( @cli.command( - short_help=u"Displays currently-installed dependency graph information.", + short_help="Displays currently-installed dependency graph information.", context_settings=CONTEXT_SETTINGS ) @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")) else: 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() edit(filename=p) return 0 diff --git a/pipenv/cli/options.py b/pipenv/cli/options.py index 7e0652a9..7cde367c 100644 --- a/pipenv/cli/options.py +++ b/pipenv/cli/options.py @@ -1,6 +1,3 @@ -# -*- coding=utf-8 -*- -from __future__ import absolute_import - import os import click.types @@ -51,7 +48,7 @@ class PipenvGroup(DYMMixin, Group): ) -class State(object): +class State: def __init__(self): self.index = None self.extra_index_urls = [] @@ -68,7 +65,7 @@ class State(object): self.lockoptions = LockOptions() -class InstallState(object): +class InstallState: def __init__(self): self.dev = False self.pre = False @@ -84,7 +81,7 @@ class InstallState(object): self.editables = [] -class LockOptions(object): +class LockOptions: def __init__(self): self.dev_only = False self.emit_requirements = False @@ -110,7 +107,7 @@ def extra_index_option(f): state.extra_index_urls.extend(list(value)) return value 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) @@ -142,7 +139,7 @@ def skip_lock_option(f): state.installstate.skip_lock = value return value 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, show_envvar=True)(f) @@ -153,7 +150,7 @@ def keep_outdated_option(f): state.installstate.keep_outdated = value return value 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) @@ -204,7 +201,7 @@ def pre_option(f): state = ctx.ensure_object(State) state.installstate.pre = 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) @@ -371,7 +368,7 @@ def deploy_option(f): state.installstate.deploy = value return value 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) diff --git a/pipenv/cmdparse.py b/pipenv/cmdparse.py index 2e550e22..a61cd71d 100644 --- a/pipenv/cmdparse.py +++ b/pipenv/cmdparse.py @@ -2,8 +2,6 @@ import itertools import re import shlex -import six - class ScriptEmptyError(ValueError): pass @@ -28,7 +26,7 @@ class Script(object): @classmethod def parse(cls, value): - if isinstance(value, six.string_types): + if isinstance(value, str): value = shlex.split(value) if not value: raise ScriptEmptyError(value) diff --git a/pipenv/core.py b/pipenv/core.py index 5e6a2217..c0618f31 100644 --- a/pipenv/core.py +++ b/pipenv/core.py @@ -1,7 +1,4 @@ -# -*- coding=utf-8 -*- -from __future__ import absolute_import, print_function - -import io +import importlib import json as simplejson import logging import os @@ -10,7 +7,6 @@ import time import warnings import click -import six import delegator import dotenv @@ -42,9 +38,9 @@ from .utils import ( if is_type_checking(): - from typing import Dict, List, Optional, Union, Text + from typing import Dict, List, Optional, Union from pipenv.vendor.requirementslib.models.requirements import Requirement - TSourceDict = Dict[Text, Union[Text, bool]] + TSourceDict = Dict[str, Union[str, bool]] # Packages that should be ignored later. @@ -96,7 +92,7 @@ def which(command, location=None, allow_global=False): if not (location and os.path.exists(location)) and not allow_global: raise RuntimeError("location not created nor specified") - version_str = "python{0}".format(".".join([str(v) for v in sys.version_info[:2]])) + version_str = "python{}".format(".".join([str(v) for v in sys.version_info[:2]])) is_python = command in ("python", os.path.basename(sys.executable), version_str) if not allow_global: if os.name == "nt": @@ -158,7 +154,7 @@ def load_dot_env(): else: if environments.PIPENV_DOTENV_LOCATION: click.echo( - "{0}: file {1}={2} does not exist!!\n{3}".format( + "{}: file {}={} does not exist!!\n{}".format( crayons.red("Warning", bold=True), crayons.normal("PIPENV_DOTENV_LOCATION", bold=True), crayons.normal(environments.PIPENV_DOTENV_LOCATION, bold=True), @@ -167,13 +163,13 @@ def load_dot_env(): err=True, ) dotenv.load_dotenv(dotenv_file, override=True) - six.moves.reload_module(environments) + importlib.reload(environments) def add_to_path(p): """Adds a given path to the PATH.""" if p not in os.environ["PATH"]: - os.environ["PATH"] = "{0}{1}{2}".format(p, os.pathsep, os.environ["PATH"]) + os.environ["PATH"] = "{}{}{}".format(p, os.pathsep, os.environ["PATH"]) def cleanup_virtualenv(bare=True): @@ -185,7 +181,7 @@ def cleanup_virtualenv(bare=True): vistir.path.rmtree(project.virtualenv_location) except OSError as e: click.echo( - "{0} An error occurred while removing {1}!".format( + "{} An error occurred while removing {}!".format( crayons.red("Error: ", bold=True), crayons.green(project.virtualenv_location), ), @@ -206,7 +202,7 @@ def import_requirements(r=None, dev=False): # Default path, if none is provided. if r is None: r = project.requirements_location - with open(r, "r") as f: + with open(r) as f: contents = f.read() indexes = [] trusted_hosts = [] @@ -222,7 +218,7 @@ def import_requirements(r=None, dev=False): if package.name not in BAD_PACKAGES: if package.link is not None: package_string = ( - "-e {0}".format(package.link) + f"-e {package.link}" if package.editable else str(package.link) ) @@ -240,8 +236,8 @@ def ensure_environment(): if os.name != "nt": if "LANG" not in os.environ: click.echo( - "{0}: the environment variable {1} is not set!" - "\nWe recommend setting this in {2} (or equivalent) for " + "{}: the environment variable {} is not set!" + "\nWe recommend setting this in {} (or equivalent) for " "proper expected behavior.".format( crayons.red("Warning", bold=True), crayons.normal("LANG", bold=True), @@ -302,7 +298,7 @@ def ensure_pipfile(validate=True, skip_requirements=False, system=False): sp.ok(environments.PIPENV_SPINNER_OK_TEXT.format("Success!")) # Warn the user of side-effects. click.echo( - u"{0}: Your {1} now contains pinned versions, if your {2} did. \n" + "{0}: Your {1} now contains pinned versions, if your {2} did. \n" "We recommend updating your {1} to specify the {3} version, instead." "".format( crayons.red("Warning", bold=True), @@ -326,7 +322,7 @@ def ensure_pipfile(validate=True, skip_requirements=False, system=False): # Write changes out to disk. if changed: click.echo( - crayons.normal(u"Fixing package names in Pipfile...", bold=True), err=True + crayons.normal("Fixing package names in Pipfile...", bold=True), err=True ) project.write_toml(p) @@ -364,10 +360,10 @@ def ensure_python(three=None, python=None): def abort(msg=''): click.echo( - "{0}\nYou can specify specific versions of Python with:\n{1}".format( + "{}\nYou can specify specific versions of Python with:\n{}".format( crayons.red(msg), crayons.yellow( - "$ pipenv --python {0}".format( + "$ pipenv --python {}".format( os.sep.join(("path", "to", "python")) ) ) @@ -387,12 +383,12 @@ def ensure_python(three=None, python=None): python = PIPENV_DEFAULT_PYTHON_VERSION path_to_python = find_a_system_python(python) if environments.is_verbose(): - click.echo(u"Using python: {0}".format(python), err=True) - click.echo(u"Path to python: {0}".format(path_to_python), err=True) + click.echo(f"Using python: {python}", err=True) + click.echo(f"Path to python: {path_to_python}", err=True) if not path_to_python and python is not None: # We need to install Python. click.echo( - u"{0}: Python {1} {2}".format( + "{}: Python {} {}".format( crayons.red("Warning", bold=True), crayons.cyan(python), fix_utf8("was not found on your system..."), @@ -426,11 +422,11 @@ def ensure_python(three=None, python=None): except ValueError: abort() except InstallerError as e: - abort('Something went wrong while installing Python:\n{}'.format(e.err)) - s = "{0} {1} {2}".format( + abort(f'Something went wrong while installing Python:\n{e.err}') + s = "{} {} {}".format( "Would you like us to install", - crayons.green("CPython {0}".format(version)), - "with {0}?".format(installer), + crayons.green(f"CPython {version}"), + f"with {installer}?", ) # Prompt the user to continue... if not (PIPENV_YES or click.confirm(s, default=True)): @@ -438,12 +434,12 @@ def ensure_python(three=None, python=None): else: # Tell the user we're installing Python. click.echo( - u"{0} {1} {2} {3}{4}".format( - crayons.normal(u"Installing", bold=True), - crayons.green(u"CPython {0}".format(version), bold=True), - crayons.normal(u"with {0}".format(installer.cmd), bold=True), - crayons.normal(u"(this may take a few minutes)"), - crayons.normal(u"...", bold=True), + "{} {} {} {}{}".format( + crayons.normal("Installing", bold=True), + crayons.green(f"CPython {version}", bold=True), + crayons.normal(f"with {installer.cmd}", bold=True), + crayons.normal("(this may take a few minutes)"), + crayons.normal("...", bold=True), ) ) with create_spinner("Installing python...") as sp: @@ -471,7 +467,7 @@ def ensure_python(three=None, python=None): assert python_version(path_to_python) == version except AssertionError: click.echo( - "{0}: The Python you just installed is not available on your {1}, apparently." + "{}: The Python you just installed is not available on your {}, apparently." "".format( crayons.red("Warning", bold=True), crayons.normal("PATH", bold=True), @@ -496,7 +492,7 @@ def ensure_virtualenv(three=None, python=None, site_packages=None, pypi_mirror=N ensure_environment() # Ensure Python is available. python = ensure_python(three=three, python=python) - if python is not None and not isinstance(python, six.string_types): + if python is not None and not isinstance(python, str): python = python.path.as_posix() # Create the virtualenv. # Abort if --system (or running in a virtualenv). @@ -520,7 +516,7 @@ def ensure_virtualenv(three=None, python=None, site_packages=None, pypi_mirror=N USING_DEFAULT_PYTHON = False # Ensure python is installed before deleting existing virtual env python = ensure_python(three=three, python=python) - if python is not None and not isinstance(python, six.string_types): + if python is not None and not isinstance(python, str): python = python.path.as_posix() click.echo(crayons.red("Virtualenv already exists!"), err=True) @@ -587,8 +583,8 @@ def ensure_project( python_version(path_to_python) or "" ): click.echo( - "{0}: Your Pipfile requires {1} {2}, " - "but you are using {3} ({4}).".format( + "{}: Your Pipfile requires {} {}, " + "but you are using {} ({}).".format( crayons.red("Warning", bold=True), crayons.normal("python_version", bold=True), crayons.cyan(project.required_python_version), @@ -598,13 +594,13 @@ def ensure_project( err=True, ) click.echo( - " {0} and rebuilding the virtual environment " + " {} and rebuilding the virtual environment " "may resolve the issue.".format(crayons.green("$ pipenv --rm")), err=True, ) if not deploy: click.echo( - " {0} will surely fail." + " {} will surely fail." "".format(crayons.yellow("$ pipenv check")), err=True, ) @@ -636,7 +632,7 @@ def do_where(virtualenv=False, bare=True): if not project.pipfile_exists: click.echo( "No Pipfile present at project home. Consider running " - "{0} first to automatically generate a Pipfile for you." + "{} first to automatically generate a Pipfile for you." "".format(crayons.green("`pipenv install`")), err=True, ) @@ -646,7 +642,7 @@ def do_where(virtualenv=False, bare=True): if not bare: location = shorten_path(location) click.echo( - "Pipfile found at {0}.\n Considering this to be the project home." + "Pipfile found at {}.\n Considering this to be the project home." "".format(crayons.green(location)), err=True, ) @@ -656,7 +652,7 @@ def do_where(virtualenv=False, bare=True): location = project.virtualenv_location if not bare: click.echo( - "Virtualenv location: {0}".format(crayons.green(location)), err=True + f"Virtualenv location: {crayons.green(location)}", err=True ) else: click.echo(location) @@ -681,7 +677,7 @@ def _cleanup_procs(procs, failed_deps_queue, retry=True): # additional passes at installation if "does not match installed location" in c.err: project.environment.expand_egg_links() - click.echo("{0}".format( + click.echo("{}".format( crayons.yellow( "Failed initial installation: Failed to overwrite existing " "package, likely due to path aliasing. Expanding and trying " @@ -706,7 +702,7 @@ def _cleanup_procs(procs, failed_deps_queue, retry=True): dep = c.dep.copy() dep.use_pep517 = False click.echo( - "{0} {1}! Will try again.".format( + "{} {}! Will try again.".format( crayons.red("An error occurred while installing"), crayons.green(dep.as_line()), ), err=True @@ -814,7 +810,7 @@ def do_install_dependencies( If emit_requirements is True, simply spits out a requirements format to stdout. """ - from six.moves import queue + import queue if emit_requirements: bare = True # Load the lockfile if it exists, or if dev_only is being used. @@ -830,7 +826,7 @@ def do_install_dependencies( if not bare: click.echo( crayons.normal( - fix_utf8("Installing dependencies from Pipfile.lock ({0})...".format( + fix_utf8("Installing dependencies from Pipfile.lock ({})...".format( lockfile["_meta"].get("hash", {}).get("sha256")[-6:] )), bold=True, @@ -925,21 +921,21 @@ def do_create_virtualenv(python=None, site_packages=None, pypi_mirror=None): crayons.normal(fix_utf8("Creating a virtualenv for this project..."), bold=True), err=True ) click.echo( - u"Pipfile: {0}".format(crayons.yellow(project.pipfile_location, bold=True)), + f"Pipfile: {crayons.yellow(project.pipfile_location, bold=True)}", err=True, ) # Default to using sys.executable, if Python wasn't provided. - using_string = u"Using" + using_string = "Using" if not python: python = sys.executable using_string = "Using default python from" click.echo( - u"{0} {1} {3} {2}".format( + "{0} {1} {3} {2}".format( crayons.normal(using_string, bold=True), crayons.yellow(python, bold=True), crayons.normal(fix_utf8("to create virtualenv..."), bold=True), - crayons.green("({0})".format(python_version(python))), + crayons.green(f"({python_version(python)})"), ), err=True, ) @@ -948,8 +944,8 @@ def do_create_virtualenv(python=None, site_packages=None, pypi_mirror=None): vistir.compat.Path(sys.executable).absolute().as_posix(), "-m", "virtualenv", - "--prompt=({0}) ".format(project.name), - "--python={0}".format(python), + f"--prompt=({project.name}) ", + f"--python={python}", project.get_location_for_virtualenv(), ] @@ -967,17 +963,17 @@ def do_create_virtualenv(python=None, site_packages=None, pypi_mirror=None): # Actually create the virtualenv. error = None - with create_spinner(u"Creating virtual environment...") as sp: + with create_spinner("Creating virtual environment...") as sp: with interrupt_handled_subprocess(cmd, combine_stderr=False, env=pip_config) as c: - click.echo(crayons.cyan(u"{0}".format(c.out)), err=True) + click.echo(crayons.cyan(f"{c.out}"), err=True) if c.returncode != 0: error = c.err if environments.is_verbose() else exceptions.prettify_exc(c.err) - sp.fail(environments.PIPENV_SPINNER_FAIL_TEXT.format(u"Failed creating virtual environment")) + sp.fail(environments.PIPENV_SPINNER_FAIL_TEXT.format("Failed creating virtual environment")) else: - sp.green.ok(environments.PIPENV_SPINNER_OK_TEXT.format(u"Successfully created virtual environment!")) + sp.green.ok(environments.PIPENV_SPINNER_OK_TEXT.format("Successfully created virtual environment!")) if error is not None: raise exceptions.VirtualenvCreationException( - extra=crayons.red("{0}".format(error)) + extra=crayons.red(f"{error}") ) # Associate project directory with the environment. @@ -1026,7 +1022,7 @@ def get_downloads_info(names_map, section): # Get the version info from the filenames. version = parse_download_fname(fname, name) # Get the hash of each file. - cmd = '{0} hash "{1}"'.format( + cmd = '{} hash "{}"'.format( escape_grouped_arguments(which_pip()), os.sep.join([project.download_location, fname]), ) @@ -1090,9 +1086,9 @@ def do_lock( if write: # Alert the user of progress. click.echo( - u"{0} {1} {2}".format( - crayons.normal(u"Locking"), - crayons.yellow(u"[{0}]".format(pipfile_section.replace("_", "-"))), + "{} {} {}".format( + crayons.normal("Locking"), + crayons.yellow("[{}]".format(pipfile_section.replace("_", "-"))), crayons.normal(fix_utf8("dependencies...")), ), err=True, @@ -1138,9 +1134,9 @@ def do_lock( if write: project.write_lockfile(lockfile) click.echo( - "{0}".format( + "{}".format( crayons.normal( - "Updated Pipfile.lock ({0})!".format( + "Updated Pipfile.lock ({})!".format( lockfile["_meta"].get("hash", {}).get("sha256")[-6:] ), bold=True, @@ -1162,10 +1158,10 @@ def do_purge(bare=False, downloads=False, allow_global=False): return # Remove comments from the output, if any. - installed = set([ + installed = { pep423_name(pkg.project_name) for pkg in project.environment.get_installed_packages() - ]) - bad_pkgs = set([pep423_name(pkg) for pkg in BAD_PACKAGES]) + } + bad_pkgs = {pep423_name(pkg) for pkg in BAD_PACKAGES} # Remove setuptools, pip, etc from targets for removal to_remove = installed - bad_pkgs @@ -1178,15 +1174,15 @@ def do_purge(bare=False, downloads=False, allow_global=False): if not bare: click.echo( - fix_utf8("Found {0} installed package(s), purging...".format(len(to_remove))) + fix_utf8(f"Found {len(to_remove)} installed package(s), purging...") ) - command = "{0} uninstall {1} -y".format( + command = "{} uninstall {} -y".format( escape_grouped_arguments(which_pip(allow_global=allow_global)), " ".join(to_remove), ) if environments.is_verbose(): - click.echo("$ {0}".format(command)) + click.echo(f"$ {command}") c = delegator.run(command) if c.return_code != 0: raise exceptions.UninstallError(installed, command, c.out + c.err, c.return_code) @@ -1243,7 +1239,7 @@ def do_init( if deploy: click.echo( crayons.red( - "Your Pipfile.lock ({0}) is out of date. Expected: ({1}).".format( + "Your Pipfile.lock ({}) is out of date. Expected: ({}).".format( old_hash[-6:], new_hash[-6:] ) ) @@ -1253,8 +1249,8 @@ def do_init( elif (system or allow_global) and not (PIPENV_VIRTUALENV): click.echo( crayons.yellow(fix_utf8( - "Pipfile.lock ({0}) out of date, but installation " - "uses {1} re-building lockfile must happen in " + "Pipfile.lock ({}) out of date, but installation " + "uses {} re-building lockfile must happen in " "isolation. Please rebuild lockfile in a virtualenv. " "Continuing anyway...".format( old_hash[-6:], "--system" @@ -1315,9 +1311,9 @@ def do_init( # Hint the user what to do to activate the virtualenv. if not allow_global and not deploy and "PIPENV_ACTIVE" not in os.environ: click.echo( - "To activate this project's virtualenv, run {0}.\n" + "To activate this project's virtualenv, run {}.\n" "Alternatively, run a command " - "inside the virtualenv with {1}.".format( + "inside the virtualenv with {}.".format( crayons.yellow("pipenv shell"), crayons.yellow("pipenv run") ) ) @@ -1325,12 +1321,12 @@ def do_init( def get_pip_args( pre=False, # type: bool - verbose=False, # type: bool, - upgrade=False, # type: bool, - require_hashes=False, # type: bool, - no_build_isolation=False, # type: bool, - no_use_pep517=False, # type: bool, - no_deps=False, # type: bool, + verbose=False, # type: bool + upgrade=False, # type: bool + require_hashes=False, # type: bool + no_build_isolation=False, # type: bool + no_use_pep517=False, # type: bool + no_deps=False, # type: bool selective_upgrade=False, # type: bool src_dir=None, # type: Optional[str] ): @@ -1346,7 +1342,7 @@ def get_pip_args( "no_deps": ["--no-deps"], "selective_upgrade": [ "--upgrade-strategy=only-if-needed", - "--exists-action={0}".format(PIP_EXISTS_ACTION or "i") + "--exists-action={}".format(PIP_EXISTS_ACTION or "i") ], "src_dir": src_dir, } @@ -1379,13 +1375,13 @@ def get_requirement_line( requirement.line_instance.vcsrepo line = requirement.line_instance.line if requirement.line_instance.markers: - line = '{0}; {1}'.format(line, requirement.line_instance.markers) + line = f'{line}; {requirement.line_instance.markers}' if not format_for_file: - line = '"{0}"'.format(line) + line = f'"{line}"' if requirement.editable: if not format_for_file: return ["-e", line] - return '-e {0}'.format(line) + return f'-e {line}' if not format_for_file: return [line] return line @@ -1412,7 +1408,7 @@ def write_requirement_to_file( ) if environments.is_verbose(): click.echo( - "Writing supplied requirement line to temporary file: {0!r}".format(line), + f"Writing supplied requirement line to temporary file: {line!r}", err=True ) f.write(vistir.misc.to_bytes(line)) @@ -1478,14 +1474,14 @@ def pip_install( pypi_mirror=pypi_mirror ) if r: - with io.open(r, "r") as fh: + with open(r, "r") as fh: if "--hash" not in fh.read(): ignore_hashes = True if environments.is_verbose(): piplogger.setLevel(logging.WARN) if requirement: click.echo( - crayons.normal("Installing {0!r}".format(requirement.name), bold=True), + crayons.normal(f"Installing {requirement.name!r}", bold=True), err=True, ) @@ -1502,7 +1498,7 @@ def pip_install( pip_command.extend(line) pip_command.extend(prepare_pip_source_args(sources)) if environments.is_verbose(): - click.echo("$ {0}".format(pip_command), err=True) + click.echo(f"$ {pip_command}", err=True) cache_dir = vistir.compat.Path(PIPENV_CACHE_DIR) DEFAULT_EXISTS_ACTION = "w" if selective_upgrade: @@ -1519,7 +1515,7 @@ def pip_install( } if src_dir: if environments.is_verbose(): - click.echo("Using source directory: {0!r}".format(src_dir), err=True) + click.echo(f"Using source directory: {src_dir!r}", err=True) pip_config.update( {"PIP_SRC": vistir.misc.fs_str(src_dir)} ) @@ -1541,7 +1537,7 @@ def pip_download(package_name): ), } for source in project.sources: - cmd = '{0} download "{1}" -i {2} -d {3}'.format( + cmd = '{} download "{}" -i {} -d {}'.format( escape_grouped_arguments(which_pip()), package_name, source["url"], @@ -1572,8 +1568,8 @@ def fallback_which(command, location=None, allow_global=False, system=False): from .vendor.pythonfinder import Finder if not command: raise ValueError("fallback_which: Must provide a command to search for...") - if not isinstance(command, six.string_types): - raise TypeError("Provided command must be a string, received {0!r}".format(command)) + if not isinstance(command, str): + raise TypeError(f"Provided command must be a string, received {command!r}") global_search = system or allow_global if location is None: global_search = True @@ -1620,7 +1616,7 @@ def system_which(command, mult=False): }) result = None try: - c = delegator.run("{0} {1}".format(_which, command)) + c = delegator.run(f"{_which} {command}") try: # Which Not found... if c.return_code == 127: @@ -1652,7 +1648,7 @@ def format_help(help): """Formats the help string.""" help = help.replace("Options:", str(crayons.normal("Options:", bold=True))) help = help.replace( - "Usage: pipenv", str("Usage: {0}".format(crayons.normal("pipenv", bold=True))) + "Usage: pipenv", str("Usage: {}".format(crayons.normal("pipenv", bold=True))) ) help = help.replace(" check", str(crayons.red(" check", bold=True))) help = help.replace(" clean", str(crayons.red(" clean", bold=True))) @@ -1669,40 +1665,38 @@ def format_help(help): additional_help = """ Usage Examples: Create a new project using Python 3.7, specifically: - $ {1} + $ {} Remove project virtualenv (inferred from current directory): - $ {9} + $ {} Install all dependencies for a project (including dev): - $ {2} + $ {} Create a lockfile containing pre-releases: - $ {6} + $ {} Show a graph of your installed dependencies: - $ {4} + $ {} Check your installed dependencies for security vulnerabilities: - $ {7} + $ {} Install a local setup.py into your virtual environment/Pipfile: - $ {5} + $ {} Use a lower-level pip command: - $ {8} + $ {} Commands:""".format( - crayons.yellow("pipenv --three"), crayons.yellow("pipenv --python 3.7"), - crayons.yellow("pipenv install --dev"), - crayons.yellow("pipenv lock"), - crayons.yellow("pipenv graph"), - crayons.yellow("pipenv install -e ."), - crayons.yellow("pipenv lock --pre"), - crayons.yellow("pipenv check"), - crayons.yellow("pipenv run pip freeze"), crayons.yellow("pipenv --rm"), + crayons.yellow("pipenv install --dev"), + crayons.yellow("pipenv lock --pre"), + crayons.yellow("pipenv graph"), + crayons.yellow("pipenv check"), + crayons.yellow("pipenv install -e ."), + crayons.yellow("pipenv run pip freeze"), ) help = help.replace("Commands:", additional_help) return help @@ -1737,7 +1731,7 @@ def format_pip_output(out, r=None): else: yield line - out = "\n".join([l for l in gen(out)]) + out = "\n".join([line for line in gen(out)]) return out @@ -1745,11 +1739,11 @@ def warn_in_virtualenv(): # Only warn if pipenv isn't already active. if environments.is_in_virtualenv() and not environments.is_quiet(): click.echo( - "{0}: Pipenv found itself running within a virtual environment, " + "{}: Pipenv found itself running within a virtual environment, " "so it will automatically use that environment, instead of " "creating its own for any project. You can set " - "{1} to force pipenv to ignore that environment and create " - "its own instead. You can set {2} to suppress this " + "{} to force pipenv to ignore that environment and create " + "its own instead. You can set {} to suppress this " "warning.".format( crayons.green("Courtesy Notice"), crayons.normal("PIPENV_IGNORE_VIRTUALENVS=1", bold=True), @@ -1770,7 +1764,7 @@ def ensure_lockfile(keep_outdated=False, pypi_mirror=None): if new_hash != old_hash: click.echo( crayons.yellow( - fix_utf8("Pipfile.lock ({0}) out of date, updating to ({1})...".format( + fix_utf8("Pipfile.lock ({}) out of date, updating to ({})...".format( old_hash[-6:], new_hash[-6:] )), bold=True, @@ -1852,15 +1846,15 @@ def do_outdated(pypi_mirror=None, pre=False, clear=False): version = get_version(project.packages[name_in_pipfile]) rdeps = reverse_deps.get(canonicalize_name(package)) if isinstance(rdeps, Mapping) and "required" in rdeps: - required = " {0} required".format(rdeps["required"]) + required = " {} required".format(rdeps["required"]) if version: - pipfile_version_text = " ({0} set in Pipfile)".format(version) + pipfile_version_text = f" ({version} set in Pipfile)" else: pipfile_version_text = " (Unpinned in Pipfile)" click.echo( crayons.yellow( - "Skipped Update of Package {0!s}: {1!s} installed,{2!s}{3!s}, " - "{4!s} available.".format( + "Skipped Update of Package {!s}: {!s} installed,{!s}{!s}, " + "{!s} available.".format( package, old_version, required, pipfile_version_text, new_version ) ), err=True @@ -1870,7 +1864,7 @@ def do_outdated(pypi_mirror=None, pre=False, clear=False): sys.exit(0) for package, new_version, old_version in outdated: click.echo( - "Package {0!r} out-of-date: {1!r} installed, {2!r} available.".format( + "Package {!r} out-of-date: {!r} installed, {!r} available.".format( package, old_version, new_version ) ) @@ -1963,12 +1957,12 @@ def do_install( # Download requirements file try: download_file(requirements_url, temp_reqs) - except IOError: + except OSError: fd.close() os.unlink(temp_reqs) click.echo( crayons.red( - u"Unable to find requirements file at {0}.".format( + "Unable to find requirements file at {}.".format( crayons.normal(requirements_url) ) ), @@ -1994,13 +1988,13 @@ def do_install( # Don't print the temp file path if remote since it will be deleted. req_path = requirements_url if remote else project.path_to(requirementstxt) error = ( - u"Unexpected syntax in {0}. Are you sure this is a " + "Unexpected syntax in {}. Are you sure this is a " "requirements.txt style file?".format(req_path) ) traceback = e except AssertionError as e: error = ( - u"Requirements file doesn't appear to exist. Please ensure the file exists in your " + "Requirements file doesn't appear to exist. Please ensure the file exists in your " "project directory or you provided the correct path." ) traceback = e @@ -2018,11 +2012,11 @@ def do_install( crayons.normal(fix_utf8("Discovering imports from local codebase..."), bold=True) ) for req in import_from_code(code): - click.echo(" Found {0}!".format(crayons.green(req))) + click.echo(f" Found {crayons.green(req)}!") project.add_package_to_pipfile(req) # Allow more than one package to be provided. package_args = [p for p in packages] + [ - "-e {0}".format(pkg) for pkg in editable_packages + f"-e {pkg}" for pkg in editable_packages ] # Support for --selective-upgrade. # We should do this part first to make sure that we actually do selectively upgrade @@ -2068,7 +2062,7 @@ def do_install( from .vendor.requirementslib.models.requirements import Requirement # make a tuple of (display_name, entry) - pkg_list = packages + ['-e {0}'.format(pkg) for pkg in editable_packages] + pkg_list = packages + [f'-e {pkg}' for pkg in editable_packages] if not system and not project.virtualenv_exists: do_init( dev=dev, @@ -2085,7 +2079,7 @@ def do_install( for pkg_line in pkg_list: click.echo( crayons.normal( - fix_utf8("Installing {0}...".format(crayons.green(pkg_line, bold=True))), + fix_utf8(f"Installing {crayons.green(pkg_line, bold=True)}..."), bold=True, ) ) @@ -2095,11 +2089,11 @@ def do_install( os.environ["PIP_USER"] = vistir.compat.fs_str("0") if "PYTHONHOME" in os.environ: del os.environ["PYTHONHOME"] - sp.text = "Resolving {0}...".format(pkg_line) + sp.text = f"Resolving {pkg_line}..." try: pkg_requirement = Requirement.from_line(pkg_line) except ValueError as e: - sp.write_err(vistir.compat.fs_str("{0}: {1}".format(crayons.red("WARNING"), e))) + sp.write_err(vistir.compat.fs_str("{}: {}".format(crayons.red("WARNING"), e))) sp.red.fail(environments.PIPENV_SPINNER_FAIL_TEXT.format("Installation Failed")) sys.exit(1) if index_url: @@ -2107,9 +2101,9 @@ def do_install( no_deps = False sp.text = "Installing..." try: - sp.text = "Installing {0}...".format(pkg_requirement.name) + sp.text = f"Installing {pkg_requirement.name}..." if environments.is_verbose(): - sp.hide_and_write("Installing package: {0}".format(pkg_requirement.as_line(include_hashes=False))) + sp.hide_and_write(f"Installing package: {pkg_requirement.as_line(include_hashes=False)}") c = pip_install( pkg_requirement, ignore_hashes=True, @@ -2124,19 +2118,19 @@ def do_install( ) if not c.ok: sp.write_err( - u"{0} An error occurred while installing {1}!".format( - crayons.red(u"Error: ", bold=True), crayons.green(pkg_line) + "{} An error occurred while installing {}!".format( + crayons.red("Error: ", bold=True), crayons.green(pkg_line) ), ) sp.write_err( - vistir.compat.fs_str(u"Error text: {0}".format(c.out)) + vistir.compat.fs_str(f"Error text: {c.out}") ) sp.write_err(crayons.cyan(vistir.compat.fs_str(format_pip_error(c.err)))) if environments.is_verbose(): sp.write_err(crayons.cyan(vistir.compat.fs_str(format_pip_output(c.out)))) if "setup.py egg_info" in c.err: sp.write_err(vistir.compat.fs_str( - "This is likely caused by a bug in {0}. " + "This is likely caused by a bug in {}. " "Report this to its maintainers.".format( crayons.green(pkg_requirement.name) ) @@ -2145,7 +2139,7 @@ def do_install( sys.exit(1) except (ValueError, RuntimeError) as e: sp.write_err(vistir.compat.fs_str( - "{0}: {1}".format(crayons.red("WARNING"), e), + "{}: {}".format(crayons.red("WARNING"), e), )) sp.red.fail(environments.PIPENV_SPINNER_FAIL_TEXT.format( "Installation Failed", @@ -2154,8 +2148,8 @@ def do_install( # Warn if --editable wasn't passed. if pkg_requirement.is_vcs and not pkg_requirement.editable and not PIPENV_RESOLVE_VCS: sp.write_err( - "{0}: You installed a VCS dependency in non-editable mode. " - "This will work fine, but sub-dependencies will not be resolved by {1}." + "{}: You installed a VCS dependency in non-editable mode. " + "This will work fine, but sub-dependencies will not be resolved by {}." "\n To enable this sub-dependency functionality, specify that this dependency is editable." "".format( crayons.red("Warning", bold=True), @@ -2163,11 +2157,11 @@ def do_install( ) ) sp.write(vistir.compat.fs_str( - u"{0} {1} {2} {3}{4}".format( - crayons.normal(u"Adding", bold=True), - crayons.green(u"{0}".format(pkg_requirement.name), bold=True), - crayons.normal(u"to Pipfile's", bold=True), - crayons.yellow(u"[dev-packages]" if dev else u"[packages]", bold=True), + "{} {} {} {}{}".format( + crayons.normal("Adding", bold=True), + crayons.green(f"{pkg_requirement.name}", bold=True), + crayons.normal("to Pipfile's", bold=True), + crayons.yellow("[dev-packages]" if dev else "[packages]", bold=True), crayons.normal(fix_utf8("..."), bold=True), ) )) @@ -2177,7 +2171,7 @@ def do_install( except ValueError: import traceback sp.write_err( - "{0} {1}".format( + "{} {}".format( crayons.red("Error:", bold=True), traceback.format_exc() ) ) @@ -2232,10 +2226,10 @@ def do_uninstall( if not any([packages, editable_packages, all_dev, all]): raise exceptions.PipenvUsageError("No package provided!", ctx=ctx) editable_pkgs = [ - Requirement.from_line("-e {0}".format(p)).name for p in editable_packages if p + Requirement.from_line(f"-e {p}").name for p in editable_packages if p ] packages += editable_pkgs - package_names = set(p for p in packages if p) + package_names = {p for p in packages if p} package_map = { canonicalize_name(p): p for p in packages if p } @@ -2252,14 +2246,14 @@ def do_uninstall( if "dev-packages" not in project.parsed_pipfile and not project_pkg_names["dev"]: click.echo( crayons.normal( - "No {0} to uninstall.".format(crayons.yellow("[dev-packages]")), + "No {} to uninstall.".format(crayons.yellow("[dev-packages]")), bold=True, ) ) return click.echo( crayons.normal( - fix_utf8("Un-installing {0}...".format(crayons.yellow("[dev-packages]"))), bold=True + fix_utf8("Un-installing {}...".format(crayons.yellow("[dev-packages]"))), bold=True ) ) package_names = set(project_pkg_names["dev"]) - set(project_pkg_names["default"]) @@ -2269,7 +2263,7 @@ def do_uninstall( ignored_packages = bad_pkgs & set(list(package_map.keys())) for ignored_pkg in ignored_packages: if environments.is_verbose(): - click.echo("Ignoring {0}.".format(ignored_pkg), err=True) + click.echo(f"Ignoring {ignored_pkg}.", err=True) package_names.discard(package_map[ignored_pkg]) used_packages = project_pkg_names["combined"] & installed_package_names @@ -2277,7 +2271,7 @@ def do_uninstall( if all: click.echo( crayons.normal( - fix_utf8("Un-installing all {0} and {1}...".format( + fix_utf8("Un-installing all {} and {}...".format( crayons.yellow("[dev-packages]"), crayons.yellow("[packages]"), )), bold=True @@ -2297,7 +2291,7 @@ def do_uninstall( for normalized, package_name in selected_pkg_map.items(): click.echo( crayons.normal( - fix_utf8("Uninstalling {0}...".format(crayons.green(package_name))), bold=True + fix_utf8(f"Uninstalling {crayons.green(package_name)}..."), bold=True ) ) # Uninstall the package. @@ -2316,7 +2310,7 @@ def do_uninstall( package_name, dev=True ) if normalized in lockfile_packages: - click.echo("{0} {1} {2} {3}".format( + click.echo("{} {} {} {}".format( crayons.cyan("Removing"), crayons.green(package_name), crayons.cyan("from"), @@ -2332,14 +2326,14 @@ def do_uninstall( if normalized in lockfile_packages: continue click.echo( - "No package {0} to remove from Pipfile.".format( + "No package {} to remove from Pipfile.".format( crayons.green(package_name) ) ) continue click.echo( - fix_utf8("Removing {0} from Pipfile...".format(crayons.green(package_name))) + fix_utf8(f"Removing {crayons.green(package_name)} from Pipfile...") ) # Remove package from both packages and dev-packages. if in_dev_packages: @@ -2405,8 +2399,8 @@ def _inline_activate_virtualenv(): # Catch all errors, just in case. except Exception: click.echo( - u"{0}: There was an unexpected error while activating your " - u"virtualenv. Continuing anyway...".format( + "{}: There was an unexpected error while activating your " + "virtualenv. Continuing anyway...".format( crayons.red("Warning", bold=True) ), err=True, @@ -2456,7 +2450,7 @@ def _launch_windows_subprocess(script): # a "command" that is non-executable. See pypa/pipenv#2727. try: return subprocess.Popen([command] + script.args, **options) - except WindowsError as e: + except OSError as e: if e.winerror != 193: raise @@ -2475,7 +2469,7 @@ def do_run_posix(script, command): if not command_path: if project.has_script(command): click.echo( - "{0}: the command {1} (from {2}) could not be found within {3}." + "{}: the command {} (from {}) could not be found within {}." "".format( crayons.red("Error", bold=True), crayons.yellow(script.command), @@ -2486,7 +2480,7 @@ def do_run_posix(script, command): ) else: click.echo( - "{0}: the command {1} could not be found within {2} or Pipfile's {3}." + "{}: the command {} could not be found within {} or Pipfile's {}." "".format( crayons.red("Error", bold=True), crayons.yellow(command), @@ -2497,7 +2491,7 @@ def do_run_posix(script, command): ) sys.exit(1) os.execl( - command_path, command_path, *[os.path.expandvars(arg) for arg in script.args] + command_path, command_path, *(os.path.expandvars(arg) for arg in script.args) ) @@ -2533,7 +2527,7 @@ def do_run(command, args, three=None, python=False, pypi_mirror=None): script = project.build_script(command, args) cmd_string = ' '.join([script.command] + script.args) if environments.is_verbose(): - click.echo(crayons.normal("$ {0}".format(cmd_string)), err=True) + click.echo(crayons.normal(f"$ {cmd_string}"), err=True) except ScriptEmptyError: click.echo("Can't run script {0!r}-it's empty?", err=True) run_args = [script] @@ -2596,7 +2590,7 @@ def do_check( ) ) for dep in deps_required: - click.echo(" - {0}".format(crayons.green(dep))) + click.echo(f" - {crayons.green(dep)}") sys.exit(1) else: sys.exit(0) @@ -2621,7 +2615,7 @@ def do_check( try: results = simplejson.loads(c.out.strip()) except JSONDecodeError: - click.echo("{0}\n{1}\n{2}".format( + click.echo("{}\n{}\n{}".format( crayons.white(decode_for_output("Failed parsing pep508 results: "), bold=True), c.out.strip(), c.err.strip() @@ -2638,7 +2632,7 @@ def do_check( except AssertionError: failed = True click.echo( - "Specifier {0} does not match {1} ({2})." + "Specifier {} does not match {} ({})." "".format( crayons.green(marker), crayons.cyan(specifier), @@ -2663,7 +2657,7 @@ def do_check( if not quiet and not environments.is_quiet(): click.echo( crayons.normal( - "Notice: Ignoring CVE(s) {0}".format(crayons.yellow(", ".join(ignore))) + "Notice: Ignoring CVE(s) {}".format(crayons.yellow(", ".join(ignore))) ), err=True, ) @@ -2674,13 +2668,13 @@ def do_check( if output == "default": switch = "json" - cmd = _cmd + [safety_path, "check", "--{0}".format(switch)] + cmd = _cmd + [safety_path, "check", f"--{switch}"] if db: if not quiet and not environments.is_quiet(): - click.echo(crayons.normal("Using local database {}".format(db))) - cmd.append("--db={0}".format(db)) + click.echo(crayons.normal(f"Using local database {db}")) + cmd.append(f"--db={db}") elif key or PIPENV_PYUP_API_KEY: - cmd = cmd + ["--key={0}".format(key or PIPENV_PYUP_API_KEY)] + cmd = cmd + [f"--key={key or PIPENV_PYUP_API_KEY}"] if ignored: for cve in ignored: cmd += cve @@ -2694,14 +2688,14 @@ def do_check( raise exceptions.PipenvCmdError(c.cmd, c.out, c.err, c.return_code) for (package, resolved, installed, description, vuln) in results: click.echo( - "{0}: {1} {2} resolved ({3} installed)!".format( + "{}: {} {} resolved ({} installed)!".format( crayons.normal(vuln, bold=True), crayons.green(package), crayons.yellow(resolved, bold=False), crayons.yellow(installed, bold=True), ) ) - click.echo("{0}".format(description)) + click.echo(f"{description}") click.echo() if c.ok: click.echo(crayons.green("All good!")) @@ -2715,16 +2709,16 @@ def do_check( def do_graph(bare=False, json=False, json_tree=False, reverse=False): from pipenv.vendor.vistir.compat import JSONDecodeError - import pipdeptree + from pipenv.vendor import pipdeptree pipdeptree_path = pipdeptree.__file__.rstrip("cdo") try: python_path = which("python") except AttributeError: click.echo( - u"{0}: {1}".format( + "{}: {}".format( crayons.red("Warning", bold=True), - u"Unable to display currently-installed dependency graph information here. " - u"Please run within a Pipenv project.", + "Unable to display currently-installed dependency graph information here. " + "Please run within a Pipenv project.", ), err=True, ) @@ -2738,30 +2732,30 @@ def do_graph(bare=False, json=False, json_tree=False, reverse=False): if reverse and json: click.echo( - u"{0}: {1}".format( + "{}: {}".format( crayons.red("Warning", bold=True), - u"Using both --reverse and --json together is not supported. " - u"Please select one of the two options.", + "Using both --reverse and --json together is not supported. " + "Please select one of the two options.", ), err=True, ) sys.exit(1) if reverse and json_tree: click.echo( - u"{0}: {1}".format( + "{}: {}".format( crayons.red("Warning", bold=True), - u"Using both --reverse and --json-tree together is not supported. " - u"Please select one of the two options.", + "Using both --reverse and --json-tree together is not supported. " + "Please select one of the two options.", ), err=True, ) sys.exit(1) if json and json_tree: click.echo( - u"{0}: {1}".format( + "{}: {}".format( crayons.red("Warning", bold=True), - u"Using both --json and --json-tree together is not supported. " - u"Please select one of the two options.", + "Using both --json and --json-tree together is not supported. " + "Please select one of the two options.", ), err=True, ) @@ -2775,9 +2769,9 @@ def do_graph(bare=False, json=False, json_tree=False, reverse=False): flag = "--reverse" if not project.virtualenv_exists: click.echo( - u"{0}: No virtualenv has been created for this project yet! Consider " - u"running {1} first to automatically generate one for you or see " - u"{2} for further instructions.".format( + "{}: No virtualenv has been created for this project yet! Consider " + "running {} first to automatically generate one for you or see " + "{} for further instructions.".format( crayons.red("Warning", bold=True), crayons.green("`pipenv install`"), crayons.green("`pipenv install --help`"), @@ -2839,9 +2833,9 @@ def do_graph(bare=False, json=False, json_tree=False, reverse=False): click.echo(c.out) if c.return_code != 0: click.echo( - "{0} {1}".format( + "{} {}".format( crayons.red("ERROR: ", bold=True), - crayons.white("{0}".format(c.err, bold=True)), + crayons.white(f"{c.err}"), ), err=True, ) @@ -2910,7 +2904,7 @@ def do_clean( for bad_package in BAD_PACKAGES: if canonicalize_name(bad_package) in installed_package_names: if environments.is_verbose(): - click.echo("Ignoring {0}.".format(bad_package), err=True) + click.echo(f"Ignoring {bad_package}.", err=True) installed_package_names.remove(canonicalize_name(bad_package)) # Intelligently detect if --dev should be used or not. locked_packages = { @@ -2928,7 +2922,7 @@ def do_clean( if not bare: click.echo( crayons.white( - fix_utf8("Uninstalling {0}...".format(apparent_bad_package)), bold=True + fix_utf8(f"Uninstalling {apparent_bad_package}..."), bold=True ) ) # Uninstall the package. diff --git a/pipenv/environment.py b/pipenv/environment.py index 1a8535a3..983354a5 100644 --- a/pipenv/environment.py +++ b/pipenv/environment.py @@ -1,9 +1,5 @@ -# -*- coding=utf-8 -*- -from __future__ import absolute_import, print_function - import contextlib import importlib -import io import json import operator import os @@ -14,7 +10,6 @@ from sysconfig import get_paths, get_python_version import itertools import pkg_resources -import six import pipenv @@ -37,7 +32,7 @@ BASE_WORKING_SET = pkg_resources.WorkingSet(sys.path) # TODO: Unittests for this class -class Environment(object): +class Environment: def __init__( self, prefix=None, # type: Optional[str] @@ -48,7 +43,7 @@ class Environment(object): sources=None, # type: Optional[List[TSource]] project=None # type: Optional[Project] ): - super(Environment, self).__init__() + super().__init__() self._modules = {'pkg_resources': pkg_resources, 'pipenv': pipenv} self.base_working_set = base_working_set if base_working_set else BASE_WORKING_SET prefix = normalize_path(prefix) @@ -89,8 +84,8 @@ class Environment(object): module = importlib.import_module(name) if name in sys.modules: try: - six.moves.reload_module(module) - six.moves.reload_module(sys.modules[name]) + importlib.reload(module) + importlib.reload(sys.modules[name]) except TypeError: del sys.modules[name] sys.modules[name] = self._modules[name] @@ -115,7 +110,7 @@ class Environment(object): try: reqs = dist.requires() # 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 for req in reqs: try: @@ -336,20 +331,20 @@ class Environment(object): sysconfig_line = "sysconfig.get_path('{0}')" if python_lib: 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' - sys_prefix = "{0}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("u'%s': u'{{0}}'.format(%s)" % (sys_prefix, sysconfig_line.format(sys_prefix))) + sys_prefix = "{}stdlib".format("" if key == "pure" else key) + pylib_lines.append(f"u'{dist_prefix}': u'{{{{0}}}}'.format({distutils_line.format(var, val)})") + pylib_lines.append(f"u'{sys_prefix}': u'{{{{0}}}}'.format({sysconfig_line.format(sys_prefix)})") if python_inc: 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 if scripts: lines.append("u'scripts': u'{{0}}'.format(%s)" % sysconfig_line.format("scripts")) if py_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 return py_command @@ -371,7 +366,7 @@ class Environment(object): ) if c.returncode == 0: 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) if "purelib" in paths: paths["libdir"] = paths["purelib"] = make_posix(paths["purelib"]) @@ -380,8 +375,8 @@ class Environment(object): paths[key] = make_posix(paths[key]) return paths else: - vistir.misc.echo("Failed to load paths: {0}".format(c.err), fg="yellow") - vistir.misc.echo("Output: {0}".format(c.out), fg="yellow") + vistir.misc.echo(f"Failed to load paths: {c.err}", fg="yellow") + vistir.misc.echo(f"Output: {c.out}", fg="yellow") return None def get_lib_paths(self): @@ -402,7 +397,7 @@ class Environment(object): paths = None if c.returncode == 0: 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) if "purelib" in paths: paths["libdir"] = paths["purelib"] = make_posix(paths["purelib"]) @@ -411,8 +406,8 @@ class Environment(object): paths[key] = make_posix(paths[key]) return paths else: - vistir.misc.echo("Failed to load paths: {0}".format(c.err), fg="yellow") - vistir.misc.echo("Output: {0}".format(c.out), fg="yellow") + vistir.misc.echo(f"Failed to load paths: {c.err}", fg="yellow") + vistir.misc.echo(f"Output: {c.out}", fg="yellow") if not paths: if not self.prefix.joinpath("lib").exists(): return {} @@ -455,15 +450,15 @@ class Environment(object): ) if c.returncode == 0: 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) for key in ("include", "platinclude"): if key in paths: paths[key] = make_posix(paths[key]) return paths else: - vistir.misc.echo("Failed to load paths: {0}".format(c.err), fg="yellow") - vistir.misc.echo("Output: {0}".format(c.out), fg="yellow") + vistir.misc.echo(f"Failed to load paths: {c.err}", fg="yellow") + vistir.misc.echo(f"Output: {c.out}", fg="yellow") return None @cached_property @@ -558,14 +553,13 @@ class Environment(object): pkg_resources = self.safe_import("pkg_resources") libdirs = self.base_paths["libdirs"].split(os.pathsep) dists = (pkg_resources.find_distributions(libdir) for libdir in libdirs) - for dist in itertools.chain.from_iterable(dists): - yield dist + yield from itertools.chain.from_iterable(dists) def find_egg(self, egg_dist): # type: (pkg_resources.Distribution) -> str """Find an egg by name in the given environment""" 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: user_site = site.getusersitepackages() except AttributeError: @@ -704,12 +698,12 @@ class Environment(object): packages = [p for p in packages if p.key == pkg] 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: nodes = [p for p in tree.keys() if p.key == pkg] else: 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] @@ -751,9 +745,9 @@ class Environment(object): for k in list(rdeps.keys()): entry = rdeps[k] if entry.get("parents"): - rdeps[k]["parents"] = set([ + rdeps[k]["parents"] = { p for p, version in chunked(2, unnest(entry["parents"])) - ]) + } return rdeps def get_working_set(self): @@ -832,8 +826,8 @@ class Environment(object): """ c = None - if isinstance(cmd, six.string_types): - script = vistir.cmdparse.Script.parse("{0} -c {1}".format(self.python, cmd)) + if isinstance(cmd, str): + script = vistir.cmdparse.Script.parse(f"{self.python} -c {cmd}") else: script = vistir.cmdparse.Script.parse([self.python, "-c"] + list(cmd)) with self.activated(): @@ -845,8 +839,8 @@ class Environment(object): if self.is_venv: activate_this = os.path.join(self.scripts_dir, "activate_this.py") if not os.path.isfile(activate_this): - raise OSError("No such file: {0!s}".format(activate_this)) - with open(activate_this, "r") as f: + raise OSError(f"No such file: {activate_this!s}") + with open(activate_this) as f: code = compile(f.read(), activate_this, "exec") exec(code, dict(__file__=activate_this)) @@ -919,7 +913,7 @@ class Environment(object): finally: sys.path = original_path sys.prefix = original_prefix - six.moves.reload_module(pkg_resources) + importlib.reload(pkg_resources) @cached_property def finders(self): @@ -950,11 +944,11 @@ class Environment(object): install_args = [ self.environment.python, "-u", "-c", SETUPTOOLS_SHIM % setup_path, 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: install_args.append( - "--install-{0}={1}".format(key, self.base_paths[key]) + f"--install-{key}={self.base_paths[key]}" ) return install_args @@ -1030,7 +1024,7 @@ class Environment(object): return -class PatchedUninstaller(object): +class PatchedUninstaller: def _permitted(self, path): return True diff --git a/pipenv/environments.py b/pipenv/environments.py index fce4bf94..ffcd0d77 100644 --- a/pipenv/environments.py +++ b/pipenv/environments.py @@ -1,5 +1,3 @@ -# -*- coding=utf-8 -*- - import os import sys @@ -30,7 +28,7 @@ def env_to_bool(val): return False if val.lower() in _true_values: 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): @@ -55,11 +53,11 @@ def get_from_env(arg, prefix="PIPENV", check_for_negation=True): :return: The value from the environment if available :rtype: Optional[Union[str, bool]] """ - negative_lookup = "NO_{0}".format(arg) + negative_lookup = f"NO_{arg}" positive_lookup = arg if prefix: - positive_lookup = "{0}_{1}".format(prefix, arg) - negative_lookup = "{0}_{1}".format(prefix, negative_lookup) + positive_lookup = f"{prefix}_{arg}" + negative_lookup = f"{prefix}_{negative_lookup}" if positive_lookup in os.environ: value = os.environ[positive_lookup] try: @@ -391,9 +389,9 @@ def is_in_virtualenv(): 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(): diff --git a/pipenv/exceptions.py b/pipenv/exceptions.py index 912a875c..306b240c 100644 --- a/pipenv/exceptions.py +++ b/pipenv/exceptions.py @@ -1,5 +1,3 @@ -# -*- coding=utf-8 -*- - import itertools import re import sys @@ -7,8 +5,6 @@ import sys from collections import namedtuple from traceback import format_tb -import six - from . import environments from ._compat import decode_for_output from .patched import crayons @@ -19,7 +15,7 @@ from .vendor.vistir.misc import echo as click_echo import vistir 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): KnownException = namedtuple( @@ -52,10 +48,10 @@ def handle_exception(exc_type, exception, traceback, hook=sys.excepthook): for line in lines: line = line.strip("'").strip('"').strip("\n").strip() if not line.startswith("File"): - line = " {0}".format(line) + line = f" {line}" else: - line = " {0}".format(line) - line = "[{0!s}]: {1}".format( + line = f" {line}" + line = "[{!s}]: {}".format( exception.__class__.__name__, line ) formatted_lines.append(line) @@ -86,12 +82,12 @@ class PipenvException(ClickException): if isinstance(self.extra, STRING_TYPES): self.extra = [self.extra] for extra in self.extra: - extra = "[pipenv.exceptions.{0!s}]: {1}".format( + extra = "[pipenv.exceptions.{!s}]: {}".format( self.__class__.__name__, extra ) extra = decode_for_output(extra, 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): @@ -100,23 +96,23 @@ class PipenvCmdError(PipenvException): self.out = out self.err = err self.exit_code = exit_code - message = "Error running command: {0}".format(cmd) + message = f"Error running command: {cmd}" PipenvException.__init__(self, message) def show(self, file=None): if file is None: file = vistir.misc.get_text_stderr() - click_echo("{0} {1}".format( + click_echo("{} {}".format( 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) if self.out: - click_echo("{0} {1}".format( + click_echo("{} {}".format( crayons.normal("OUTPUT: "), decode_for_output(self.out, file) ), err=True) if self.err: - click_echo("{0} {1}".format( + click_echo("{} {}".format( crayons.normal("STDERR: "), decode_for_output(self.err, file) ), err=True) @@ -130,13 +126,13 @@ class JSONParseError(PipenvException): def show(self, file=None): if file is None: file = vistir.misc.get_text_stderr() - message = "{0}\n{1}".format( + message = "{}\n{}".format( crayons.normal("Failed parsing JSON results:", bold=True), decode_for_output(self.message.strip(), file) ) click_echo(message, err=True) if self.error_text: - click_echo("{0} {1}".format( + click_echo("{} {}".format( crayons.normal("ERROR TEXT:", bold=True), decode_for_output(self.error_text, file) ), err=True) @@ -187,7 +183,7 @@ class PipenvFileError(FileError): if not message: message = crayons.normal("Please ensure that the file exists!", bold=True) message = self.formatted_message.format( - crayons.normal("{0} not found!".format(filename), bold=True), + crayons.normal(f"{filename} not found!", bold=True), message ) 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): extra = kwargs.pop("extra", []) message = ( - "{0} {1}".format( + "{} {}".format( crayons.red("Aborting!", bold=True), crayons.normal( "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): def __init__(self, filename="Pipfile.lock", extra=None, **kwargs): extra = kwargs.pop("extra", []) - message = "{0} {1} {2}".format( + message = "{} {} {}".format( crayons.normal("You need to run", bold=True), crayons.red("$ pipenv lock", 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): @@ -250,16 +246,16 @@ class SystemUsageError(PipenvOptionsError): def __init__(self, option_name="system", message=None, ctx=None, **kwargs): extra = kwargs.pop("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( crayons.red("Warning", bold=True) ), ] if message is None: 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): @@ -267,7 +263,7 @@ class PipfileException(PipenvFileError): from .core import project 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 extra = kwargs.pop("extra", []) PipenvFileError.__init__(self, filename, hint, extra=extra, **kwargs) @@ -310,7 +306,7 @@ class VirtualenvCreationException(VirtualenvException): # note we need the format interpolation because ``crayons.ColoredString`` # is not an actual string type but is only a preparation for interpolation # 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: extra = str( crayons.red("Virtualenv creation interrupted by user", bold=True) @@ -322,17 +318,17 @@ class VirtualenvCreationException(VirtualenvException): class UninstallError(PipenvException): def __init__(self, package, command, return_values, return_code, **kwargs): extra = [ - "{0} {1}".format( + "{} {}".format( 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()]) if isinstance(package, (tuple, list, set)): package = " ".join(package) - message = "{0!s} {1!s}...".format( + message = "{!s} {!s}...".format( 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 PipenvException.__init__(self, message=message, extra=extra) @@ -343,11 +339,11 @@ class InstallError(PipenvException): def __init__(self, package, **kwargs): package_message = "" if package is not None: - package_message = "Couldn't install package: {0}\n".format( - crayons.normal("{0!s}".format(package), bold=True) + package_message = "Couldn't install package: {}\n".format( + crayons.normal(f"{package!s}", bold=True) ) - message = "{0} {1}".format( - "{0}".format(package_message), + message = "{} {}".format( + f"{package_message}", crayons.yellow("Package installation failed...") ) extra = kwargs.pop("extra", []) @@ -356,9 +352,9 @@ class InstallError(PipenvException): class CacheError(PipenvException): def __init__(self, path, **kwargs): - message = "{0} {1}\n{2}".format( + message = "{} {}\n{}".format( 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.') ) PipenvException.__init__(self, message=message) @@ -366,7 +362,7 @@ class CacheError(PipenvException): class DependencyConflict(PipenvException): def __init__(self, message): - extra = ["{0} {1}".format( + extra = ["{} {}".format( crayons.red("The operation failed...", bold=True), crayons.red("A dependency conflict was detected and could not be resolved."), )] @@ -376,12 +372,12 @@ class DependencyConflict(PipenvException): class ResolutionFailure(PipenvException): def __init__(self, message, no_version_found=False): 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 " - "First try clearing your dependency cache with {1}, then try the original command again.\n " - "Alternatively, you can use {2} to bypass this mechanism, then run " - "{3} to inspect the situation.\n " - "Hint: try {4} if it is a pre-release dependency." + "First try clearing your dependency cache with {}, then try the original command again.\n " + "Alternatively, you can use {} to bypass this mechanism, then run " + "{} to inspect the situation.\n " + "Hint: try {} if it is a pre-release dependency." "".format( crayons.red("Warning", bold=True), crayons.yellow("$ pipenv lock --clear"), @@ -392,9 +388,9 @@ class ResolutionFailure(PipenvException): ) if "no version found at all" in message: no_version_found = True - message = crayons.yellow("{0}".format(message)) + message = crayons.yellow(f"{message}") if no_version_found: - message = "{0}\n{1}".format( + message = "{}\n{}".format( message, crayons.cyan( "Please check your version specifier and version number. " @@ -426,18 +422,18 @@ class RequirementError(PipenvException): if getattr(req, k, None) ] 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: values = [(k, req.get(k)) for k in keys_fn() if req.get(k)] req_value = "\n".join([ - " {0}: {1}".format(k, v) for k, v in values + f" {k}: {v}" for k, v in values ]) else: 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("{0!r}".format(req_value))) + crayons.normal(decode_for_output(f"{req_value!r}")) ) extra = [str(req)] PipenvException.__init__(self, message, extra=extra) @@ -460,8 +456,8 @@ def prettify_exc(error): _, error, info = error.rpartition(exc.prefix) else: _, error, info = error.rpartition(split_string) - errors.append("{0} {1}".format(error, info)) + errors.append(f"{error} {info}") if not errors: - return "{}".format(vistir.misc.decode_for_output(error)) + return f"{vistir.misc.decode_for_output(error)}" return "\n".join(errors) diff --git a/pipenv/help.py b/pipenv/help.py index e8fbf1c8..813f06a8 100644 --- a/pipenv/help.py +++ b/pipenv/help.py @@ -1,4 +1,3 @@ -# coding: utf-8 import os import pprint import sys @@ -20,11 +19,11 @@ def print_utf(line): def get_pipenv_diagnostics(): print("
$ pipenv --support") print("") - print("Pipenv version: `{0!r}`".format(pipenv.__version__)) + print(f"Pipenv version: `{pipenv.__version__!r}`") print("") - print("Pipenv location: `{0!r}`".format(os.path.dirname(pipenv.__file__))) + print(f"Pipenv location: `{os.path.dirname(pipenv.__file__)!r}`") print("") - print("Python location: `{0!r}`".format(sys.executable)) + print(f"Python location: `{sys.executable!r}`") print("") print("Python installations found:") print("") @@ -32,7 +31,7 @@ def get_pipenv_diagnostics(): finder = pythonfinder.Finder(system=False, global_search=True) python_paths = finder.find_all_python_versions() for python in python_paths: - print(" - `{}`: `{}`".format(python.py_version.version, python.path)) + print(f" - `{python.py_version.version}`: `{python.path}`") print("") print("PEP 508 Information:") @@ -44,39 +43,39 @@ def get_pipenv_diagnostics(): print("System environment variables:") print("") for key in os.environ: - print(" - `{0}`".format(key)) + print(f" - `{key}`") print("") - print_utf(u"Pipenv–specific environment variables:") + print_utf("Pipenv–specific environment variables:") print("") for key in os.environ: if key.startswith("PIPENV"): - print(" - `{0}`: `{1}`".format(key, os.environ[key])) + print(f" - `{key}`: `{os.environ[key]}`") print("") - print_utf(u"Debug–specific environment variables:") + print_utf("Debug–specific environment variables:") print("") for key in ("PATH", "SHELL", "EDITOR", "LANG", "PWD", "VIRTUAL_ENV"): if key in os.environ: - print(" - `{0}`: `{1}`".format(key, os.environ[key])) + print(f" - `{key}`: `{os.environ[key]}`") print("") print("") print("---------------------------") print("") 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("```toml") - with open(project.pipfile_location, "r") as f: + with open(project.pipfile_location) as f: print(f.read()) print("```") print("") if project.lockfile_exists: print("") print_utf( - u"Contents of `Pipfile.lock` ({0!r}):".format(project.lockfile_location) + f"Contents of `Pipfile.lock` ({project.lockfile_location!r}):" ) print("") print("```json") - with open(project.lockfile_location, "r") as f: + with open(project.lockfile_location) as f: print(f.read()) print("```") print("
") diff --git a/pipenv/installers.py b/pipenv/installers.py index 1e81047d..653ff09b 100644 --- a/pipenv/installers.py +++ b/pipenv/installers.py @@ -1,7 +1,6 @@ import os import operator import re -import six from abc import ABCMeta, abstractmethod @@ -11,7 +10,7 @@ from .utils import find_windows_executable @attr.s -class Version(object): +class Version: major = attr.ib() minor = attr.ib() @@ -29,7 +28,7 @@ class Version(object): """ match = re.match(r'^(\d+)\.(\d+)(?:\.(\d+))?$', name) 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)) minor = int(match.group(2)) patch = match.group(3) @@ -59,17 +58,16 @@ class InstallerNotFound(RuntimeError): class InstallerError(RuntimeError): def __init__(self, desc, c): - super(InstallerError, self).__init__(desc) + super().__init__(desc) self.out = c.out self.err = c.err -@six.add_metaclass(ABCMeta) -class Installer(object): +class Installer(metaclass=ABCMeta): def __init__(self): self.cmd = self._find_installer() - super(Installer, self).__init__() + super().__init__() def __str__(self): return self.__class__.__name__ @@ -109,7 +107,7 @@ class Installer(object): # 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), # 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): return candidate @@ -119,12 +117,12 @@ class Installer(object): timeout = kwargs.pop('timeout', delegator.TIMEOUT) if kwargs: 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) c = delegator.run(args, block=False, timeout=timeout) c.block() if c.return_code != 0: - raise InstallerError('failed to run {0}'.format(args), c) + raise InstallerError(f'failed to run {args}', c) return c @abstractmethod @@ -149,7 +147,7 @@ class Installer(object): ), key=operator.attrgetter('cmpkey')) except ValueError: raise ValueError( - 'no installable version found for {0!r}'.format(name), + f'no installable version found for {name!r}', ) return best_match diff --git a/pipenv/pep508checker.py b/pipenv/pep508checker.py index 3e864795..a771dec0 100644 --- a/pipenv/pep508checker.py +++ b/pipenv/pep508checker.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import json import os import platform diff --git a/pipenv/progress.py b/pipenv/progress.py index 8968150c..b9216884 100644 --- a/pipenv/progress.py +++ b/pipenv/progress.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ clint.textui.progress ~~~~~~~~~~~~~~~~~ @@ -7,7 +6,6 @@ This module provides the progressbar functionality. """ -from __future__ import absolute_import import os import sys @@ -37,7 +35,7 @@ else: BAR_EMPTY_CHAR = str(crayons.black("▉")) 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: if os.name == "nt": BAR_TEMPLATE = " %s%s%s %i/%i - %s\r" @@ -51,7 +49,7 @@ ETA_INTERVAL = 1 ETA_SMA_WINDOW = 9 -class Bar(object): +class Bar: def __enter__(self): return self diff --git a/pipenv/project.py b/pipenv/project.py index 6d589429..5103bb6d 100644 --- a/pipenv/project.py +++ b/pipenv/project.py @@ -9,8 +9,8 @@ import operator import os import re import sys +import urllib.parse -import six import toml import tomlkit import vistir @@ -89,13 +89,13 @@ class _LockFileEncoder(json.JSONEncoder): def encode(self, obj): content = super(_LockFileEncoder, self).encode(obj) - if not isinstance(content, six.text_type): + if not isinstance(content, str): content = content.decode("utf-8") return content def preferred_newlines(f): - if isinstance(f.newlines, six.text_type): + if isinstance(f.newlines, str): return f.newlines return DEFAULT_NEWLINES @@ -568,7 +568,7 @@ class Project(object): _pipfile_cache.clear() def _parse_pipfile(self, contents): - # type: () -> Union[tomlkit.toml_document.TOMLDocument, TPipfile] + # type: (str) -> Union[tomlkit.toml_document.TOMLDocument, TPipfile] try: return tomlkit.parse(contents) except Exception: @@ -614,7 +614,7 @@ class Project(object): return False def build_script(self, name, extra_args=None): - # type: (str, Optional[List[str]]) + # type: (str, Optional[List[str]]) -> Script try: script = Script.parse(self.parsed_pipfile["scripts"][name]) except KeyError: @@ -1011,7 +1011,7 @@ class Project(object): self.write_toml(p) 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(".", "") diff --git a/pipenv/resolver.py b/pipenv/resolver.py index 80de9281..a3e75c13 100644 --- a/pipenv/resolver.py +++ b/pipenv/resolver.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- - -from __future__ import absolute_import, print_function import json import logging 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 name = None 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: name = pkg_resources.safe_name(base_name).replace("-", "_") if not any(pkg == _ for _ in [base_name, name]): 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 = next(iter(p for p in path_options if os.path.exists(p)), None) if path is not None: @@ -92,11 +89,11 @@ def handle_parsed_args(parsed): return parsed -class Entry(object): +class Entry: """A resolved entry from a resolver run""" 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 self.name = name if isinstance(entry_dict, dict): @@ -173,7 +170,7 @@ class Entry(object): markers = set() keys_in_dict = [k for k in marker_keys if k in entry_dict] 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 } if "markers" in entry_dict: @@ -216,18 +213,17 @@ class Entry(object): from pipenv.vendor.requirementslib.models.markers import normalize_marker_str if not marker: return None - from pipenv.vendor import six from pipenv.vendor.vistir.compat import Mapping marker_str = None if isinstance(marker, Mapping): marker_dict, _ = Entry.get_markers_from_dict(marker) if marker_dict: - marker_str = "{0}".format(marker_dict.popitem()[1]) + marker_str = f"{marker_dict.popitem()[1]}" elif isinstance(marker, (list, set, tuple)): marker_str = " and ".join([normalize_marker_str(m) for m in marker if m]) - elif isinstance(marker, six.string_types): - marker_str = "{0}".format(normalize_marker_str(marker)) - if isinstance(marker_str, six.string_types): + elif isinstance(marker, str): + marker_str = f"{normalize_marker_str(marker)}" + if isinstance(marker_str, str): return marker_str return None @@ -317,9 +313,9 @@ class Entry(object): if not any(specifier.startswith(k) for k in Specifier._operators.keys()): if specifier.strip().lower() in ["any", "", "*"]: return "*" - specifier = "=={0}".format(specifier) + specifier = f"=={specifier}" elif specifier.startswith("==") and specifier.count("=") > 3: - specifier = "=={0}".format(specifier.lstrip("=")) + specifier = "=={}".format(specifier.lstrip("=")) return specifier @staticmethod @@ -448,7 +444,7 @@ class Entry(object): self.can_use_updated = False satisfied_by_value = getattr(constraint, "satisfied_by", None) if satisfied_by_value: - satisfied_by = "{0}".format( + satisfied_by = "{}".format( self.clean_specifier(str(satisfied_by_value.version)) ) satisfied_by_versions.add(satisfied_by) @@ -525,9 +521,9 @@ class Entry(object): str(pinned_version), prereleases=True ): if is_verbose(): - print("Tried constraint: {0!r}".format(constraint), file=sys.stderr) + print(f"Tried constraint: {constraint!r}", file=sys.stderr) msg = ( - "Cannot resolve conflicting version {0}{1} while {2}{3} is " + "Cannot resolve conflicting version {}{} while {}{} is " "locked.".format( self.name, constraint.req.specifier, self.name, self.updated_specifier @@ -543,8 +539,8 @@ class Entry(object): if not parent.validate_specifiers(): from pipenv.exceptions import DependencyConflict msg = ( - "Cannot resolve conflicting versions: (Root: {0}) {1}{2} (Pipfile) " - "Incompatible with {3}{4} (resolved)\n".format( + "Cannot resolve conflicting versions: (Root: {}) {}{} (Pipfile) " + "Incompatible with {}{} (resolved)\n".format( self.name, parent.pipfile_name, parent.pipfile_entry.requirement.specifiers, parent.name, parent.updated_specifiers @@ -565,7 +561,7 @@ class Entry(object): except AttributeError: result = getattr(entry, key) except AttributeError: - result = super(Entry, self).__getattribute__(key) + result = super().__getattribute__(key) return result if any(key.startswith(v) for v in old_version): lockfile_entry = Entry.__getattribute__(self, "lockfile_entry") @@ -576,9 +572,9 @@ class Entry(object): except AttributeError: result = getattr(lockfile_entry, key) except AttributeError: - result = super(Entry, self).__getattribute__(key) + result = super().__getattribute__(key) return result - return super(Entry, self).__getattribute__(key) + return super().__getattribute__(key) def clean_results(results, resolver, project, dev=False): @@ -751,9 +747,9 @@ def main(): warnings.simplefilter("ignore", category=ResourceWarning) replace_with_text_stream("stdout") replace_with_text_stream("stderr") - os.environ["PIP_DISABLE_PIP_VERSION_CHECK"] = str("1") - os.environ["PYTHONIOENCODING"] = str("utf-8") - os.environ["PYTHONUNBUFFERED"] = str("1") + os.environ["PIP_DISABLE_PIP_VERSION_CHECK"] = "1" + os.environ["PYTHONIOENCODING"] = "utf-8" + os.environ["PYTHONUNBUFFERED"] = "1" parsed = handle_parsed_args(parsed) _main(parsed.pre, parsed.clear, parsed.verbose, parsed.system, parsed.write, parsed.requirements_dir, parsed.packages, parse_only=parsed.parse_only, diff --git a/pipenv/shells.py b/pipenv/shells.py index af3b0c03..9550322c 100644 --- a/pipenv/shells.py +++ b/pipenv/shells.py @@ -52,7 +52,7 @@ def _get_activate_script(cmd, venv): # for proper activation. venv_location = re.sub(r'([ &$()\[\]])', r"\\\1", str(venv)) # 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): @@ -63,7 +63,7 @@ def _handover(cmd, args): sys.exit(subprocess.call(args, shell=True, universal_newlines=True)) -class Shell(object): +class Shell: def __init__(self, cmd): self.cmd = cmd self.args = [] @@ -77,7 +77,7 @@ class Shell(object): @contextlib.contextmanager def inject_path(self, venv): 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, os.environ["PATH"], @@ -90,9 +90,9 @@ class Shell(object): name = os.path.basename(venv) os.environ["VIRTUAL_ENV"] = str(venv) 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: - os.environ["PS1"] = "({0}) {1}".format(name, os.environ["PS1"]) + os.environ["PS1"] = "({}) {}".format(name, os.environ["PS1"]) with self.inject_path(venv): os.chdir(cwd) _handover(self.cmd, self.args + list(args)) @@ -147,10 +147,10 @@ class Bash(Shell): bashrc_path = Path.home().joinpath(".bashrc") with NamedTemporaryFile("w+") as rcfile: 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) - export_path = 'export PATH="{0}:$PATH"\n'.format(":".join( + export_path = 'export PATH="{}:$PATH"\n'.format(":".join( self._format_path(python) for python in _iter_python(venv) )) @@ -162,18 +162,18 @@ class Bash(Shell): class MsysBash(Bash): def _format_path(self, python): - s = super(MsysBash, self)._format_path(python) + s = super()._format_path(python) if not python.drive: return s # 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): def fork(self, venv, cwd, args): if cwd: os.environ["CMDER_START"] = cwd - super(CmderEmulatedShell, self).fork(venv, cwd, args) + super().fork(venv, cwd, args) class CmderCommandPrompt(CmderEmulatedShell): @@ -181,7 +181,7 @@ class CmderCommandPrompt(CmderEmulatedShell): rc = os.path.expandvars("%CMDER_ROOT%\\vendor\\init.bat") if os.path.exists(rc): self.args.extend(["/k", rc]) - super(CmderCommandPrompt, self).fork(venv, cwd, args) + super().fork(venv, cwd, args) class CmderPowershell(Shell): @@ -196,10 +196,10 @@ class CmderPowershell(Shell): "-NoProfile", "-NoExit", "-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. diff --git a/pipenv/utils.py b/pipenv/utils.py index feece1db..6057bdea 100644 --- a/pipenv/utils.py +++ b/pipenv/utils.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import print_function - import contextlib import errno import logging @@ -14,11 +11,10 @@ import sys import warnings from contextlib import contextmanager from distutils.spawn import find_executable +from urllib.parse import urlparse -import six import toml from click import echo as click_echo -from six.moves.urllib.parse import urlparse import crayons import parse @@ -137,7 +133,7 @@ def run_command(cmd, *args, **kwargs): from ._compat import decode_for_output from .cmdparse import Script 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) if not isinstance(cmd, Script): raise TypeError("Command input must be a string, list or tuple") @@ -147,14 +143,14 @@ def run_command(cmd, *args, **kwargs): try: cmd_string = cmd.cmdify() 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) 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) return_code = c.return_code if environments.is_verbose(): - click_echo("Command output: {0}".format( + click_echo("Command output: {}".format( crayons.cyan(decode_for_output(c.out)) ), err=True) if not c.ok and catch_exceptions: @@ -223,10 +219,10 @@ def escape_grouped_arguments(s): def clean_pkg_version(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.""" 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. if not sources[0].get("verify_ssl", True): 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( - ["--trusted-host", "{0}{1}".format(url_parts.host, url_port)] + ["--trusted-host", f"{url_parts.host}{url_port}"] ) # Add additional sources as extra indexes. 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. if not source.get("verify_ssl", True): 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( - ["--trusted-host", "{0}{1}".format(url_parts.host, url_port)] + ["--trusted-host", f"{url_parts.host}{url_port}"] ) return pip_args @@ -314,7 +310,7 @@ def get_source_list( if index: sources.append(get_project_index(index)) if extra_indexes: - if isinstance(extra_indexes, six.string_types): + if isinstance(extra_indexes, str): extra_indexes = [extra_indexes] for source in extra_indexes: extra_src = get_project_index(source) @@ -375,7 +371,7 @@ def get_pipenv_sitedir(): return None -class Resolver(object): +class Resolver: def __init__( self, constraints, req_dir, project, sources, index_lookup=None, markers_lookup=None, skipped=None, clear=False, pre=False @@ -495,13 +491,13 @@ class Resolver(object): except ValueError: direct_url = DIRECT_URL_RE.match(line) if direct_url: - line = "{0}#egg={1}".format(line, direct_url.groupdict()["name"]) + line = "{}#egg={}".format(line, direct_url.groupdict()["name"]) try: req = Requirement.from_line(line) 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: - 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: try: index_lookup[req.normalized_name] = project.get_source( @@ -680,8 +676,8 @@ class Resolver(object): index_lookup, markers_lookup = {}, {} deps = set() if dev: - deps.update(set([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.dev_packages}) + deps.update({req.as_line() for req in pipfile.packages}) constraints, skipped, index_lookup, markers_lookup = cls.get_metadata( list(deps), index_lookup, markers_lookup, project, project.sources, req_dir=req_dir, pre=pre, clear=clear @@ -737,9 +733,9 @@ class Resolver(object): if self.sources: requirementstxt_sources = " ".join(args_to_add) if args_to_add else "" 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_file.write(u"\n".join([c for c in constraints])) + constraints_file.write("\n".join([c for c in constraints])) constraints_file.close() return constraints_file.name @@ -820,7 +816,7 @@ class Resolver(object): from pipenv.patched.piptools.cache import CorruptCacheError from .exceptions import CacheError, ResolutionFailure with temp_environ(): - os.environ["PIP_NO_USE_PEP517"] = str("") + os.environ["PIP_NO_USE_PEP517"] = "" try: results = self.resolver.resolve(max_rounds=environments.PIPENV_MAX_ROUNDS) except CorruptCacheError as e: @@ -876,7 +872,7 @@ class Resolver(object): if not checksum: continue if not checksum.startswith("sha256:"): - checksum = "sha256:{0}".format(checksum) + checksum = f"sha256:{checksum}" cleaned_checksums.append(checksum) return cleaned_checksums @@ -895,7 +891,7 @@ class Resolver(object): "python.org" in source["url"] or "pypi.org" in source["url"] 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() try: # Grab the hashes from the new warehouse API. @@ -916,7 +912,7 @@ class Resolver(object): except (ValueError, KeyError, ConnectionError): if environments.is_verbose(): click_echo( - "{0}: Error generating hash for {1}".format( + "{}: Error generating hash for {}".format( crayons.red("Warning", bold=True), ireq.name ), 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 = pep423_name(req.name) entry = {} - if isinstance(pf_entry, six.string_types): + if isinstance(pf_entry, str): entry["version"] = pf_entry.lstrip("=") else: entry.update(pf_entry) @@ -1150,7 +1146,7 @@ def resolve(cmd, sp): while True: result = None try: - result = c.expect(u"\n", timeout=environments.PIPENV_INSTALL_TIMEOUT) + result = c.expect("\n", timeout=environments.PIPENV_INSTALL_TIMEOUT) except TIMEOUT: pass except EOF: @@ -1160,7 +1156,7 @@ def resolve(cmd, sp): break if result: _out = c.subprocess.before - _out = decode_output("{0}".format(_out)) + _out = decode_output(f"{_out}") out += _out # sp.text = to_native_string("{0}".format(_out[:100])) if environments.is_verbose(): @@ -1342,13 +1338,13 @@ def venv_resolve_deps( if c.ok: sp.green.ok(environments.PIPENV_SPINNER_OK_TEXT.format("Success!")) 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: sp.red.fail(environments.PIPENV_SPINNER_FAIL_TEXT.format("Locking Failed!")) - click_echo("Output: {0}".format(c.out.strip()), err=True) - click_echo("Error: {0}".format(c.err.strip()), err=True) + click_echo(f"Output: {c.out.strip()}", err=True) + click_echo(f"Error: {c.err.strip()}", err=True) try: - with open(target_file.name, "r") as fh: + with open(target_file.name) as fh: results = json.load(fh) except (IndexError, JSONDecodeError): click_echo(c.out.strip(), err=True) @@ -1432,13 +1428,13 @@ def resolve_deps( def is_star(val): - return isinstance(val, six.string_types) and val == "*" + return isinstance(val, str) and val == "*" def is_pinned(val): if isinstance(val, Mapping): 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): @@ -1477,7 +1473,7 @@ def mkdir_p(newdir): pass elif os.path.isfile(newdir): 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 ) ) @@ -1530,7 +1526,7 @@ def is_installable_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"] - if not isinstance(path, six.string_types) or path == "*": + if not isinstance(path, str) or path == "*": return False # 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 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): return True @@ -1595,11 +1591,11 @@ def proper_case(package_name): """Properly case project name from pypi.org.""" # Hit the simple API. 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: - raise IOError( - "Unable to find package {0} in PyPI repository.".format(package_name) + raise OSError( + f"Unable to find package {package_name} in PyPI repository." ) r = parse.parse("https://pypi.org/pypi/{name}/json", r.url) @@ -1646,7 +1642,7 @@ def normalize_path(path): def get_url_name(url): - if not isinstance(url, six.string_types): + if not isinstance(url, str): return return urllib3_util.parse_url(url).host @@ -1656,10 +1652,10 @@ def get_canonical_names(packages): from .vendor.packaging.utils import canonicalize_name if not isinstance(packages, Sequence): - if not isinstance(packages, six.string_types): + if not isinstance(packages, str): return 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): @@ -1686,8 +1682,7 @@ def walk_up(bottom): if new_path == bottom: return - for x in walk_up(new_path): - yield x + yield from walk_up(new_path) def find_requirements(max_depth=3): @@ -1733,7 +1728,7 @@ def load_path(python): import json python = Path(python).as_posix() 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: return json.loads(c.out.strip()) else: @@ -1768,7 +1763,7 @@ def download_file(url, filename): """Downloads file from url to a path with filename""" r = _get_requests_session().get(url, stream=True) if not r.ok: - raise IOError("Unable to download file") + raise OSError("Unable to download file") with open(filename, "wb") as f: f.write(r.content) @@ -1783,13 +1778,13 @@ def normalize_drive(path): See: """ - if os.name != "nt" or not isinstance(path, six.string_types): + if os.name != "nt" or not isinstance(path, str): return path drive, tail = os.path.splitdrive(path) # Only match (lower cased) local drives (e.g. 'c:'), not UNC mounts. if drive.islower() and len(drive) == 2 and drive[1] == ":": - return "{}{}".format(drive.upper(), tail) + return f"{drive.upper()}{tail}" return path @@ -1806,7 +1801,7 @@ def is_readonly_path(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 os.chmod(fn, stat.S_IWRITE | stat.S_IWUSR | stat.S_IRUSR) return @@ -1834,7 +1829,7 @@ def handle_remove_readonly(func, path, exc): set_write_bit(path) try: func(path) - except (OSError, IOError) as e: + except OSError as e: if e.errno in [errno.EACCES, errno.EPERM]: warnings.warn(default_warning_message.format(path), ResourceWarning) return @@ -1848,14 +1843,14 @@ def handle_remove_readonly(func, path, exc): def escape_cmd(cmd): if any(special_char in cmd for special_char in ["<", ">", "&", ".", "^", "|", "?"]): - cmd = '\"{0}\"'.format(cmd) + cmd = f'\"{cmd}\"' return cmd def safe_expandvars(value): """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 value @@ -1932,13 +1927,13 @@ def translate_markers(pipfile_entry): if 'extra' not in marker: marker_set.add(marker) for m in pipfile_markers: - entry = "{0}".format(pipfile_entry[m]) + entry = f"{pipfile_entry[m]}" 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) if marker_set: 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)) ))).replace('"', "'") 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 # 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): - version = "{0}".format(dep["version"]) + version = "{}".format(dep["version"]) if not version.startswith("=="): - version = "=={0}".format(version) + version = f"=={version}" lockfile["version"] = version if is_vcs(dep): ref = dep.get("ref", None) @@ -2139,10 +2134,10 @@ def is_url_equal(url, other_url): "https://mydomain.com/some?some_query") False """ - if not isinstance(url, six.string_types): - raise TypeError("Expected string for url, received {0!r}".format(url)) - if not isinstance(other_url, six.string_types): - raise TypeError("Expected string for url, received {0!r}".format(other_url)) + if not isinstance(url, str): + raise TypeError(f"Expected string for url, received {url!r}") + if not isinstance(other_url, str): + raise TypeError(f"Expected string for url, received {other_url!r}") parsed_url = urllib3_util.parse_url(url) parsed_other_url = urllib3_util.parse_url(other_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") "c:/users/user/venvs/some_venv" """ - if not isinstance(path, six.string_types): - raise TypeError("Expected a string for path, received {0!r}...".format(path)) + if not isinstance(path, str): + raise TypeError(f"Expected a string for path, received {path!r}...") starts_with_sep = path.startswith(os.path.sep) separated = normalize_path(path).split(os.path.sep) if isinstance(separated, (list, tuple)): path = posixpath.join(*separated) if starts_with_sep: - path = "/{0}".format(path) + path = f"/{path}" return path @@ -2198,9 +2193,9 @@ def find_python(finder, line=None): :rtype: str """ - if line and not isinstance(line, six.string_types): + if line and not isinstance(line, str): 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 os.name == "nt": @@ -2218,11 +2213,11 @@ def find_python(finder, line=None): if not result: result = finder.which(line) if not result and not line.startswith("python"): - line = "python{0}".format(line) + line = f"python{line}" result = find_python(finder, line) if result: - if not isinstance(result, six.string_types): + if not isinstance(result, str): return result.path.as_posix() return result return @@ -2239,8 +2234,8 @@ def is_python_command(line): :rtype: bool """ - if not isinstance(line, six.string_types): - raise TypeError("Not a valid command to check: {0!r}".format(line)) + if not isinstance(line, str): + raise TypeError(f"Not a valid command to check: {line!r}") from pipenv.vendor.pythonfinder.utils import PYTHON_IMPLEMENTATIONS is_version = re.match(r'\d+(\.\d+)*', line) diff --git a/setup.cfg b/setup.cfg index 1a6e415e..1f307af9 100644 --- a/setup.cfg +++ b/setup.cfg @@ -4,9 +4,14 @@ license = MIT license_file = LICENSE [flake8] -exclude = - .git,__pycache__,docs/,pipenv/vendor/,pipenv/patched,get-pipenv.py, - .eggs/,setup.py,tests/fixtures/ +extend-exclude = + docs/, + pipenv/vendor/, + pipenv/patched/, + get-pipenv.py, + setup.py, + tests/fixtures/, + tests/test_artifacts/ ignore = # The default ignore list: E121,E123,E126,E226,E24,E704, diff --git a/setup.py b/setup.py index 3bd5538a..5de7e239 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- import codecs import os import sys @@ -53,7 +52,7 @@ class DebCommand(Command): @staticmethod def status(s): """Prints things in bold.""" - print("\033[1m{0}\033[0m".format(s)) + print(f"\033[1m{s}\033[0m") def initialize_options(self): pass @@ -67,12 +66,12 @@ class DebCommand(Command): rmtree(os.path.join(here, "deb_dist")) except FileNotFoundError: pass - self.status(u"Creating debian mainfest...") + self.status("Creating debian mainfest...") os.system( "python setup.py --command-packages=stdeb.command sdist_dsc -z artful --package3=pipenv --depends3=python3-virtualenv-clone" ) - self.status(u"Building .deb...") - os.chdir("deb_dist/pipenv-{0}".format(about["__version__"])) + self.status("Building .deb...") + os.chdir("deb_dist/pipenv-{}".format(about["__version__"])) os.system("dpkg-buildpackage -rfakeroot -uc -us") @@ -85,7 +84,7 @@ class UploadCommand(Command): @staticmethod def status(s): """Prints things in bold.""" - print("\033[1m{0}\033[0m".format(s)) + print(f"\033[1m{s}\033[0m") def initialize_options(self): pass @@ -100,11 +99,11 @@ class UploadCommand(Command): except FileNotFoundError: pass 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...") os.system("twine upload dist/*") 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") sys.exit() diff --git a/tasks/__init__.py b/tasks/__init__.py index 267a033e..07a054a9 100644 --- a/tasks/__init__.py +++ b/tasks/__init__.py @@ -1,4 +1,3 @@ -# -*- coding=utf-8 -*- # Copied from pip's vendoring process # see https://github.com/pypa/pip/blob/95bcf8c5f6394298035a7332c441868f3b0169f4/tasks/__init__.py from pathlib import Path diff --git a/tasks/release.py b/tasks/release.py index 0a56fee9..a292e3d7 100644 --- a/tasks/release.py +++ b/tasks/release.py @@ -1,4 +1,3 @@ -# -*- coding=utf-8 -*- import datetime import os import pathlib @@ -107,11 +106,11 @@ def release(ctx, manual=False, local=False, dry_run=False, pre=False, tag=None, if pre: log("generating towncrier draft...") 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: ctx.run("towncrier") 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") 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, "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"] )) if 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: log("Truncating...") 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, truncate=trunc_month ) - log("target_day: {0}".format(target_day)) + log(f"target_day: {target_day}") target_timetuple = target_day.timetuple()[:3] new_version = current_version.replace(release=target_timetuple) 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) if new_version.pre_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) else: 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())) ) if commit: - ctx.run("git add {0}".format(version_file.as_posix())) + ctx.run(f"git add {version_file.as_posix()}") log("Committing...") ctx.run('git commit -s -m "Bumped version."') return str(new_version) diff --git a/tasks/vendoring/__init__.py b/tasks/vendoring/__init__.py index 8b237aea..0966e3dd 100644 --- a/tasks/vendoring/__init__.py +++ b/tasks/vendoring/__init__.py @@ -1,4 +1,3 @@ -# -*- coding=utf-8 -*- # Taken from pip # see https://github.com/pypa/pip/blob/95bcf8c5f6394298035a7332c441868f3b0169f4/tasks/vendoring/__init__.py """"Vendoring script, python 3.5 needed""" @@ -102,7 +101,7 @@ def remove_all(paths): def log(msg): - print("[vendoring.%s] %s" % (TASK_NAME, msg)) + print(f"[vendoring.{TASK_NAME}] {msg}") def _get_git_root(ctx): @@ -222,8 +221,8 @@ def update_safety(ctx): log("generating lockfile...") packages = "\n".join(["safety", "requests[security]"]) env = {"PIPENV_PACKAGES": packages} - resolve_cmd = "python {0}".format(root.joinpath("pipenv/resolver.py").as_posix()) - py27_resolve_cmd = "python2.7 {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 {}".format(root.joinpath("pipenv/resolver.py").as_posix()) _, _, 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 = json.loads(resolved.strip()) @@ -231,11 +230,11 @@ def update_safety(ctx): pkg_dict, pkg_dict_py2 = {}, {} for pkg in resolved: name = pkg.pop("name") - pkg["version"] = "=={0}".format(pkg["version"]) + pkg["version"] = "=={}".format(pkg["version"]) pkg_dict[name] = pkg for pkg in resolved_py2: name = pkg.pop("name") - pkg["version"] = "=={0}".format(pkg["version"]) + pkg["version"] = "=={}".format(pkg["version"]) pkg_dict_py2[name] = pkg merged = merge_items([pkg_dict, pkg_dict_py2]) 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)) 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) - 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), ) - log("downloading deps via pip: {0}".format(pip_command)) + log(f"downloading deps via pip: {pip_command}") ctx.run(pip_command) yaml_build_dir = build_dir / "pyyaml" @@ -268,8 +267,8 @@ def update_safety(ctx): with ctx.cd(str(safety_dir)): 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()) - log("installing dependencies: {0}".format(install_cmd)) + 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(f"installing dependencies: {install_cmd}") ctx.run(install_cmd) safety_dir = safety_dir.absolute() yaml_dir = lib_dir / "yaml" @@ -299,23 +298,23 @@ def update_safety(ctx): log("dropping ignored files...") for pattern in ignore_patterns: for path in lib_dir.rglob(pattern): - log("removing {0!s}".format(path)) + log(f"removing {path!s}") path.unlink() for dep in ignore_subdeps: if lib_dir.joinpath(dep).exists(): - log("cleaning up {0}".format(dep)) + log(f"cleaning up {dep}") drop_dir(lib_dir.joinpath(dep)) for path in itertools.chain.from_iterable(( - lib_dir.rglob("{0}*.egg-info".format(dep)), - lib_dir.rglob("{0}*.dist-info".format(dep)) + lib_dir.rglob(f"{dep}*.egg-info"), + lib_dir.rglob(f"{dep}*.dist-info") )): - log("cleaning up {0}".format(path)) + log(f"cleaning up {path}") drop_dir(path) for fn in ignore_files: for path in lib_dir.rglob(fn): - log("cleaning up {0}".format(path)) + log(f"cleaning up {path}") path.unlink() - zip_name = "{0}/safety.zip".format(str(patched_dir)) + zip_name = f"{str(patched_dir)}/safety.zip" log("writing zipfile...") with zipfile.ZipFile(zip_name, 'w', compression=zipfile.ZIP_DEFLATED, compresslevel=6) as zf: _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: new_name = rename_dict.get(item.name, LIBRARY_DIRNAMES.get(item.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 try: item.rename(str(new_path)) @@ -346,7 +345,7 @@ def write_backport_imports(ctx, vendor_dir): backport_libs = detect_vendored_libs(backport_dir) init_py_lines = backport_init.read_text().splitlines() 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: log("Adding backport %s to __init__.py exports" % lib) init_py_lines.append(lib_line) @@ -366,29 +365,29 @@ def _ensure_package_in_requirements(ctx, requirements_file, package): if m.lower() == package or ( specifiers and m[: min(specifiers)].lower() == package ): - matched_req = "{0}".format(m) + matched_req = f"{m}" requirement = matched_req log("Matched req: %r" % 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) requirements_file.write_text("\n".join(req_file_lines)) - requirement = "{0}".format(package) + requirement = f"{package}" return requirement def install_pyyaml(ctx, vendor_dir): build_dir = vendor_dir / "build" 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) build_dir.mkdir() 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), ) 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)}) yaml_build_dir = next(build_dir.glob('pip-download-*/pyyaml_*')) yaml_dir = vendor_dir / "yaml" @@ -404,8 +403,8 @@ def install_pyyaml(ctx, vendor_dir): def install(ctx, vendor_dir, package=None): - requirements_file = vendor_dir / "{0}.txt".format(vendor_dir.name) - requirement = "-r {0}".format(requirements_file.as_posix()) + requirements_file = vendor_dir / f"{vendor_dir.name}.txt" + requirement = f"-r {requirements_file.as_posix()}" log("Using requirements file: %s" % requirement) if 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 # the chain. 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, ) ) @@ -427,20 +426,20 @@ def install(ctx, vendor_dir, package=None): vendor_dir.joinpath(pkg).joinpath("LICENSE").write_text( license_file.read_text() ) - elif vendor_dir.joinpath("{0}.py".format(pkg)).exists(): - vendor_dir.joinpath("{0}.LICENSE".format(pkg)).write_text( + elif vendor_dir.joinpath(f"{pkg}.py").exists(): + vendor_dir.joinpath(f"{pkg}.LICENSE").write_text( license_file.read_text() ) else: pkg = pkg.replace("-", "?").replace("_", "?") 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_dir(): target = vendor_dir.joinpath(matched_path).joinpath("LICENSE") else: - target = vendor_dir.joinpath("{0}.LICENSE".format(matched_path)) + target = vendor_dir.joinpath(f"{matched_path}.LICENSE") target.write_text( license_file.read_text() ) @@ -529,7 +528,7 @@ def redo_imports(ctx, library, vendor_dir=None): log("Using vendor dir: %s" % vendor_dir) vendored_libs = detect_vendored_libs(vendor_dir) 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("Rewriting imports for %s..." % item) if item.is_dir(): @@ -581,7 +580,7 @@ def packages_missing_licenses( possible_pkgs.append(LIBRARY_DIRNAMES[pkg]) for pkgpath in possible_pkgs: 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(): for license_path in LICENSES: license_path = pkgpath.joinpath(license_path) @@ -591,7 +590,7 @@ def packages_missing_licenses( break elif pkgpath.exists() or py_path.exists(): 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 if license_path.exists(): match_found = True @@ -635,16 +634,16 @@ def download_licenses( ctx.run("pip install flit") # needed for the next step for req in requirements: 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: - exe_cmd = "{0} --no-build-isolation -d {1} {2}".format( + exe_cmd = "{} --no-build-isolation -d {} {}".format( cmd, tmp_dir.as_posix(), req ) try: ctx.run(exe_cmd) except invoke.exceptions.UnexpectedExit as e: 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 parse_target = ( "Disabling PEP 517 processing is invalid: project specifies a build " @@ -655,9 +654,9 @@ def download_licenses( if backend is not None: if "." in backend: backend, _, _ = backend.partition(".") - ctx.run("pip install {0}".format(backend)) + ctx.run(f"pip install {backend}") 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(): extract_license(vendor_dir, sdist) @@ -667,7 +666,7 @@ def download_licenses( def extract_license(vendor_dir, sdist): if sdist.stem.endswith(".tar"): 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()) elif sdist.suffix in (".zip", ".whl"): with zipfile.ZipFile(sdist) as zip: @@ -676,7 +675,7 @@ def extract_license(vendor_dir, sdist): raise NotImplementedError("new sdist type!") 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) @@ -690,7 +689,7 @@ def find_and_extract_license(vendor_dir, tar, members): if "LICENSE" in name or "COPYING" in name: if "/test" in name: # some testing licenses in hml5lib and distlib - log("Ignoring {}".format(name)) + log(f"Ignoring {name}") continue found = True 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""" libname = libname_from_dir(sdist_name) 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] _, _, name = url.rpartition("/") dest = license_destination(vendor_dir, libname, name) r = requests.get(url, allow_redirects=True) - log("Downloading {}".format(url)) + log(f"Downloading {url}") r.raise_for_status() dest.write_bytes(r.content) @@ -738,7 +737,7 @@ def license_destination(vendor_dir, libname, filename): override = vendor_dir / LIBRARY_DIRNAMES[libname] if not override.exists() and override.parent.exists(): # for flattened subdeps, specifically backports/weakref.py - return (vendor_dir / override.parent) / "{0}.{1}".format( + return (vendor_dir / override.parent) / "{}.{}".format( override.name, 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 / LIBRARY_DIRNAMES[libname] / filename # 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): @@ -754,7 +753,7 @@ def extract_license_member(vendor_dir, tar, member, name): dirname = list(mpath.parents)[-2].name # -1 is . libname = libname_from_dir(dirname) dest = license_destination(vendor_dir, libname, mpath.name) - log("Extracting {} into {}".format(name, dest)) + log(f"Extracting {name} into {dest}") try: fileobj = tar.extractfile(member) 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" ) if patch_description: - patch_fn = "{0}-{1}.patch".format(pkg.parts[1], patch_description) + patch_fn = f"{pkg.parts[1]}-{patch_description}.patch" else: - patch_fn = "{0}.patch".format(pkg.parts[1]) + patch_fn = f"{pkg.parts[1]}.patch" command = "git diff {base} -p {root} > {out}".format( base=base, root=Path("pipenv").joinpath(pkg), @@ -826,13 +825,13 @@ def unpin_and_copy_requirements(ctx, requirement_file, name="requirements.txt"): "PIPENV_PYTHON": "3.6", } 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() 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) requirement_file.rename( - requirement_file.parent.joinpath("{}.bak".format(name)) + requirement_file.parent.joinpath(f"{name}.bak") ) new_requirements.write_text("\n".join(result)) return result @@ -886,8 +885,8 @@ def install_yaml(ctx): @invoke.task def vendor_artifact(ctx, package, version=None): - simple = requests.get("https://pypi.org/simple/{0}/".format(package)) - pkg_str = "{0}-{1}".format(package, version) + simple = requests.get(f"https://pypi.org/simple/{package}/") + pkg_str = f"{package}-{version}" soup = bs4.BeautifulSoup(simple.content) links = [ 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_path = urllib3_parse(link).path.rpartition("/") 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: shutil.copyfileobj(fp, target_handle) diff --git a/tasks/vendoring/safety/__main__.py b/tasks/vendoring/safety/__main__.py index 9c6bbba2..e1bcb4a0 100644 --- a/tasks/vendoring/safety/__main__.py +++ b/tasks/vendoring/safety/__main__.py @@ -1,5 +1,4 @@ """Allow safety to be executable through `python -m safety`.""" -from __future__ import absolute_import import os import sys @@ -38,7 +37,7 @@ def insert_before_site_packages(*paths): if __name__ == "__main__": 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) sys.modules['yaml'] = sys.modules[yaml_lib] from safety.cli import cli diff --git a/tasks/vendoring/safety/requirements.txt b/tasks/vendoring/safety/requirements.txt index a521ea82..ba28876a 100644 --- a/tasks/vendoring/safety/requirements.txt +++ b/tasks/vendoring/safety/requirements.txt @@ -26,4 +26,4 @@ importlib-resources==1.4.0 zipp==1.2.0 contextlib2==0.6.0.post1 enum34==1.1.10 -scandir==1.10.0 \ No newline at end of file +scandir==1.10.0 diff --git a/tests/fixtures/cython-import-package/setup.cfg b/tests/fixtures/cython-import-package/setup.cfg index a43ee22b..7069d27d 100644 --- a/tests/fixtures/cython-import-package/setup.cfg +++ b/tests/fixtures/cython-import-package/setup.cfg @@ -53,6 +53,5 @@ install_requires = universal = 1 [egg_info] -tag_build = +tag_build = tag_date = 0 - diff --git a/tests/fixtures/cython-import-package/setup.py b/tests/fixtures/cython-import-package/setup.py index 78eeeeda..3a816a94 100644 --- a/tests/fixtures/cython-import-package/setup.py +++ b/tests/fixtures/cython-import-package/setup.py @@ -23,7 +23,7 @@ with open(os.path.join(ROOT, 'src', PACKAGE_NAME.replace("-", "_"), '__init__.py VERSION = ast.literal_eval(line[len('__version__ = '):].strip()) break 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? diff --git a/tests/fixtures/fake-package/docs/conf.py b/tests/fixtures/fake-package/docs/conf.py index 3aded982..5f59ed52 100644 --- a/tests/fixtures/fake-package/docs/conf.py +++ b/tests/fixtures/fake-package/docs/conf.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # # Configuration file for the Sphinx documentation builder. # diff --git a/tests/fixtures/fake-package/setup.py b/tests/fixtures/fake-package/setup.py index 1d2c88f8..3048d506 100644 --- a/tests/fixtures/fake-package/setup.py +++ b/tests/fixtures/fake-package/setup.py @@ -16,7 +16,7 @@ with open(os.path.join(ROOT, 'src', PACKAGE_NAME.replace("-", "_"), '__init__.py VERSION = ast.literal_eval(line[len('__version__ = '):].strip()) break 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? diff --git a/tests/fixtures/fake-package/tasks/__init__.py b/tests/fixtures/fake-package/tasks/__init__.py index a8cedab4..9b68d16c 100644 --- a/tests/fixtures/fake-package/tasks/__init__.py +++ b/tests/fixtures/fake-package/tasks/__init__.py @@ -152,14 +152,14 @@ def build_docs(ctx): minor = [str(i) for i in _current_version.release[:2]] docs_folder = (ROOT / 'docs').as_posix() 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.extend(["-A", "'Dan Ryan '"]) args.extend(["-R", str(_current_version)]) args.extend(["-V", ".".join(minor)]) args.extend(["-e", "-M", "-F", f"src/{PACKAGE_NAME}"]) print("Building docs...") - ctx.run("sphinx-apidoc {0}".format(" ".join(args))) + ctx.run("sphinx-apidoc {}".format(" ".join(args))) @invoke.task diff --git a/tests/fixtures/legacy-backend-package/setup.cfg b/tests/fixtures/legacy-backend-package/setup.cfg index 1e5f1ed8..4d98081c 100644 --- a/tests/fixtures/legacy-backend-package/setup.cfg +++ b/tests/fixtures/legacy-backend-package/setup.cfg @@ -45,7 +45,7 @@ dev = [options] zip_safe = true python_requires = >=2.6,!=3.0,!=3.1,!=3.2,!=3.3 -setup_requires = +setup_requires = setuptools_scm>=3.3.1 install_requires = attrs @@ -55,7 +55,7 @@ install_requires = universal = 1 [egg_info] -tag_build = +tag_build = tag_date = 0 diff --git a/tests/fixtures/legacy-backend-package/setup.py b/tests/fixtures/legacy-backend-package/setup.py index e41a3e36..bb43fcaa 100644 --- a/tests/fixtures/legacy-backend-package/setup.py +++ b/tests/fixtures/legacy-backend-package/setup.py @@ -16,7 +16,7 @@ with open(os.path.join(ROOT, 'src', PACKAGE_NAME.replace("-", "_"), '__init__.py VERSION = ast.literal_eval(line[len('__version__ = '):].strip()) break 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? diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 20374e01..3686d167 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -1,6 +1,3 @@ -# -*- coding=utf-8 -*- -from __future__ import absolute_import, print_function - import errno import json import logging @@ -49,11 +46,11 @@ def check_internet(): try_internet(url) except KeyboardInterrupt: warnings.warn( - "Skipped connecting to internet: {0}".format(url), RuntimeWarning + f"Skipped connecting to internet: {url}", RuntimeWarning ) except Exception: warnings.warn( - "Failed connecting to internet: {0}".format(url), RuntimeWarning + f"Failed connecting to internet: {url}", RuntimeWarning ) else: has_internet = True @@ -223,7 +220,7 @@ WE_HAVE_INTERNET = check_internet() WE_HAVE_GITHUB_SSH_KEYS = False -class _Pipfile(object): +class _Pipfile: def __init__(self, path): self.path = path if self.path.exists(): @@ -234,7 +231,7 @@ class _Pipfile(object): self.document["requires"] = self.document.get("requires", tomlkit.table()) self.document["packages"] = self.document.get("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): section = "packages" if not dev else "dev_packages" @@ -292,15 +289,15 @@ class _Pipfile(object): fixture_pypi = os.getenv("ARTIFACT_PYPI_URL") if fixture_pypi: if pkg and not filename: - url = "{0}/artifacts/{1}".format(fixture_pypi, pkg) + url = f"{fixture_pypi}/artifacts/{pkg}" else: - url = "{0}/artifacts/{1}/{2}".format(fixture_pypi, pkg, filename) + url = f"{fixture_pypi}/artifacts/{pkg}/{filename}" return url if pkg and not filename: return cls.get_fixture_path(file_path).as_uri() -class _PipenvInstance(object): +class _PipenvInstance: """An instance of a Pipenv Project...""" def __init__( self, pypi=None, pipfile=True, chdir=False, path=None, home_dir=None, @@ -351,7 +348,7 @@ class _PipenvInstance(object): self.chdir = chdir 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_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: os.environ['PIPENV_CACHE_DIR'] = fs_str(tempdir.name) c = delegator.run( - 'pipenv {0}'.format(cmd), block=block, + f'pipenv {cmd}', block=block, cwd=os.path.abspath(self.path), env=os.environ.copy() ) if 'PIPENV_CACHE_DIR' in os.environ: @@ -400,7 +397,7 @@ class _PipenvInstance(object): # Pretty output for failing tests. if block: - print('$ pipenv {0}'.format(cmd)) + print(f'$ pipenv {cmd}') print(c.out) print(c.err, file=sys.stderr) if c.return_code != 0: @@ -412,13 +409,13 @@ class _PipenvInstance(object): @property def pipfile(self): 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()) @property def lockfile(self): p_path = self.lockfile_path - with open(p_path, 'r') as f: + with open(p_path) as f: return json.loads(f.read()) @property @@ -433,7 +430,7 @@ def _rmtree_func(path, ignore_errors=True, onerror=None): onerror = handle_remove_readonly try: 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 if exc.errno != errno.ENOENT: raise @@ -459,7 +456,7 @@ def PipenvInstance(pip_src_dir, monkeypatch, pypi): m.setenv("PIPENV_NOSPIN", fs_str("1")) m.setenv("CI", 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("ARTIFACT_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("CI", 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) warnings.simplefilter("ignore", category=ResourceWarning) warnings.filterwarnings("ignore", category=ResourceWarning, message="unclosed.*") @@ -494,7 +491,7 @@ def testsroot(): return TESTS_ROOT -class VirtualEnv(object): +class VirtualEnv: def __init__(self, name="venv", base_dir=None): if base_dir is None: base_dir = Path(_create_tracked_dir()) diff --git a/tests/integration/test_cli.py b/tests/integration/test_cli.py index f87a3723..fa5d88e8 100644 --- a/tests/integration/test_cli.py +++ b/tests/integration/test_cli.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import absolute_import, print_function """Tests to ensure `pipenv --option` works. """ @@ -120,22 +118,22 @@ def test_pipenv_graph_reverse(PipenvInstance): ] 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) - 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 if dep_name == 'openpyxl': 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 else: - dep_match = re.search(r'^[ -]*{}==[\d.]+$'.format(dep_name), output, flags=re.MULTILINE) - assert dep_match is not None, '{} not found at beginning of line in {}'.format(dep_name, output) + dep_match = re.search(fr'^[ -]*{dep_name}==[\d.]+$', output, flags=re.MULTILINE) + 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) - assert dep_requests_match is not None, 'constraint {} not found in {}'.format(dep_constraint, output) + dep_requests_match = re.search(fr'^ +- tablib==0.13.0 \[requires: {dep_constraint}\]$', output, flags=re.MULTILINE) + assert dep_requests_match is not None, f'constraint {dep_constraint} not found in {output}' 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")') c = p.pipenv('install -e .') 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 c = p.pipenv('clean') 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 @@ -178,7 +176,7 @@ def test_pipenv_clean_pip_warnings(PipenvInstance): f.write('from setuptools import setup; setup(name="empty")') # create a fake git repo to trigger a pip freeze warning 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 c = p.pipenv('clean') assert c.return_code == 0 diff --git a/tests/integration/test_install_basic.py b/tests/integration/test_install_basic.py index e47f8f2e..d77b90e5 100644 --- a/tests/integration/test_install_basic.py +++ b/tests/integration/test_install_basic.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import absolute_import, print_function import os import pytest @@ -55,7 +53,7 @@ def test_mirror_install(PipenvInstance): assert "pypi.org" not in mirror_url # This should sufficiently demonstrate the mirror functionality # 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 # Ensure the --pypi-mirror parameter hasn't altered the Pipfile or Pipfile.lock sources assert len(p.pipfile["source"]) == 1 @@ -91,8 +89,8 @@ def test_complex_lock(PipenvInstance): c = p.pipenv("install apscheduler") assert c.return_code == 0 assert "apscheduler" in p.pipfile["packages"] - assert "funcsigs" in p.lockfile[u"default"] - assert "futures" in p.lockfile[u"default"] + assert "funcsigs" in p.lockfile["default"] + assert "futures" in p.lockfile["default"] @flaky @@ -286,7 +284,7 @@ def test_requirements_to_pipfile(PipenvInstance, pypi): # Write a requirements file 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") assert c.return_code == 0 @@ -430,7 +428,7 @@ def test_system_and_deploy_work(PipenvInstance): c = p.pipenv("--rm") assert c.return_code == 0 Path(p.pipfile_path).write_text( - u""" + """ [packages] tablib = "*" """.strip() diff --git a/tests/integration/test_install_markers.py b/tests/integration/test_install_markers.py index a0c3a279..ecfaa6c5 100644 --- a/tests/integration/test_install_markers.py +++ b/tests/integration/test_install_markers.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import absolute_import, print_function import os import sys diff --git a/tests/integration/test_install_twists.py b/tests/integration/test_install_twists.py index 79396fa6..59989be5 100644 --- a/tests/integration/test_install_twists.py +++ b/tests/integration/test_install_twists.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import absolute_import, print_function import os import shutil import sys @@ -54,8 +52,8 @@ testpipenv = {path = ".", editable = true, extras = ["dev"]} assert "six" in p.lockfile["default"] c = p.pipenv("uninstall --all") assert c.return_code == 0 - print("Current directory: {0}".format(os.getcwd()), file=sys.stderr) - c = p.pipenv("install {0}".format(line)) + print(f"Current directory: {os.getcwd()}", file=sys.stderr) + c = p.pipenv(f"install {line}") assert c.return_code == 0 assert "testpipenv" in p.pipfile["packages"] assert p.pipfile["packages"]["testpipenv"]["path"] == "." @@ -67,7 +65,7 @@ testpipenv = {path = ".", editable = true, extras = ["dev"]} @pytest.mark.install @pytest.mark.needs_internet @flaky -class TestDirectDependencies(object): +class TestDirectDependencies: """Ensure dependency_links are parsed and installed. This is needed for private repo dependencies. @@ -126,7 +124,7 @@ setup( def test_e_dot(PipenvInstance, pip_src_dir): with PipenvInstance() as p: 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 @@ -239,7 +237,7 @@ def test_local_package(PipenvInstance, pip_src_dir, testsroot): with tarfile.open(copy_to, "r:gz") as tgz: 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 all( 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 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 key = [k for k in p.pipfile["packages"].keys()][0] dep = p.pipfile["packages"][key] @@ -286,7 +284,7 @@ def test_relative_paths(PipenvInstance, testsroot): mkdir_p(artifact_path) shutil.copy(source_path, os.path.join(artifact_path, file_name)) # 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 key = next(k for k in p.pipfile["packages"].keys()) 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) with open(fake_file, "w") as f: f.write("") - c = p.pipenv("install {}".format(target_package)) + c = p.pipenv(f"install {target_package}") assert c.return_code == 0 assert target_package in p.pipfile["packages"] 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: 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) pipfile_string += '"{0}" = {{path = "./{0}", editable = true}}\n'.format(pkg_name) diff --git a/tests/integration/test_lock.py b/tests/integration/test_lock.py index 453ea11d..292d7516 100644 --- a/tests/integration/test_lock.py +++ b/tests/integration/test_lock.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - import json import os import sys @@ -389,13 +387,13 @@ six = {version = "*", index = "testpypi"} fake-package = "*" """.strip() 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 - 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 '-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 {}'.format(mirror_url) not in c.out.strip() + assert f'--extra-index-url {mirror_url}' not in c.out.strip() @pytest.mark.lock @@ -650,7 +648,7 @@ requests = "*" @pytest.mark.install def test_lock_no_warnings(PipenvInstance): with PipenvInstance(chdir=True) as p: - os.environ["PYTHONWARNINGS"] = str("once") + os.environ["PYTHONWARNINGS"] = "once" c = p.pipenv("install six") assert c.return_code == 0 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", "*") assert "pathlib2" in p.pipfile["packages"] 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") assert c.return_code == 0, c.err 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: requests_uri = p._pipfile.get_fixture_path("git/requests").as_uri() p._pipfile.add("requests", { - "editable": True, "git": "{0}".format(requests_uri), + "editable": True, "git": f"{requests_uri}", "ref": "v2.18.4" }) p._pipfile.add("urllib3", "==1.21.1") diff --git a/tests/integration/test_pipenv.py b/tests/integration/test_pipenv.py index a8c2b5e2..d5fb8747 100644 --- a/tests/integration/test_pipenv.py +++ b/tests/integration/test_pipenv.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import absolute_import, print_function """Misc. tests that don't fit anywhere. 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') assert c.return_code == 0 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() assert '==1.3' in pipfile_contents pipfile_contents = pipfile_contents.replace('==1.3', '*') diff --git a/tests/integration/test_project.py b/tests/integration/test_project.py index 44872b0e..2cd0dc4d 100644 --- a/tests/integration/test_project.py +++ b/tests/integration/test_project.py @@ -1,5 +1,3 @@ -# -*- coding=utf-8 -*- -from __future__ import absolute_import, print_function import io import os import tarfile @@ -84,7 +82,7 @@ six = {{version = "*", index = "pypi"}} @pytest.mark.install @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): with PipenvInstance(chdir=True) as p: # Initial pipfile + lockfile generation @@ -93,15 +91,15 @@ def test_maintain_file_line_endings(PipenvInstance, newlines): # Rewrite each file with parameterized newlines for fn in [p.pipfile_path, p.lockfile_path]: - with io.open(fn) as f: + with open(fn) as f: contents = f.read() written_newlines = f.newlines - assert written_newlines == u'\n', '{0!r} != {1!r} for {2}'.format( - written_newlines, u'\n', fn, + assert written_newlines == '\n', '{!r} != {!r} for {}'.format( + written_newlines, '\n', fn, ) # 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) # 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 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. 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, ) # 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 tarfile.open(source_path, "r:gz") as tarinfo: 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 project = Project() assert "tablib" in [ @@ -185,14 +183,14 @@ def test_run_in_virtualenv_with_global_context(PipenvInstance, virtualenv): project.virtualenv_location, virtualenv.as_posix() ) 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), env=os.environ.copy() ) assert c.return_code == 0, (c.out, c.err) assert "Courtesy Notice" in c.err, (c.out, c.err) 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() ) assert c.return_code == 0, (c.out, c.err) @@ -243,4 +241,3 @@ pytest = "*" f.write(contents) c = p.pipenv('install --skip-lock') assert c.return_code == 0 - diff --git a/tests/integration/test_run.py b/tests/integration/test_run.py index 28f97e48..8cd39115 100644 --- a/tests/integration/test_run.py +++ b/tests/integration/test_run.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import absolute_import, print_function import os import pytest diff --git a/tests/integration/test_sync.py b/tests/integration/test_sync.py index 1c5b3e96..d0f6132f 100644 --- a/tests/integration/test_sync.py +++ b/tests/integration/test_sync.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import absolute_import, print_function import json import os @@ -38,9 +36,9 @@ verify_ssl = true [packages] six = "*" """.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 - c = p.pipenv('sync --pypi-mirror {0}'.format(mirror_url)) + c = p.pipenv(f'sync --pypi-mirror {mirror_url}') assert c.return_code == 0 @@ -112,4 +110,4 @@ requests = "*" c = p.pipenv('sync --sequential --verbose') for package in p.lockfile['default']: - assert 'Successfully installed {}'.format(package) in c.out + assert f'Successfully installed {package}' in c.out diff --git a/tests/integration/test_uninstall.py b/tests/integration/test_uninstall.py index 5825d436..1f363485 100644 --- a/tests/integration/test_uninstall.py +++ b/tests/integration/test_uninstall.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import absolute_import, print_function import os import shutil @@ -63,7 +61,7 @@ def test_mirror_uninstall(PipenvInstance): ) 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 "django" in p.pipfile["packages"] assert "django" in p.lockfile["default"] @@ -77,7 +75,7 @@ def test_mirror_uninstall(PipenvInstance): c = p.pipenv("run python -m django --version") 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 "django" not in p.pipfile["dev-packages"] 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: shutil.copy(source_path, os.path.join(p.path, file_name)) 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 c = p.pipenv("uninstall --all") assert c.return_code == 0 diff --git a/tests/integration/test_windows.py b/tests/integration/test_windows.py index 43efaef1..e4effecf 100644 --- a/tests/integration/test_windows.py +++ b/tests/integration/test_windows.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import absolute_import, print_function import os import pytest @@ -50,7 +48,7 @@ def test_local_path_windows(PipenvInstance): except OSError: whl = whl.absolute() with PipenvInstance(chdir=True) as p: - c = p.pipenv('install "{0}"'.format(whl)) + c = p.pipenv(f'install "{whl}"') assert c.return_code == 0 @@ -66,7 +64,7 @@ def test_local_path_windows_forward_slash(PipenvInstance): except OSError: whl = whl.absolute() 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 @@ -75,7 +73,7 @@ def test_pipenv_clean_windows(PipenvInstance): with PipenvInstance(chdir=True) as p: c = p.pipenv('install requests') 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 c = p.pipenv('clean --dry-run') diff --git a/tests/pytest-pypi/pyproject.toml b/tests/pytest-pypi/pyproject.toml index b0471b7f..864b334a 100644 --- a/tests/pytest-pypi/pyproject.toml +++ b/tests/pytest-pypi/pyproject.toml @@ -1,3 +1,3 @@ [build-system] requires = ["setuptools", "wheel"] -build-backend = "setuptools.build_meta:__legacy__" \ No newline at end of file +build-backend = "setuptools.build_meta:__legacy__" diff --git a/tests/pytest-pypi/pytest_pypi/app.py b/tests/pytest-pypi/pytest_pypi/app.py index 96bb774e..784150f8 100644 --- a/tests/pytest-pypi/pytest_pypi/app.py +++ b/tests/pytest-pypi/pytest_pypi/app.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import absolute_import, print_function import collections import contextlib import io @@ -42,11 +40,11 @@ def get_pypi_package_names(): return pypi_packages -class Package(object): +class Package: """Package represents a collection of releases from one or more directories""" def __init__(self, name): - super(Package, self).__init__() + super().__init__() self.name = name self.releases = {} self._package_dirs = set() @@ -58,7 +56,7 @@ class Package(object): with open(os.path.join(path, 'api.json')) as f: return json.load(f) 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() releases = response["releases"] files = { @@ -75,12 +73,12 @@ class Package(object): else: del releases[release] 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) return response def __repr__(self): - return " {% endfor %} - \ No newline at end of file + diff --git a/tests/pytest-pypi/setup.py b/tests/pytest-pypi/setup.py index 100432e5..2fcdd58b 100644 --- a/tests/pytest-pypi/setup.py +++ b/tests/pytest-pypi/setup.py @@ -24,7 +24,7 @@ class UploadCommand(Command): @staticmethod def status(s): """Prints things in bold.""" - print('\033[1m{0}\033[0m'.format(s)) + print(f'\033[1m{s}\033[0m') def initialize_options(self): pass @@ -40,13 +40,13 @@ class UploadCommand(Command): pass 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...') os.system('twine upload dist/*') 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') sys.exit() diff --git a/tests/unit/test_core.py b/tests/unit/test_core.py index 8eca202c..d7981a47 100644 --- a/tests/unit/test_core.py +++ b/tests/unit/test_core.py @@ -1,6 +1,6 @@ import os -import mock +from unittest import mock import pytest 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') key, val = 'SOME_KEY', 'some_value' 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.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') key, val = 'SOME_KEY', 'some_value' 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.setattr("pipenv.environments.PIPENV_DOTENV_LOCATION", str(dotenv_path)) diff --git a/tests/unit/test_environments.py b/tests/unit/test_environments.py index 6baf84c8..efeb2424 100644 --- a/tests/unit/test_environments.py +++ b/tests/unit/test_environments.py @@ -11,12 +11,12 @@ from pipenv.utils import temp_environ list(itertools.product(("ENABLE_SOMETHING",), ("FAKEPREFIX", None), (True, False))), ) def test_get_from_env(arg, prefix, use_negation): - negated_arg = "NO_{0}".format(arg) + negated_arg = f"NO_{arg}" positive_var = arg negative_var = negated_arg if prefix: - negative_var = "{0}_{1}".format(prefix, negative_var) - positive_var = "{0}_{1}".format(prefix, positive_var) + negative_var = f"{prefix}_{negative_var}" + positive_var = f"{prefix}_{positive_var}" # set the positive first for var_to_set, opposite_var in ((arg, negated_arg), (negated_arg, arg)): os.environ.pop(var_to_set, None) diff --git a/tests/unit/test_patched.py b/tests/unit/test_patched.py index 69461e24..7137ea2f 100644 --- a/tests/unit/test_patched.py +++ b/tests/unit/test_patched.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - import pytest from notpip._internal.index.package_finder import PackageFinder diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py index 24df26a6..47a755ff 100644 --- a/tests/unit/test_utils.py +++ b/tests/unit/test_utils.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import os 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()] -@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 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) assert deps[0] == "django==1.10" diff --git a/tests/unit/test_vendor.py b/tests/unit/test_vendor.py index aea93112..62f317b9 100644 --- a/tests/unit/test_vendor.py +++ b/tests/unit/test_vendor.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # We need to import the patched packages directly from sys.path, so the # identity checks can pass. import pipenv # noqa @@ -82,6 +81,6 @@ def test_token_date(dt, content): def test_dump_nonascii_string(): - content = u'name = "Stažené"\n' + content = 'name = "Stažené"\n' toml_content = tomlkit.dumps(tomlkit.loads(content)) assert toml_content == content