From 73c856507cd8b337ce0b6c7f5b19fbe524c83de6 Mon Sep 17 00:00:00 2001 From: Sourcery AI <> Date: Tue, 14 Feb 2023 21:10:14 +0000 Subject: [PATCH] 'Refactored by Sourcery' --- pipenv/cli/command.py | 20 +- pipenv/cli/options.py | 15 +- pipenv/core.py | 320 ++++++++---------- pipenv/environment.py | 93 +++-- pipenv/environments.py | 29 +- pipenv/exceptions.py | 32 +- pipenv/installers.py | 9 +- pipenv/patched/pip/__pip-runner__.py | 6 +- pipenv/patched/pip/_internal/build_env.py | 17 +- pipenv/patched/pip/_internal/cache.py | 19 +- .../pip/_internal/cli/autocompletion.py | 55 ++- .../patched/pip/_internal/cli/base_command.py | 12 +- .../patched/pip/_internal/cli/cmdoptions.py | 23 +- .../patched/pip/_internal/cli/main_parser.py | 15 +- pipenv/patched/pip/_internal/cli/parser.py | 50 +-- .../patched/pip/_internal/cli/req_command.py | 11 +- .../pip/_internal/commands/__init__.py | 8 +- .../patched/pip/_internal/commands/cache.py | 15 +- .../patched/pip/_internal/commands/check.py | 5 +- .../pip/_internal/commands/completion.py | 10 +- .../pip/_internal/commands/configuration.py | 14 +- .../patched/pip/_internal/commands/debug.py | 23 +- .../patched/pip/_internal/commands/freeze.py | 5 +- pipenv/patched/pip/_internal/commands/hash.py | 4 +- .../patched/pip/_internal/commands/index.py | 8 +- .../patched/pip/_internal/commands/install.py | 29 +- pipenv/patched/pip/_internal/commands/list.py | 30 +- .../patched/pip/_internal/commands/search.py | 30 +- pipenv/patched/pip/_internal/commands/show.py | 18 +- .../pip/_internal/commands/uninstall.py | 5 +- pipenv/patched/pip/_internal/configuration.py | 28 +- pipenv/patched/pip/_internal/exceptions.py | 73 ++-- .../patched/pip/_internal/index/collector.py | 32 +- .../pip/_internal/index/package_finder.py | 22 +- .../pip/_internal/locations/__init__.py | 19 +- .../pip/_internal/locations/_distutils.py | 7 +- .../pip/_internal/locations/_sysconfig.py | 8 +- .../patched/pip/_internal/locations/base.py | 10 +- .../pip/_internal/metadata/__init__.py | 2 +- .../patched/pip/_internal/metadata/_json.py | 29 +- pipenv/patched/pip/_internal/metadata/base.py | 63 ++-- .../_internal/metadata/importlib/_dists.py | 12 +- .../pip/_internal/metadata/importlib/_envs.py | 21 +- .../pip/_internal/metadata/pkg_resources.py | 19 +- .../pip/_internal/models/direct_url.py | 7 +- .../pip/_internal/models/format_control.py | 16 +- pipenv/patched/pip/_internal/models/link.py | 33 +- .../pip/_internal/models/search_scope.py | 14 +- pipenv/patched/pip/_internal/network/auth.py | 35 +- .../patched/pip/_internal/network/download.py | 9 +- .../patched/pip/_internal/network/session.py | 26 +- pipenv/patched/pip/_internal/network/utils.py | 11 +- .../operations/build/build_tracker.py | 2 +- .../operations/build/metadata_legacy.py | 2 +- .../operations/build/wheel_legacy.py | 3 +- .../pip/_internal/operations/freeze.py | 49 +-- .../pip/_internal/operations/install/wheel.py | 80 +---- .../pip/_internal/operations/prepare.py | 29 +- pipenv/patched/pip/_internal/pyproject.py | 40 +-- .../patched/pip/_internal/req/constructors.py | 66 ++-- pipenv/patched/pip/_internal/req/req_file.py | 75 ++-- .../patched/pip/_internal/req/req_install.py | 82 ++--- .../pip/_internal/req/req_uninstall.py | 28 +- .../_internal/resolution/legacy/resolver.py | 18 +- .../_internal/resolution/resolvelib/base.py | 2 +- .../resolution/resolvelib/candidates.py | 26 +- .../resolution/resolvelib/factory.py | 66 ++-- .../resolution/resolvelib/found_candidates.py | 20 +- .../resolution/resolvelib/provider.py | 6 +- .../resolution/resolvelib/requirements.py | 2 +- .../pip/_internal/self_outdated_check.py | 10 +- pipenv/patched/pip/_internal/utils/compat.py | 14 +- .../pip/_internal/utils/compatibility_tags.py | 49 ++- .../pip/_internal/utils/deprecation.py | 26 +- .../pip/_internal/utils/direct_url_helpers.py | 13 +- .../patched/pip/_internal/utils/encoding.py | 2 +- .../patched/pip/_internal/utils/filesystem.py | 22 +- .../patched/pip/_internal/utils/filetypes.py | 4 +- pipenv/patched/pip/_internal/utils/glibc.py | 5 +- pipenv/patched/pip/_internal/utils/hashes.py | 19 +- pipenv/patched/pip/_internal/utils/logging.py | 18 +- pipenv/patched/pip/_internal/utils/misc.py | 85 ++--- pipenv/patched/pip/_internal/utils/models.py | 9 +- .../pip/_internal/utils/setuptools_build.py | 6 +- .../patched/pip/_internal/utils/subprocess.py | 9 +- .../patched/pip/_internal/utils/temp_dir.py | 10 +- pipenv/patched/pip/_internal/utils/urls.py | 7 +- pipenv/patched/pip/_internal/utils/wheel.py | 7 +- pipenv/patched/pip/_internal/vcs/bazaar.py | 6 +- pipenv/patched/pip/_internal/vcs/git.py | 29 +- pipenv/patched/pip/_internal/vcs/mercurial.py | 9 +- .../patched/pip/_internal/vcs/subversion.py | 20 +- .../pip/_internal/vcs/versioncontrol.py | 38 +-- pipenv/patched/pip/_internal/wheel_builder.py | 18 +- .../pip/_vendor/cachecontrol/adapter.py | 4 +- .../_vendor/cachecontrol/caches/file_cache.py | 4 +- .../pip/_vendor/cachecontrol/controller.py | 25 +- .../pip/_vendor/cachecontrol/heuristics.py | 4 +- .../pip/_vendor/cachecontrol/serialize.py | 34 +- .../patched/pip/_vendor/chardet/__init__.py | 4 +- .../pip/_vendor/chardet/chardistribution.py | 31 +- .../pip/_vendor/chardet/charsetgroupprober.py | 16 +- .../pip/_vendor/chardet/eucjpprober.py | 11 +- .../pip/_vendor/chardet/hebrewprober.py | 15 +- .../pip/_vendor/chardet/mbcharsetprober.py | 11 +- .../pip/_vendor/chardet/sbcharsetprober.py | 52 +-- .../patched/pip/_vendor/chardet/sjisprober.py | 11 +- .../pip/_vendor/chardet/universaldetector.py | 72 ++-- .../pip/_vendor/chardet/utf1632prober.py | 62 ++-- .../patched/pip/_vendor/chardet/utf8prober.py | 16 +- pipenv/patched/pip/_vendor/colorama/ansi.py | 2 +- .../pip/_vendor/colorama/ansitowin32.py | 32 +- pipenv/patched/pip/_vendor/six.py | 152 ++++++--- .../patched/pip/_vendor/typing_extensions.py | 85 +++-- pipenv/project.py | 141 ++++---- pipenv/resolver.py | 64 ++-- pipenv/shells.py | 21 +- 117 files changed, 1364 insertions(+), 1962 deletions(-) diff --git a/pipenv/cli/command.py b/pipenv/cli/command.py index f0cbcc91e0..1484790c45 100644 --- a/pipenv/cli/command.py +++ b/pipenv/cli/command.py @@ -280,7 +280,7 @@ def uninstall(ctx, state, all_dev=False, all=False, **kwargs): """Uninstalls a provided package and removes it from Pipfile.""" from ..core import do_uninstall - retcode = do_uninstall( + if retcode := do_uninstall( state.project, packages=state.installstate.packages, editable_packages=state.installstate.editables, @@ -293,8 +293,7 @@ def uninstall(ctx, state, all_dev=False, all=False, **kwargs): pypi_mirror=state.pypi_mirror, categories=state.installstate.categories, ctx=ctx, - ) - if retcode: + ): sys.exit(retcode) @@ -667,7 +666,7 @@ def sync(ctx, state, bare=False, user=False, unused=False, **kwargs): """Installs all packages specified in Pipfile.lock.""" from ..core import do_sync - retcode = do_sync( + if retcode := do_sync( state.project, dev=state.installstate.dev, python=state.python, @@ -680,8 +679,7 @@ def sync(ctx, state, bare=False, user=False, unused=False, **kwargs): system=state.system, extra_pip_args=state.installstate.extra_pip_args, categories=state.installstate.categories, - ) - if retcode: + ): ctx.abort() @@ -720,13 +718,15 @@ def scripts(state): scripts = state.project.parsed_pipfile.get("scripts", {}) first_column_width = max(len(word) for word in ["Command"] + list(scripts)) second_column_width = max(len(word) for word in ["Script"] + list(scripts.values())) - lines = ["{0:<{width}} Script".format("Command", width=first_column_width)] - lines.append("{} {}".format("-" * first_column_width, "-" * second_column_width)) + lines = [ + "{0:<{width}} Script".format("Command", width=first_column_width), + f'{"-" * first_column_width} {"-" * second_column_width}', + ] lines.extend( "{0:<{width}} {1}".format(name, script, width=first_column_width) for name, script in scripts.items() ) - echo("\n".join(line for line in lines)) + echo("\n".join(lines)) @cli.command( @@ -786,7 +786,7 @@ def requirements( if categories_list: for category in categories_list: category = get_lockfile_section_using_pipfile_category(category.strip()) - deps.update(lockfile.get(category, {})) + deps |= lockfile.get(category, {}) else: if dev or dev_only: deps.update(lockfile["develop"]) diff --git a/pipenv/cli/options.py b/pipenv/cli/options.py index e3fe51cfb5..853b46c682 100644 --- a/pipenv/cli/options.py +++ b/pipenv/cli/options.py @@ -515,21 +515,22 @@ def validate_python_path(ctx, param, value): # autodetection but it may also be a value which will be searched in # the path or an absolute path. To report errors as early as possible # we'll report absolute paths which do not exist: - if isinstance(value, (str, bytes)): - if os.path.isabs(value) and not os.path.isfile(value): - raise BadParameter("Expected Python at path %s does not exist" % value) + if ( + isinstance(value, (str, bytes)) + and os.path.isabs(value) + and not os.path.isfile(value) + ): + raise BadParameter(f"Expected Python at path {value} does not exist") return value def validate_bool_or_none(ctx, param, value): - if value is not None: - return click_types.BOOL(value) - return False + return click_types.BOOL(value) if value is not None else False def validate_pypi_mirror(ctx, param, value): if value and not is_valid_url(value): - raise BadParameter("Invalid PyPI mirror URL: %s" % value) + raise BadParameter(f"Invalid PyPI mirror URL: {value}") return value diff --git a/pipenv/core.py b/pipenv/core.py index d3b2882b6d..2049b21fa9 100644 --- a/pipenv/core.py +++ b/pipenv/core.py @@ -116,8 +116,6 @@ def do_clear(project): # Ignore FileNotFoundError. This is needed for Python 2.7. import errno - if e.errno == errno.ENOENT: - pass raise @@ -148,8 +146,7 @@ def import_requirements(project, r=None, dev=False): # Default path, if none is provided. if r is None: r = project.requirements_location - with open(r) as f: - contents = f.read() + contents = Path(r).read_text() indexes = [] trusted_hosts = [] # Find and add extra indexes. @@ -169,7 +166,9 @@ def import_requirements(project, r=None, dev=False): ] for package in reqs: if package.name not in BAD_PACKAGES: - if package.link is not None: + if package.link is None: + project.add_package_to_pipfile(str(package.req), dev=dev) + else: if package.editable: package_string = f"-e {package.link}" else: @@ -179,25 +178,18 @@ def import_requirements(project, r=None, dev=False): safe = False if pw and not re.match(r"\${[\W\w]+}", pw): safe = False - if safe: - package_string = str(package.link._url) - else: - package_string = str(package.link) + package_string = str(package.link._url) if safe else str(package.link) project.add_package_to_pipfile(package_string, dev=dev) - else: - project.add_package_to_pipfile(str(package.req), dev=dev) for index in indexes: # don't require HTTPS for trusted hosts (see: https://pip.pypa.io/en/stable/cli/pip/#cmdoption-trusted-host) host_and_port = get_host_and_port(index) - require_valid_https = not any( - ( - v in trusted_hosts - for v in ( - host_and_port, - host_and_port.partition(":")[ - 0 - ], # also check if hostname without port is in trusted_hosts - ) + require_valid_https = all( + v not in trusted_hosts + for v in ( + host_and_port, + host_and_port.partition(":")[ + 0 + ], # also check if hostname without port is in trusted_hosts ) ) project.add_index_to_pipfile(index, verify_ssl=require_valid_https) @@ -206,18 +198,17 @@ def import_requirements(project, r=None, dev=False): def ensure_environment(): # Skip this on Windows... - if os.name != "nt": - if "LANG" not in os.environ: - click.echo( - "{}: the environment variable {} is not set!" - "\nWe recommend setting this in {} (or equivalent) for " - "proper expected behavior.".format( - click.style("Warning", fg="red", bold=True), - click.style("LANG", bold=True), - click.style("~/.profile", fg="green"), - ), - err=True, - ) + if os.name != "nt" and "LANG" not in os.environ: + click.echo( + "{}: the environment variable {} is not set!" + "\nWe recommend setting this in {} (or equivalent) for " + "proper expected behavior.".format( + click.style("Warning", fg="red", bold=True), + click.style("LANG", bold=True), + click.style("~/.profile", fg="green"), + ), + err=True, + ) def ensure_pipfile(project, validate=True, skip_requirements=False, system=False): @@ -225,9 +216,9 @@ def ensure_pipfile(project, validate=True, skip_requirements=False, system=False # Assert Pipfile exists. python = ( - project._which("python") - if not (project.s.USING_DEFAULT_PYTHON or system) - else None + None + if (project.s.USING_DEFAULT_PYTHON or system) + else project._which("python") ) if project.pipfile_is_empty: # Show an error message and exit if system is passed and no pipfile exists @@ -280,9 +271,7 @@ def ensure_pipfile(project, validate=True, skip_requirements=False, system=False if validate and project.virtualenv_exists and not project.s.PIPENV_SKIP_VALIDATION: # Ensure that Pipfile is using proper casing. p = project.parsed_pipfile - changed = project.ensure_proper_casing() - # Write changes out to disk. - if changed: + if changed := project.ensure_proper_casing(): click.echo( click.style("Fixing package names in Pipfile...", bold=True), err=True ) @@ -310,8 +299,7 @@ def find_a_system_python(line): # Use the windows finder executable if (line.startswith("py ") or line.startswith("py.exe ")) and os.name == "nt": line = line.split(" ", 1)[1].lstrip("-") - python_entry = find_python(finder, line) - return python_entry + return find_python(finder, line) def ensure_python(project, python=None): @@ -473,7 +461,6 @@ def abort(): # If interrupted, cleanup the virtualenv. cleanup_virtualenv(project, bare=False) sys.exit(1) - # If --python or was passed... elif (python) or (site_packages is not None): project.s.USING_DEFAULT_PYTHON = False # Ensure python is installed before deleting existing virtual env @@ -485,12 +472,12 @@ def abort(): # If VIRTUAL_ENV is set, there is a possibility that we are # going to remove the active virtualenv that the user cares # about, so confirm first. - if "VIRTUAL_ENV" in os.environ: - if not ( - project.s.PIPENV_YES - or click.confirm("Use existing virtualenv?", default=True) - ): - abort() + if ( + "VIRTUAL_ENV" in os.environ + and not project.s.PIPENV_YES + and not click.confirm("Use existing virtualenv?", default=True) + ): + abort() click.echo(click.style("Using existing virtualenv...", bold=True), err=True) # Remove the virtualenv. cleanup_virtualenv(project, bare=True) @@ -532,41 +519,39 @@ def ensure_project( site_packages=site_packages, pypi_mirror=pypi_mirror, ) - if warn: - # Warn users if they are using the wrong version of Python. - if project.required_python_version: - path_to_python = project._which("python") or project._which("py") - if path_to_python and project.required_python_version not in ( - python_version(path_to_python) or "" - ): - click.echo( - "{}: Your Pipfile requires {} {}, " - "but you are using {} ({}).".format( - click.style("Warning", fg="red", bold=True), - click.style("python_version", bold=True), - click.style(project.required_python_version, fg="cyan"), - click.style( - python_version(path_to_python) or "unknown", fg="cyan" - ), - click.style(shorten_path(path_to_python), fg="green"), + if warn and project.required_python_version: + path_to_python = project._which("python") or project._which("py") + if path_to_python and project.required_python_version not in ( + python_version(path_to_python) or "" + ): + click.echo( + "{}: Your Pipfile requires {} {}, " + "but you are using {} ({}).".format( + click.style("Warning", fg="red", bold=True), + click.style("python_version", bold=True), + click.style(project.required_python_version, fg="cyan"), + click.style( + python_version(path_to_python) or "unknown", fg="cyan" ), - err=True, - ) + click.style(shorten_path(path_to_python), fg="green"), + ), + err=True, + ) + click.echo( + " {} and rebuilding the virtual environment " + "may resolve the issue.".format( + click.style("$ pipenv --rm", fg="green") + ), + err=True, + ) + if not deploy: click.echo( - " {} and rebuilding the virtual environment " - "may resolve the issue.".format( - click.style("$ pipenv --rm", fg="green") - ), + " {} will surely fail." + "".format(click.style("$ pipenv check", fg="yellow")), err=True, ) - if not deploy: - click.echo( - " {} will surely fail." - "".format(click.style("$ pipenv check", fg="yellow")), - err=True, - ) - else: - raise exceptions.DeployException + else: + raise exceptions.DeployException # Ensure the Pipfile exists. ensure_pipfile( project, @@ -800,10 +785,7 @@ def batch_install_iteration( del os.environ["PYTHONHOME"] if "GIT_CONFIG" in os.environ: del os.environ["GIT_CONFIG"] - use_pep517 = True - if not retry and not is_artifact: - use_pep517 = False - + use_pep517 = bool(retry or is_artifact) cmds = pip_install_deps( project, deps=deps_to_install, @@ -902,7 +884,7 @@ def do_install_dependencies( while not failed_deps_queue.empty(): failed_dep = failed_deps_queue.get() retry_list.append(failed_dep) - install_kwargs.update({"retry": False}) + install_kwargs["retry"] = False batch_install( project, retry_list, @@ -978,11 +960,7 @@ def do_create_virtualenv(project, python=None, site_packages=None, pypi_mirror=N if site_packages: click.secho("Making site-packages available...", bold=True, err=True) - if pypi_mirror: - pip_config = {"PIP_INDEX_URL": pypi_mirror} - else: - pip_config = {} - + pip_config = {"PIP_INDEX_URL": pypi_mirror} if pypi_mirror else {} error = None with console.status( "Creating virtual environment...", spinner=project.s.PIPENV_SPINNER @@ -1133,7 +1111,7 @@ def do_lock( click.echo( "{} {} {}".format( click.style("Locking"), - click.style("[{}]".format(pipfile_category), fg="yellow"), + click.style(f"[{pipfile_category}]", fg="yellow"), click.style("dependencies..."), ), err=True, @@ -1185,26 +1163,23 @@ def do_lock( ][missing_pkg].copy() # Overwrite any category packages with default packages. for category in lockfile_categories: - if category == "default": - pass if lockfile.get(category): lockfile[category].update( overwrite_with_default(lockfile.get("default", {}), lockfile[category]) ) - if write: - lockfile.update({"_meta": project.get_lockfile_meta()}) - project.write_lockfile(lockfile) - click.echo( - "{}".format( - click.style( - "Updated Pipfile.lock ({})!".format(project.get_lockfile_hash()), - bold=True, - ) - ), - err=True, - ) - else: + if not write: return lockfile + lockfile.update({"_meta": project.get_lockfile_meta()}) + project.write_lockfile(lockfile) + click.echo( + "{}".format( + click.style( + f"Updated Pipfile.lock ({project.get_lockfile_hash()})!", + bold=True, + ) + ), + err=True, + ) def do_purge(project, bare=False, downloads=False, allow_global=False): @@ -1279,13 +1254,16 @@ def do_init( if categories is None: categories = [] - if not system and not project.s.PIPENV_USE_SYSTEM: - if not project.virtualenv_exists: - try: - do_create_virtualenv(project, python=python, pypi_mirror=pypi_mirror) - except KeyboardInterrupt: - cleanup_virtualenv(project, bare=False) - sys.exit(1) + if ( + not system + and not project.s.PIPENV_USE_SYSTEM + and not project.virtualenv_exists + ): + try: + do_create_virtualenv(project, python=python, pypi_mirror=pypi_mirror) + except KeyboardInterrupt: + cleanup_virtualenv(project, bare=False) + sys.exit(1) # Ensure the Pipfile exists. if not deploy: ensure_pipfile(project, system=system) @@ -1300,18 +1278,13 @@ def do_init( if new_hash != old_hash: if deploy: click.secho( - "Your Pipfile.lock ({}) is out of date. Expected: ({}).".format( - old_hash[-6:], new_hash[-6:] - ), + f"Your Pipfile.lock ({old_hash[-6:]}) is out of date. Expected: ({new_hash[-6:]}).", fg="red", ) raise exceptions.DeployException elif (system or allow_global) and not (project.s.PIPENV_VIRTUALENV): click.secho( - "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"), + f"Pipfile.lock ({old_hash[-6:]}) out of date, but installation uses --system re-building lockfile must happen in isolation. Please rebuild lockfile in a virtualenv. Continuing anyway...", fg="yellow", err=True, ) @@ -1337,8 +1310,6 @@ def do_init( ) # Write out the lockfile if it doesn't exist. if not project.lockfile_exists and not skip_lock: - # Unless we're in a virtualenv not managed by pipenv, abort if we're - # using the system's python. if (system or allow_global) and not (project.s.PIPENV_VIRTUALENV): raise exceptions.PipenvOptionsError( "--system", @@ -1346,21 +1317,20 @@ def do_init( "not installation of specific packages. Aborting.\n" "See also: --deploy flag.", ) - else: - click.secho( - "Pipfile.lock not found, creating...", - bold=True, - err=True, - ) - do_lock( - project, - system=system, - pre=pre, - keep_outdated=keep_outdated, - write=True, - pypi_mirror=pypi_mirror, - categories=categories, - ) + click.secho( + "Pipfile.lock not found, creating...", + bold=True, + err=True, + ) + do_lock( + project, + system=system, + pre=pre, + keep_outdated=keep_outdated, + write=True, + pypi_mirror=pypi_mirror, + categories=categories, + ) do_install_dependencies( project, dev=dev, @@ -1408,18 +1378,17 @@ def get_pip_args( "no_deps": ["--no-deps"], "selective_upgrade": [ "--upgrade-strategy=only-if-needed", - "--exists-action={}".format(project.s.PIP_EXISTS_ACTION or "i"), + f'--exists-action={project.s.PIP_EXISTS_ACTION or "i"}', ], "src_dir": src_dir, } arg_set = ["--no-input"] if project.settings.get("disable_pip_input", True) else [] - for key in arg_map.keys(): + for key in arg_map: if key in locals() and locals().get(key): arg_set.extend(arg_map.get(key)) elif key == "selective_upgrade" and not locals().get(key): arg_set.append("--exists-action=i") - for extra_pip_arg in extra_pip_args: - arg_set.append(extra_pip_arg) + arg_set.extend(iter(extra_pip_args)) return list(dict.fromkeys(arg_set)) @@ -1429,22 +1398,18 @@ def get_requirement_line( include_hashes: bool = True, format_for_file: bool = False, ) -> Union[List[str], str]: - if requirement.vcs or requirement.is_file_or_url: - if src_dir and requirement.line_instance.wheel_kwargs: - requirement.line_instance._wheel_kwargs.update({"src_dir": src_dir}) - line = requirement.line_instance.line - if requirement.line_instance.markers: - line = f"{line}; {requirement.line_instance.markers}" - if not format_for_file: - line = f'"{line}"' - if requirement.editable: - if not format_for_file: - return ["-e", line] - return f"-e {line}" + if not requirement.vcs and not requirement.is_file_or_url: + return requirement.as_line(include_hashes=include_hashes, as_list=not format_for_file) + if src_dir and requirement.line_instance.wheel_kwargs: + requirement.line_instance._wheel_kwargs.update({"src_dir": src_dir}) + line = requirement.line_instance.line + if requirement.line_instance.markers: + line = f"{line}; {requirement.line_instance.markers}" if not format_for_file: - return [line] - return line - return requirement.as_line(include_hashes=include_hashes, as_list=not format_for_file) + line = f'"{line}"' + if requirement.editable: + return f"-e {line}" if format_for_file else ["-e", line] + return line if format_for_file else [line] def write_requirement_to_file( @@ -1495,16 +1460,18 @@ def pip_install( ): piplogger = logging.getLogger("pipenv.patched.pip._internal.commands.install") trusted_hosts = get_trusted_hosts() - if not allow_global: - src_dir = os.getenv( - "PIP_SRC", os.getenv("PIP_SRC_DIR", project.virtualenv_src_location) + src_dir = ( + os.getenv("PIP_SRC", os.getenv("PIP_SRC_DIR")) + if allow_global + else os.getenv( + "PIP_SRC", + os.getenv("PIP_SRC_DIR", project.virtualenv_src_location), ) - else: - src_dir = os.getenv("PIP_SRC", os.getenv("PIP_SRC_DIR")) + ) if requirement: if requirement.editable or not requirement.hashes: ignore_hashes = True - elif not (requirement.is_vcs or requirement.editable or requirement.vcs): + elif not requirement.is_vcs and not requirement.vcs: ignore_hashes = False line = None # Try installing for each source in project.sources. @@ -1587,9 +1554,7 @@ def pip_install( if project.s.is_verbose(): click.echo(f"$ {cmd_list_to_shell(pip_command)}", err=True) cache_dir = Path(project.s.PIPENV_CACHE_DIR) - default_exists_action = "w" - if selective_upgrade: - default_exists_action = "i" + default_exists_action = "i" if selective_upgrade else "w" exists_action = project.s.PIP_EXISTS_ACTION or default_exists_action pip_config = { "PIP_CACHE_DIR": cache_dir.as_posix(), @@ -1601,7 +1566,7 @@ def pip_install( if src_dir: if project.s.is_verbose(): click.echo(f"Using source directory: {src_dir!r}", err=True) - pip_config.update({"PIP_SRC": src_dir}) + pip_config["PIP_SRC"] = src_dir c = subprocess_run(pip_command, block=block, env=pip_config) c.env = pip_config return c @@ -1619,12 +1584,14 @@ def pip_install_deps( use_pep517=True, extra_pip_args: Optional[List] = None, ): - if not allow_global: - src_dir = os.getenv( - "PIP_SRC", os.getenv("PIP_SRC_DIR", project.virtualenv_src_location) + src_dir = ( + os.getenv("PIP_SRC", os.getenv("PIP_SRC_DIR")) + if allow_global + else os.getenv( + "PIP_SRC", + os.getenv("PIP_SRC_DIR", project.virtualenv_src_location), ) - else: - src_dir = os.getenv("PIP_SRC", os.getenv("PIP_SRC_DIR")) + ) if not requirements_dir: requirements_dir = vistir.path.create_tracked_tempdir( prefix="pipenv", suffix="requirements" @@ -1739,12 +1706,9 @@ def pip_install_deps( if src_dir: if project.s.is_verbose(): click.echo(f"Using source directory: {src_dir!r}", err=True) - pip_config.update({"PIP_SRC": src_dir}) + pip_config["PIP_SRC"] = src_dir c = subprocess_run(pip_command, block=False, capture_output=True, env=pip_config) - if file == standard_requirements: - c.deps = standard_deps - else: - c.deps = editable_deps + c.deps = standard_deps if file == standard_requirements else editable_deps c.env = pip_config cmds.append(c) if project.s.is_verbose(): @@ -1810,13 +1774,9 @@ def fallback_which(command, location=None, allow_global=False, system=False): global_search = True finder = Finder(system=False, global_search=global_search, path=location) if is_python_command(command): - result = find_python(finder, command) - if result: + if result := find_python(finder, command): return result - result = finder.which(command) - if result: - return result.path.as_posix() - return "" + return result.path.as_posix() if (result := finder.which(command)) else "" def format_help(help): diff --git a/pipenv/environment.py b/pipenv/environment.py index 5edfaad79c..2d33d48a22 100644 --- a/pipenv/environment.py +++ b/pipenv/environment.py @@ -56,7 +56,7 @@ def __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 + self.base_working_set = base_working_set or BASE_WORKING_SET prefix = normalize_path(prefix) self._python = None if python is not None: @@ -72,7 +72,7 @@ def __init__( pipfile = project.parsed_pipfile self.pipfile = pipfile self.extra_dists = [] - prefix = prefix if prefix else sys.prefix + prefix = prefix or sys.prefix self.prefix = Path(prefix) self._base_paths = {} if self.is_venv: @@ -86,11 +86,14 @@ def safe_import(self, name: str) -> ModuleType: self._modules[name] = importlib.import_module(name) module = self._modules[name] if not module: - dist = next( - iter(dist for dist in self.base_working_set if dist.project_name == name), + if dist := next( + iter( + dist + for dist in self.base_working_set + if dist.project_name == name + ), None, - ) - if dist: + ): dist.activate() module = importlib.import_module(name) return module @@ -109,8 +112,7 @@ def resolve_dist( :rtype: set(:class:`pkg_resources.Distribution`) """ - deps = set() - deps.add(dist) + deps = {dist} try: reqs = dist.requires() # KeyError = limited metadata can be found @@ -140,8 +142,7 @@ def add_dist(self, dist_name: str) -> None: def python_version(self) -> str: with self.activated(): sysconfig = self.safe_import("sysconfig") - py_version = sysconfig.get_python_version() - return py_version + return sysconfig.get_python_version() def find_libdir(self) -> Optional[Path]: libdir = self.prefix / "lib" @@ -151,14 +152,13 @@ def find_libdir(self) -> Optional[Path]: def python_info(self) -> Dict[str, str]: include_dir = self.prefix / "include" if not os.path.exists(include_dir): - include_dirs = self.get_include_path() - if include_dirs: - include_path = include_dirs.get( + if include_dirs := self.get_include_path(): + if include_path := include_dirs.get( "include", include_dirs.get("platinclude") - ) - if not include_path: + ): + include_dir = Path(include_path) + else: return {} - include_dir = Path(include_path) python_path = next(iter(list(include_dir.iterdir())), None) if python_path and python_path.name.startswith("python"): python_version = python_path.name.replace("python", "") @@ -261,10 +261,7 @@ def base_paths(self) -> Dict[str, str]: paths["prefix"] = prefix purelib = paths["purelib"] = make_posix(paths["purelib"]) platlib = paths["platlib"] = make_posix(paths["platlib"]) - if purelib == platlib: - lib_dirs = purelib - else: - lib_dirs = purelib + os.pathsep + platlib + lib_dirs = purelib if purelib == platlib else purelib + os.pathsep + platlib paths["libdir"] = purelib paths["PYTHONPATH"] = os.pathsep.join(["", ".", lib_dirs]) paths["libdirs"] = lib_dirs @@ -347,15 +344,15 @@ def build_command( ) sysconfig_line = "sysconfig.get_path('{0}')" if python_lib: - for key in ("purelib", "platlib", "stdlib", "platstdlib"): - pylib_lines.append( - f"u'{key}': u'{{0}}'.format({sysconfig_line.format(key)})" - ) + pylib_lines.extend( + f"u'{key}': u'{{0}}'.format({sysconfig_line.format(key)})" + for key in ("purelib", "platlib", "stdlib", "platstdlib") + ) if python_inc: - for key in ("include", "platinclude"): - pyinc_lines.append( - f"u'{key}': u'{{0}}'.format({sysconfig_line.format(key)})" - ) + pyinc_lines.extend( + f"u'{key}': u'{{0}}'.format({sysconfig_line.format(key)})" + for key in ("include", "platinclude") + ) lines = pylib_lines + pyinc_lines if scripts: lines.append( @@ -366,7 +363,7 @@ def build_command( "u'py_version_short': u'{0}'.format(sysconfig.get_python_version())," ) lines_as_str = ",".join(lines) - py_command = py_command % lines_as_str + py_command %= lines_as_str return py_command def get_paths(self) -> Optional[Dict[str, str]]: @@ -483,8 +480,7 @@ def sys_prefix(self) -> str: command = [self.python, "-c", "import sys; print(sys.prefix)"] c = subprocess_run(command) - sys_prefix = Path(c.stdout.strip()).as_posix() - return sys_prefix + return Path(c.stdout.strip()).as_posix() @cached_property def paths(self) -> Dict[str, str]: @@ -524,7 +520,7 @@ def expand_egg_links(self) -> None: if not loc.exists(): continue for pth in loc.iterdir(): - if not pth.suffix == ".egg-link": + if pth.suffix != ".egg-link": continue contents = [ vistir.path.normalize_path(line.strip()) @@ -589,12 +585,11 @@ def dist_is_in_project(self, dist: pkg_resources.Distribution) -> bool: def get_installed_packages(self) -> List[pkg_resources.Distribution]: """Returns all of the installed packages in a given environment""" workingset = self.get_working_set() - packages = [ + return [ pkg for pkg in workingset if self.dist_is_in_project(pkg) and pkg.key != "python" ] - return packages @contextlib.contextmanager def get_finder(self, pre: bool = False) -> ContextManager[PackageFinder]: @@ -608,10 +603,9 @@ def get_finder(self, pre: bool = False) -> ContextManager[PackageFinder]: pip_options.cache_dir = self.project.s.PIPENV_CACHE_DIR pip_options.pre = self.pipfile.get("pre", pre) session = pip_command._build_session(pip_options) - finder = get_package_finder( + yield get_package_finder( install_cmd=pip_command, options=pip_options, session=session ) - yield finder def get_package_info( self, pre: bool = False @@ -664,7 +658,7 @@ def _get_requirements_for_package(cls, node, key_tree, parent=None, chain=None): d = node.as_dict() if parent: - d["required_version"] = node.version_spec if node.version_spec else "Any" + d["required_version"] = node.version_spec or "Any" else: d["required_version"] = d["installed_version"] @@ -752,8 +746,7 @@ def get_working_set(self): :rtype: :class:`pkg_resources.WorkingSet` """ - working_set = pkg_resources.WorkingSet(self.sys_path) - return working_set + return pkg_resources.WorkingSet(self.sys_path) def is_installed(self, pkgname): """Given a package name, returns whether it is installed in the environment @@ -877,7 +870,7 @@ def activated(self): original_path = sys.path original_prefix = sys.prefix prefix = self.prefix.as_posix() - with vistir.contextmanagers.temp_environ(), vistir.contextmanagers.temp_path(): + with (vistir.contextmanagers.temp_environ(), vistir.contextmanagers.temp_path()): os.environ["PATH"] = os.pathsep.join( [ self.script_basedir, @@ -890,12 +883,11 @@ def activated(self): if self.is_venv: os.environ["PYTHONPATH"] = self.base_paths["PYTHONPATH"] os.environ["VIRTUAL_ENV"] = prefix - else: - if not self.project.s.PIPENV_USE_SYSTEM and not os.environ.get( + elif not self.project.s.PIPENV_USE_SYSTEM and not os.environ.get( "VIRTUAL_ENV" ): - os.environ["PYTHONPATH"] = self.base_paths["PYTHONPATH"] - os.environ.pop("PYTHONHOME", None) + os.environ["PYTHONPATH"] = self.base_paths["PYTHONPATH"] + os.environ.pop("PYTHONHOME", None) sys.path = self.sys_path sys.prefix = self.sys_prefix try: @@ -908,11 +900,10 @@ def activated(self): def finders(self): from pipenv.vendor.pythonfinder import Finder - finders = [ + return [ Finder(path=self.base_paths["scripts"], global_search=gs, system=False) for gs in (False, True) ] - return finders @property def finder(self): @@ -923,9 +914,8 @@ def which(self, search, as_path=True): result = next(iter(filter(None, (find(finder) for finder in self.finders))), None) if not result: result = self._which(search) - else: - if as_path: - result = str(result.path) + elif as_path: + result = str(result.path) return result def install(self, requirements): @@ -977,15 +967,14 @@ def uninstall(self, pkgname, *args, **kwargs): auto_confirm = kwargs.pop("auto_confirm", True) verbose = kwargs.pop("verbose", False) with self.activated(): - monkey_patch = next( + if monkey_patch := next( iter( dist for dist in self.base_working_set if dist.project_name == "recursive-monkey-patch" ), None, - ) - if monkey_patch: + ): monkey_patch.activate() dist = next( iter(d for d in self.get_working_set() if d.project_name == pkgname), None diff --git a/pipenv/environments.py b/pipenv/environments.py index 64f74f5a0b..0d0603fa59 100644 --- a/pipenv/environments.py +++ b/pipenv/environments.py @@ -225,7 +225,7 @@ def __init__(self) -> None: _spinners.SPINNERS[None] = {"interval": 80, "frames": " "} self.PIPENV_SPINNER = None else: - pipenv_spinner = "dots" if not os.name == "nt" else "bouncingBar" + pipenv_spinner = "dots" if os.name != "nt" else "bouncingBar" self.PIPENV_SPINNER = get_from_env( "SPINNER", check_for_negation=False, default=pipenv_spinner ) @@ -241,11 +241,10 @@ def __init__(self) -> None: if not os.path.isfile(pipenv_pipfile): raise RuntimeError("Given PIPENV_PIPFILE is not found!") - else: - pipenv_pipfile = normalize_pipfile_path(pipenv_pipfile) - # Overwrite environment variable so that subprocesses can get the correct path. - # See https://github.com/pypa/pipenv/issues/3584 - os.environ["PIPENV_PIPFILE"] = pipenv_pipfile + pipenv_pipfile = normalize_pipfile_path(pipenv_pipfile) + # Overwrite environment variable so that subprocesses can get the correct path. + # See https://github.com/pypa/pipenv/issues/3584 + os.environ["PIPENV_PIPFILE"] = pipenv_pipfile self.PIPENV_PIPFILE = pipenv_pipfile """If set, this specifies a custom Pipfile location. @@ -405,13 +404,11 @@ def is_quiet(self, threshold=-1): def is_using_venv() -> bool: """Check for venv-based virtual environment which sets sys.base_prefix""" - if getattr(sys, "real_prefix", None) is not None: - # virtualenv venvs - result = True - else: - # PEP 405 venvs - result = sys.prefix != getattr(sys, "base_prefix", sys.prefix) - return result + return ( + True + if getattr(sys, "real_prefix", None) is not None + else sys.prefix != getattr(sys, "base_prefix", sys.prefix) + ) def is_in_virtualenv(): @@ -425,8 +422,8 @@ def is_in_virtualenv(): pipenv_active = os.environ.get("PIPENV_ACTIVE", False) virtual_env = bool(os.environ.get("VIRTUAL_ENV")) ignore_virtualenvs = bool(get_from_env("IGNORE_VIRTUALENVS")) - return virtual_env and not (pipenv_active or ignore_virtualenvs) + return virtual_env and not pipenv_active and not ignore_virtualenvs -PIPENV_SPINNER_FAIL_TEXT = "✘ {0}" if not PIPENV_HIDE_EMOJIS else "{0}" -PIPENV_SPINNER_OK_TEXT = "✔ {0}" if not PIPENV_HIDE_EMOJIS else "{0}" +PIPENV_SPINNER_FAIL_TEXT = "{0}" if PIPENV_HIDE_EMOJIS else "✘ {0}" +PIPENV_SPINNER_OK_TEXT = "{0}" if PIPENV_HIDE_EMOJIS else "✔ {0}" diff --git a/pipenv/exceptions.py b/pipenv/exceptions.py index 21c0ae7797..a5d5ae9c15 100644 --- a/pipenv/exceptions.py +++ b/pipenv/exceptions.py @@ -39,10 +39,7 @@ def handle_exception(exc_type, exception, traceback, hook=sys.excepthook): formatted_lines = [] for line in lines: line = line.strip("'").strip('"').strip("\n").strip() - if not line.startswith("File"): - line = f" {line}" - else: - line = f" {line}" + line = f" {line}" if line.startswith("File") else f" {line}" line = "[{!s}]: {}".format(exception.__class__.__name__, line) formatted_lines.append(line) # use new exception prettification rules to format exceptions according to @@ -100,17 +97,9 @@ def show(self, file=None): file=file, ) if self.out: - click.echo( - "{} {}".format("OUTPUT: ", self.out), - file=file, - err=True, - ) + click.echo(f"OUTPUT: {self.out}", file=file, err=True) if self.err: - click.echo( - "{} {}".format("STDERR: ", self.err), - file=file, - err=True, - ) + click.echo(f"STDERR: {self.err}", file=file, err=True) class JSONParseError(PipenvException): @@ -151,9 +140,7 @@ def __init__(self, message=None, ctx=None, **kwargs): def show(self, file=None): if file is None: file = vistir.misc.get_text_stderr() - color = None - if self.ctx is not None: - color = self.ctx.color + color = self.ctx.color if self.ctx is not None else None if self.extra: if isinstance(self.extra, str): self.extra = [self.extra] @@ -436,10 +423,8 @@ def prettify_exc(error): entire traceback, for better UX""" errors = [] for exc in KNOWN_EXCEPTIONS: - search_string = exc.match_string if exc.match_string else exc.exception_name - split_string = ( - exc.show_from_string if exc.show_from_string else exc.exception_name - ) + search_string = exc.match_string or exc.exception_name + split_string = exc.show_from_string or exc.exception_name if search_string in error: # for known exceptions with no display rules and no prefix # we should simply show nothing @@ -451,7 +436,4 @@ def prettify_exc(error): else: _, error, info = error.rpartition(split_string) errors.append(f"{error} {info}") - if not errors: - return error - - return "\n".join(errors) + return "\n".join(errors) if errors else error diff --git a/pipenv/installers.py b/pipenv/installers.py index 2e49da9602..ec44f908c6 100644 --- a/pipenv/installers.py +++ b/pipenv/installers.py @@ -28,9 +28,9 @@ def parse(cls, name): match = re.match(r"^(\d+)\.(\d+)(?:\.(\d+))?$", name) if not match: raise ValueError(f"invalid version name {name!r}") - major = int(match.group(1)) - minor = int(match.group(2)) - patch = match.group(3) + major = int(match[1]) + minor = int(match[2]) + patch = match[3] if patch is not None: patch = int(patch) return cls(major, minor, patch) @@ -223,10 +223,9 @@ def install(self, version): A ValueError is raised if the given version does not have a match in asdf. A InstallerError is raised if the asdf command fails. """ - c = self._run( + return self._run( "install", "python", str(version), timeout=self.project.s.PIPENV_INSTALL_TIMEOUT, ) - return c diff --git a/pipenv/patched/pip/__pip-runner__.py b/pipenv/patched/pip/__pip-runner__.py index 49a148a097..c766d0e6c3 100644 --- a/pipenv/patched/pip/__pip-runner__.py +++ b/pipenv/patched/pip/__pip-runner__.py @@ -18,9 +18,7 @@ def version_str(version): # type: ignore if sys.version_info[:2] < PYTHON_REQUIRES: raise SystemExit( - "This version of pip does not support python {} (requires >={}).".format( - version_str(sys.version_info[:2]), version_str(PYTHON_REQUIRES) - ) + f"This version of pip does not support python {version_str(sys.version_info[:2])} (requires >={version_str(PYTHON_REQUIRES)})." ) # From here on, we can use Python 3 features, but the syntax must remain @@ -35,7 +33,7 @@ def version_str(version): # type: ignore class PipImportRedirectingFinder: @classmethod - def find_spec(self, fullname, path=None, target=None): # type: ignore + def find_spec(cls, fullname, path=None, target=None): # type: ignore if fullname != "pip": return None diff --git a/pipenv/patched/pip/_internal/build_env.py b/pipenv/patched/pip/_internal/build_env.py index 6985dd5a74..33d01fd640 100644 --- a/pipenv/patched/pip/_internal/build_env.py +++ b/pipenv/patched/pip/_internal/build_env.py @@ -49,12 +49,11 @@ def get_runnable_pip() -> str: """ source = pathlib.Path(pip_location).resolve().parent - if not source.is_dir(): - # This would happen if someone is using pip from inside a zip file. In that - # case, we can use that directly. - return str(source) - - return os.fsdecode(source / "__pip-runner__.py") + return ( + os.fsdecode(source / "__pip-runner__.py") + if source.is_dir() + else str(source) + ) def _get_system_sitepackages() -> Set[str]: @@ -141,8 +140,7 @@ def __enter__(self) -> None: } path = self._bin_dirs[:] - old_path = self._save_env["PATH"] - if old_path: + if old_path := self._save_env["PATH"]: path.extend(old_path.split(os.pathsep)) pythonpath = [self._site_dir] @@ -252,8 +250,7 @@ def _install_requirements( ) ) - index_urls = finder.index_urls - if index_urls: + if index_urls := finder.index_urls: args.extend(["-i", index_urls[0]]) for extra_index in index_urls[1:]: args.extend(["--extra-index-url", extra_index]) diff --git a/pipenv/patched/pip/_internal/cache.py b/pipenv/patched/pip/_internal/cache.py index 332304d688..5d0bfafefe 100644 --- a/pipenv/patched/pip/_internal/cache.py +++ b/pipenv/patched/pip/_internal/cache.py @@ -79,12 +79,7 @@ def _get_cache_path_parts(self, link: Link) -> List[str]: # difference for our use case here. hashed = _hash_dict(key_parts) - # We want to nest the directories some to prevent having a ton of top - # level directories where we might run out of sub directories on some - # FS. - parts = [hashed[:2], hashed[2:4], hashed[4:6], hashed[6:]] - - return parts + return [hashed[:2], hashed[2:4], hashed[4:6], hashed[6:]] def _get_candidates(self, link: Link, canonical_package_name: str) -> List[Any]: can_not_cache = not self.cache_dir or not canonical_package_name or not link @@ -98,8 +93,7 @@ def _get_candidates(self, link: Link, canonical_package_name: str) -> List[Any]: candidates = [] path = self.get_path_for_link(link) if os.path.isdir(path): - for candidate in os.listdir(path): - candidates.append((candidate, path)) + candidates.extend((candidate, path) for candidate in os.listdir(path)) return candidates def get_path_for_link(self, link: Link) -> str: @@ -243,9 +237,7 @@ def get( supported_tags: List[Tag], ) -> Link: cache_entry = self.get_cache_entry(link, package_name, supported_tags) - if cache_entry is None: - return link - return cache_entry.link + return link if cache_entry is None else cache_entry.link def get_cache_entry( self, @@ -270,10 +262,7 @@ def get_cache_entry( package_name=package_name, supported_tags=supported_tags, ) - if retval is not link: - return CacheEntry(retval, persistent=False) - - return None + return CacheEntry(retval, persistent=False) if retval is not link else None @staticmethod def record_download_origin(cache_dir: str, download_info: DirectUrl) -> None: diff --git a/pipenv/patched/pip/_internal/cli/autocompletion.py b/pipenv/patched/pip/_internal/cli/autocompletion.py index 5144fa9ddc..d5bf08f649 100644 --- a/pipenv/patched/pip/_internal/cli/autocompletion.py +++ b/pipenv/patched/pip/_internal/cli/autocompletion.py @@ -28,12 +28,9 @@ def autocomplete() -> None: subcommands = list(commands_dict) options = [] - # subcommand - subcommand_name: Optional[str] = None - for word in cwords: - if word in subcommands: - subcommand_name = word - break + subcommand_name: Optional[str] = next( + (word for word in cwords if word in subcommands), None + ) # subcommand options if subcommand_name is not None: # special case: 'help' subcommand has no options @@ -47,14 +44,12 @@ def autocomplete() -> None: if should_list_installed: env = get_default_environment() lc = current.lower() - installed = [ + if installed := [ dist.canonical_name for dist in env.iter_installed_distributions(local_only=True) if dist.canonical_name.startswith(lc) and dist.canonical_name not in cwords[1:] - ] - # if there are no dists installed, fall back to option completion - if installed: + ]: for dist in installed: print(dist) sys.exit(1) @@ -71,29 +66,25 @@ def autocomplete() -> None: for opt in subcommand.parser.option_list_all: if opt.help != optparse.SUPPRESS_HELP: - for opt_str in opt._long_opts + opt._short_opts: - options.append((opt_str, opt.nargs)) - + options.extend( + (opt_str, opt.nargs) + for opt_str in opt._long_opts + opt._short_opts + ) # filter out previously specified options from available options prev_opts = [x.split("=")[0] for x in cwords[1 : cword - 1]] options = [(x, v) for (x, v) in options if x not in prev_opts] # filter options by current input options = [(k, v) for k, v in options if k.startswith(current)] - # get completion type given cwords and available subcommand options - completion_type = get_path_completion_type( + if completion_type := get_path_completion_type( cwords, cword, subcommand.parser.option_list_all, - ) - # get completion files and directories if ``completion_type`` is - # ````, ```` or ```` - if completion_type: + ): paths = auto_complete_paths(current, completion_type) options = [(path, 0) for path in paths] for option in options: opt_label = option[0] - # append '=' to options which require args - if option[1] and option[0][:2] == "--": + if option[1] and opt_label[:2] == "--": opt_label += "=" print(opt_label) else: @@ -106,11 +97,10 @@ def autocomplete() -> None: for opt in flattened_opts: if opt.help != optparse.SUPPRESS_HELP: subcommands += opt._long_opts + opt._short_opts - else: - # get completion type given cwords and all available options - completion_type = get_path_completion_type(cwords, cword, flattened_opts) - if completion_type: - subcommands = list(auto_complete_paths(current, completion_type)) + elif completion_type := get_path_completion_type( + cwords, cword, flattened_opts + ): + subcommands = list(auto_complete_paths(current, completion_type)) print(" ".join([x for x in subcommands if x.startswith(current)])) sys.exit(1) @@ -132,11 +122,14 @@ def get_path_completion_type( if opt.help == optparse.SUPPRESS_HELP: continue for o in str(opt).split("/"): - if cwords[cword - 2].split("=")[0] == o: - if not opt.metavar or any( - x in ("path", "file", "dir") for x in opt.metavar.split("/") - ): - return opt.metavar + if cwords[cword - 2].split("=")[0] == o and ( + not opt.metavar + or any( + x in ("path", "file", "dir") + for x in opt.metavar.split("/") + ) + ): + return opt.metavar return None diff --git a/pipenv/patched/pip/_internal/cli/base_command.py b/pipenv/patched/pip/_internal/cli/base_command.py index 0af0114cc6..db69e0070a 100644 --- a/pipenv/patched/pip/_internal/cli/base_command.py +++ b/pipenv/patched/pip/_internal/cli/base_command.py @@ -132,11 +132,13 @@ def _main(self, args: List[str]) -> int: if options.exists_action: os.environ["PIP_EXISTS_ACTION"] = " ".join(options.exists_action) - if options.require_venv and not self.ignore_require_venv: - # If a venv is required check if it can really be found - if not running_under_virtualenv(): - logger.critical("Could not find an activated virtualenv (required).") - sys.exit(VIRTUALENV_NOT_FOUND) + if ( + options.require_venv + and not self.ignore_require_venv + and not running_under_virtualenv() + ): + logger.critical("Could not find an activated virtualenv (required).") + sys.exit(VIRTUALENV_NOT_FOUND) if options.cache_dir: options.cache_dir = normalize_path(options.cache_dir) diff --git a/pipenv/patched/pip/_internal/cli/cmdoptions.py b/pipenv/patched/pip/_internal/cli/cmdoptions.py index a833f86e60..0ea1d20dc3 100644 --- a/pipenv/patched/pip/_internal/cli/cmdoptions.py +++ b/pipenv/patched/pip/_internal/cli/cmdoptions.py @@ -91,12 +91,11 @@ def check_dist_restriction(options: Values, check_target: bool = False) -> None: ":none:)." ) - if check_target: - if dist_restriction_set and not options.target_dir: - raise CommandError( - "Can not use any platform or abi specific options unless " - "installing via '--target'" - ) + if check_target and dist_restriction_set and not options.target_dir: + raise CommandError( + "Can not use any platform or abi specific options unless " + "installing via '--target'" + ) def _path_option_check(option: Option, opt: str, value: str) -> str: @@ -633,15 +632,13 @@ def add_target_python_options(cmd_opts: OptionGroup) -> None: def make_target_python(options: Values) -> TargetPython: - target_python = TargetPython( + return TargetPython( platforms=options.platforms, py_version_info=options.python_version, abis=options.abis, implementation=options.implementation, ) - return target_python - def prefer_binary() -> Option: return Option( @@ -897,15 +894,11 @@ def _handle_merge_hash( algo, digest = value.split(":", 1) except ValueError: parser.error( - "Arguments to {} must be a hash name " # noqa - "followed by a value, like --hash=sha256:" - "abcde...".format(opt_str) + f"Arguments to {opt_str} must be a hash name followed by a value, like --hash=sha256:abcde..." ) if algo not in STRONG_HASHES: parser.error( - "Allowed hash algorithms for {} are {}.".format( # noqa - opt_str, ", ".join(STRONG_HASHES) - ) + f'Allowed hash algorithms for {opt_str} are {", ".join(STRONG_HASHES)}.' ) parser.values.hashes.setdefault(algo, []).append(digest) diff --git a/pipenv/patched/pip/_internal/cli/main_parser.py b/pipenv/patched/pip/_internal/cli/main_parser.py index d4d97bb7e0..fa13b1fd22 100644 --- a/pipenv/patched/pip/_internal/cli/main_parser.py +++ b/pipenv/patched/pip/_internal/cli/main_parser.py @@ -52,16 +52,15 @@ def identify_python_interpreter(python: str) -> Optional[str]: # If it's a directory, assume it's a virtual environment and # look for the environment's Python executable. if os.path.exists(python): - if os.path.isdir(python): - # bin/python for Unix, Scripts/python.exe for Windows - # Try both in case of odd cases like cygwin. - for exe in ("bin/python", "Scripts/python.exe"): - py = os.path.join(python, exe) - if os.path.exists(py): - return py - else: + if not os.path.isdir(python): return python + # bin/python for Unix, Scripts/python.exe for Windows + # Try both in case of odd cases like cygwin. + for exe in ("bin/python", "Scripts/python.exe"): + py = os.path.join(python, exe) + if os.path.exists(py): + return py # Could not find the interpreter specified return None diff --git a/pipenv/patched/pip/_internal/cli/parser.py b/pipenv/patched/pip/_internal/cli/parser.py index a1e851cfcf..abc15afc72 100644 --- a/pipenv/patched/pip/_internal/cli/parser.py +++ b/pipenv/patched/pip/_internal/cli/parser.py @@ -55,42 +55,32 @@ def _format_option_strings( return "".join(opts) def format_heading(self, heading: str) -> str: - if heading == "Options": - return "" - return heading + ":\n" + return "" if heading == "Options" else heading + ":\n" def format_usage(self, usage: str) -> str: """ Ensure there is only one newline between usage and the first heading if there is no description. """ - msg = "\nUsage: {}\n".format(self.indent_lines(textwrap.dedent(usage), " ")) - return msg + return f'\nUsage: {self.indent_lines(textwrap.dedent(usage), " ")}\n' def format_description(self, description: str) -> str: # leave full control over description to us - if description: - if hasattr(self.parser, "main"): - label = "Commands" - else: - label = "Description" - # some doc strings have initial newlines, some don't - description = description.lstrip("\n") - # some doc strings have final newlines and spaces, some don't - description = description.rstrip() - # dedent, then reindent - description = self.indent_lines(textwrap.dedent(description), " ") - description = f"{label}:\n{description}\n" - return description - else: + if not description: return "" + label = "Commands" if hasattr(self.parser, "main") else "Description" + # some doc strings have initial newlines, some don't + description = description.lstrip("\n") + # some doc strings have final newlines and spaces, some don't + description = description.rstrip() + # dedent, then reindent + description = self.indent_lines(textwrap.dedent(description), " ") + description = f"{label}:\n{description}\n" + return description def format_epilog(self, epilog: str) -> str: # leave full control over epilog to us - if epilog: - return epilog - else: - return "" + return epilog or "" def indent_lines(self, text: str, indent: str) -> str: new_lines = [indent + line for line in text.split("\n")] @@ -200,8 +190,7 @@ def _get_ordered_configuration_items( # Yield each group in their override order for section in override_order: - for key, val in section_items[section]: - yield key, val + yield from section_items[section] def _update_defaults(self, defaults: Dict[str, Any]) -> Dict[str, Any]: """Updates the given defaults with values from the config files and @@ -214,7 +203,7 @@ def _update_defaults(self, defaults: Dict[str, Any]) -> Dict[str, Any]: # Then set the options with those values for key, val in self._get_ordered_configuration_items(): # '--' because configuration supports only long names - option = self.get_option("--" + key) + option = self.get_option(f"--{key}") # Ignore options not present in this parser. E.g. non-globals put # in [global] by users that want them to apply to all applicable @@ -229,9 +218,7 @@ def _update_defaults(self, defaults: Dict[str, Any]) -> Dict[str, Any]: val = strtobool(val) except ValueError: self.error( - "{} is not a valid value for {} option, " # noqa - "please specify a boolean value like yes/no, " - "true/false or 1/0 instead.".format(val, key) + f"{val} is not a valid value for {key} option, please specify a boolean value like yes/no, true/false or 1/0 instead." ) elif option.action == "count": with suppress(ValueError): @@ -240,10 +227,7 @@ def _update_defaults(self, defaults: Dict[str, Any]) -> Dict[str, Any]: val = int(val) if not isinstance(val, int) or val < 0: self.error( - "{} is not a valid value for {} option, " # noqa - "please instead specify either a non-negative integer " - "or a boolean value like yes/no or false/true " - "which is equivalent to 1/0.".format(val, key) + f"{val} is not a valid value for {key} option, please instead specify either a non-negative integer or a boolean value like yes/no or false/true which is equivalent to 1/0." ) elif option.action == "append": val = val.split() diff --git a/pipenv/patched/pip/_internal/cli/req_command.py b/pipenv/patched/pip/_internal/cli/req_command.py index 91758e40ee..cf7f284a4d 100644 --- a/pipenv/patched/pip/_internal/cli/req_command.py +++ b/pipenv/patched/pip/_internal/cli/req_command.py @@ -83,11 +83,9 @@ def _get_index_urls(cls, options: Values) -> Optional[List[str]]: """Return a list of index urls from user-provided options.""" index_urls = [] if not getattr(options, "no_index", False): - url = getattr(options, "index_url", None) - if url: + if url := getattr(options, "index_url", None): index_urls.append(url) - urls = getattr(options, "extra_index_urls", None) - if urls: + if urls := getattr(options, "extra_index_urls", None): index_urls.extend(urls) # Return None rather than an empty list return index_urls or None @@ -213,7 +211,7 @@ def warn_if_run_as_root() -> None: # # We choose sys.platform over utils.compat.WINDOWS here to enable Mypy platform # checks: https://mypy.readthedocs.io/en/stable/common_issues.html - if sys.platform == "win32" or sys.platform == "cygwin": + if sys.platform in ["win32", "cygwin"]: return if os.getuid() != 0: @@ -469,8 +467,7 @@ def trace_basic_info(finder: PackageFinder) -> None: """ # Display where finder is looking for packages search_scope = finder.search_scope - locations = search_scope.get_formatted_locations() - if locations: + if locations := search_scope.get_formatted_locations(): logger.info(locations) def _build_package_finder( diff --git a/pipenv/patched/pip/_internal/commands/__init__.py b/pipenv/patched/pip/_internal/commands/__init__.py index ac1cd44185..c1182d7705 100644 --- a/pipenv/patched/pip/_internal/commands/__init__.py +++ b/pipenv/patched/pip/_internal/commands/__init__.py @@ -113,9 +113,7 @@ def create_command(name: str, **kwargs: Any) -> Command: module_path, class_name, summary = commands_dict[name] module = importlib.import_module(module_path) command_class = getattr(module, class_name) - command = command_class(name=name, summary=summary, **kwargs) - - return command + return command_class(name=name, summary=summary, **kwargs) def get_similar_commands(name: str) -> Optional[str]: @@ -124,9 +122,7 @@ def get_similar_commands(name: str) -> Optional[str]: name = name.lower() - close_commands = get_close_matches(name, commands_dict.keys()) - - if close_commands: + if close_commands := get_close_matches(name, commands_dict.keys()): return close_commands[0] else: return None diff --git a/pipenv/patched/pip/_internal/commands/cache.py b/pipenv/patched/pip/_internal/commands/cache.py index 8735a81694..257c633f08 100644 --- a/pipenv/patched/pip/_internal/commands/cache.py +++ b/pipenv/patched/pip/_internal/commands/cache.py @@ -127,11 +127,7 @@ def list_cache_items(self, options: Values, args: List[Any]) -> None: if len(args) > 1: raise CommandError("Too many arguments") - if args: - pattern = args[0] - else: - pattern = "*" - + pattern = args[0] if args else "*" files = self._find_wheels(options, pattern) if options.list_format == "human": self.format_for_human(files) @@ -155,10 +151,7 @@ def format_for_abspath(self, files: List[str]) -> None: if not files: return - results = [] - for filename in files: - results.append(filename) - + results = list(files) logger.info("\n".join(sorted(results))) def remove_cache_items(self, options: Values, args: List[Any]) -> None: @@ -176,7 +169,7 @@ def remove_cache_items(self, options: Values, args: List[Any]) -> None: files += self._find_http_files(options) else: # Add the pattern to the log message - no_matching_msg += ' for pattern "{}"'.format(args[0]) + no_matching_msg += f' for pattern "{args[0]}"' if not files: logger.warning(no_matching_msg) @@ -218,6 +211,6 @@ def _find_wheels(self, options: Values, pattern: str) -> List[str]: # match the hyphen before the version, followed by anything else. # # PEP 427: https://www.python.org/dev/peps/pep-0427/ - pattern = pattern + ("*.whl" if "-" in pattern else "-*.whl") + pattern += "*.whl" if "-" in pattern else "-*.whl" return filesystem.find_files(wheel_dir, pattern) diff --git a/pipenv/patched/pip/_internal/commands/check.py b/pipenv/patched/pip/_internal/commands/check.py index 9436070633..78c52509f5 100644 --- a/pipenv/patched/pip/_internal/commands/check.py +++ b/pipenv/patched/pip/_internal/commands/check.py @@ -48,6 +48,5 @@ def run(self, options: Values, args: List[str]) -> int: if missing or conflicting or parsing_probs: return ERROR - else: - write_output("No broken requirements found.") - return SUCCESS + write_output("No broken requirements found.") + return SUCCESS diff --git a/pipenv/patched/pip/_internal/commands/completion.py b/pipenv/patched/pip/_internal/commands/completion.py index 316a07b851..ce50284962 100644 --- a/pipenv/patched/pip/_internal/commands/completion.py +++ b/pipenv/patched/pip/_internal/commands/completion.py @@ -112,15 +112,13 @@ def add_options(self) -> None: def run(self, options: Values, args: List[str]) -> int: """Prints the completion code of the given shell""" shells = COMPLETION_SCRIPTS.keys() - shell_options = ["--" + shell for shell in sorted(shells)] + shell_options = [f"--{shell}" for shell in sorted(shells)] if options.shell in shells: script = textwrap.dedent( COMPLETION_SCRIPTS.get(options.shell, "").format(prog=get_prog()) ) print(BASE_COMPLETION.format(script=script, shell=options.shell)) - return SUCCESS else: - sys.stderr.write( - "ERROR: You must pass {}\n".format(" or ".join(shell_options)) - ) - return SUCCESS + sys.stderr.write(f'ERROR: You must pass {" or ".join(shell_options)}\n') + + return SUCCESS diff --git a/pipenv/patched/pip/_internal/commands/configuration.py b/pipenv/patched/pip/_internal/commands/configuration.py index e801728fa4..283c869093 100644 --- a/pipenv/patched/pip/_internal/commands/configuration.py +++ b/pipenv/patched/pip/_internal/commands/configuration.py @@ -242,23 +242,15 @@ def open_in_editor(self, options: Values, args: List[str]) -> None: e.filename = editor raise except subprocess.CalledProcessError as e: - raise PipError( - "Editor Subprocess exited with exit code {}".format(e.returncode) - ) + raise PipError(f"Editor Subprocess exited with exit code {e.returncode}") def _get_n_args(self, args: List[str], example: str, n: int) -> Any: """Helper to make sure the command got the right number of arguments""" if len(args) != n: - msg = ( - "Got unexpected number of arguments, expected {}. " - '(example: "{} config {}")' - ).format(n, get_prog(), example) + msg = f'Got unexpected number of arguments, expected {n}. (example: "{get_prog()} config {example}")' raise PipError(msg) - if n == 1: - return args[0] - else: - return args + return args[0] if n == 1 else args def _save_configuration(self) -> None: # We successfully ran a modifying command. Need to save the diff --git a/pipenv/patched/pip/_internal/commands/debug.py b/pipenv/patched/pip/_internal/commands/debug.py index d35a8ec7b9..6689783789 100644 --- a/pipenv/patched/pip/_internal/commands/debug.py +++ b/pipenv/patched/pip/_internal/commands/debug.py @@ -65,8 +65,7 @@ def get_vendor_version_from_module(module_name: str) -> Optional[str]: # Try to find version in debundled module info. assert module.__file__ is not None env = get_environment([os.path.dirname(module.__file__)]) - dist = env.get_distribution(module_name) - if dist: + if dist := env.get_distribution(module_name): version = str(dist.version) return version @@ -86,10 +85,7 @@ def show_actual_vendor_versions(vendor_txt_versions: Dict[str, str]) -> None: ) actual_version = expected_version elif parse_version(actual_version) != parse_version(expected_version): - extra_message = ( - " (CONFLICT: vendor.txt suggests version should" - " be {})".format(expected_version) - ) + extra_message = f" (CONFLICT: vendor.txt suggests version should be {expected_version})" logger.info("%s==%s%s", module_name, actual_version, extra_message) @@ -107,13 +103,11 @@ def show_tags(options: Values) -> None: target_python = make_target_python(options) tags = target_python.get_tags() - # Display the target options that were explicitly provided. - formatted_target = target_python.format_given() - suffix = "" - if formatted_target: + if formatted_target := target_python.format_given(): suffix = f" (target: {formatted_target})" - - msg = "Compatible tags: {}{}".format(len(tags), suffix) + else: + suffix = "" + msg = f"Compatible tags: {len(tags)}{suffix}" logger.info(msg) if options.verbose < 1 and len(tags) > tag_limit: @@ -134,10 +128,7 @@ def show_tags(options: Values) -> None: def ca_bundle_info(config: Configuration) -> str: - levels = set() - for key, _ in config.items(): - levels.add(key.split(".")[0]) - + levels = {key.split(".")[0] for key, _ in config.items()} if not levels: return "Not specified" diff --git a/pipenv/patched/pip/_internal/commands/freeze.py b/pipenv/patched/pip/_internal/commands/freeze.py index 0db16434c5..e19bc4f2ed 100644 --- a/pipenv/patched/pip/_internal/commands/freeze.py +++ b/pipenv/patched/pip/_internal/commands/freeze.py @@ -59,10 +59,7 @@ def add_options(self) -> None: "--all", dest="freeze_all", action="store_true", - help=( - "Do not skip these packages in the output:" - " {}".format(", ".join(DEV_PKGS)) - ), + help=f'Do not skip these packages in the output: {", ".join(DEV_PKGS)}', ) self.cmd_opts.add_option( "--exclude-editable", diff --git a/pipenv/patched/pip/_internal/commands/hash.py b/pipenv/patched/pip/_internal/commands/hash.py index ed12ae1250..b7f85112da 100644 --- a/pipenv/patched/pip/_internal/commands/hash.py +++ b/pipenv/patched/pip/_internal/commands/hash.py @@ -31,9 +31,7 @@ def add_options(self) -> None: choices=STRONG_HASHES, action="store", default=FAVORITE_HASH, - help="The hash algorithm to use: one of {}".format( - ", ".join(STRONG_HASHES) - ), + help=f'The hash algorithm to use: one of {", ".join(STRONG_HASHES)}', ) self.parser.insert_option_group(0, self.cmd_opts) diff --git a/pipenv/patched/pip/_internal/commands/index.py b/pipenv/patched/pip/_internal/commands/index.py index e0fc9d140a..041d24215b 100644 --- a/pipenv/patched/pip/_internal/commands/index.py +++ b/pipenv/patched/pip/_internal/commands/index.py @@ -126,13 +126,11 @@ def get_available_package_versions(self, options: Values, args: List[Any]) -> No versions = set(versions) if not versions: - raise DistributionNotFound( - "No matching distribution found for {}".format(query) - ) + raise DistributionNotFound(f"No matching distribution found for {query}") formatted_versions = [str(ver) for ver in sorted(versions, reverse=True)] latest = formatted_versions[0] - write_output("{} ({})".format(query, latest)) - write_output("Available versions: {}".format(", ".join(formatted_versions))) + write_output(f"{query} ({latest})") + write_output(f'Available versions: {", ".join(formatted_versions)}') print_dist_installation_info(query, latest) diff --git a/pipenv/patched/pip/_internal/commands/install.py b/pipenv/patched/pip/_internal/commands/install.py index 90ea985870..080fbbba34 100644 --- a/pipenv/patched/pip/_internal/commands/install.py +++ b/pipenv/patched/pip/_internal/commands/install.py @@ -425,11 +425,10 @@ def run(self, options: Values, args: List[str]) -> int: json.dump(report.to_dict(), f, indent=2, ensure_ascii=False) if options.dry_run: - would_install_items = sorted( + if would_install_items := sorted( (r.metadata["name"], r.metadata["version"]) for r in requirement_set.requirements_to_install - ) - if would_install_items: + ): write_output( "Would install %s", " ".join("-".join(item) for item in would_install_items), @@ -464,17 +463,11 @@ def run(self, options: Values, args: List[str]) -> int: global_options=global_options, ) - # If we're using PEP 517, we cannot do a legacy setup.py install - # so we fail here. - pep517_build_failure_names: List[str] = [ + if pep517_build_failure_names := [ r.name for r in build_failures if r.use_pep517 # type: ignore - ] - if pep517_build_failure_names: + ]: raise InstallationError( - "Could not build wheels for {}, which is required to " - "install pyproject.toml-based projects".format( - ", ".join(pep517_build_failure_names) - ) + f'Could not build wheels for {", ".join(pep517_build_failure_names)}, which is required to install pyproject.toml-based projects' ) # For now, we just warn about failures building legacy @@ -539,8 +532,7 @@ def run(self, options: Values, args: List[str]) -> int: resolver_variant=self.determine_resolver_variant(options), ) - installed_desc = " ".join(items) - if installed_desc: + if installed_desc := " ".join(items): write_output( "Successfully installed %s", installed_desc, @@ -819,13 +811,10 @@ def create_os_error_message( It may occur anytime during the execution of the install command. """ - parts = [] + parts = ["Could not install packages due to an OSError"] - # Mention the error if we are not going to show a traceback - parts.append("Could not install packages due to an OSError") if not show_traceback: - parts.append(": ") - parts.append(str(error)) + parts.extend((": ", str(error))) else: parts.append(".") @@ -835,10 +824,10 @@ def create_os_error_message( # Suggest useful actions to the user: # (1) using user site-packages or (2) verifying the permissions if error.errno == errno.EACCES: - user_option_part = "Consider using the `--user` option" permissions_part = "Check the permissions" if not running_under_virtualenv() and not using_user_site: + user_option_part = "Consider using the `--user` option" parts.extend( [ user_option_part, diff --git a/pipenv/patched/pip/_internal/commands/list.py b/pipenv/patched/pip/_internal/commands/list.py index 90e358ae14..ed755af127 100644 --- a/pipenv/patched/pip/_internal/commands/list.py +++ b/pipenv/patched/pip/_internal/commands/list.py @@ -231,8 +231,8 @@ def iter_packages_latest_infos( finder = self._build_package_finder(options, session) def latest_info( - dist: "_DistWithLatestInfo", - ) -> Optional["_DistWithLatestInfo"]: + dist: "_DistWithLatestInfo", + ) -> Optional["_DistWithLatestInfo"]: all_candidates = finder.find_all_candidates(dist.canonical_name) if not options.pre: # Remove prereleases @@ -250,10 +250,7 @@ def latest_info( return None remote_version = best_candidate.version - if best_candidate.link.is_wheel: - typ = "wheel" - else: - typ = "sdist" + typ = "wheel" if best_candidate.link.is_wheel else "sdist" dist.latest_version = remote_version dist.latest_filetype = typ return dist @@ -287,13 +284,13 @@ def output_package_listing_columns( self, data: List[List[str]], header: List[str] ) -> None: # insert the header first: we need to know the size of column names - if len(data) > 0: + if data: data.insert(0, header) pkg_strings, sizes = tabulate(data) # Create and add a separator. - if len(data) > 0: + if data: pkg_strings.insert(1, " ".join(map(lambda x: "-" * x, sizes))) for val in pkg_strings: @@ -318,10 +315,7 @@ def format_for_columns( header.append("Editable project location") if options.verbose >= 1: - header.append("Location") - if options.verbose >= 1: - header.append("Installer") - + header.extend(("Location", "Installer")) data = [] for proj in pkgs: # if we're working on the 'outdated' list, separate out the @@ -329,17 +323,12 @@ def format_for_columns( row = [proj.raw_name, str(proj.version)] if running_outdated: - row.append(str(proj.latest_version)) - row.append(proj.latest_filetype) - + row.extend((str(proj.latest_version), proj.latest_filetype)) if has_editables: row.append(proj.editable_project_location or "") if options.verbose >= 1: - row.append(proj.location or "") - if options.verbose >= 1: - row.append(proj.installer) - + row.extend(((proj.location or ""), proj.installer)) data.append(row) return data, header @@ -358,8 +347,7 @@ def format_for_json(packages: "_ProcessedDists", options: Values) -> str: if options.outdated: info["latest_version"] = str(dist.latest_version) info["latest_filetype"] = dist.latest_filetype - editable_project_location = dist.editable_project_location - if editable_project_location: + if editable_project_location := dist.editable_project_location: info["editable_project_location"] = editable_project_location data.append(info) return json.dumps(data) diff --git a/pipenv/patched/pip/_internal/commands/search.py b/pipenv/patched/pip/_internal/commands/search.py index de26dc5d48..c71fb95aea 100644 --- a/pipenv/patched/pip/_internal/commands/search.py +++ b/pipenv/patched/pip/_internal/commands/search.py @@ -57,14 +57,9 @@ def run(self, options: Values, args: List[str]) -> int: pypi_hits = self.search(query, options) hits = transform_hits(pypi_hits) - terminal_width = None - if sys.stdout.isatty(): - terminal_width = shutil.get_terminal_size()[0] - + terminal_width = shutil.get_terminal_size()[0] if sys.stdout.isatty() else None print_results(hits, terminal_width=terminal_width) - if pypi_hits: - return SUCCESS - return NO_MATCHES_FOUND + return SUCCESS if pypi_hits else NO_MATCHES_FOUND def search(self, query: List[str], options: Values) -> List[Dict[str, str]]: index_url = options.index @@ -97,19 +92,19 @@ def transform_hits(hits: List[Dict[str, str]]) -> List["TransformedHit"]: summary = hit["summary"] version = hit["version"] - if name not in packages.keys(): - packages[name] = { - "name": name, - "summary": summary, - "versions": [version], - } - else: + if name in packages: packages[name]["versions"].append(version) # if this is the highest version, replace summary and score if version == highest_version(packages[name]["versions"]): packages[name]["summary"] = summary + else: + packages[name] = { + "name": name, + "summary": summary, + "versions": [version], + } return list(packages.values()) @@ -142,10 +137,9 @@ def print_results( if name_column_width is None: name_column_width = ( max( - [ - len(hit["name"]) + len(highest_version(hit.get("versions", ["-"]))) - for hit in hits - ] + len(hit["name"]) + + len(highest_version(hit.get("versions", ["-"]))) + for hit in hits ) + 4 ) diff --git a/pipenv/patched/pip/_internal/commands/show.py b/pipenv/patched/pip/_internal/commands/show.py index e36551789f..143db4968f 100644 --- a/pipenv/patched/pip/_internal/commands/show.py +++ b/pipenv/patched/pip/_internal/commands/show.py @@ -42,11 +42,13 @@ def run(self, options: Values, args: List[str]) -> int: query = args results = search_packages_info(query) - if not print_results( - results, list_files=options.files, verbose=options.verbose - ): - return ERROR - return SUCCESS + return ( + SUCCESS + if print_results( + results, list_files=options.files, verbose=options.verbose + ) + else ERROR + ) class _PackageInfo(NamedTuple): @@ -110,11 +112,7 @@ def _get_requiring_packages(current_dist: BaseDistribution) -> Iterator[str]: entry_points = [] files_iter = dist.iter_declared_entries() - if files_iter is None: - files: Optional[List[str]] = None - else: - files = sorted(files_iter) - + files = None if files_iter is None else sorted(files_iter) metadata = dist.metadata yield _PackageInfo( diff --git a/pipenv/patched/pip/_internal/commands/uninstall.py b/pipenv/patched/pip/_internal/commands/uninstall.py index 7360ea3f27..c961418787 100644 --- a/pipenv/patched/pip/_internal/commands/uninstall.py +++ b/pipenv/patched/pip/_internal/commands/uninstall.py @@ -100,11 +100,10 @@ def run(self, options: Values, args: List[str]) -> int: ) for req in reqs_to_uninstall.values(): - uninstall_pathset = req.uninstall( + if uninstall_pathset := req.uninstall( auto_confirm=options.yes, verbose=self.verbosity > 0, - ) - if uninstall_pathset: + ): uninstall_pathset.commit() if options.root_user_action == "warn": warn_if_run_as_root() diff --git a/pipenv/patched/pip/_internal/configuration.py b/pipenv/patched/pip/_internal/configuration.py index fdb3f87bb8..0078a57df5 100644 --- a/pipenv/patched/pip/_internal/configuration.py +++ b/pipenv/patched/pip/_internal/configuration.py @@ -50,17 +50,12 @@ def _normalize_name(name: str) -> str: """Make a name consistent regardless of source (environment or file)""" name = name.lower().replace("_", "-") - if name.startswith("--"): - name = name[2:] # only prefer long opts - return name + return name.removeprefix("--") def _disassemble_key(name: str) -> List[str]: if "." not in name: - error_message = ( - "Key does not contain dot separated section and key. " - "Perhaps you wanted to use 'global.{}' instead?" - ).format(name) + error_message = f"Key does not contain dot separated section and key. Perhaps you wanted to use 'global.{name}' instead?" raise ConfigurationError(error_message) return name.split(".", 1) @@ -103,9 +98,7 @@ def __init__(self, isolated: bool, load_only: Optional[Kind] = None) -> None: if load_only is not None and load_only not in VALID_LOAD_ONLY: raise ConfigurationError( - "Got invalid value for load_only - should be one of {}".format( - ", ".join(map(repr, VALID_LOAD_ONLY)) - ) + f'Got invalid value for load_only - should be one of {", ".join(map(repr, VALID_LOAD_ONLY))}' ) self.isolated = isolated self.load_only = load_only @@ -230,14 +223,14 @@ def _dictionary(self) -> Dict[str, Any]: retval = {} for variant in OVERRIDE_ORDER: - retval.update(self._config[variant]) + retval |= self._config[variant] return retval def _load_config_files(self) -> None: """Loads configuration from configuration files""" config_files = dict(self.iter_config_files()) - if config_files[kinds.ENV][0:1] == [os.devnull]: + if config_files[kinds.ENV][:1] == [os.devnull]: logger.debug( "Skipping loading configuration files due to " "environment's PIP_CONFIG_FILE being os.devnull" @@ -304,7 +297,7 @@ def _normalized_keys( """ normalized = {} for name, val in items: - key = section + "." + _normalize_name(name) + key = f"{section}.{_normalize_name(name)}" normalized[key] = val return normalized @@ -354,16 +347,15 @@ def get_values_in_config(self, variant: Kind) -> Dict[str, Any]: def _get_parser_to_modify(self) -> Tuple[str, RawConfigParser]: # Determine which parser to modify assert self.load_only - parsers = self._parsers[self.load_only] - if not parsers: + if parsers := self._parsers[self.load_only]: + # Use the highest priority parser. + return parsers[-1] + else: # This should not happen if everything works correctly. raise ConfigurationError( "Fatal Internal error [id=2]. Please report as a bug." ) - # Use the highest priority parser. - return parsers[-1] - # XXX: This is patched in the tests. def _mark_as_modified(self, fname: str, parser: RawConfigParser) -> None: file_parser_tuple = (fname, parser) diff --git a/pipenv/patched/pip/_internal/exceptions.py b/pipenv/patched/pip/_internal/exceptions.py index ab0e420449..49fc9341ad 100644 --- a/pipenv/patched/pip/_internal/exceptions.py +++ b/pipenv/patched/pip/_internal/exceptions.py @@ -44,11 +44,7 @@ def _prefix_with_indent( prefix: str, indent: str, ) -> Text: - if isinstance(s, Text): - text = s - else: - text = console.render_str(s) - + text = s if isinstance(s, Text) else console.render_str(s) return console.render_str(prefix, overflow="ignore") + console.render_str( f"\n{indent}", overflow="ignore" ).join(text.split(allow_blank=True)) @@ -122,34 +118,32 @@ def __rich_console__( yield f"[{colour} bold]{self.kind}[/]: [bold]{self.reference}[/]" yield "" - if not options.ascii_only: - # Present the main message, with relevant context indented. - if self.context is not None: - yield _prefix_with_indent( - self.message, - console, - prefix=f"[{colour}]×[/] ", - indent=f"[{colour}]│[/] ", - ) - yield _prefix_with_indent( - self.context, - console, - prefix=f"[{colour}]╰─>[/] ", - indent=f"[{colour}] [/] ", - ) - else: - yield _prefix_with_indent( - self.message, - console, - prefix="[red]×[/] ", - indent=" ", - ) - else: + if options.ascii_only: yield self.message if self.context is not None: yield "" yield self.context + elif self.context is not None: + yield _prefix_with_indent( + self.message, + console, + prefix=f"[{colour}]×[/] ", + indent=f"[{colour}]│[/] ", + ) + yield _prefix_with_indent( + self.context, + console, + prefix=f"[{colour}]╰─>[/] ", + indent=f"[{colour}] [/] ", + ) + else: + yield _prefix_with_indent( + self.message, + console, + prefix="[red]×[/] ", + indent=" ", + ) if self.note_stmt is not None or self.hint_stmt is not None: yield "" @@ -247,10 +241,7 @@ def __init__( def __str__(self) -> str: # Use `dist` in the error message because its stringification # includes more information, like the version and location. - return "None {} metadata found for distribution: {}".format( - self.metadata_name, - self.dist, - ) + return f"None {self.metadata_name} metadata found for distribution: {self.dist}" class UserInstallationInvalid(InstallationError): @@ -450,9 +441,7 @@ def __str__(self) -> str: for cls, errors_of_cls in groupby(self.errors, lambda e: e.__class__): lines.append(cls.head) lines.extend(e.body() for e in errors_of_cls) - if lines: - return "\n".join(lines) - return "" + return "\n".join(lines) if lines else "" def __bool__(self) -> bool: return bool(self.errors) @@ -556,16 +545,8 @@ def body(self) -> str: # In the case of URL-based requirements, display the original URL # seen in the requirements file rather than the package name, # so the output can be directly copied into the requirements file. - package = ( - self.req.original_link - if self.req.original_link - # In case someone feeds something downright stupid - # to InstallRequirement's constructor. - else getattr(self.req, "req", None) - ) - return " {} --hash={}:{}".format( - package or "unknown package", FAVORITE_HASH, self.gotten_hash - ) + package = self.req.original_link or getattr(self.req, "req", None) + return f' {package or "unknown package"} --hash={FAVORITE_HASH}:{self.gotten_hash}' class HashUnpinned(HashError): @@ -608,7 +589,7 @@ def __init__(self, allowed: Dict[str, List[str]], gots: Dict[str, "_Hash"]) -> N self.gots = gots def body(self) -> str: - return " {}:\n{}".format(self._requirement_name(), self._hash_comparison()) + return f" {self._requirement_name()}:\n{self._hash_comparison()}" def _hash_comparison(self) -> str: """ diff --git a/pipenv/patched/pip/_internal/index/collector.py b/pipenv/patched/pip/_internal/index/collector.py index c368a833e9..dbd8ba7058 100644 --- a/pipenv/patched/pip/_internal/index/collector.py +++ b/pipenv/patched/pip/_internal/index/collector.py @@ -57,10 +57,14 @@ def _match_vcs_scheme(url: str) -> Optional[str]: Returns the matched VCS scheme, or None if there's no match. """ - for scheme in vcs.schemes: - if url.lower().startswith(scheme) and url[len(scheme)] in "+:": - return scheme - return None + return next( + ( + scheme + for scheme in vcs.schemes + if url.lower().startswith(scheme) and url[len(scheme)] in "+:" + ), + None, + ) class _NotAPIContent(Exception): @@ -182,8 +186,7 @@ def _get_encoding_from_headers(headers: ResponseHeaders) -> Optional[str]: if headers and "Content-Type" in headers: m = email.message.Message() m["content-type"] = headers["Content-Type"] - charset = m.get_param("charset") - if charset: + if charset := m.get_param("charset"): return str(charset) return None @@ -304,10 +307,7 @@ def handle_starttag(self, tag: str, attrs: List[Tuple[str, Optional[str]]]) -> N self.anchors.append(dict(attrs)) def get_href(self, attrs: List[Tuple[str, Optional[str]]]) -> Optional[str]: - for name, value in attrs: - if name == "href": - return value - return None + return next((value for name, value in attrs if name == "href"), None) def _handle_get_simple_fail( @@ -336,9 +336,7 @@ def _make_index_content( def _get_index_content(link: Link, *, session: PipSession) -> Optional["IndexContent"]: url = link.url.split("#", 1)[0] - # Check for VCS schemes that do not support lookup as web pages. - vcs_scheme = _match_vcs_scheme(url) - if vcs_scheme: + if vcs_scheme := _match_vcs_scheme(url): logger.warning( "Cannot look at %s URL %s because it does not support lookup as web pages.", vcs_scheme, @@ -382,8 +380,7 @@ def _get_index_content(link: Link, *, session: PipSession) -> Optional["IndexCon except RetryError as exc: _handle_get_simple_fail(link, exc) except SSLError as exc: - reason = "There was a problem confirming the ssl certificate: " - reason += str(exc) + reason = f"There was a problem confirming the ssl certificate: {str(exc)}" _handle_get_simple_fail(link, reason, meth=logger.info) except requests.ConnectionError as exc: _handle_get_simple_fail(link, f"connection error: {exc}") @@ -416,7 +413,7 @@ def __init__( ) -> None: self.search_scope = search_scope self.session = session - self.index_lookup = index_lookup if index_lookup else {} + self.index_lookup = index_lookup or {} @classmethod def create( @@ -448,12 +445,11 @@ def create( no_index=options.no_index, index_lookup=index_lookup, ) - link_collector = LinkCollector( + return LinkCollector( session=session, search_scope=search_scope, index_lookup=index_lookup, ) - return link_collector @property def find_links(self) -> List[str]: diff --git a/pipenv/patched/pip/_internal/index/package_finder.py b/pipenv/patched/pip/_internal/index/package_finder.py index b6e92f2be8..219ae1e72d 100644 --- a/pipenv/patched/pip/_internal/index/package_finder.py +++ b/pipenv/patched/pip/_internal/index/package_finder.py @@ -229,8 +229,7 @@ def evaluate_link(self, link: Link) -> Tuple[LinkType, str]: reason = f"Missing project version for {self.project_name}" return (LinkType.format_invalid, reason) - match = self._py_version_re.search(version) - if match: + if match := self._py_version_re.search(version): version = version[: match.start()] py_version = match.group(1) if py_version != self._target_python.py_version: @@ -299,12 +298,7 @@ def filter_unallowed_hashes( matches_or_no_digest.append(candidate) - if match_count: - filtered = matches_or_no_digest - else: - # Make sure we're not returning back the given value. - filtered = list(candidates) - + filtered = matches_or_no_digest if match_count else list(candidates) if len(filtered) == len(candidates): discard_message = "discarding no candidates" else: @@ -541,8 +535,7 @@ def _sort_key( except ValueError: if not ignore_compatibility: raise UnsupportedWheel( - "{} is not a supported wheel for this platform. It " - "can't be sorted.".format(wheel.filename) + f"{wheel.filename} is not a supported wheel for this platform. It can't be sorted." ) pri = -(support_num) if self._prefer_binary: @@ -573,10 +566,7 @@ def sort_best_candidate( Return the best candidate per the instance's sort order, or None if no candidate is acceptable. """ - if not candidates: - return None - best_candidate = max(candidates, key=self._sort_key) - return best_candidate + return max(candidates, key=self._sort_key) if candidates else None def compute_best_candidate( self, @@ -1036,6 +1026,4 @@ def _extract_version_from_fragment(fragment: str, canonical_name: str) -> Option except ValueError: return None version = fragment[version_start:] - if not version: - return None - return version + return version or None diff --git a/pipenv/patched/pip/_internal/locations/__init__.py b/pipenv/patched/pip/_internal/locations/__init__.py index d9a4daec1d..acc9d54f80 100644 --- a/pipenv/patched/pip/_internal/locations/__init__.py +++ b/pipenv/patched/pip/_internal/locations/__init__.py @@ -328,7 +328,10 @@ def get_scheme( # /usr/local instead of /usr. Debian also places lib in dist-packages # instead of site-packages, but the /usr/local check should cover it. skip_linux_system_special_case = ( - not (user or home or prefix or running_under_virtualenv()) + not user + and not home + and not prefix + and not running_under_virtualenv() and old_v.parts[1:3] == ("usr", "local") and len(new_v.parts) > 1 and new_v.parts[1] == "usr" @@ -432,11 +435,11 @@ def _looks_like_deb_system_dist_packages(value: str) -> bool: we can't do anything about this Debian bug, and this detection allows us to skip the warning when needed. """ - if not _looks_like_debian_scheme(): - return False - if value == "/usr/lib/python3/dist-packages": - return True - return False + return ( + value == "/usr/lib/python3/dist-packages" + if _looks_like_debian_scheme() + else False + ) def get_purelib() -> str: @@ -471,9 +474,7 @@ def get_platlib() -> str: def _deduplicated(v1: str, v2: str) -> List[str]: """Deduplicate values from a list.""" - if v1 == v2: - return [v1] - return [v1, v2] + return [v1] if v1 == v2 else [v1, v2] def _looks_like_apple_library(path: str) -> bool: diff --git a/pipenv/patched/pip/_internal/locations/_distutils.py b/pipenv/patched/pip/_internal/locations/_distutils.py index 86b947db75..cd90ac2883 100644 --- a/pipenv/patched/pip/_internal/locations/_distutils.py +++ b/pipenv/patched/pip/_internal/locations/_distutils.py @@ -79,17 +79,14 @@ def distutils_scheme( i.root = root or i.root i.finalize_options() - scheme = {} - for key in SCHEME_KEYS: - scheme[key] = getattr(i, "install_" + key) - + scheme = {key: getattr(i, f"install_{key}") for key in SCHEME_KEYS} # install_lib specified in setup.cfg should install *everything* # into there (i.e. it takes precedence over both purelib and # platlib). Note, i.install_lib is *always* set after # finalize_options(); we only want to override here if the user # has explicitly requested it hence going back to the config if "install_lib" in d.get_option_dict("install"): - scheme.update(dict(purelib=i.install_lib, platlib=i.install_lib)) + scheme |= dict(purelib=i.install_lib, platlib=i.install_lib) if running_under_virtualenv(): if home: diff --git a/pipenv/patched/pip/_internal/locations/_sysconfig.py b/pipenv/patched/pip/_internal/locations/_sysconfig.py index be05b097dd..a91ed40102 100644 --- a/pipenv/patched/pip/_internal/locations/_sysconfig.py +++ b/pipenv/patched/pip/_internal/locations/_sysconfig.py @@ -78,9 +78,7 @@ def _infer_prefix() -> str: suffixed = f"{os.name}_prefix" if suffixed in _AVAILABLE_SCHEMES: return suffixed - if os.name in _AVAILABLE_SCHEMES: # On Windows, prefx is just called "nt". - return os.name - return "posix_prefix" + return os.name if os.name in _AVAILABLE_SCHEMES else "posix_prefix" def _infer_user() -> str: @@ -103,9 +101,7 @@ def _infer_home() -> str: if _PREFERRED_SCHEME_API: return _PREFERRED_SCHEME_API("home") suffixed = f"{os.name}_home" - if suffixed in _AVAILABLE_SCHEMES: - return suffixed - return "posix_home" + return suffixed if suffixed in _AVAILABLE_SCHEMES else "posix_home" # Update these keys if the user sets a custom home. diff --git a/pipenv/patched/pip/_internal/locations/base.py b/pipenv/patched/pip/_internal/locations/base.py index 395ece4e9a..34a251a522 100644 --- a/pipenv/patched/pip/_internal/locations/base.py +++ b/pipenv/patched/pip/_internal/locations/base.py @@ -34,11 +34,11 @@ def change_root(new_root: str, pathname: str) -> str: This is borrowed from Python's standard library's distutils module. """ if os.name == "posix": - if not os.path.isabs(pathname): - return os.path.join(new_root, pathname) - else: - return os.path.join(new_root, pathname[1:]) - + return ( + os.path.join(new_root, pathname[1:]) + if os.path.isabs(pathname) + else os.path.join(new_root, pathname) + ) elif os.name == "nt": (drive, path) = os.path.splitdrive(pathname) if path[0] == "\\": diff --git a/pipenv/patched/pip/_internal/metadata/__init__.py b/pipenv/patched/pip/_internal/metadata/__init__.py index f6ac515bc4..2b70b184d0 100644 --- a/pipenv/patched/pip/_internal/metadata/__init__.py +++ b/pipenv/patched/pip/_internal/metadata/__init__.py @@ -46,7 +46,7 @@ def _should_use_importlib_metadata() -> bool: return False import importlib.metadata - return bool(getattr(importlib.metadata, "_PIP_USE_IMPORTLIB_METADATA", True)) + return getattr(importlib.metadata, "_PIP_USE_IMPORTLIB_METADATA", True) class Backend(Protocol): diff --git a/pipenv/patched/pip/_internal/metadata/_json.py b/pipenv/patched/pip/_internal/metadata/_json.py index 336b52f1ef..a96669bfca 100644 --- a/pipenv/patched/pip/_internal/metadata/_json.py +++ b/pipenv/patched/pip/_internal/metadata/_json.py @@ -42,20 +42,21 @@ def msg_to_json(msg: Message) -> Dict[str, Any]: """Convert a Message object into a JSON-compatible dictionary.""" def sanitise_header(h: Union[Header, str]) -> str: - if isinstance(h, Header): - chunks = [] - for bytes, encoding in decode_header(h): - if encoding == "unknown-8bit": - try: - # See if UTF-8 works - bytes.decode("utf-8") - encoding = "utf-8" - except UnicodeDecodeError: - # If not, latin1 at least won't fail - encoding = "latin1" - chunks.append((bytes, encoding)) - return str(make_header(chunks)) - return str(h) + if not isinstance(h, Header): + return str(h) + + chunks = [] + for bytes, encoding in decode_header(h): + if encoding == "unknown-8bit": + try: + # See if UTF-8 works + bytes.decode("utf-8") + encoding = "utf-8" + except UnicodeDecodeError: + # If not, latin1 at least won't fail + encoding = "latin1" + chunks.append((bytes, encoding)) + return str(make_header(chunks)) result = {} for field, multi in METADATA_FIELDS: diff --git a/pipenv/patched/pip/_internal/metadata/base.py b/pipenv/patched/pip/_internal/metadata/base.py index 375c3fddee..e71fd6159e 100644 --- a/pipenv/patched/pip/_internal/metadata/base.py +++ b/pipenv/patched/pip/_internal/metadata/base.py @@ -172,19 +172,13 @@ def editable_project_location(self) -> Optional[str]: This is the directory where pyproject.toml or setup.py is located. None if the distribution is not installed in editable mode. """ - # TODO: this property is relatively costly to compute, memoize it ? - direct_url = self.direct_url - if direct_url: + if direct_url := self.direct_url: if direct_url.is_local_editable(): return url_to_path(direct_url.url) - else: - # Search for an .egg-link file by walking sys.path, as it was - # done before by dist_is_editable(). - egg_link_path = egg_link_path_from_sys_path(self.raw_name) - if egg_link_path: - # TODO: get project location from second line of egg_link file - # (https://github.com/pypa/pip/issues/10243) - return self.location + elif egg_link_path := egg_link_path_from_sys_path(self.raw_name): + # TODO: get project location from second line of egg_link file + # (https://github.com/pypa/pip/issues/10243) + return self.location return None @property @@ -225,9 +219,7 @@ def installed_by_distutils(self) -> bool: treat this specially on uninstallation. """ info_location = self.info_location - if not info_location: - return False - return pathlib.Path(info_location).is_file() + return pathlib.Path(info_location).is_file() if info_location else False @property def installed_as_egg(self) -> bool: @@ -237,9 +229,7 @@ def installed_as_egg(self) -> bool: of) easy_install. """ location = self.location - if not location: - return False - return location.endswith(".egg") + return location.endswith(".egg") if location else False @property def installed_with_setuptools_egg_info(self) -> bool: @@ -252,12 +242,14 @@ def installed_with_setuptools_egg_info(self) -> bool: also installs an ``.egg-info``, but as a file, not a directory. This property is *False* for that case. Also see ``installed_by_distutils``. """ - info_location = self.info_location - if not info_location: - return False - if not info_location.endswith(".egg-info"): + if info_location := self.info_location: + return ( + pathlib.Path(info_location).is_dir() + if info_location.endswith(".egg-info") + else False + ) + else: return False - return pathlib.Path(info_location).is_dir() @property def installed_with_dist_info(self) -> bool: @@ -268,12 +260,14 @@ def installed_with_dist_info(self) -> bool: setuptools (but through pip, not directly), or anything using the standardized build backend interface (PEP 517). """ - info_location = self.info_location - if not info_location: - return False - if not info_location.endswith(".dist-info"): + if info_location := self.info_location: + return ( + pathlib.Path(info_location).is_dir() + if info_location.endswith(".dist-info") + else False + ) + else: return False - return pathlib.Path(info_location).is_dir() @property def canonical_name(self) -> NormalizedName: @@ -324,8 +318,7 @@ def installer(self) -> str: except (OSError, ValueError, NoneMetadataError): return "" # Fail silently if the installer file cannot be read. for line in installer_text.splitlines(): - cleaned_line = line.strip() - if cleaned_line: + if cleaned_line := line.strip(): return cleaned_line return "" @@ -485,11 +478,15 @@ def _iter_declared_entries_from_legacy(self) -> Optional[Iterator[str]]: info_rel = pathlib.Path(info).relative_to(root) except ValueError: # info is not relative to root. return paths - if not info_rel.parts: # info *is* root. - return paths return ( - _convert_installed_files_path(pathlib.Path(p).parts, info_rel.parts) - for p in paths + ( + _convert_installed_files_path( + pathlib.Path(p).parts, info_rel.parts + ) + for p in paths + ) + if info_rel.parts + else paths ) def iter_declared_entries(self) -> Optional[Iterator[str]]: diff --git a/pipenv/patched/pip/_internal/metadata/importlib/_dists.py b/pipenv/patched/pip/_internal/metadata/importlib/_dists.py index 9dc0f3549b..544de5794a 100644 --- a/pipenv/patched/pip/_internal/metadata/importlib/_dists.py +++ b/pipenv/patched/pip/_internal/metadata/importlib/_dists.py @@ -140,15 +140,11 @@ def from_wheel(cls, wheel: Wheel, name: str) -> BaseDistribution: @property def location(self) -> Optional[str]: - if self._info_location is None: - return None - return str(self._info_location.parent) + return None if self._info_location is None else str(self._info_location.parent) @property def info_location(self) -> Optional[str]: - if self._info_location is None: - return None - return str(self._info_location) + return None if self._info_location is None else str(self._info_location) @property def installed_location(self) -> Optional[str]: @@ -164,9 +160,7 @@ def _get_dist_name_from_location(self) -> Optional[str]: if self._info_location is None: return None stem, suffix = os.path.splitext(self._info_location.name) - if suffix not in (".dist-info", ".egg-info"): - return None - return stem.split("-", 1)[0] + return stem.split("-", 1)[0] if suffix in (".dist-info", ".egg-info") else None @property def canonical_name(self) -> NormalizedName: diff --git a/pipenv/patched/pip/_internal/metadata/importlib/_envs.py b/pipenv/patched/pip/_internal/metadata/importlib/_envs.py index 0d97c20c96..7d904bc3c0 100644 --- a/pipenv/patched/pip/_internal/metadata/importlib/_envs.py +++ b/pipenv/patched/pip/_internal/metadata/importlib/_envs.py @@ -26,9 +26,11 @@ def _looks_like_wheel(location: str) -> bool: return False if not os.path.isfile(location): return False - if not Wheel.wheel_file_re.match(os.path.basename(location)): - return False - return zipfile.is_zipfile(location) + return ( + zipfile.is_zipfile(location) + if Wheel.wheel_file_re.match(os.path.basename(location)) + else False + ) class _DistributionFinder: @@ -77,10 +79,7 @@ def find(self, location: str) -> Iterator[BaseDistribution]: The path can be either a directory, or a ZIP archive. """ for dist, info_location in self._find_impl(location): - if info_location is None: - installed_location: Optional[BasePath] = None - else: - installed_location = info_location.parent + installed_location = None if info_location is None else info_location.parent yield Distribution(dist, info_location, installed_location) def find_linked(self, location: str) -> Iterator[BaseDistribution]: @@ -165,17 +164,13 @@ def default(cls) -> BaseEnvironment: @classmethod def from_paths(cls, paths: Optional[List[str]]) -> BaseEnvironment: - if paths is None: - return cls(sys.path) - return cls(paths) + return cls(sys.path) if paths is None else cls(paths) def _iter_distributions(self) -> Iterator[BaseDistribution]: finder = _DistributionFinder() for location in self._paths: yield from finder.find(location) - for dist in finder.find_eggs(location): - # _emit_egg_deprecation(dist.location) # TODO: Enable this. - yield dist + yield from finder.find_eggs(location) # This must go last because that's how pkg_resources tie-breaks. yield from finder.find_linked(location) diff --git a/pipenv/patched/pip/_internal/metadata/pkg_resources.py b/pipenv/patched/pip/_internal/metadata/pkg_resources.py index dcb2bc04c0..c982809905 100644 --- a/pipenv/patched/pip/_internal/metadata/pkg_resources.py +++ b/pipenv/patched/pip/_internal/metadata/pkg_resources.py @@ -136,8 +136,7 @@ def location(self) -> Optional[str]: @property def installed_location(self) -> Optional[str]: - egg_link = egg_link_path_from_location(self.raw_name) - if egg_link: + if egg_link := egg_link_path_from_location(self.raw_name): location = egg_link elif self.location: location = self.location @@ -242,15 +241,17 @@ def _search_distribution(self, name: str) -> Optional[BaseDistribution]: match the behavior of ``pkg_resources.get_distribution()``. """ canonical_name = canonicalize_name(name) - for dist in self.iter_all_distributions(): - if dist.canonical_name == canonical_name: - return dist - return None + return next( + ( + dist + for dist in self.iter_all_distributions() + if dist.canonical_name == canonical_name + ), + None, + ) def get_distribution(self, name: str) -> Optional[BaseDistribution]: - # Search the distribution by looking through the working set. - dist = self._search_distribution(name) - if dist: + if dist := self._search_distribution(name): return dist # If distribution could not be found, call working_set.require to diff --git a/pipenv/patched/pip/_internal/models/direct_url.py b/pipenv/patched/pip/_internal/models/direct_url.py index 09b540f916..0287aaff45 100644 --- a/pipenv/patched/pip/_internal/models/direct_url.py +++ b/pipenv/patched/pip/_internal/models/direct_url.py @@ -170,9 +170,7 @@ def _remove_auth_from_netloc(self, netloc: str) -> str: and user_pass == "git" ): return netloc - if ENV_VAR_RE.match(user_pass): - return netloc - return netloc_no_user_pass + return netloc if ENV_VAR_RE.match(user_pass) else netloc_no_user_pass @property def redacted_url(self) -> str: @@ -182,10 +180,9 @@ def redacted_url(self) -> str: """ purl = urllib.parse.urlsplit(self.url) netloc = self._remove_auth_from_netloc(purl.netloc) - surl = urllib.parse.urlunsplit( + return urllib.parse.urlunsplit( (purl.scheme, netloc, purl.path, purl.query, purl.fragment) ) - return surl def validate(self) -> None: self.from_dict(self.to_dict()) diff --git a/pipenv/patched/pip/_internal/models/format_control.py b/pipenv/patched/pip/_internal/models/format_control.py index 7b84f562d9..4f9fd910e1 100644 --- a/pipenv/patched/pip/_internal/models/format_control.py +++ b/pipenv/patched/pip/_internal/models/format_control.py @@ -33,9 +33,7 @@ def __eq__(self, other: object) -> bool: return all(getattr(self, k) == getattr(other, k) for k in self.__slots__) def __repr__(self) -> str: - return "{}({}, {})".format( - self.__class__.__name__, self.no_binary, self.only_binary - ) + return f"{self.__class__.__name__}({self.no_binary}, {self.only_binary})" @staticmethod def handle_mutual_excludes(value: str, target: Set[str], other: Set[str]) -> None: @@ -62,13 +60,13 @@ def handle_mutual_excludes(value: str, target: Set[str], other: Set[str]) -> Non def get_allowed_formats(self, canonical_name: str) -> FrozenSet[str]: result = {"binary", "source"} - if canonical_name in self.only_binary: - result.discard("source") - elif canonical_name in self.no_binary: - result.discard("binary") - elif ":all:" in self.only_binary: + if ( + canonical_name in self.only_binary + or canonical_name not in self.no_binary + and ":all:" in self.only_binary + ): result.discard("source") - elif ":all:" in self.no_binary: + elif canonical_name in self.no_binary or ":all:" in self.no_binary: result.discard("binary") return frozenset(result) diff --git a/pipenv/patched/pip/_internal/models/link.py b/pipenv/patched/pip/_internal/models/link.py index 6a0d6d27fa..657780d9a7 100644 --- a/pipenv/patched/pip/_internal/models/link.py +++ b/pipenv/patched/pip/_internal/models/link.py @@ -124,21 +124,14 @@ def _clean_url_path(path: str, is_local_path: bool) -> str: """ Clean the path portion of a URL. """ - if is_local_path: - clean_func = _clean_file_url_path - else: - clean_func = _clean_url_path_part - + clean_func = _clean_file_url_path if is_local_path else _clean_url_path_part # Split on the reserved characters prior to cleaning so that # revision strings in VCS URLs are properly preserved. parts = _reserved_chars_re.split(path) cleaned_parts = [] for to_clean, reserved in pairwise(itertools.chain(parts, [""])): - cleaned_parts.append(clean_func(to_clean)) - # Normalize %xx escapes (e.g. %2f -> %2F) - cleaned_parts.append(reserved.upper()) - + cleaned_parts.extend((clean_func(to_clean), reserved.upper())) return "".join(cleaned_parts) @@ -225,7 +218,7 @@ def __init__( self._hashes = {**hashes, **hashes_from_link} self.comes_from = comes_from - self.requires_python = requires_python if requires_python else None + self.requires_python = requires_python or None self.yanked_reason = yanked_reason self.dist_info_metadata = dist_info_metadata @@ -297,16 +290,14 @@ def from_element( ) def __str__(self) -> str: - if self.requires_python: - rp = f" (requires-python:{self.requires_python})" - else: - rp = "" - if self.comes_from: - return "{} (from {}){}".format( - redact_auth_from_url(self._url), self.comes_from, rp - ) - else: + if not self.comes_from: return redact_auth_from_url(str(self._url)) + rp = ( + f" (requires-python:{self.requires_python})" + if self.requires_python + else "" + ) + return f"{redact_auth_from_url(self._url)} (from {self.comes_from}){rp}" def __repr__(self) -> str: return f"" @@ -390,9 +381,7 @@ def _egg_fragment(self) -> Optional[str]: @property def subdirectory_fragment(self) -> Optional[str]: match = self._subdirectory_fragment_re.search(self._url) - if not match: - return None - return match.group(1) + return match.group(1) if match else None def metadata_link(self) -> Optional["Link"]: """Implementation of PEP 658 parsing.""" diff --git a/pipenv/patched/pip/_internal/models/search_scope.py b/pipenv/patched/pip/_internal/models/search_scope.py index 73c6222767..2ad22d91e7 100644 --- a/pipenv/patched/pip/_internal/models/search_scope.py +++ b/pipenv/patched/pip/_internal/models/search_scope.py @@ -76,12 +76,12 @@ def __init__( self.find_links = find_links self.index_urls = index_urls self.no_index = no_index - self.index_lookup = index_lookup if index_lookup else {} + self.index_lookup = index_lookup or {} def get_formatted_locations(self) -> str: lines = [] - redacted_index_urls = [] if self.index_urls and self.index_urls != [PyPI.simple_url]: + redacted_index_urls = [] for url in self.index_urls: redacted_index_url = redact_auth_from_url(url) @@ -102,15 +102,11 @@ def get_formatted_locations(self) -> str: redacted_index_urls.append(redacted_index_url) - lines.append( - "Looking in indexes: {}".format(", ".join(redacted_index_urls)) - ) + lines.append(f'Looking in indexes: {", ".join(redacted_index_urls)}') if self.find_links: lines.append( - "Looking in links: {}".format( - ", ".join(redact_auth_from_url(url) for url in self.find_links) - ) + f'Looking in links: {", ".join(redact_auth_from_url(url) for url in self.find_links)}' ) return "\n".join(lines) @@ -131,7 +127,7 @@ def mkurl_pypi_url(url: str) -> str: # implementations might break if they relied on easy_install's # behavior. if not loc.endswith("/"): - loc = loc + "/" + loc = f"{loc}/" return loc index_urls = self.index_urls diff --git a/pipenv/patched/pip/_internal/network/auth.py b/pipenv/patched/pip/_internal/network/auth.py index 1e025e03b0..3a6d141a00 100644 --- a/pipenv/patched/pip/_internal/network/auth.py +++ b/pipenv/patched/pip/_internal/network/auth.py @@ -73,14 +73,10 @@ def get_auth_info(self, url: str, username: Optional[str]) -> Optional[AuthInfo] if hasattr(self.keyring, "get_credential"): logger.debug("Getting credentials from keyring for %s", url) cred = self.keyring.get_credential(url, username) - if cred is not None: - return cred.username, cred.password - return None - + return (cred.username, cred.password) if cred is not None else None if username is not None: logger.debug("Getting password from keyring for %s", url) - password = self.keyring.get_password(url, username) - if password: + if password := self.keyring.get_password(url, username): return username, password return None @@ -126,9 +122,7 @@ def _get_password(self, service_name: str, username: str) -> Optional[str]: capture_output=True, env=env, ) - if res.returncode: - return None - return res.stdout.decode("utf-8").strip(os.linesep) + return None if res.returncode else res.stdout.decode("utf-8").strip(os.linesep) def _set_password(self, service_name: str, username: str, password: str) -> None: """Mirror the implementation of keyring.set_password using cli""" @@ -161,9 +155,7 @@ def get_keyring_provider() -> KeyRingBaseProvider: str(exc), ) - # Fallback to Cli Provider if `keyring` isn't installed - cli = shutil.which("keyring") - if cli: + if cli := shutil.which("keyring"): return KeyRingCliProvider(cli) return KeyRingNullProvider() @@ -245,9 +237,7 @@ def _get_new_credentials( # Find a matching index url for this request index_url = self._get_index_url(url) if index_url: - # Split the credentials from the url. - index_info = split_auth_netloc_from_url(index_url) - if index_info: + if index_info := split_auth_netloc_from_url(index_url): index_url, _, index_url_user_password = index_info logger.debug("Found index url %s", index_url) @@ -260,21 +250,16 @@ def _get_new_credentials( # Get creds from netrc if we still don't have them if allow_netrc: - netrc_auth = get_netrc_auth(original_url) - if netrc_auth: + if netrc_auth := get_netrc_auth(original_url): logger.debug("Found credentials in netrc for %s", netloc) return netrc_auth # If we don't have a password and keyring is available, use it. if allow_keyring: - # The index url is more specific than the netloc, so try it first - # fmt: off - kr_auth = ( - get_keyring_auth(index_url, username) or - get_keyring_auth(netloc, username) - ) - # fmt: on - if kr_auth: + if kr_auth := ( + get_keyring_auth(index_url, username) + or get_keyring_auth(netloc, username) + ): logger.debug("Found credentials in keyring for %s", netloc) return kr_auth diff --git a/pipenv/patched/pip/_internal/network/download.py b/pipenv/patched/pip/_internal/network/download.py index 4d3d19e049..5e1737cec8 100644 --- a/pipenv/patched/pip/_internal/network/download.py +++ b/pipenv/patched/pip/_internal/network/download.py @@ -42,7 +42,7 @@ def _prepare_download( logged_url = redact_auth_from_url(url) if total_length: - logged_url = "{} ({})".format(logged_url, format_size(total_length)) + logged_url = f"{logged_url} ({format_size(total_length)})" if is_from_cache(resp): logger.info("Using cached %s", logged_url) @@ -96,9 +96,7 @@ def _get_http_response_filename(resp: Response, link: Link) -> str: the link filename if not provided. """ filename = link.filename # fallback - # Have a look at the Content-Disposition header for a better guess - content_disposition = resp.headers.get("content-disposition") - if content_disposition: + if content_disposition := resp.headers.get("content-disposition"): filename = parse_content_disposition(content_disposition, filename) ext: Optional[str] = splitext(filename)[1] if not ext: @@ -106,8 +104,7 @@ def _get_http_response_filename(resp: Response, link: Link) -> str: if ext: filename += ext if not ext and link.url != resp.url: - ext = os.path.splitext(resp.url)[1] - if ext: + if ext := os.path.splitext(resp.url)[1]: filename += ext return filename diff --git a/pipenv/patched/pip/_internal/network/session.py b/pipenv/patched/pip/_internal/network/session.py index 93947612ff..598245728a 100644 --- a/pipenv/patched/pip/_internal/network/session.py +++ b/pipenv/patched/pip/_internal/network/session.py @@ -118,7 +118,13 @@ def user_agent() -> str: }, } - if data["implementation"]["name"] == "CPython": + if ( + data["implementation"]["name"] == "CPython" + or data["implementation"]["name"] != "PyPy" + and data["implementation"]["name"] == "Jython" + or data["implementation"]["name"] != "PyPy" + and data["implementation"]["name"] == "IronPython" + ): data["implementation"]["version"] = platform.python_version() elif data["implementation"]["name"] == "PyPy": pypy_version_info = sys.pypy_version_info # type: ignore @@ -127,13 +133,6 @@ def user_agent() -> str: data["implementation"]["version"] = ".".join( [str(x) for x in pypy_version_info] ) - elif data["implementation"]["name"] == "Jython": - # Complete Guess - data["implementation"]["version"] = platform.python_version() - elif data["implementation"]["name"] == "IronPython": - # Complete Guess - data["implementation"]["version"] = platform.python_version() - if sys.platform.startswith("linux"): from pipenv.patched.pip._vendor import distro @@ -144,13 +143,12 @@ def user_agent() -> str: zip(["name", "version", "id"], linux_distribution), ) ) - libc = dict( + if libc := dict( filter( lambda x: x[1], zip(["lib", "version"], libc_ver()), ) - ) - if libc: + ): distro_infos["libc"] = libc if distro_infos: data["distro"] = distro_infos @@ -427,14 +425,14 @@ def add_trusted_host( self.mount( build_url_from_netloc(host, scheme="http") + "/", self._trusted_host_adapter ) - self.mount(build_url_from_netloc(host) + "/", self._trusted_host_adapter) + self.mount(f"{build_url_from_netloc(host)}/", self._trusted_host_adapter) if not host_port[1]: self.mount( build_url_from_netloc(host, scheme="http") + ":", self._trusted_host_adapter, ) # Mount wildcard ports for the same host. - self.mount(build_url_from_netloc(host) + ":", self._trusted_host_adapter) + self.mount(f"{build_url_from_netloc(host)}:", self._trusted_host_adapter) def iter_secure_origins(self) -> Generator[SecureOrigin, None, None]: yield from SECURE_ORIGINS @@ -461,7 +459,7 @@ def is_secure_origin(self, location: Link) -> bool: # configured on this PackageFinder instance. for secure_origin in self.iter_secure_origins(): secure_protocol, secure_host, secure_port = secure_origin - if origin_protocol != secure_protocol and secure_protocol != "*": + if origin_protocol != secure_protocol != "*": continue try: diff --git a/pipenv/patched/pip/_internal/network/utils.py b/pipenv/patched/pip/_internal/network/utils.py index 98e3ac1abf..32d7ef8cf8 100644 --- a/pipenv/patched/pip/_internal/network/utils.py +++ b/pipenv/patched/pip/_internal/network/utils.py @@ -60,7 +60,7 @@ def response_chunks( """Given a requests Response, provide the data chunks.""" try: # Special case for urllib3. - for chunk in response.raw.stream( + yield from response.raw.stream( chunk_size, # We use decode_content=False here because we don't # want urllib3 to mess with the raw bytes we get @@ -85,12 +85,11 @@ def response_chunks( # By setting this not to decode automatically we # hope to eliminate problems with the second case. decode_content=False, - ): - yield chunk + ) except AttributeError: # Standard file-like object. while True: - chunk = response.raw.read(chunk_size) - if not chunk: + if chunk := response.raw.read(chunk_size): + yield chunk + else: break - yield chunk diff --git a/pipenv/patched/pip/_internal/operations/build/build_tracker.py b/pipenv/patched/pip/_internal/operations/build/build_tracker.py index d7e22c51b9..dcc7acd7f3 100644 --- a/pipenv/patched/pip/_internal/operations/build/build_tracker.py +++ b/pipenv/patched/pip/_internal/operations/build/build_tracker.py @@ -88,7 +88,7 @@ def add(self, req: InstallRequirement) -> None: except FileNotFoundError: pass else: - message = "{} is already being built: {}".format(req.link, contents) + message = f"{req.link} is already being built: {contents}" raise LookupError(message) # If we're here, req should really not be building already. diff --git a/pipenv/patched/pip/_internal/operations/build/metadata_legacy.py b/pipenv/patched/pip/_internal/operations/build/metadata_legacy.py index 73e377ed13..b27d0e1120 100644 --- a/pipenv/patched/pip/_internal/operations/build/metadata_legacy.py +++ b/pipenv/patched/pip/_internal/operations/build/metadata_legacy.py @@ -27,7 +27,7 @@ def _find_egg_info(directory: str) -> str: if len(filenames) > 1: raise InstallationError( - "More than one .egg-info directory found in {}".format(directory) + f"More than one .egg-info directory found in {directory}" ) return os.path.join(directory, filenames[0]) diff --git a/pipenv/patched/pip/_internal/operations/build/wheel_legacy.py b/pipenv/patched/pip/_internal/operations/build/wheel_legacy.py index 6f514e8b23..72675fb222 100644 --- a/pipenv/patched/pip/_internal/operations/build/wheel_legacy.py +++ b/pipenv/patched/pip/_internal/operations/build/wheel_legacy.py @@ -92,11 +92,10 @@ def build_wheel_legacy( return None names = os.listdir(tempd) - wheel_path = get_legacy_build_wheel_path( + return get_legacy_build_wheel_path( names=names, temp_dir=tempd, name=name, command_args=wheel_args, command_output=output, ) - return wheel_path diff --git a/pipenv/patched/pip/_internal/operations/freeze.py b/pipenv/patched/pip/_internal/operations/freeze.py index 48b5b328a3..a25fc5a5c3 100644 --- a/pipenv/patched/pip/_internal/operations/freeze.py +++ b/pipenv/patched/pip/_internal/operations/freeze.py @@ -82,11 +82,22 @@ def freeze( yield line continue - if line.startswith("-e") or line.startswith("--editable"): - if line.startswith("-e"): - line = line[2:].strip() - else: - line = line[len("--editable") :].strip().lstrip("=") + if line.startswith("-e"): + line = ( + line[2:].strip() + if line.startswith("-e") + else line[len("--editable") :].strip().lstrip("=") + ) + line_req = install_req_from_editable( + line, + isolated=isolated, + ) + elif line.startswith("--editable"): + line = ( + line[2:].strip() + if line.startswith("-e") + else line[len("--editable") :].strip().lstrip("=") + ) line_req = install_req_from_editable( line, isolated=isolated, @@ -110,24 +121,21 @@ def freeze( ) else: line_req_canonical_name = canonicalize_name(line_req.name) - if line_req_canonical_name not in installations: - # either it's not installed, or it is installed - # but has been processed already - if not req_files[line_req.name]: - logger.warning( - "Requirement file [%s] contains %s, but " - "package %r is not installed", - req_file_path, - COMMENT_RE.sub("", line).strip(), - line_req.name, - ) - else: - req_files[line_req.name].append(req_file_path) - else: + if line_req_canonical_name in installations: yield str(installations[line_req_canonical_name]).rstrip() del installations[line_req_canonical_name] req_files[line_req.name].append(req_file_path) + elif not req_files[line_req.name]: + logger.warning( + "Requirement file [%s] contains %s, but " + "package %r is not installed", + req_file_path, + COMMENT_RE.sub("", line).strip(), + line_req.name, + ) + else: + req_files[line_req.name].append(req_file_path) # Warn about requirements that were included multiple times (in a # single requirements file or in different requirements files). for name, files in req_files.items(): @@ -237,8 +245,7 @@ def from_dist(cls, dist: BaseDistribution) -> "FrozenRequirement": req, comments = _get_editable_info(dist) else: comments = [] - direct_url = dist.direct_url - if direct_url: + if direct_url := dist.direct_url: # if PEP 610 metadata is present, use it req = direct_url_as_pep440_direct_reference(direct_url, dist.raw_name) else: diff --git a/pipenv/patched/pip/_internal/operations/install/wheel.py b/pipenv/patched/pip/_internal/operations/install/wheel.py index 588a40a882..69fbd21e25 100644 --- a/pipenv/patched/pip/_internal/operations/install/wheel.py +++ b/pipenv/patched/pip/_internal/operations/install/wheel.py @@ -162,16 +162,12 @@ def message_about_scripts_not_on_PATH(scripts: Sequence[str]) -> Optional[str]: for parent_dir, dir_scripts in warn_for.items(): sorted_scripts: List[str] = sorted(dir_scripts) if len(sorted_scripts) == 1: - start_text = "script {} is".format(sorted_scripts[0]) + start_text = f"script {sorted_scripts[0]} is" else: - start_text = "scripts {} are".format( - ", ".join(sorted_scripts[:-1]) + " and " + sorted_scripts[-1] - ) + start_text = f'scripts {", ".join(sorted_scripts[:-1]) + " and " + sorted_scripts[-1]} are' msg_lines.append( - "The {} installed in '{}' which is not on PATH.".format( - start_text, parent_dir - ) + f"The {start_text} installed in '{parent_dir}' which is not on PATH." ) last_line_fmt = ( @@ -265,8 +261,10 @@ def get_csv_rows_for_installed( path = _fs_to_record_path(f, lib_dir) digest, length = rehash(f) installed_rows.append((path, digest, length)) - for installed_record_path in installed.values(): - installed_rows.append((installed_record_path, "", "")) + installed_rows.extend( + (installed_record_path, "", "") + for installed_record_path in installed.values() + ) return installed_rows @@ -280,63 +278,24 @@ def get_console_script_specs(console: Dict[str, str]) -> List[str]: scripts_to_generate = [] - # Special case pip and setuptools to generate versioned wrappers - # - # The issue is that some projects (specifically, pip and setuptools) use - # code in setup.py to create "versioned" entry points - pip2.7 on Python - # 2.7, pip3.3 on Python 3.3, etc. But these entry points are baked into - # the wheel metadata at build time, and so if the wheel is installed with - # a *different* version of Python the entry points will be wrong. The - # correct fix for this is to enhance the metadata to be able to describe - # such versioned entry points, but that won't happen till Metadata 2.0 is - # available. - # In the meantime, projects using versioned entry points will either have - # incorrect versioned entry points, or they will not be able to distribute - # "universal" wheels (i.e., they will need a wheel per Python version). - # - # Because setuptools and pip are bundled with _ensurepip and virtualenv, - # we need to use universal wheels. So, as a stopgap until Metadata 2.0, we - # override the versioned entry points in the wheel and generate the - # correct ones. This code is purely a short-term measure until Metadata 2.0 - # is available. - # - # To add the level of hack in this section of code, in order to support - # ensurepip this code will look for an ``ENSUREPIP_OPTIONS`` environment - # variable which will control which version scripts get installed. - # - # ENSUREPIP_OPTIONS=altinstall - # - Only pipX.Y and easy_install-X.Y will be generated and installed - # ENSUREPIP_OPTIONS=install - # - pipX.Y, pipX, easy_install-X.Y will be generated and installed. Note - # that this option is technically if ENSUREPIP_OPTIONS is set and is - # not altinstall - # DEFAULT - # - The default behavior is to install pip, pipX, pipX.Y, easy_install - # and easy_install-X.Y. - pip_script = console.pop("pip", None) - if pip_script: + if pip_script := console.pop("pip", None): if "ENSUREPIP_OPTIONS" not in os.environ: - scripts_to_generate.append("pip = " + pip_script) + scripts_to_generate.append(f"pip = {pip_script}") if os.environ.get("ENSUREPIP_OPTIONS", "") != "altinstall": - scripts_to_generate.append( - "pip{} = {}".format(sys.version_info[0], pip_script) - ) + scripts_to_generate.append(f"pip{sys.version_info[0]} = {pip_script}") scripts_to_generate.append(f"pip{get_major_minor_version()} = {pip_script}") # Delete any other versioned pip entry points pip_ep = [k for k in console if re.match(r"pip(\d+(\.\d+)?)?$", k)] for k in pip_ep: del console[k] - easy_install_script = console.pop("easy_install", None) - if easy_install_script: + if easy_install_script := console.pop("easy_install", None): if "ENSUREPIP_OPTIONS" not in os.environ: - scripts_to_generate.append("easy_install = " + easy_install_script) + scripts_to_generate.append(f"easy_install = {easy_install_script}") scripts_to_generate.append( - "easy_install-{} = {}".format( - get_major_minor_version(), easy_install_script - ) + f"easy_install-{get_major_minor_version()} = {easy_install_script}" ) # Delete any other versioned easy_install entry points easy_install_ep = [ @@ -406,10 +365,7 @@ def save(self) -> None: class MissingCallableSuffix(InstallationError): def __init__(self, entry_point: str) -> None: super().__init__( - "Invalid script entry point: {} - A callable " - "suffix is required. Cf https://packaging.python.org/" - "specifications/entry-points/#use-for-scripts for more " - "information.".format(entry_point) + f"Invalid script entry point: {entry_point} - A callable suffix is required. Cf https://packaging.python.org/specifications/entry-points/#use-for-scripts for more information." ) @@ -454,11 +410,7 @@ def _install_wheel( """ info_dir, metadata = parse_wheel(wheel_zip, name) - if wheel_root_is_purelib(metadata): - lib_dir = scheme.purelib - else: - lib_dir = scheme.platlib - + lib_dir = scheme.purelib if wheel_root_is_purelib(metadata) else scheme.platlib # Record details of the files moved # installed = files copied from the wheel to the destination # changed = files changed while installing (scripts #! line typically) @@ -710,7 +662,7 @@ def req_error_context(req_description: str) -> Generator[None, None, None]: try: yield except InstallationError as e: - message = "For req: {}. {}".format(req_description, e.args[0]) + message = f"For req: {req_description}. {e.args[0]}" raise InstallationError(message) from e diff --git a/pipenv/patched/pip/_internal/operations/prepare.py b/pipenv/patched/pip/_internal/operations/prepare.py index a0b63f5cf8..cf751ec9d3 100644 --- a/pipenv/patched/pip/_internal/operations/prepare.py +++ b/pipenv/patched/pip/_internal/operations/prepare.py @@ -120,11 +120,7 @@ def get_file_url( if download_dir: already_downloaded_path = _check_download_dir(link, download_dir, hashes) - if already_downloaded_path: - from_path = already_downloaded_path - else: - from_path = link.file_path - + from_path = already_downloaded_path or link.file_path # If --require-hashes is off, `hashes` is either empty, the # link's embedded hash, or MissingHashes; it is required to # match. If --require-hashes is on, we are satisfied by any @@ -308,11 +304,7 @@ def _ensure_link_req_src_dir( # TODO: this check is now probably dead code if is_installable_dir(req.source_dir): raise PreviousBuildDirError( - "pip can't proceed with requirements '{}' due to a" - "pre-existing build directory ({}). This is likely " - "due to a previous installation that failed . pip is " - "being responsible and not assuming it can delete this. " - "Please delete it and try again.".format(req, req.source_dir) + f"pip can't proceed with requirements '{req}' due to apre-existing build directory ({req.source_dir}). This is likely due to a previous installation that failed . pip is being responsible and not assuming it can delete this. Please delete it and try again." ) def _get_linked_req_hashes(self, req: InstallRequirement) -> Hashes: @@ -543,8 +535,7 @@ def _prepare_linked_requirement( ) except NetworkConnectionError as exc: raise InstallationError( - "Could not install requirement {} because of HTTP " - "error {} for URL {}".format(req, exc, link) + f"Could not install requirement {req} because of HTTP error {exc} for URL {link}" ) else: file_path = self._downloaded[link.url] @@ -574,14 +565,13 @@ def _prepare_linked_requirement( if local_file: req.local_file_path = local_file.path - dist = _get_prepared_distribution( + return _get_prepared_distribution( req, self.build_tracker, self.finder, self.build_isolation, self.check_build_deps, ) - return dist def save_linked_requirement(self, req: InstallRequirement) -> None: assert self.download_dir is not None @@ -621,9 +611,7 @@ def prepare_editable_requirement( with indent_log(): if self.require_hashes: raise InstallationError( - "The editable requirement {} cannot be installed when " - "requiring hashes, because there is no single file to " - "hash.".format(req) + f"The editable requirement {req} cannot be installed when requiring hashes, because there is no single file to hash." ) req.ensure_has_source_dir(self.src_dir) req.update_editable() @@ -649,10 +637,9 @@ def prepare_installed_requirement( ) -> BaseDistribution: """Prepare an already-installed requirement.""" assert req.satisfied_by, "req should have been satisfied but isn't" - assert skip_reason is not None, ( - "did not get skip reason skipped but req.satisfied_by " - "is set to {}".format(req.satisfied_by) - ) + assert ( + skip_reason is not None + ), f"did not get skip reason skipped but req.satisfied_by is set to {req.satisfied_by}" logger.info( "Requirement %s: %s (%s)", skip_reason, req, req.satisfied_by.version ) diff --git a/pipenv/patched/pip/_internal/pyproject.py b/pipenv/patched/pip/_internal/pyproject.py index ff80cb82d9..bfd7327bf9 100644 --- a/pipenv/patched/pip/_internal/pyproject.py +++ b/pipenv/patched/pip/_internal/pyproject.py @@ -72,31 +72,25 @@ def load_pyproject_toml( # opposed to False can occur when the value is provided via an # environment variable or config file option (due to the quirk of # strtobool() returning an integer in pip's configuration code). - if has_pyproject and not has_setup: - if use_pep517 is not None and not use_pep517: - raise InstallationError( - "Disabling PEP 517 processing is invalid: " - "project does not have a setup.py" - ) + if ( + has_pyproject + and not has_setup + and (use_pep517 is None or use_pep517) + or (not has_pyproject or has_setup) + and build_system + and "build-backend" in build_system + and (use_pep517 is None or use_pep517) + ): use_pep517 = True + elif has_pyproject and not has_setup: + raise InstallationError( + "Disabling PEP 517 processing is invalid: " + "project does not have a setup.py" + ) elif build_system and "build-backend" in build_system: - if use_pep517 is not None and not use_pep517: - raise InstallationError( - "Disabling PEP 517 processing is invalid: " - "project specifies a build backend of {} " - "in pyproject.toml".format(build_system["build-backend"]) - ) - use_pep517 = True - - # If we haven't worked out whether to use PEP 517 yet, - # and the user hasn't explicitly stated a preference, - # we do so if the project has a pyproject.toml file - # or if we cannot import setuptools. - - # We fallback to PEP 517 when without setuptools, - # so setuptools can be installed as a default build backend. - # For more info see: - # https://discuss.python.org/t/pip-without-setuptools-could-the-experience-be-improved/11810/9 + raise InstallationError( + f'Disabling PEP 517 processing is invalid: project specifies a build backend of {build_system["build-backend"]} in pyproject.toml' + ) elif use_pep517 is None: use_pep517 = has_pyproject or not importlib.util.find_spec("setuptools") diff --git a/pipenv/patched/pip/_internal/req/constructors.py b/pipenv/patched/pip/_internal/req/constructors.py index cc4b2a83e9..79c91d3a39 100644 --- a/pipenv/patched/pip/_internal/req/constructors.py +++ b/pipenv/patched/pip/_internal/req/constructors.py @@ -43,8 +43,8 @@ def _strip_extras(path: str) -> Tuple[str, Optional[str]]: m = re.match(r"^(.+)(\[[^\]]+\])$", path) extras = None if m: - path_no_extras = m.group(1) - extras = m.group(2) + path_no_extras = m[1] + extras = m[2] else: path_no_extras = path @@ -52,9 +52,11 @@ def _strip_extras(path: str) -> Tuple[str, Optional[str]]: def convert_extras(extras: Optional[str]) -> Set[str]: - if not extras: - return set() - return get_requirement("placeholder" + extras.lower()).extras + return ( + get_requirement(f"placeholder{extras.lower()}").extras + if extras + else set() + ) def parse_editable(editable_req: str) -> Tuple[Optional[str], str, Set[str]]: @@ -83,7 +85,7 @@ def parse_editable(editable_req: str) -> Tuple[Optional[str], str, Set[str]]: return ( package_name, url_no_extras, - get_requirement("placeholder" + extras.lower()).extras, + get_requirement(f"placeholder{extras.lower()}").extras, ) else: return package_name, url_no_extras, set() @@ -103,13 +105,12 @@ def parse_editable(editable_req: str) -> Tuple[Optional[str], str, Set[str]]: f"(beginning with {backends})." ) - package_name = link.egg_fragment - if not package_name: + if package_name := link.egg_fragment: + return package_name, url, set() + else: raise InstallationError( - "Could not detect requirement name for '{}', please specify one " - "with #egg=your_package_name".format(editable_req) + f"Could not detect requirement name for '{editable_req}', please specify one with #egg=your_package_name" ) - return package_name, url, set() def check_first_requirement_in_file(filename: str) -> None: @@ -244,9 +245,7 @@ def _looks_like_path(name: str) -> bool: return True if os.path.altsep is not None and os.path.altsep in name: return True - if name.startswith("."): - return True - return False + return bool(name.startswith(".")) def _get_url_from_path(path: str, name: str) -> Optional[str]: @@ -284,17 +283,11 @@ def _get_url_from_path(path: str, name: str) -> Optional[str]: def parse_req_from_line(name: str, line_source: Optional[str]) -> RequirementParts: - if is_url(name): - marker_sep = "; " - else: - marker_sep = ";" + marker_sep = "; " if is_url(name) else ";" if marker_sep in name: name, markers_as_string = name.split(marker_sep, 1) markers_as_string = markers_as_string.strip() - if not markers_as_string: - markers = None - else: - markers = Marker(markers_as_string) + markers = Marker(markers_as_string) if markers_as_string else None else: markers = None name = name.strip() @@ -332,9 +325,7 @@ def parse_req_from_line(name: str, line_source: Optional[str]) -> RequirementPar extras = convert_extras(extras_as_string) def with_source(text: str) -> str: - if not line_source: - return text - return f"{text} (from {line_source})" + return f"{text} (from {line_source})" if line_source else text def _parse_req_string(req_as_string: str) -> Requirement: try: @@ -343,8 +334,8 @@ def _parse_req_string(req_as_string: str) -> Requirement: if os.path.sep in req_as_string: add_msg = "It looks like a path." add_msg += deduce_helpful_msg(req_as_string) - elif "=" in req_as_string and not any( - op in req_as_string for op in operators + elif "=" in req_as_string and all( + op not in req_as_string for op in operators ): add_msg = "= is not a valid operator. Did you mean == ?" else: @@ -365,11 +356,7 @@ def _parse_req_string(req_as_string: str) -> Requirement: raise InstallationError(msg) return req - if req_as_string is not None: - req: Optional[Requirement] = _parse_req_string(req_as_string) - else: - req = None - + req = _parse_req_string(req_as_string) if req_as_string is not None else None return RequirementParts(req, link, markers, extras) @@ -434,9 +421,7 @@ def install_req_from_req_string( ): # Explicitly disallow pypi packages that depend on external urls raise InstallationError( - "Packages installed from PyPI cannot depend on packages " - "which are not also hosted on PyPI.\n" - "{} depends on {} ".format(comes_from.name, req) + f"Packages installed from PyPI cannot depend on packages which are not also hosted on PyPI.\n{comes_from.name} depends on {req} " ) return InstallRequirement( @@ -456,8 +441,8 @@ def install_req_from_parsed_requirement( user_supplied: bool = False, config_settings: Optional[Dict[str, str]] = None, ) -> InstallRequirement: - if parsed_req.is_editable: - req = install_req_from_editable( + return ( + install_req_from_editable( parsed_req.requirement, comes_from=parsed_req.comes_from, use_pep517=use_pep517, @@ -466,9 +451,8 @@ def install_req_from_parsed_requirement( user_supplied=user_supplied, config_settings=config_settings, ) - - else: - req = install_req_from_line( + if parsed_req.is_editable + else install_req_from_line( parsed_req.requirement, comes_from=parsed_req.comes_from, use_pep517=use_pep517, @@ -479,7 +463,7 @@ def install_req_from_parsed_requirement( user_supplied=user_supplied, config_settings=config_settings, ) - return req + ) def install_req_from_link_and_ireq( diff --git a/pipenv/patched/pip/_internal/req/req_file.py b/pipenv/patched/pip/_internal/req/req_file.py index aa0a2b23e3..990b666ff0 100644 --- a/pipenv/patched/pip/_internal/req/req_file.py +++ b/pipenv/patched/pip/_internal/req/req_file.py @@ -168,11 +168,7 @@ def handle_requirement_line( ) -> ParsedRequirement: # preserve for the nested code path - line_comes_from = "{} {} (line {})".format( - "-c" if line.constraint else "-r", - line.filename, - line.lineno, - ) + line_comes_from = f'{"-c" if line.constraint else "-r"} {line.filename} (line {line.lineno})' assert line.is_requirement @@ -185,22 +181,20 @@ def handle_requirement_line( comes_from=line_comes_from, constraint=line.constraint, ) - else: - # get the options that apply to requirements - req_options = {} - for dest in SUPPORTED_OPTIONS_REQ_DEST: - if dest in line.opts.__dict__ and line.opts.__dict__[dest]: - req_options[dest] = line.opts.__dict__[dest] - - line_source = f"line {line.lineno} of {line.filename}" - return ParsedRequirement( - requirement=line.requirement, - is_editable=line.is_editable, - comes_from=line_comes_from, - constraint=line.constraint, - options=req_options, - line_source=line_source, - ) + req_options = { + dest: line.opts.__dict__[dest] + for dest in SUPPORTED_OPTIONS_REQ_DEST + if dest in line.opts.__dict__ and line.opts.__dict__[dest] + } + line_source = f"line {line.lineno} of {line.filename}" + return ParsedRequirement( + requirement=line.requirement, + is_editable=line.is_editable, + comes_from=line_comes_from, + constraint=line.constraint, + options=req_options, + line_source=line_source, + ) def handle_option_line( @@ -297,18 +291,16 @@ def handle_line( """ if line.is_requirement: - parsed_req = handle_requirement_line(line, options) - return parsed_req - else: - handle_option_line( - line.opts, - line.filename, - line.lineno, - finder, - options, - session, - ) - return None + return handle_requirement_line(line, options) + handle_option_line( + line.opts, + line.filename, + line.lineno, + finder, + options, + session, + ) + return None class RequirementsFileParser: @@ -416,9 +408,8 @@ def break_args_options(line: str) -> Tuple[str, str]: for token in tokens: if token.startswith("-") or token.startswith("--"): break - else: - args.append(token) - options.pop(0) + args.append(token) + options.pop(0) return " ".join(args), " ".join(options) @@ -460,7 +451,7 @@ def join_lines(lines_enum: ReqFileLines) -> ReqFileLines: if not line.endswith("\\") or COMMENT_RE.match(line): if COMMENT_RE.match(line): # this ensures comments are always matched later - line = " " + line + line = f" {line}" if new_line: new_line.append(line) assert primary_line_number is not None @@ -487,8 +478,7 @@ def ignore_comments(lines_enum: ReqFileLines) -> ReqFileLines: """ for line_number, line in lines_enum: line = COMMENT_RE.sub("", line) - line = line.strip() - if line: + if line := line.strip(): yield line_number, line @@ -510,11 +500,8 @@ def expand_env_variables(lines_enum: ReqFileLines) -> ReqFileLines: """ for line_number, line in lines_enum: for env_var, var_name in ENV_VAR_RE.findall(line): - value = os.getenv(var_name) - if not value: - continue - - line = line.replace(env_var, value) + if value := os.getenv(var_name): + line = line.replace(env_var, value) yield line_number, line diff --git a/pipenv/patched/pip/_internal/req/req_install.py b/pipenv/patched/pip/_internal/req/req_install.py index 30b14fdc87..10aa560557 100644 --- a/pipenv/patched/pip/_internal/req/req_install.py +++ b/pipenv/patched/pip/_internal/req/req_install.py @@ -146,9 +146,9 @@ def __init__( # Set to True after successful installation self.install_succeeded: Optional[bool] = None # Supplied options - self.install_options = install_options if install_options else [] - self.global_options = global_options if global_options else [] - self.hash_options = hash_options if hash_options else {} + self.install_options = install_options or [] + self.global_options = global_options or [] + self.hash_options = hash_options or {} self.config_settings = config_settings # Set to True after successful preparation of this requirement self.prepared = False @@ -189,7 +189,7 @@ def __str__(self) -> str: if self.req: s = str(self.req) if self.link: - s += " from {}".format(redact_auth_from_url(self.link.url)) + s += f" from {redact_auth_from_url(self.link.url)}" elif self.link: s = redact_auth_from_url(self.link.url) else: @@ -228,9 +228,7 @@ def format_debug(self) -> str: # Things that are valid for all kinds of requirements? @property def name(self) -> Optional[str]: - if self.req is None: - return None - return self.req.name + return None if self.req is None else self.req.name @functools.lru_cache() # use cached_property in python 3.8+ def supports_pyproject_editable(self) -> bool: @@ -311,7 +309,7 @@ def from_path(self) -> Optional[str]: else: comes_from = self.comes_from.from_path() if comes_from: - s += "->" + comes_from + s += f"->{comes_from}" return s def ensure_build_location( @@ -407,24 +405,10 @@ def check_if_exists(self, use_user_site: bool) -> None: if not existing_dist: return - version_compatible = self.req.specifier.contains( + if version_compatible := self.req.specifier.contains( existing_dist.version, prereleases=True, - ) - if not version_compatible: - self.satisfied_by = None - if use_user_site: - if existing_dist.in_usersite: - self.should_reinstall = True - elif running_under_virtualenv() and existing_dist.in_site_packages: - raise InstallationError( - f"Will not install to the user site because it will " - f"lack sys.path precedence to {existing_dist.raw_name} " - f"in {existing_dist.location}" - ) - else: - self.should_reinstall = True - else: + ): if self.editable: self.should_reinstall = True # when installing editables, nothing pre-existing should ever @@ -433,12 +417,26 @@ def check_if_exists(self, use_user_site: bool) -> None: else: self.satisfied_by = existing_dist + else: + self.satisfied_by = None + if use_user_site and existing_dist.in_usersite or not use_user_site: + self.should_reinstall = True + elif ( + use_user_site + and not existing_dist.in_usersite + and running_under_virtualenv() + and existing_dist.in_site_packages + ): + raise InstallationError( + f"Will not install to the user site because it will " + f"lack sys.path precedence to {existing_dist.raw_name} " + f"in {existing_dist.location}" + ) + # Things valid for wheels @property def is_wheel(self) -> bool: - if not self.link: - return False - return self.link.is_wheel + return self.link.is_wheel if self.link else False # Things valid for sdists @property @@ -450,16 +448,12 @@ def unpacked_source_directory(self) -> str: @property def setup_py_path(self) -> str: assert self.source_dir, f"No source dir for {self}" - setup_py = os.path.join(self.unpacked_source_directory, "setup.py") - - return setup_py + return os.path.join(self.unpacked_source_directory, "setup.py") @property def setup_cfg_path(self) -> str: assert self.source_dir, f"No source dir for {self}" - setup_cfg = os.path.join(self.unpacked_source_directory, "setup.cfg") - - return setup_cfg + return os.path.join(self.unpacked_source_directory, "setup.cfg") @property def pyproject_toml_path(self) -> str: @@ -676,7 +670,7 @@ def _clean_zip_name(name: str, prefix: str) -> str: path = os.path.join(parentdir, path) name = _clean_zip_name(path, rootdir) - return self.name + "/" + name + return f"{self.name}/{name}" def archive(self, build_dir: Optional[str]) -> None: """Saves archive to provided build_dir. @@ -688,13 +682,12 @@ def archive(self, build_dir: Optional[str]) -> None: return create_archive = True - archive_name = "{}-{}.zip".format(self.name, self.metadata["version"]) + archive_name = f'{self.name}-{self.metadata["version"]}.zip' archive_path = os.path.join(build_dir, archive_name) if os.path.exists(archive_path): response = ask_path_exists( - "The file {} exists. (i)gnore, (w)ipe, " - "(b)ackup, (a)bort ".format(display_path(archive_path)), + f"The file {display_path(archive_path)} exists. (i)gnore, (w)ipe, (b)ackup, (a)bort ", ("i", "w", "b", "a"), ) if response == "i": @@ -731,7 +724,7 @@ def archive(self, build_dir: Optional[str]) -> None: parentdir=dirpath, rootdir=dir, ) - zipdir = zipfile.ZipInfo(dir_arcname + "/") + zipdir = zipfile.ZipInfo(f"{dir_arcname}/") zipdir.external_attr = 0x1ED << 16 # 0o755 zip_output.writestr(zipdir, "") for filename in filenames: @@ -888,19 +881,16 @@ def check_invalid_constraint_type(req: InstallRequirement) -> str: def _has_option(options: Values, reqs: List[InstallRequirement], option: str) -> bool: if getattr(options, option, None): return True - for req in reqs: - if getattr(req, option, None): - return True - return False + return any(getattr(req, option, None) for req in reqs) def _install_option_ignored( install_options: List[str], reqs: List[InstallRequirement] ) -> bool: - for req in reqs: - if (install_options or req.install_options) and not req.use_pep517: - return False - return True + return not any( + (install_options or req.install_options) and not req.use_pep517 + for req in reqs + ) class LegacySetupPyOptionsCheckMode(Enum): diff --git a/pipenv/patched/pip/_internal/req/req_uninstall.py b/pipenv/patched/pip/_internal/req/req_uninstall.py index 8e8625912c..926ea42419 100644 --- a/pipenv/patched/pip/_internal/req/req_uninstall.py +++ b/pipenv/patched/pip/_internal/req/req_uninstall.py @@ -73,13 +73,10 @@ def uninstallation_paths(dist: BaseDistribution) -> Generator[str, None, None]: msg = "Cannot uninstall {dist}, RECORD file not found.".format(dist=dist) installer = dist.installer if not installer or installer == "pip": - dep = "{}=={}".format(dist.raw_name, dist.version) - msg += ( - " You might be able to recover from this via: " - "'pip install --force-reinstall --no-deps {}'.".format(dep) - ) + dep = f"{dist.raw_name}=={dist.version}" + msg += f" You might be able to recover from this via: 'pip install --force-reinstall --no-deps {dep}'." else: - msg += " Hint: The package was installed by {}.".format(installer) + msg += f" Hint: The package was installed by {installer}." raise UninstallationError(msg) for entry in entries: @@ -88,10 +85,8 @@ def uninstallation_paths(dist: BaseDistribution) -> Generator[str, None, None]: if path.endswith(".py"): dn, fn = os.path.split(path) base = fn[:-3] - path = os.path.join(dn, base + ".pyc") - yield path - path = os.path.join(dn, base + ".pyo") - yield path + yield os.path.join(dn, f"{base}.pyc") + yield os.path.join(dn, f"{base}.pyo") def compact(paths: Iterable[str]) -> Set[str]: @@ -520,7 +515,7 @@ def from_dist(cls, dist: BaseDistribution) -> "UninstallPathSet": os.path.dirname(dist_location), "easy-install.pth", ) - paths_to_remove.add_pth(easy_install_pth, "./" + easy_install_egg) + paths_to_remove.add_pth(easy_install_pth, f"./{easy_install_egg}") elif dist.installed_with_dist_info: for path in uninstallation_paths(dist): @@ -551,11 +546,7 @@ def from_dist(cls, dist: BaseDistribution) -> "UninstallPathSet": dist_location, ) - if dist.in_usersite: - bin_dir = get_bin_user() - else: - bin_dir = get_bin_prefix() - + bin_dir = get_bin_user() if dist.in_usersite else get_bin_prefix() # find distutils scripts= scripts try: for script in dist.iter_distutils_script_names(): @@ -614,10 +605,7 @@ def remove(self) -> None: # windows uses '\r\n' with py3k, but uses '\n' with py2.x lines = fh.readlines() self._saved_lines = lines - if any(b"\r\n" in line for line in lines): - endline = "\r\n" - else: - endline = "\n" + endline = "\r\n" if any(b"\r\n" in line for line in lines) else "\n" # handle missing trailing newline if lines and not lines[-1].endswith(endline.encode("utf-8")): lines[-1] = lines[-1] + endline.encode("utf-8") diff --git a/pipenv/patched/pip/_internal/resolution/legacy/resolver.py b/pipenv/patched/pip/_internal/resolution/legacy/resolver.py index 4889a8b811..84c1a34c97 100644 --- a/pipenv/patched/pip/_internal/resolution/legacy/resolver.py +++ b/pipenv/patched/pip/_internal/resolution/legacy/resolver.py @@ -231,9 +231,7 @@ def _add_requirement_to_set( tags = compatibility_tags.get_supported() if requirement_set.check_supported_wheels and not wheel.supported(tags): raise InstallationError( - "{} is not a supported wheel on this platform.".format( - wheel.filename - ) + f"{wheel.filename} is not a supported wheel on this platform." ) # This next bit is really a sanity check. @@ -254,7 +252,7 @@ def _add_requirement_to_set( except KeyError: existing_req = None - has_conflicting_requirement = ( + if has_conflicting_requirement := ( parent_req_name is None and existing_req and not existing_req.constraint @@ -262,8 +260,7 @@ def _add_requirement_to_set( and existing_req.req and install_req.req and existing_req.req.specifier != install_req.req.specifier - ) - if has_conflicting_requirement: + ): raise InstallationError( "Double requirement given: {} (already in {}, name={!r})".format( install_req, existing_req, install_req.name @@ -282,14 +279,11 @@ def _add_requirement_to_set( if install_req.constraint or not existing_req.constraint: return [], existing_req - does_not_satisfy_constraint = install_req.link and not ( + if does_not_satisfy_constraint := install_req.link and not ( existing_req.link and install_req.link.path == existing_req.link.path - ) - if does_not_satisfy_constraint: + ): raise InstallationError( - "Could not satisfy constraints for '{}': " - "installation from path or url cannot be " - "constrained to a version".format(install_req.name) + f"Could not satisfy constraints for '{install_req.name}': installation from path or url cannot be constrained to a version" ) # If we're now installing a constraint, mark the existing # object for real installation. diff --git a/pipenv/patched/pip/_internal/resolution/resolvelib/base.py b/pipenv/patched/pip/_internal/resolution/resolvelib/base.py index 01e8b3b9c2..71df437382 100644 --- a/pipenv/patched/pip/_internal/resolution/resolvelib/base.py +++ b/pipenv/patched/pip/_internal/resolution/resolvelib/base.py @@ -16,7 +16,7 @@ def format_name(project: str, extras: FrozenSet[str]) -> str: if not extras: return project canonical_extras = sorted(canonicalize_name(e) for e in extras) - return "{}[{}]".format(project, ",".join(canonical_extras)) + return f'{project}[{",".join(canonical_extras)}]' class Constraint: diff --git a/pipenv/patched/pip/_internal/resolution/resolvelib/candidates.py b/pipenv/patched/pip/_internal/resolution/resolvelib/candidates.py index fb3f4f2511..80cb77f9f2 100644 --- a/pipenv/patched/pip/_internal/resolution/resolvelib/candidates.py +++ b/pipenv/patched/pip/_internal/resolution/resolvelib/candidates.py @@ -46,19 +46,14 @@ def as_base_candidate(candidate: Candidate) -> Optional[BaseCandidate]: EditableCandidate, LinkCandidate, ) - if isinstance(candidate, base_candidate_classes): - return candidate - return None + return candidate if isinstance(candidate, base_candidate_classes) else None def make_install_req_from_link( link: Link, template: InstallRequirement ) -> InstallRequirement: assert not template.editable, "template is editable" - if template.req: - line = str(template.req) - else: - line = link.url + line = str(template.req) if template.req else link.url ireq = install_req_from_line( line, user_supplied=template.user_supplied, @@ -201,11 +196,7 @@ def version(self) -> CandidateVersion: return self._version def format_for_error(self) -> str: - return "{} {} (from {})".format( - self.name, - self.version, - self._link.file_path if self._link.is_file else self._link, - ) + return f"{self.name} {self.version} (from {self._link.file_path if self._link.is_file else self._link})" def _prepare_distribution(self) -> BaseDistribution: raise NotImplementedError("Override in subclass") @@ -438,7 +429,7 @@ def __init__( def __str__(self) -> str: name, rest = str(self.base).split(" ", 1) - return "{}[{}] {}".format(name, ",".join(self.extras), rest) + return f'{name}[{",".join(self.extras)}] {rest}' def __repr__(self) -> str: return "{class_name}(base={base!r}, extras={extras!r})".format( @@ -469,9 +460,7 @@ def version(self) -> CandidateVersion: return self.base.version def format_for_error(self) -> str: - return "{} [{}]".format( - self.base.format_for_error(), ", ".join(sorted(self.extras)) - ) + return f'{self.base.format_for_error()} [{", ".join(sorted(self.extras))}]' @property def is_installed(self) -> bool: @@ -507,10 +496,9 @@ def iter_dependencies(self, with_requires: bool) -> Iterable[Optional[Requiremen ) for r in self.base.dist.iter_dependencies(valid_extras): - requirement = factory.make_requirement_from_spec( + if requirement := factory.make_requirement_from_spec( str(r), self.base._ireq, valid_extras - ) - if requirement: + ): yield requirement def get_install_requirement(self) -> Optional[InstallRequirement]: diff --git a/pipenv/patched/pip/_internal/resolution/resolvelib/factory.py b/pipenv/patched/pip/_internal/resolution/resolvelib/factory.py index 774674df3a..107b6a3640 100644 --- a/pipenv/patched/pip/_internal/resolution/resolvelib/factory.py +++ b/pipenv/patched/pip/_internal/resolution/resolvelib/factory.py @@ -159,9 +159,7 @@ def _make_candidate_from_dist( except KeyError: base = AlreadyInstalledCandidate(dist, template, factory=self) self._installed_candidate_cache[dist.canonical_name] = base - if not extras: - return base - return self._make_extras_candidate(base, extras) + return self._make_extras_candidate(base, extras) if extras else base def _make_candidate_from_link( self, @@ -221,9 +219,7 @@ def _make_candidate_from_link( return None base = self._link_candidate_cache[link] - if not extras: - return base - return self._make_extras_candidate(base, extras) + return self._make_extras_candidate(base, extras) if extras else base def _iter_found_candidates( self, @@ -271,9 +267,7 @@ def _get_installed_candidate() -> Optional[Candidate]: template=template, ) # The candidate is a known incompatibility. Don't use it. - if id(candidate) in incompatible_ids: - return None - return candidate + return None if id(candidate) in incompatible_ids else candidate def iter_index_candidate_infos() -> Iterator[IndexCandidateInfo]: result = self._finder.find_best_candidate( @@ -303,7 +297,7 @@ def is_pinned(specifier: SpecifierSet) -> bool: # PackageFinder returns earlier versions first, so we reverse. for ican in reversed(icans): - if not (all_yanked and pinned) and ican.link.is_yanked: + if (not all_yanked or not pinned) and ican.link.is_yanked: continue func = functools.partial( self._make_candidate_from_link, @@ -357,14 +351,13 @@ def _iter_candidates_from_constraints( """ for link in constraint.links: self._fail_if_link_is_unsupported_wheel(link) - candidate = self._make_candidate_from_link( + if candidate := self._make_candidate_from_link( link, extras=frozenset(), template=install_req_from_link_and_ireq(link, template), name=canonicalize_name(identifier), version=None, - ) - if candidate: + ): yield candidate def find_candidates( @@ -420,21 +413,22 @@ def find_candidates( # If none of the requirements want an explicit candidate, we can ask # the finder for candidates. - if not explicit_candidates: - return self._iter_found_candidates( + return ( + ( + c + for c in explicit_candidates + if id(c) not in incompat_ids + and constraint.is_satisfied_by(c) + and all(req.is_satisfied_by(c) for req in requirements[identifier]) + ) + if explicit_candidates + else self._iter_found_candidates( ireqs, constraint.specifier, constraint.hashes, prefers_installed, incompat_ids, ) - - return ( - c - for c in explicit_candidates - if id(c) not in incompat_ids - and constraint.is_satisfied_by(c) - and all(req.is_satisfied_by(c) for req in requirements[identifier]) ) def _make_requirement_from_install_req( @@ -475,9 +469,7 @@ def collect_root_requirements( collected = CollectedRootRequirements([], {}, {}) for i, ireq in enumerate(root_ireqs): if ireq.constraint: - # Ensure we only accept valid constraints - problem = check_invalid_constraint_type(ireq) - if problem: + if problem := check_invalid_constraint_type(ireq): raise InstallationError(problem) if not ireq.match_markers(): continue @@ -520,9 +512,11 @@ def make_requires_python_requirement( if self._ignore_requires_python: return None # Don't bother creating a dependency for an empty Requires-Python. - if not str(specifier): - return None - return RequiresPythonRequirement(specifier, self._python_candidate) + return ( + RequiresPythonRequirement(specifier, self._python_candidate) + if str(specifier) + else None + ) def get_wheel_cache_entry( self, link: Link, name: Optional[str] @@ -596,11 +590,7 @@ def _report_requires_python_error( def _report_single_requirement_conflict( self, req: Requirement, parent: Optional[Candidate] ) -> DistributionNotFound: - if parent is None: - req_disp = str(req) - else: - req_disp = f"{req} (from {parent.name})" - + req_disp = str(req) if parent is None else f"{req} (from {parent.name})" cands = self._finder.find_all_candidates(req.project_name) skipped_by_requires_python = self._finder.requires_python_skipped_reasons() versions = [str(v) for v in sorted({c.version for c in cands})] @@ -687,11 +677,7 @@ def describe_trigger(parent: Candidate) -> str: trigger = describe_trigger(parent) triggers.add(trigger) - if triggers: - info = text_join(sorted(triggers)) - else: - info = "the requested packages" - + info = text_join(sorted(triggers)) if triggers else "the requested packages" msg = ( "Cannot install {} because these package versions " "have conflicting dependencies.".format(info) @@ -705,9 +691,9 @@ def describe_trigger(parent: Candidate) -> str: relevant_constraints.add(req.name) msg = msg + "\n " if parent: - msg = msg + f"{parent.name} {parent.version} depends on " + msg = f"{msg}{parent.name} {parent.version} depends on " else: - msg = msg + "The user requested " + msg = f"{msg}The user requested " msg = msg + req.format_for_error() for key in relevant_constraints: spec = constraints[key].specifier diff --git a/pipenv/patched/pip/_internal/resolution/resolvelib/found_candidates.py b/pipenv/patched/pip/_internal/resolution/resolvelib/found_candidates.py index 57eb386fff..ab7fd5ded8 100644 --- a/pipenv/patched/pip/_internal/resolution/resolvelib/found_candidates.py +++ b/pipenv/patched/pip/_internal/resolution/resolvelib/found_candidates.py @@ -8,6 +8,7 @@ something. """ + import functools from collections.abc import Sequence from typing import TYPE_CHECKING, Any, Callable, Iterator, Optional, Set, Tuple @@ -18,20 +19,7 @@ IndexCandidateInfo = Tuple[_BaseVersion, Callable[[], Optional[Candidate]]] -if TYPE_CHECKING: - SequenceCandidate = Sequence[Candidate] -else: - # For compatibility: Python before 3.9 does not support using [] on the - # Sequence class. - # - # >>> from collections.abc import Sequence - # >>> Sequence[str] - # Traceback (most recent call last): - # File "", line 1, in - # TypeError: 'ABCMeta' object is not subscriptable - # - # TODO: Remove this block after dropping Python 3.8 support. - SequenceCandidate = Sequence +SequenceCandidate = Sequence[Candidate] if TYPE_CHECKING else Sequence def _iter_built(infos: Iterator[IndexCandidateInfo]) -> Iterator[Candidate]: @@ -150,6 +138,4 @@ def __len__(self) -> int: @functools.lru_cache(maxsize=1) def __bool__(self) -> bool: - if self._prefers_installed and self._installed: - return True - return any(self) + return True if self._prefers_installed and self._installed else any(self) diff --git a/pipenv/patched/pip/_internal/resolution/resolvelib/provider.py b/pipenv/patched/pip/_internal/resolution/resolvelib/provider.py index 90b0358bb2..13485e93e4 100644 --- a/pipenv/patched/pip/_internal/resolution/resolvelib/provider.py +++ b/pipenv/patched/pip/_internal/resolution/resolvelib/provider.py @@ -70,9 +70,7 @@ def _get_with_identifier( # kinds of identifiers: normalized PEP 503 names, normalized names plus # extras, and Requires-Python, we can cheat a bit here. name, open_bracket, _ = identifier.partition("[") - if open_bracket and name in mapping: - return mapping[name] - return default + return mapping[name] if open_bracket and name in mapping else default class PipProvider(_ProviderBase): @@ -150,7 +148,7 @@ def get_preference( # type: ignore self._known_depths[parent.name] if parent is not None else 0.0 for _, parent in information[identifier] ) - inferred_depth = min(d for d in parent_depths) + 1.0 + inferred_depth = min(parent_depths) + 1.0 else: inferred_depth = 1.0 self._known_depths[identifier] = inferred_depth diff --git a/pipenv/patched/pip/_internal/resolution/resolvelib/requirements.py b/pipenv/patched/pip/_internal/resolution/resolvelib/requirements.py index dc038aa6f1..5b6894b8ac 100644 --- a/pipenv/patched/pip/_internal/resolution/resolvelib/requirements.py +++ b/pipenv/patched/pip/_internal/resolution/resolvelib/requirements.py @@ -70,7 +70,7 @@ def format_for_error(self) -> str: # risking a change in meaning. (Hopefully! Not all edge cases have # been checked) parts = [s.strip() for s in str(self).split(",")] - if len(parts) == 0: + if not parts: return "" elif len(parts) == 1: return parts[0] diff --git a/pipenv/patched/pip/_internal/self_outdated_check.py b/pipenv/patched/pip/_internal/self_outdated_check.py index 26c277e2f6..bcbfd93315 100644 --- a/pipenv/patched/pip/_internal/self_outdated_check.py +++ b/pipenv/patched/pip/_internal/self_outdated_check.py @@ -36,8 +36,7 @@ def _get_statefile_name(key: str) -> str: key_bytes = key.encode() - name = hashlib.sha224(key_bytes).hexdigest() - return name + return hashlib.sha224(key_bytes).hexdigest() class SelfCheckState: @@ -150,7 +149,7 @@ def was_installed_by_pip(pkg: str) -> bool: installed by system package manager, such as dnf on Fedora. """ dist = get_default_environment().get_distribution(pkg) - return dist is not None and "pip" == dist.installer + return dist is not None and dist.installer == "pip" def _get_current_remote_pip_version( @@ -175,10 +174,7 @@ def _get_current_remote_pip_version( selection_prefs=selection_prefs, ) best_candidate = finder.find_best_candidate("pip").best_candidate - if best_candidate is None: - return None - - return str(best_candidate.version) + return None if best_candidate is None else str(best_candidate.version) def _self_version_check_logic( diff --git a/pipenv/patched/pip/_internal/utils/compat.py b/pipenv/patched/pip/_internal/utils/compat.py index 51b5f01ff6..9cb93790b2 100644 --- a/pipenv/patched/pip/_internal/utils/compat.py +++ b/pipenv/patched/pip/_internal/utils/compat.py @@ -40,14 +40,12 @@ def get_path_uid(path: str) -> int: fd = os.open(path, os.O_RDONLY | os.O_NOFOLLOW) file_uid = os.fstat(fd).st_uid os.close(fd) - else: # AIX and Jython - # WARNING: time of check vulnerability, but best we can do w/o NOFOLLOW - if not os.path.islink(path): - # older versions of Jython don't have `os.fstat` - file_uid = os.stat(path).st_uid - else: - # raise OSError for parity with os.O_NOFOLLOW above - raise OSError(f"{path} is a symlink; Will not return uid for symlinks") + elif os.path.islink(path): + # raise OSError for parity with os.O_NOFOLLOW above + raise OSError(f"{path} is a symlink; Will not return uid for symlinks") + else: + # older versions of Jython don't have `os.fstat` + file_uid = os.stat(path).st_uid return file_uid diff --git a/pipenv/patched/pip/_internal/utils/compatibility_tags.py b/pipenv/patched/pip/_internal/utils/compatibility_tags.py index 945bcf2924..29bf750399 100644 --- a/pipenv/patched/pip/_internal/utils/compatibility_tags.py +++ b/pipenv/patched/pip/_internal/utils/compatibility_tags.py @@ -24,55 +24,51 @@ def version_info_to_nodot(version_info: Tuple[int, ...]) -> str: def _mac_platforms(arch: str) -> List[str]: - match = _osx_arch_pat.match(arch) - if match: + if match := _osx_arch_pat.match(arch): name, major, minor, actual_arch = match.groups() mac_version = (int(major), int(minor)) - arches = [ - # Since we have always only checked that the platform starts - # with "macosx", for backwards-compatibility we extract the - # actual prefix provided by the user in case they provided - # something like "macosxcustom_". It may be good to remove - # this as undocumented or deprecate it in the future. - "{}_{}".format(name, arch[len("macosx_") :]) + return [ + f'{name}_{arch[len("macosx_"):]}' for arch in mac_platforms(mac_version, actual_arch) ] else: # arch pattern didn't match (?!) - arches = [arch] - return arches + return [arch] def _custom_manylinux_platforms(arch: str) -> List[str]: arches = [arch] arch_prefix, arch_sep, arch_suffix = arch.partition("_") - if arch_prefix == "manylinux2014": + if arch_prefix == "manylinux2010": + # manylinux1 wheels run on most manylinux2010 systems with the + # exception of wheels depending on ncurses. PEP 571 states + # manylinux1 wheels should be considered manylinux2010 wheels: + # https://www.python.org/dev/peps/pep-0571/#backwards-compatibility-with-manylinux1-wheels + arches.append(f"manylinux1{arch_sep}{arch_suffix}") + elif arch_prefix == "manylinux2014": # manylinux1/manylinux2010 wheels run on most manylinux2014 systems # with the exception of wheels depending on ncurses. PEP 599 states # manylinux1/manylinux2010 wheels should be considered # manylinux2014 wheels: # https://www.python.org/dev/peps/pep-0599/#backwards-compatibility-with-manylinux2010-wheels if arch_suffix in {"i686", "x86_64"}: - arches.append("manylinux2010" + arch_sep + arch_suffix) - arches.append("manylinux1" + arch_sep + arch_suffix) - elif arch_prefix == "manylinux2010": - # manylinux1 wheels run on most manylinux2010 systems with the - # exception of wheels depending on ncurses. PEP 571 states - # manylinux1 wheels should be considered manylinux2010 wheels: - # https://www.python.org/dev/peps/pep-0571/#backwards-compatibility-with-manylinux1-wheels - arches.append("manylinux1" + arch_sep + arch_suffix) + arches.extend( + ( + f"manylinux2010{arch_sep}{arch_suffix}", + f"manylinux1{arch_sep}{arch_suffix}", + ) + ) return arches def _get_custom_platforms(arch: str) -> List[str]: arch_prefix, arch_sep, arch_suffix = arch.partition("_") if arch.startswith("macosx"): - arches = _mac_platforms(arch) + return _mac_platforms(arch) elif arch_prefix in ["manylinux2014", "manylinux2010"]: - arches = _custom_manylinux_platforms(arch) + return _custom_manylinux_platforms(arch) else: - arches = [arch] - return arches + return [arch] def _expand_allowed_platforms(platforms: Optional[List[str]]) -> Optional[List[str]]: @@ -129,10 +125,7 @@ def get_supported( """ supported: List[Tag] = [] - python_version: Optional[PythonVersion] = None - if version is not None: - python_version = _get_python_version(version) - + python_version = _get_python_version(version) if version is not None else None interpreter = _get_custom_interpreter(impl, version) platforms = _expand_allowed_platforms(platforms) diff --git a/pipenv/patched/pip/_internal/utils/deprecation.py b/pipenv/patched/pip/_internal/utils/deprecation.py index f3b792b0e7..9cc1c3c7dd 100644 --- a/pipenv/patched/pip/_internal/utils/deprecation.py +++ b/pipenv/patched/pip/_internal/utils/deprecation.py @@ -29,16 +29,18 @@ def _showwarning( file: Optional[TextIO] = None, line: Optional[str] = None, ) -> None: - if file is not None: - if _original_showwarning is not None: - _original_showwarning(message, category, filename, lineno, file, line) - elif issubclass(category, PipDeprecationWarning): + if ( + file is not None + and _original_showwarning is not None + or file is None + and not issubclass(category, PipDeprecationWarning) + ): + _original_showwarning(message, category, filename, lineno, file, line) + elif file is None: # We use a specially named logger which will handle all of the # deprecation messages for pip. logger = logging.getLogger("pipenv.patched.pip._internal.deprecations") logger.warning(message) - else: - _original_showwarning(message, category, filename, lineno, file, line) def install_warning_logger() -> None: @@ -87,9 +89,9 @@ def deprecated( (reason, f"{DEPRECATION_MSG_PREFIX}{{}}"), ( gone_in, - "pip {} will enforce this behaviour change." - if not is_gone - else "Since pip {}, this is no longer supported.", + "Since pip {}, this is no longer supported." + if is_gone + else "pip {} will enforce this behaviour change.", ), ( replacement, @@ -97,9 +99,9 @@ def deprecated( ), ( feature_flag, - "You can use the flag --use-feature={} to test the upcoming behaviour." - if not is_gone - else None, + None + if is_gone + else "You can use the flag --use-feature={} to test the upcoming behaviour.", ), ( issue, diff --git a/pipenv/patched/pip/_internal/utils/direct_url_helpers.py b/pipenv/patched/pip/_internal/utils/direct_url_helpers.py index 6c381d7600..f0175e028a 100644 --- a/pipenv/patched/pip/_internal/utils/direct_url_helpers.py +++ b/pipenv/patched/pip/_internal/utils/direct_url_helpers.py @@ -9,12 +9,10 @@ def direct_url_as_pep440_direct_reference(direct_url: DirectUrl, name: str) -> str: """Convert a DirectUrl to a pip requirement string.""" direct_url.validate() # if invalid, this is a pip bug - requirement = name + " @ " + requirement = f"{name} @ " fragments = [] if isinstance(direct_url.info, VcsInfo): - requirement += "{}+{}@{}".format( - direct_url.info.vcs, direct_url.url, direct_url.info.commit_id - ) + requirement += f"{direct_url.info.vcs}+{direct_url.url}@{direct_url.info.commit_id}" elif isinstance(direct_url.info, ArchiveInfo): requirement += direct_url.url if direct_url.info.hash: @@ -23,7 +21,7 @@ def direct_url_as_pep440_direct_reference(direct_url: DirectUrl, name: str) -> s assert isinstance(direct_url.info, DirInfo) requirement += direct_url.url if direct_url.subdirectory: - fragments.append("subdirectory=" + direct_url.subdirectory) + fragments.append(f"subdirectory={direct_url.subdirectory}") if fragments: requirement += "#" + "&".join(fragments) return requirement @@ -76,10 +74,7 @@ def direct_url_from_link( subdirectory=link.subdirectory_fragment, ) else: - hash = None - hash_name = link.hash_name - if hash_name: - hash = f"{hash_name}={link.hash}" + hash = f"{hash_name}={link.hash}" if (hash_name := link.hash_name) else None return DirectUrl( url=link.url_without_fragment, info=ArchiveInfo(hash=hash), diff --git a/pipenv/patched/pip/_internal/utils/encoding.py b/pipenv/patched/pip/_internal/utils/encoding.py index 008f06a79b..eef791eb6f 100644 --- a/pipenv/patched/pip/_internal/utils/encoding.py +++ b/pipenv/patched/pip/_internal/utils/encoding.py @@ -26,7 +26,7 @@ def auto_decode(data: bytes) -> str: return data[len(bom) :].decode(encoding) # Lets check the first two lines as in PEP263 for line in data.split(b"\n")[:2]: - if line[0:1] == b"#" and ENCODING_RE.search(line): + if line[:1] == b"#" and ENCODING_RE.search(line): result = ENCODING_RE.search(line) assert result is not None encoding = result.groups()[0].decode("ascii") diff --git a/pipenv/patched/pip/_internal/utils/filesystem.py b/pipenv/patched/pip/_internal/utils/filesystem.py index d8369f22ae..fa57e4e6bc 100644 --- a/pipenv/patched/pip/_internal/utils/filesystem.py +++ b/pipenv/patched/pip/_internal/utils/filesystem.py @@ -24,17 +24,15 @@ def check_path_owner(path: str) -> bool: previous = None while path != previous: if os.path.lexists(path): - # Check if path is writable by current user. - if os.geteuid() == 0: - # Special handling for root user in order to handle properly - # cases where users use sudo without -H flag. - try: - path_uid = get_path_uid(path) - except OSError: - return False - return path_uid == 0 - else: + if os.geteuid() != 0: return os.access(path, os.W_OK) + # Special handling for root user in order to handle properly + # cases where users use sudo without -H flag. + try: + path_uid = get_path_uid(path) + except OSError: + return False + return path_uid == 0 else: previous, path = path, os.path.dirname(path) return False # assume we don't own the path @@ -131,9 +129,7 @@ def find_files(path: str, pattern: str) -> List[str]: def file_size(path: str) -> Union[int, float]: # If it's a symlink, return 0. - if os.path.islink(path): - return 0 - return os.path.getsize(path) + return 0 if os.path.islink(path) else os.path.getsize(path) def format_file_size(path: str) -> str: diff --git a/pipenv/patched/pip/_internal/utils/filetypes.py b/pipenv/patched/pip/_internal/utils/filetypes.py index db548fc10d..c9f7180208 100644 --- a/pipenv/patched/pip/_internal/utils/filetypes.py +++ b/pipenv/patched/pip/_internal/utils/filetypes.py @@ -22,6 +22,4 @@ def is_archive_file(name: str) -> bool: """Return True if `name` is a considered as an archive file.""" ext = splitext(name)[1].lower() - if ext in ARCHIVE_EXTENSIONS: - return True - return False + return ext in ARCHIVE_EXTENSIONS diff --git a/pipenv/patched/pip/_internal/utils/glibc.py b/pipenv/patched/pip/_internal/utils/glibc.py index 7bd3c20681..4a179dfa22 100644 --- a/pipenv/patched/pip/_internal/utils/glibc.py +++ b/pipenv/patched/pip/_internal/utils/glibc.py @@ -82,7 +82,4 @@ def libc_ver() -> Tuple[str, str]: in case the lookup fails. """ glibc_version = glibc_version_string() - if glibc_version is None: - return ("", "") - else: - return ("glibc", glibc_version) + return ("", "") if glibc_version is None else ("glibc", glibc_version) diff --git a/pipenv/patched/pip/_internal/utils/hashes.py b/pipenv/patched/pip/_internal/utils/hashes.py index e4232e1683..e94a5d7c38 100644 --- a/pipenv/patched/pip/_internal/utils/hashes.py +++ b/pipenv/patched/pip/_internal/utils/hashes.py @@ -51,12 +51,11 @@ def __and__(self, other: "Hashes") -> "Hashes": if not self: return other - # Otherwise only hashes that present in both objects are allowed. - new = {} - for alg, values in other._allowed.items(): - if alg not in self._allowed: - continue - new[alg] = [v for v in values if v in self._allowed[alg]] + new = { + alg: [v for v in values if v in self._allowed[alg]] + for alg, values in other._allowed.items() + if alg in self._allowed + } return Hashes(new) @property @@ -110,9 +109,11 @@ def __bool__(self) -> bool: return bool(self._allowed) def __eq__(self, other: object) -> bool: - if not isinstance(other, Hashes): - return NotImplemented - return self._allowed == other._allowed + return ( + self._allowed == other._allowed + if isinstance(other, Hashes) + else NotImplemented + ) def __hash__(self) -> int: return hash( diff --git a/pipenv/patched/pip/_internal/utils/logging.py b/pipenv/patched/pip/_internal/utils/logging.py index f905a9e754..3fe11f856f 100644 --- a/pipenv/patched/pip/_internal/utils/logging.py +++ b/pipenv/patched/pip/_internal/utils/logging.py @@ -45,10 +45,11 @@ def _is_broken_pipe_error(exc_class: Type[BaseException], exc: BaseException) -> # On Windows, a broken pipe can show up as EINVAL rather than EPIPE: # https://bugs.python.org/issue19612 # https://bugs.python.org/issue30418 - if not WINDOWS: - return False - - return isinstance(exc, OSError) and exc.errno in (errno.EINVAL, errno.EPIPE) + return ( + isinstance(exc, OSError) and exc.errno in (errno.EINVAL, errno.EPIPE) + if WINDOWS + else False + ) @contextlib.contextmanager @@ -99,10 +100,7 @@ def get_message_start(self, formatted: str, levelno: int) -> str: # Then the message already has a prefix. We don't want it to # look like "WARNING: DEPRECATION: ...." return "" - if levelno < logging.ERROR: - return "WARNING: " - - return "ERROR: " + return "WARNING: " if levelno < logging.ERROR else "ERROR: " def format(self, record: logging.LogRecord) -> str: """ @@ -113,9 +111,7 @@ def format(self, record: logging.LogRecord) -> str: message_start = self.get_message_start(formatted, record.levelno) formatted = message_start + formatted - prefix = "" - if self.add_timestamp: - prefix = f"{self.formatTime(record)} " + prefix = f"{self.formatTime(record)} " if self.add_timestamp else "" prefix += " " * get_indentation() formatted = "".join([prefix + line for line in formatted.splitlines(True)]) return formatted diff --git a/pipenv/patched/pip/_internal/utils/misc.py b/pipenv/patched/pip/_internal/utils/misc.py index 84220b68f4..ff2d886429 100644 --- a/pipenv/patched/pip/_internal/utils/misc.py +++ b/pipenv/patched/pip/_internal/utils/misc.py @@ -74,11 +74,7 @@ def get_pip_version() -> str: pip_pkg_dir = os.path.join(os.path.dirname(__file__), "..", "..") pip_pkg_dir = os.path.abspath(pip_pkg_dir) - return "pip {} from {} (python {})".format( - __version__, - pip_pkg_dir, - get_major_minor_version(), - ) + return f"pip {__version__} from {pip_pkg_dir} (python {get_major_minor_version()})" def normalize_version_info(py_version_info: Tuple[int, ...]) -> Tuple[int, int, int]: @@ -106,19 +102,14 @@ def ensure_dir(path: str) -> None: os.makedirs(path) except OSError as e: # Windows can raise spurious ENOTEMPTY errors. See #6426. - if e.errno != errno.EEXIST and e.errno != errno.ENOTEMPTY: + if e.errno not in [errno.EEXIST, errno.ENOTEMPTY]: raise def get_prog() -> str: - try: + with contextlib.suppress(AttributeError, TypeError, IndexError): prog = os.path.basename(sys.argv[0]) - if prog in ("__main__.py", "-c"): - return f"{sys.executable} -m pip" - else: - return prog - except (AttributeError, TypeError, IndexError): - pass + return f"{sys.executable} -m pip" if prog in ("__main__.py", "-c") else prog return "pip" @@ -154,7 +145,7 @@ def display_path(path: str) -> str: if possible.""" path = os.path.normcase(os.path.abspath(path)) if path.startswith(os.getcwd() + os.path.sep): - path = "." + path[len(os.getcwd()) :] + path = f".{path[len(os.getcwd()):]}" return path @@ -219,9 +210,9 @@ def strtobool(val: str) -> int: 'val' is anything else. """ val = val.lower() - if val in ("y", "yes", "t", "true", "on", "1"): + if val in {"y", "yes", "t", "true", "on", "1"}: return 1 - elif val in ("n", "no", "f", "false", "off", "0"): + elif val in {"n", "no", "f", "false", "off", "0"}: return 0 else: raise ValueError(f"invalid truth value {val!r}") @@ -231,11 +222,11 @@ def format_size(bytes: float) -> str: if bytes > 1000 * 1000: return "{:.1f} MB".format(bytes / 1000.0 / 1000) elif bytes > 10 * 1000: - return "{} kB".format(int(bytes / 1000)) + return f"{int(bytes / 1000)} kB" elif bytes > 1000: return "{:.1f} kB".format(bytes / 1000.0) else: - return "{} bytes".format(int(bytes)) + return f"{int(bytes)} bytes" def tabulate(rows: Iterable[Iterable[Any]]) -> Tuple[List[str], List[int]]: @@ -264,9 +255,7 @@ def is_installable_dir(path: str) -> bool: return False if os.path.isfile(os.path.join(path, "pyproject.toml")): return True - if os.path.isfile(os.path.join(path, "setup.py")): - return True - return False + return bool(os.path.isfile(os.path.join(path, "setup.py"))) def read_chunks( @@ -274,10 +263,10 @@ def read_chunks( ) -> Generator[bytes, None, None]: """Yield pieces of data from a file-like object until EOF.""" while True: - chunk = file.read(size) - if not chunk: + if chunk := file.read(size): + yield chunk + else: break - yield chunk def normalize_path(path: str, resolve_symlinks: bool = True) -> str: @@ -286,10 +275,7 @@ def normalize_path(path: str, resolve_symlinks: bool = True) -> str: """ path = os.path.expanduser(path) - if resolve_symlinks: - path = os.path.realpath(path) - else: - path = os.path.abspath(path) + path = os.path.realpath(path) if resolve_symlinks else os.path.abspath(path) return os.path.normcase(path) @@ -313,10 +299,8 @@ def renames(old: str, new: str) -> None: head, tail = os.path.split(old) if head and tail: - try: + with contextlib.suppress(OSError): os.removedirs(head) - except OSError: - pass def is_local(path: str) -> bool: @@ -328,9 +312,11 @@ def is_local(path: str) -> bool: Caution: this function assumes the head of path has been normalized with normalize_path. """ - if not running_under_virtualenv(): - return True - return path.startswith(normalize_path(sys.prefix)) + return ( + path.startswith(normalize_path(sys.prefix)) + if running_under_virtualenv() + else True + ) def write_output(msg: Any, *args: Any) -> None: @@ -439,14 +425,7 @@ def split_auth_from_netloc(netloc: str) -> NetlocTuple: # the password attribute of urlsplit()'s return value). auth, netloc = netloc.rsplit("@", 1) pw: Optional[str] = None - if ":" in auth: - # Split from the left because that's how urllib.parse.urlsplit() - # behaves if more than one : is present (which again can be checked - # using the password attribute of the return value) - user, pw = auth.split(":", 1) - else: - user, pw = auth, None - + user, pw = auth.split(":", 1) if ":" in auth else (auth, None) user = urllib.parse.unquote(user) if pw is not None: pw = urllib.parse.unquote(pw) @@ -539,12 +518,7 @@ def __str__(self) -> str: # This is useful for testing. def __eq__(self, other: Any) -> bool: - if type(self) != type(other): - return False - - # The string being used for redaction doesn't also have to match, - # just the raw, original string. - return self.secret == other.secret + return False if type(self) != type(other) else self.secret == other.secret def hide_value(value: str) -> HiddenText: @@ -568,17 +542,14 @@ def protect_pip_from_modification_on_windows(modifying_pip: bool) -> None: f"pip{sys.version_info.major}.{sys.version_info.minor}", ] - # See https://github.com/pypa/pip/issues/1299 for more discussion - should_show_use_python_msg = ( - modifying_pip and WINDOWS and os.path.basename(sys.argv[0]) in pip_names - ) - - if should_show_use_python_msg: + if should_show_use_python_msg := ( + modifying_pip + and WINDOWS + and os.path.basename(sys.argv[0]) in pip_names + ): new_command = [sys.executable, "-m", "pip"] + sys.argv[1:] raise CommandError( - "To modify pip, please run the following command:\n{}".format( - " ".join(new_command) - ) + f'To modify pip, please run the following command:\n{" ".join(new_command)}' ) diff --git a/pipenv/patched/pip/_internal/utils/models.py b/pipenv/patched/pip/_internal/utils/models.py index b6bb21a8b2..05265c6f0e 100644 --- a/pipenv/patched/pip/_internal/utils/models.py +++ b/pipenv/patched/pip/_internal/utils/models.py @@ -33,7 +33,8 @@ def __eq__(self, other: Any) -> bool: return self._compare(other, operator.__eq__) def _compare(self, other: Any, method: Callable[[Any, Any], bool]) -> bool: - if not isinstance(other, self._defining_class): - return NotImplemented - - return method(self._compare_key, other._compare_key) + return ( + method(self._compare_key, other._compare_key) + if isinstance(other, self._defining_class) + else NotImplemented + ) diff --git a/pipenv/patched/pip/_internal/utils/setuptools_build.py b/pipenv/patched/pip/_internal/utils/setuptools_build.py index 01ef4a4ca5..1ffc9523be 100644 --- a/pipenv/patched/pip/_internal/utils/setuptools_build.py +++ b/pipenv/patched/pip/_internal/utils/setuptools_build.py @@ -182,11 +182,7 @@ def make_setuptools_install_args( if use_user_site: args += ["--user", "--prefix="] - if pycompile: - args += ["--compile"] - else: - args += ["--no-compile"] - + args += ["--compile"] if pycompile else ["--no-compile"] if header_dir: args += ["--install-headers", header_dir] diff --git a/pipenv/patched/pip/_internal/utils/subprocess.py b/pipenv/patched/pip/_internal/utils/subprocess.py index 95d483144b..c8a93adc52 100644 --- a/pipenv/patched/pip/_internal/utils/subprocess.py +++ b/pipenv/patched/pip/_internal/utils/subprocess.py @@ -139,11 +139,10 @@ def call_subprocess( env.pop(name, None) try: proc = subprocess.Popen( - # Convert HiddenText objects to the underlying str. reveal_command_args(cmd), stdin=subprocess.PIPE, stdout=subprocess.PIPE, - stderr=subprocess.STDOUT if not stdout_only else subprocess.PIPE, + stderr=subprocess.PIPE if stdout_only else subprocess.STDOUT, cwd=cwd, env=env, errors="backslashreplace", @@ -206,7 +205,7 @@ def call_subprocess( error = InstallationSubprocessError( command_description=command_desc, exit_code=proc.returncode, - output_lines=all_output if not showing_subprocess else None, + output_lines=None if showing_subprocess else all_output, ) if log_failed_cmd: subprocess_logger.error("[present-rich] %s", error) @@ -229,9 +228,7 @@ def call_subprocess( proc.returncode, cwd, ) - elif on_returncode == "ignore": - pass - else: + elif on_returncode != "ignore": raise ValueError(f"Invalid value: on_returncode={on_returncode!r}") return output diff --git a/pipenv/patched/pip/_internal/utils/temp_dir.py b/pipenv/patched/pip/_internal/utils/temp_dir.py index 47d9418864..393b28843a 100644 --- a/pipenv/patched/pip/_internal/utils/temp_dir.py +++ b/pipenv/patched/pip/_internal/utils/temp_dir.py @@ -110,15 +110,7 @@ def __init__( super().__init__() if delete is _default: - if path is not None: - # If we were given an explicit directory, resolve delete option - # now. - delete = False - else: - # Otherwise, we wait until cleanup and see what - # tempdir_registry says. - delete = None - + delete = False if path is not None else None # The only time we specify path is in for editables where it # is the value of the --src option. if path is None: diff --git a/pipenv/patched/pip/_internal/utils/urls.py b/pipenv/patched/pip/_internal/utils/urls.py index 6ba2e04f35..330508bede 100644 --- a/pipenv/patched/pip/_internal/utils/urls.py +++ b/pipenv/patched/pip/_internal/utils/urls.py @@ -8,9 +8,7 @@ def get_url_scheme(url: str) -> Optional[str]: - if ":" not in url: - return None - return url.split(":", 1)[0].lower() + return None if ":" not in url else url.split(":", 1)[0].lower() def path_to_url(path: str) -> str: @@ -19,8 +17,7 @@ def path_to_url(path: str) -> str: quoted path parts. """ path = os.path.normpath(os.path.abspath(path)) - url = urllib.parse.urljoin("file:", urllib.request.pathname2url(path)) - return url + return urllib.parse.urljoin("file:", urllib.request.pathname2url(path)) def url_to_path(url: str) -> str: diff --git a/pipenv/patched/pip/_internal/utils/wheel.py b/pipenv/patched/pip/_internal/utils/wheel.py index 8efcfd369e..0cf16c2922 100644 --- a/pipenv/patched/pip/_internal/utils/wheel.py +++ b/pipenv/patched/pip/_internal/utils/wheel.py @@ -28,7 +28,7 @@ def parse_wheel(wheel_zip: ZipFile, name: str) -> Tuple[str, Message]: metadata = wheel_metadata(wheel_zip, info_dir) version = wheel_version(metadata) except UnsupportedWheel as e: - raise UnsupportedWheel("{} has an invalid wheel, {}".format(name, str(e))) + raise UnsupportedWheel(f"{name} has an invalid wheel, {str(e)}") check_compatibility(version, name) @@ -51,7 +51,7 @@ def wheel_dist_info_dir(source: ZipFile, name: str) -> str: if len(info_dirs) > 1: raise UnsupportedWheel( - "multiple .dist-info directories found: {}".format(", ".join(info_dirs)) + f'multiple .dist-info directories found: {", ".join(info_dirs)}' ) info_dir = info_dirs[0] @@ -126,8 +126,7 @@ def check_compatibility(version: Tuple[int, ...], name: str) -> None: """ if version[0] > VERSION_COMPATIBLE[0]: raise UnsupportedWheel( - "{}'s Wheel-Version ({}) is not compatible with this version " - "of pip".format(name, ".".join(map(str, version))) + f"""{name}'s Wheel-Version ({".".join(map(str, version))}) is not compatible with this version of pip""" ) elif version > VERSION_COMPATIBLE: logger.warning( diff --git a/pipenv/patched/pip/_internal/vcs/bazaar.py b/pipenv/patched/pip/_internal/vcs/bazaar.py index c18f3b9b54..58dc533e50 100644 --- a/pipenv/patched/pip/_internal/vcs/bazaar.py +++ b/pipenv/patched/pip/_internal/vcs/bazaar.py @@ -75,7 +75,7 @@ def get_url_rev_and_auth(cls, url: str) -> Tuple[str, Optional[str], AuthInfo]: # hotfix the URL scheme after removing bzr+ from bzr+ssh:// re-add it url, rev, user_pass = super().get_url_rev_and_auth(url) if url.startswith("ssh://"): - url = "bzr+" + url + url = f"bzr+{url}" return url, rev, user_pass @classmethod @@ -88,9 +88,7 @@ def get_remote_url(cls, location: str) -> str: for x in ("checkout of branch: ", "parent branch: "): if line.startswith(x): repo = line.split(x)[1] - if cls._is_local_repository(repo): - return path_to_url(repo) - return repo + return path_to_url(repo) if cls._is_local_repository(repo) else repo raise RemoteNotFoundError @classmethod diff --git a/pipenv/patched/pip/_internal/vcs/git.py b/pipenv/patched/pip/_internal/vcs/git.py index fec2ce03ec..d9d15f765e 100644 --- a/pipenv/patched/pip/_internal/vcs/git.py +++ b/pipenv/patched/pip/_internal/vcs/git.py @@ -123,10 +123,7 @@ def get_current_branch(cls, location: str) -> Optional[str]: ) ref = output.strip() - if ref.startswith("refs/heads/"): - return ref[len("refs/heads/") :] - - return None + return ref[len("refs/heads/") :] if ref.startswith("refs/heads/") else None @classmethod def get_revision_sha(cls, dest: str, rev: str) -> Tuple[Optional[str], bool]: @@ -187,15 +184,7 @@ def _should_fetch(cls, dest: str, rev: str) -> bool: # Always fetch remote refs. return True - if not looks_like_hash(rev): - # Git fetch would fail with abbreviated commits. - return False - - if cls.has_commit(dest, rev): - # Don't fetch if we have the commit locally. - return False - - return True + return not cls.has_commit(dest, rev) if looks_like_hash(rev) else False @classmethod def resolve_revision( @@ -252,11 +241,7 @@ def is_commit_id_equal(cls, dest: str, name: Optional[str]) -> bool: dest: the repository directory. name: a string name. """ - if not name: - # Then avoid an unnecessary subprocess call. - return False - - return cls.get_revision(dest) == name + return cls.get_revision(dest) == name if name else False def fetch_new( self, dest: str, url: HiddenText, rev_options: RevOptions, verbosity: int @@ -399,8 +384,7 @@ def _git_remote_to_pip_url(url: str) -> str: # A local bare remote (git clone --mirror). # Needs a file:// prefix. return pathlib.PurePath(url).as_uri() - scp_match = SCP_REGEX.match(url) - if scp_match: + if scp_match := SCP_REGEX.match(url): # Add an ssh:// prefix and replace the ':' with a '/'. return scp_match.expand(r"ssh://\1\2/\3") # Otherwise, bail out. @@ -413,7 +397,7 @@ def has_commit(cls, location: str, rev: str) -> bool: """ try: cls.run_command( - ["rev-parse", "-q", "--verify", "sha^" + rev], + ["rev-parse", "-q", "--verify", f"sha^{rev}"], cwd=location, log_failed_cmd=False, ) @@ -494,8 +478,7 @@ def update_submodules(cls, location: str) -> None: @classmethod def get_repository_root(cls, location: str) -> Optional[str]: - loc = super().get_repository_root(location) - if loc: + if loc := super().get_repository_root(location): return loc try: r = cls.run_command( diff --git a/pipenv/patched/pip/_internal/vcs/mercurial.py b/pipenv/patched/pip/_internal/vcs/mercurial.py index 4e216bb8b2..5ccd88e707 100644 --- a/pipenv/patched/pip/_internal/vcs/mercurial.py +++ b/pipenv/patched/pip/_internal/vcs/mercurial.py @@ -93,13 +93,12 @@ def get_revision(cls, location: str) -> str: """ Return the repository-local changeset revision number, as an integer. """ - current_revision = cls.run_command( + return cls.run_command( ["parents", "--template={rev}"], show_stdout=False, stdout_only=True, cwd=location, ).strip() - return current_revision @classmethod def get_requirement_revision(cls, location: str) -> str: @@ -107,13 +106,12 @@ def get_requirement_revision(cls, location: str) -> str: Return the changeset identification hash, as a 40-character hexadecimal string """ - current_rev_hash = cls.run_command( + return cls.run_command( ["parents", "--template={node}"], show_stdout=False, stdout_only=True, cwd=location, ).strip() - return current_rev_hash @classmethod def is_commit_id_equal(cls, dest: str, name: Optional[str]) -> bool: @@ -136,8 +134,7 @@ def get_subdirectory(cls, location: str) -> Optional[str]: @classmethod def get_repository_root(cls, location: str) -> Optional[str]: - loc = super().get_repository_root(location) - if loc: + if loc := super().get_repository_root(location): return loc try: r = cls.run_command( diff --git a/pipenv/patched/pip/_internal/vcs/subversion.py b/pipenv/patched/pip/_internal/vcs/subversion.py index af4aec10d7..230254fa55 100644 --- a/pipenv/patched/pip/_internal/vcs/subversion.py +++ b/pipenv/patched/pip/_internal/vcs/subversion.py @@ -63,7 +63,7 @@ def get_revision(cls, location: str) -> str: if base == location: assert dirurl is not None - base = dirurl + "/" # save the root url + base = f"{dirurl}/" elif not dirurl or not dirurl.startswith(base): dirs[:] = [] continue # not part of the same svn tree, skip it @@ -90,7 +90,7 @@ def get_url_rev_and_auth(cls, url: str) -> Tuple[str, Optional[str], AuthInfo]: # hotfix the URL scheme after removing svn+ from svn+ssh:// re-add it url, rev, user_pass = super().get_url_rev_and_auth(url) if url.startswith("ssh://"): - url = "svn+" + url + url = f"svn+{url}" return url, rev, user_pass @staticmethod @@ -172,11 +172,7 @@ def _get_svn_url_rev(cls, location: str) -> Tuple[Optional[str], int]: except InstallationError: url, revs = None, [] - if revs: - rev = max(revs) - else: - rev = 0 - + rev = max(revs) if revs else 0 return url, rev @classmethod @@ -272,10 +268,7 @@ def get_remote_call_options(self) -> CommandArgs: # e.g. RHEL/CentOS 7, which is supported until 2024, ships with # SVN 1.7, pip should continue to support SVN 1.7. Therefore, pip # can't safely add the option if the SVN version is < 1.8 (or unknown). - if svn_version >= (1, 8): - return ["--force-interactive"] - - return [] + return ["--force-interactive"] if svn_version >= (1, 8) else [] def fetch_new( self, dest: str, url: HiddenText, rev_options: RevOptions, verbosity: int @@ -287,10 +280,7 @@ def fetch_new( rev_display, display_path(dest), ) - if verbosity <= 0: - flag = "--quiet" - else: - flag = "" + flag = "--quiet" if verbosity <= 0 else "" cmd_args = make_command( "checkout", flag, diff --git a/pipenv/patched/pip/_internal/vcs/versioncontrol.py b/pipenv/patched/pip/_internal/vcs/versioncontrol.py index 1698570f4f..9f4e024bd7 100644 --- a/pipenv/patched/pip/_internal/vcs/versioncontrol.py +++ b/pipenv/patched/pip/_internal/vcs/versioncontrol.py @@ -155,10 +155,7 @@ def __repr__(self) -> str: @property def arg_rev(self) -> Optional[str]: - if self.rev is None: - return self.vc_class.default_arg_rev - - return self.rev + return self.vc_class.default_arg_rev if self.rev is None else self.rev def to_args(self) -> CommandArgs: """ @@ -173,10 +170,7 @@ def to_args(self) -> CommandArgs: return args def to_display(self) -> str: - if not self.rev: - return "" - - return f" (to revision {self.rev})" + return f" (to revision {self.rev})" if self.rev else "" def make_new(self, rev: str) -> "RevOptions": """ @@ -255,10 +249,14 @@ def get_backend_for_scheme(self, scheme: str) -> Optional["VersionControl"]: """ Return a VersionControl object or None. """ - for vcs_backend in self._registry.values(): - if scheme in vcs_backend.schemes: - return vcs_backend - return None + return next( + ( + vcs_backend + for vcs_backend in self._registry.values() + if scheme in vcs_backend.schemes + ), + None, + ) def get_backend(self, name: str) -> Optional["VersionControl"]: """ @@ -324,9 +322,9 @@ def get_src_requirement(cls, repo_dir: str, project_name: str) -> str: revision = cls.get_requirement_revision(repo_dir) subdir = cls.get_subdirectory(repo_dir) - req = make_vcs_requirement_url(repo_url, revision, project_name, subdir=subdir) - - return req + return make_vcs_requirement_url( + repo_url, revision, project_name, subdir=subdir + ) @staticmethod def get_base_rev_args(rev: str) -> List[str]: @@ -440,9 +438,7 @@ def get_url_rev_options(self, url: HiddenText) -> Tuple[HiddenText, RevOptions]: """ secret_url, rev, user_pass = self.get_url_rev_and_auth(url.secret) username, secret_password = user_pass - password: Optional[HiddenText] = None - if secret_password is not None: - password = hide_value(secret_password) + password = hide_value(secret_password) if secret_password is not None else None extra_args = self.make_rev_args(username, password) rev_options = self.make_rev_options(rev, extra_args=extra_args) @@ -566,7 +562,7 @@ def obtain(self, dest: str, url: HiddenText, verbosity: int) -> None: self.name, url, ) - response = ask_path_exists("What to do? {}".format(prompt[0]), prompt[1]) + response = ask_path_exists(f"What to do? {prompt[0]}", prompt[1]) if response == "a": sys.exit(-1) @@ -700,6 +696,4 @@ def get_repository_root(cls, location: str) -> Optional[str]: This can do more than is_repository_directory() alone. For example, the Git override checks that Git is actually available. """ - if cls.is_repository_directory(location): - return location - return None + return location if cls.is_repository_directory(location) else None diff --git a/pipenv/patched/pip/_internal/wheel_builder.py b/pipenv/patched/pip/_internal/wheel_builder.py index fff70dcfd0..9a1c062337 100644 --- a/pipenv/patched/pip/_internal/wheel_builder.py +++ b/pipenv/patched/pip/_internal/wheel_builder.py @@ -133,17 +133,12 @@ def _should_cache( assert req.source_dir vcs_backend = vcs.get_backend_for_scheme(req.link.scheme) assert vcs_backend - if vcs_backend.is_immutable_rev_checkout(req.link.url, req.source_dir): - return True - return False - + return bool( + vcs_backend.is_immutable_rev_checkout(req.link.url, req.source_dir) + ) assert req.link base, ext = req.link.splitext() - if _contains_egg_info(base): - return True - - # Otherwise, do not cache. - return False + return bool(_contains_egg_info(base)) def _get_cache_dir( @@ -344,15 +339,14 @@ def build( for req in requirements: assert req.name cache_dir = _get_cache_dir(req, wheel_cache) - wheel_file = _build_one( + if wheel_file := _build_one( req, cache_dir, verify, build_options, global_options, req.editable and req.permit_editable_wheels, - ) - if wheel_file: + ): # Record the download origin in the cache if req.download_info is not None: # download_info is guaranteed to be set because when we build an diff --git a/pipenv/patched/pip/_vendor/cachecontrol/adapter.py b/pipenv/patched/pip/_vendor/cachecontrol/adapter.py index 509321d20f..aa27616a63 100644 --- a/pipenv/patched/pip/_vendor/cachecontrol/adapter.py +++ b/pipenv/patched/pip/_vendor/cachecontrol/adapter.py @@ -54,9 +54,7 @@ def send(self, request, cacheable_methods=None, **kw): # check for etags and add headers if appropriate request.headers.update(self.controller.conditional_headers(request)) - resp = super(CacheControlAdapter, self).send(request, **kw) - - return resp + return super(CacheControlAdapter, self).send(request, **kw) def build_response( self, request, response, from_cache=False, cacheable_methods=None diff --git a/pipenv/patched/pip/_vendor/cachecontrol/caches/file_cache.py b/pipenv/patched/pip/_vendor/cachecontrol/caches/file_cache.py index f1ddb2ebdf..8b500fac2f 100644 --- a/pipenv/patched/pip/_vendor/cachecontrol/caches/file_cache.py +++ b/pipenv/patched/pip/_vendor/cachecontrol/caches/file_cache.py @@ -164,14 +164,14 @@ class SeparateBodyFileCache(_FileCacheMixin, SeparateBodyBaseCache): """ def get_body(self, key): - name = self._fn(key) + ".body" + name = f"{self._fn(key)}.body" try: return open(name, "rb") except FileNotFoundError: return None def set_body(self, key, body): - name = self._fn(key) + ".body" + name = f"{self._fn(key)}.body" self._write(name, body) def delete(self, key): diff --git a/pipenv/patched/pip/_vendor/cachecontrol/controller.py b/pipenv/patched/pip/_vendor/cachecontrol/controller.py index 466c15528c..b64e07a5cd 100644 --- a/pipenv/patched/pip/_vendor/cachecontrol/controller.py +++ b/pipenv/patched/pip/_vendor/cachecontrol/controller.py @@ -49,7 +49,7 @@ def _urlnorm(cls, uri): """Normalize the URL to create a safe key for the cache""" (scheme, authority, path, query, fragment) = parse_uri(uri) if not scheme or not authority: - raise Exception("Only absolute URIs are allowed. uri = %s" % uri) + raise Exception(f"Only absolute URIs are allowed. uri = {uri}") scheme = scheme.lower() authority = authority.lower() @@ -60,9 +60,7 @@ def _urlnorm(cls, uri): # Could do syntax based normalization of the URI before # computing the digest. See Section 6.2.2 of Std 66. request_uri = query and "?".join([path, query]) or path - defrag_uri = scheme + "://" + authority + request_uri - - return defrag_uri + return f"{scheme}://{authority}{request_uri}" @classmethod def cache_url(cls, uri): @@ -352,15 +350,10 @@ def cache_response(self, request, response, body=None, status_codes=None): logger.debug("Caching due to etag") self._cache_set(cache_url, request, response, body, expires_time) - # Add to the cache any permanent redirects. We do this before looking - # that the Date headers. elif int(response.status) in PERMANENT_REDIRECT_STATUSES: logger.debug("Caching permanent redirect") self._cache_set(cache_url, request, response, b"") - # Add to the cache if the response headers demand it. If there - # is no date header then we can't do anything about expiring - # the cache. elif "date" in response_headers: date = calendar.timegm(parsedate_tz(response_headers["date"])) # cache when there is a max-age > 0 @@ -375,16 +368,10 @@ def cache_response(self, request, response, body=None, status_codes=None): expires_time, ) - # If the request can expire, it means we should cache it - # in the meantime. elif "expires" in response_headers: if response_headers["expires"]: expires = parsedate_tz(response_headers["expires"]) - if expires is not None: - expires_time = calendar.timegm(expires) - date - else: - expires_time = None - + expires_time = calendar.timegm(expires) - date if expires is not None else None logger.debug( "Caching b/c of expires header. expires in {0} seconds".format( expires_time @@ -423,11 +410,11 @@ def update_cached_response(self, request, response): excluded_headers = ["content-length"] cached_response.headers.update( - dict( - (k, v) + { + k: v for k, v in response.headers.items() if k.lower() not in excluded_headers - ) + } ) # we want a 200 b/c we have content via the cache diff --git a/pipenv/patched/pip/_vendor/cachecontrol/heuristics.py b/pipenv/patched/pip/_vendor/cachecontrol/heuristics.py index ebe4a96f58..2f6cac3a40 100644 --- a/pipenv/patched/pip/_vendor/cachecontrol/heuristics.py +++ b/pipenv/patched/pip/_vendor/cachecontrol/heuristics.py @@ -44,9 +44,7 @@ def update_headers(self, response): return {} def apply(self, response): - updated_headers = self.update_headers(response) - - if updated_headers: + if updated_headers := self.update_headers(response): response.headers.update(updated_headers) warning_header_value = self.warning(response) if warning_header_value is not None: diff --git a/pipenv/patched/pip/_vendor/cachecontrol/serialize.py b/pipenv/patched/pip/_vendor/cachecontrol/serialize.py index 2c2736b4e1..dfacb84486 100644 --- a/pipenv/patched/pip/_vendor/cachecontrol/serialize.py +++ b/pipenv/patched/pip/_vendor/cachecontrol/serialize.py @@ -43,21 +43,20 @@ def dumps(self, request, response, body=None): # doesn't know the difference. Forcing these to unicode will be # enough to have msgpack know the difference. data = { - u"response": { - u"body": body, # Empty bytestring if body is stored separately - u"headers": dict( - (text_type(k), text_type(v)) for k, v in response.headers.items() - ), + "response": { + u"body": body, + u"headers": { + text_type(k): text_type(v) for k, v in response.headers.items() + }, u"status": response.status, u"version": response.version, u"reason": text_type(response.reason), u"strict": response.strict, u"decode_content": response.decode_content, - } + }, + "vary": {}, } - # Construct our vary headers - data[u"vary"] = {} if u"vary" in response_headers: varied_headers = response_headers[u"vary"].split(",") for header in varied_headers: @@ -92,7 +91,7 @@ def loads(self, request, data, body_file=None): # Dispatch to the actual load method for the given version try: - return getattr(self, "_loads_v{}".format(ver))(request, data, body_file) + return getattr(self, f"_loads_v{ver}")(request, data, body_file) except AttributeError: # This is a version we don't have a loads function for, so we'll @@ -125,10 +124,7 @@ def prepare_response(self, request, cached, body_file=None): cached["response"]["headers"] = headers try: - if body_file is None: - body = io.BytesIO(body_raw) - else: - body = body_file + body = io.BytesIO(body_raw) if body_file is None else body_file except TypeError: # This can happen if cachecontrol serialized to v1 format (pickle) # using Python 2. A Python 2 str(byte string) will be unpickled as @@ -163,15 +159,15 @@ def _loads_v2(self, request, data, body_file=None): # We need to decode the items that we've base64 encoded cached["response"]["body"] = _b64_decode_bytes(cached["response"]["body"]) - cached["response"]["headers"] = dict( - (_b64_decode_str(k), _b64_decode_str(v)) + cached["response"]["headers"] = { + _b64_decode_str(k): _b64_decode_str(v) for k, v in cached["response"]["headers"].items() - ) + } cached["response"]["reason"] = _b64_decode_str(cached["response"]["reason"]) - cached["vary"] = dict( - (_b64_decode_str(k), _b64_decode_str(v) if v is not None else v) + cached["vary"] = { + _b64_decode_str(k): _b64_decode_str(v) if v is not None else v for k, v in cached["vary"].items() - ) + } return self.prepare_response(request, cached, body_file) diff --git a/pipenv/patched/pip/_vendor/chardet/__init__.py b/pipenv/patched/pip/_vendor/chardet/__init__.py index fe581623d8..12eaff8637 100644 --- a/pipenv/patched/pip/_vendor/chardet/__init__.py +++ b/pipenv/patched/pip/_vendor/chardet/__init__.py @@ -84,7 +84,7 @@ def detect_all( probers: List[CharSetProber] = [] for prober in detector.charset_probers: if isinstance(prober, CharSetGroupProber): - probers.extend(p for p in prober.probers) + probers.extend(iter(prober.probers)) else: probers.append(prober) for prober in probers: @@ -109,7 +109,7 @@ def detect_all( "language": prober.language, } ) - if len(results) > 0: + if results: return sorted(results, key=lambda result: -result["confidence"]) return [detector.result] diff --git a/pipenv/patched/pip/_vendor/chardet/chardistribution.py b/pipenv/patched/pip/_vendor/chardet/chardistribution.py index 176cb99640..c3e0831950 100644 --- a/pipenv/patched/pip/_vendor/chardet/chardistribution.py +++ b/pipenv/patched/pip/_vendor/chardet/chardistribution.py @@ -87,17 +87,12 @@ def reset(self) -> None: def feed(self, char: Union[bytes, bytearray], char_len: int) -> None: """feed a character with known length""" - if char_len == 2: - # we only care about 2-bytes character in our distribution analysis - order = self.get_order(char) - else: - order = -1 + order = self.get_order(char) if char_len == 2 else -1 if order >= 0: self._total_chars += 1 # order is valid - if order < self._table_size: - if 512 > self._char_to_freq_order[order]: - self._freq_chars += 1 + if order < self._table_size and self._char_to_freq_order[order] < 512: + self._freq_chars += 1 def get_confidence(self) -> float: """return confidence based on existing data""" @@ -142,9 +137,11 @@ def get_order(self, byte_str: Union[bytes, bytearray]) -> int: # second byte range: 0xa1 -- 0xfe # no validation needed here. State machine has done that first_char = byte_str[0] - if first_char >= 0xC4: - return 94 * (first_char - 0xC4) + byte_str[1] - 0xA1 - return -1 + return ( + 94 * (first_char - 0xC4) + byte_str[1] - 0xA1 + if first_char >= 0xC4 + else -1 + ) class EUCKRDistributionAnalysis(CharDistributionAnalysis): @@ -160,9 +157,11 @@ def get_order(self, byte_str: Union[bytes, bytearray]) -> int: # second byte range: 0xa1 -- 0xfe # no validation needed here. State machine has done that first_char = byte_str[0] - if first_char >= 0xB0: - return 94 * (first_char - 0xB0) + byte_str[1] - 0xA1 - return -1 + return ( + 94 * (first_char - 0xB0) + byte_str[1] - 0xA1 + if first_char >= 0xB0 + else -1 + ) class JOHABDistributionAnalysis(CharDistributionAnalysis): @@ -256,6 +255,4 @@ def get_order(self, byte_str: Union[bytes, bytearray]) -> int: # second byte range: 0xa1 -- 0xfe # no validation needed here. State machine has done that char = byte_str[0] - if char >= 0xA0: - return 94 * (char - 0xA1) + byte_str[1] - 0xA1 - return -1 + return 94 * (char - 0xA1) + byte_str[1] - 0xA1 if char >= 0xA0 else -1 diff --git a/pipenv/patched/pip/_vendor/chardet/charsetgroupprober.py b/pipenv/patched/pip/_vendor/chardet/charsetgroupprober.py index 6def56b4a7..b3dd917c10 100644 --- a/pipenv/patched/pip/_vendor/chardet/charsetgroupprober.py +++ b/pipenv/patched/pip/_vendor/chardet/charsetgroupprober.py @@ -51,17 +51,17 @@ def reset(self) -> None: def charset_name(self) -> Optional[str]: if not self._best_guess_prober: self.get_confidence() - if not self._best_guess_prober: - return None - return self._best_guess_prober.charset_name + return ( + self._best_guess_prober.charset_name + if self._best_guess_prober + else None + ) @property def language(self) -> Optional[str]: if not self._best_guess_prober: self.get_confidence() - if not self._best_guess_prober: - return None - return self._best_guess_prober.language + return self._best_guess_prober.language if self._best_guess_prober else None def feed(self, byte_str: Union[bytes, bytearray]) -> ProbingState: for prober in self.probers: @@ -101,6 +101,4 @@ def get_confidence(self) -> float: if best_conf < conf: best_conf = conf self._best_guess_prober = prober - if not self._best_guess_prober: - return 0.0 - return best_conf + return best_conf if self._best_guess_prober else 0.0 diff --git a/pipenv/patched/pip/_vendor/chardet/eucjpprober.py b/pipenv/patched/pip/_vendor/chardet/eucjpprober.py index 39487f4098..d59d158cb1 100644 --- a/pipenv/patched/pip/_vendor/chardet/eucjpprober.py +++ b/pipenv/patched/pip/_vendor/chardet/eucjpprober.py @@ -86,11 +86,12 @@ def feed(self, byte_str: Union[bytes, bytearray]) -> ProbingState: self._last_char[0] = byte_str[-1] - if self.state == ProbingState.DETECTING: - if self.context_analyzer.got_enough_data() and ( - self.get_confidence() > self.SHORTCUT_THRESHOLD - ): - self._state = ProbingState.FOUND_IT + if ( + self.state == ProbingState.DETECTING + and self.context_analyzer.got_enough_data() + and (self.get_confidence() > self.SHORTCUT_THRESHOLD) + ): + self._state = ProbingState.FOUND_IT return self.state diff --git a/pipenv/patched/pip/_vendor/chardet/hebrewprober.py b/pipenv/patched/pip/_vendor/chardet/hebrewprober.py index 785d0057bc..d3878941f1 100644 --- a/pipenv/patched/pip/_vendor/chardet/hebrewprober.py +++ b/pipenv/patched/pip/_vendor/chardet/hebrewprober.py @@ -252,15 +252,13 @@ def feed(self, byte_str: Union[bytes, bytearray]) -> ProbingState: # case (2) [-2:not space][-1:Non-Final letter][ # cur:space] self._final_char_visual_score += 1 - else: - # Not standing on a space - if ( + elif ( (self._before_prev == self.SPACE) and (self.is_final(self._prev)) and (cur != self.SPACE) ): - # case (3) [-2:space][-1:final letter][cur:not space] - self._final_char_visual_score += 1 + # case (3) [-2:space][-1:final letter][cur:not space] + self._final_char_visual_score += 1 self._before_prev = self._prev self._prev = cur @@ -292,12 +290,7 @@ def charset_name(self) -> str: # Still no good, back to final letter distance, maybe it'll save the # day. - if finalsub < 0.0: - return self.VISUAL_HEBREW_NAME - - # (finalsub > 0 - Logical) or (don't know what to do) default to - # Logical. - return self.LOGICAL_HEBREW_NAME + return self.VISUAL_HEBREW_NAME if finalsub < 0.0 else self.LOGICAL_HEBREW_NAME @property def language(self) -> str: diff --git a/pipenv/patched/pip/_vendor/chardet/mbcharsetprober.py b/pipenv/patched/pip/_vendor/chardet/mbcharsetprober.py index 666307e8fe..5043a65dc3 100644 --- a/pipenv/patched/pip/_vendor/chardet/mbcharsetprober.py +++ b/pipenv/patched/pip/_vendor/chardet/mbcharsetprober.py @@ -82,11 +82,12 @@ def feed(self, byte_str: Union[bytes, bytearray]) -> ProbingState: self._last_char[0] = byte_str[-1] - if self.state == ProbingState.DETECTING: - if self.distribution_analyzer.got_enough_data() and ( - self.get_confidence() > self.SHORTCUT_THRESHOLD - ): - self._state = ProbingState.FOUND_IT + if ( + self.state == ProbingState.DETECTING + and self.distribution_analyzer.got_enough_data() + and (self.get_confidence() > self.SHORTCUT_THRESHOLD) + ): + self._state = ProbingState.FOUND_IT return self.state diff --git a/pipenv/patched/pip/_vendor/chardet/sbcharsetprober.py b/pipenv/patched/pip/_vendor/chardet/sbcharsetprober.py index 0ffbcdd2c3..412230bfd2 100644 --- a/pipenv/patched/pip/_vendor/chardet/sbcharsetprober.py +++ b/pipenv/patched/pip/_vendor/chardet/sbcharsetprober.py @@ -93,10 +93,11 @@ def language(self) -> Optional[str]: def feed(self, byte_str: Union[bytes, bytearray]) -> ProbingState: # TODO: Make filter_international_words keep things in self.alphabet - if not self._model.keep_ascii_letters: - byte_str = self.filter_international_words(byte_str) - else: - byte_str = self.remove_xml_tags(byte_str) + byte_str = ( + self.remove_xml_tags(byte_str) + if self._model.keep_ascii_letters + else self.filter_international_words(byte_str) + ) if not byte_str: return self.state char_to_order_map = self._model.char_to_order_map @@ -114,30 +115,33 @@ def feed(self, byte_str: Union[bytes, bytearray]) -> ProbingState: self._freq_char += 1 if self._last_order < self.SAMPLE_SIZE: self._total_seqs += 1 - if not self._reversed: - lm_cat = language_model[self._last_order][order] - else: - lm_cat = language_model[order][self._last_order] + lm_cat = ( + language_model[order][self._last_order] + if self._reversed + else language_model[self._last_order][order] + ) self._seq_counters[lm_cat] += 1 self._last_order = order charset_name = self._model.charset_name - if self.state == ProbingState.DETECTING: - if self._total_seqs > self.SB_ENOUGH_REL_THRESHOLD: - confidence = self.get_confidence() - if confidence > self.POSITIVE_SHORTCUT_THRESHOLD: - self.logger.debug( - "%s confidence = %s, we have a winner", charset_name, confidence - ) - self._state = ProbingState.FOUND_IT - elif confidence < self.NEGATIVE_SHORTCUT_THRESHOLD: - self.logger.debug( - "%s confidence = %s, below negative shortcut threshold %s", - charset_name, - confidence, - self.NEGATIVE_SHORTCUT_THRESHOLD, - ) - self._state = ProbingState.NOT_ME + if ( + self.state == ProbingState.DETECTING + and self._total_seqs > self.SB_ENOUGH_REL_THRESHOLD + ): + confidence = self.get_confidence() + if confidence > self.POSITIVE_SHORTCUT_THRESHOLD: + self.logger.debug( + "%s confidence = %s, we have a winner", charset_name, confidence + ) + self._state = ProbingState.FOUND_IT + elif confidence < self.NEGATIVE_SHORTCUT_THRESHOLD: + self.logger.debug( + "%s confidence = %s, below negative shortcut threshold %s", + charset_name, + confidence, + self.NEGATIVE_SHORTCUT_THRESHOLD, + ) + self._state = ProbingState.NOT_ME return self.state diff --git a/pipenv/patched/pip/_vendor/chardet/sjisprober.py b/pipenv/patched/pip/_vendor/chardet/sjisprober.py index 91df077961..c1d002bd51 100644 --- a/pipenv/patched/pip/_vendor/chardet/sjisprober.py +++ b/pipenv/patched/pip/_vendor/chardet/sjisprober.py @@ -89,11 +89,12 @@ def feed(self, byte_str: Union[bytes, bytearray]) -> ProbingState: self._last_char[0] = byte_str[-1] - if self.state == ProbingState.DETECTING: - if self.context_analyzer.got_enough_data() and ( - self.get_confidence() > self.SHORTCUT_THRESHOLD - ): - self._state = ProbingState.FOUND_IT + if ( + self.state == ProbingState.DETECTING + and self.context_analyzer.got_enough_data() + and (self.get_confidence() > self.SHORTCUT_THRESHOLD) + ): + self._state = ProbingState.FOUND_IT return self.state diff --git a/pipenv/patched/pip/_vendor/chardet/universaldetector.py b/pipenv/patched/pip/_vendor/chardet/universaldetector.py index 30c441dc28..8efa4e0e8c 100644 --- a/pipenv/patched/pip/_vendor/chardet/universaldetector.py +++ b/pipenv/patched/pip/_vendor/chardet/universaldetector.py @@ -232,15 +232,17 @@ def feed(self, byte_str: Union[bytes, bytearray]) -> None: if not self._utf1632_prober: self._utf1632_prober = UTF1632Prober() - if self._utf1632_prober.state == ProbingState.DETECTING: - if self._utf1632_prober.feed(byte_str) == ProbingState.FOUND_IT: - self.result = { - "encoding": self._utf1632_prober.charset_name, - "confidence": self._utf1632_prober.get_confidence(), - "language": "", - } - self.done = True - return + if ( + self._utf1632_prober.state == ProbingState.DETECTING + and self._utf1632_prober.feed(byte_str) == ProbingState.FOUND_IT + ): + self.result = { + "encoding": self._utf1632_prober.charset_name, + "confidence": self._utf1632_prober.get_confidence(), + "language": "", + } + self.done = True + return # If we've seen escape sequences, use the EscCharSetProber, which # uses a simple state machine to check for known escape sequences in @@ -298,11 +300,9 @@ def close(self) -> ResultDict: if not self._got_data: self.logger.debug("no data received!") - # Default to ASCII if it is all we've seen so far elif self._input_state == InputState.PURE_ASCII: self.result = {"encoding": "ascii", "confidence": 1.0, "language": ""} - # If we have seen non-ASCII, return the best that met MINIMUM_THRESHOLD elif self._input_state == InputState.HIGH_BYTE: prober_confidence = None max_prober_confidence = 0.0 @@ -321,11 +321,13 @@ def close(self) -> ResultDict: confidence = max_prober.get_confidence() # Use Windows encoding name instead of ISO-8859 if we saw any # extra Windows-specific bytes - if lower_charset_name.startswith("iso-8859"): - if self._has_win_bytes: - charset_name = self.ISO_WIN_MAP.get( - lower_charset_name, charset_name - ) + if ( + lower_charset_name.startswith("iso-8859") + and self._has_win_bytes + ): + charset_name = self.ISO_WIN_MAP.get( + lower_charset_name, charset_name + ) # Rename legacy encodings with superset encodings if asked if self.should_rename_legacy: charset_name = self.LEGACY_MAP.get( @@ -338,25 +340,27 @@ def close(self) -> ResultDict: } # Log all prober confidences if none met MINIMUM_THRESHOLD - if self.logger.getEffectiveLevel() <= logging.DEBUG: - if self.result["encoding"] is None: - self.logger.debug("no probers hit minimum threshold") - for group_prober in self._charset_probers: - if not group_prober: - continue - if isinstance(group_prober, CharSetGroupProber): - for prober in group_prober.probers: - self.logger.debug( - "%s %s confidence = %s", - prober.charset_name, - prober.language, - prober.get_confidence(), - ) - else: + if ( + self.logger.getEffectiveLevel() <= logging.DEBUG + and self.result["encoding"] is None + ): + self.logger.debug("no probers hit minimum threshold") + for group_prober in self._charset_probers: + if not group_prober: + continue + if isinstance(group_prober, CharSetGroupProber): + for prober in group_prober.probers: self.logger.debug( "%s %s confidence = %s", - group_prober.charset_name, - group_prober.language, - group_prober.get_confidence(), + prober.charset_name, + prober.language, + prober.get_confidence(), ) + else: + self.logger.debug( + "%s %s confidence = %s", + group_prober.charset_name, + group_prober.language, + group_prober.get_confidence(), + ) return self.result diff --git a/pipenv/patched/pip/_vendor/chardet/utf1632prober.py b/pipenv/patched/pip/_vendor/chardet/utf1632prober.py index 6bdec63d68..d2a4e2e703 100644 --- a/pipenv/patched/pip/_vendor/chardet/utf1632prober.py +++ b/pipenv/patched/pip/_vendor/chardet/utf1632prober.py @@ -75,10 +75,7 @@ def charset_name(self) -> str: return "utf-32le" if self.is_likely_utf16be(): return "utf-16be" - if self.is_likely_utf16le(): - return "utf-16le" - # default to something valid - return "utf-16" + return "utf-16le" if self.is_likely_utf16le() else "utf-16" @property def language(self) -> str: @@ -142,13 +139,15 @@ def validate_utf32_characters(self, quad: List[int]) -> None: if ( quad[0] != 0 or quad[1] > 0x10 - or (quad[0] == 0 and quad[1] == 0 and 0xD8 <= quad[2] <= 0xDF) + or quad[1] == 0 + and 0xD8 <= quad[2] <= 0xDF ): self.invalid_utf32be = True if ( quad[3] != 0 or quad[2] > 0x10 - or (quad[3] == 0 and quad[2] == 0 and 0xD8 <= quad[1] <= 0xDF) + or quad[2] == 0 + and 0xD8 <= quad[1] <= 0xDF ): self.invalid_utf32le = True @@ -162,27 +161,34 @@ def validate_utf16_characters(self, pair: List[int]) -> None: https://en.wikipedia.org/wiki/UTF-16 """ - if not self.first_half_surrogate_pair_detected_16be: - if 0xD8 <= pair[0] <= 0xDB: - self.first_half_surrogate_pair_detected_16be = True - elif 0xDC <= pair[0] <= 0xDF: - self.invalid_utf16be = True - else: - if 0xDC <= pair[0] <= 0xDF: - self.first_half_surrogate_pair_detected_16be = False - else: - self.invalid_utf16be = True - - if not self.first_half_surrogate_pair_detected_16le: - if 0xD8 <= pair[1] <= 0xDB: - self.first_half_surrogate_pair_detected_16le = True - elif 0xDC <= pair[1] <= 0xDF: - self.invalid_utf16le = True - else: - if 0xDC <= pair[1] <= 0xDF: - self.first_half_surrogate_pair_detected_16le = False - else: - self.invalid_utf16le = True + if ( + not self.first_half_surrogate_pair_detected_16be + and 0xD8 <= pair[0] <= 0xDB + ): + self.first_half_surrogate_pair_detected_16be = True + elif ( + not self.first_half_surrogate_pair_detected_16be + and 0xDC <= pair[0] <= 0xDF + or self.first_half_surrogate_pair_detected_16be + and not 0xDC <= pair[0] <= 0xDF + ): + self.invalid_utf16be = True + elif self.first_half_surrogate_pair_detected_16be: + self.first_half_surrogate_pair_detected_16be = False + if ( + not self.first_half_surrogate_pair_detected_16le + and 0xD8 <= pair[1] <= 0xDB + ): + self.first_half_surrogate_pair_detected_16le = True + elif ( + not self.first_half_surrogate_pair_detected_16le + and 0xDC <= pair[1] <= 0xDF + or self.first_half_surrogate_pair_detected_16le + and not 0xDC <= pair[1] <= 0xDF + ): + self.invalid_utf16le = True + elif self.first_half_surrogate_pair_detected_16le: + self.first_half_surrogate_pair_detected_16le = False def feed(self, byte_str: Union[bytes, bytearray]) -> ProbingState: for c in byte_str: @@ -190,7 +196,7 @@ def feed(self, byte_str: Union[bytes, bytearray]) -> ProbingState: self.quad[mod4] = c if mod4 == 3: self.validate_utf32_characters(self.quad) - self.validate_utf16_characters(self.quad[0:2]) + self.validate_utf16_characters(self.quad[:2]) self.validate_utf16_characters(self.quad[2:4]) if c == 0: self.zeros_at_mod[mod4] += 1 diff --git a/pipenv/patched/pip/_vendor/chardet/utf8prober.py b/pipenv/patched/pip/_vendor/chardet/utf8prober.py index d96354d97c..3c28b18f12 100644 --- a/pipenv/patched/pip/_vendor/chardet/utf8prober.py +++ b/pipenv/patched/pip/_vendor/chardet/utf8prober.py @@ -64,13 +64,17 @@ def feed(self, byte_str: Union[bytes, bytearray]) -> ProbingState: if coding_state == MachineState.ITS_ME: self._state = ProbingState.FOUND_IT break - if coding_state == MachineState.START: - if self.coding_sm.get_current_charlen() >= 2: - self._num_mb_chars += 1 + if ( + coding_state == MachineState.START + and self.coding_sm.get_current_charlen() >= 2 + ): + self._num_mb_chars += 1 - if self.state == ProbingState.DETECTING: - if self.get_confidence() > self.SHORTCUT_THRESHOLD: - self._state = ProbingState.FOUND_IT + if ( + self.state == ProbingState.DETECTING + and self.get_confidence() > self.SHORTCUT_THRESHOLD + ): + self._state = ProbingState.FOUND_IT return self.state diff --git a/pipenv/patched/pip/_vendor/colorama/ansi.py b/pipenv/patched/pip/_vendor/colorama/ansi.py index 11ec695ff7..328ed9c162 100644 --- a/pipenv/patched/pip/_vendor/colorama/ansi.py +++ b/pipenv/patched/pip/_vendor/colorama/ansi.py @@ -13,7 +13,7 @@ def code_to_chars(code): return CSI + str(code) + 'm' def set_title(title): - return OSC + '2;' + title + BEL + return f'{OSC}2;{title}{BEL}' def clear_screen(mode=2): return CSI + str(mode) + 'J' diff --git a/pipenv/patched/pip/_vendor/colorama/ansitowin32.py b/pipenv/patched/pip/_vendor/colorama/ansitowin32.py index abf209e60c..bc320339ca 100644 --- a/pipenv/patched/pip/_vendor/colorama/ansitowin32.py +++ b/pipenv/patched/pip/_vendor/colorama/ansitowin32.py @@ -8,9 +8,7 @@ from .win32 import windll, winapi_test -winterm = None -if windll is not None: - winterm = WinTerm() +winterm = WinTerm() if windll is not None else None class StreamWrapper(object): @@ -48,9 +46,12 @@ def write(self, text): def isatty(self): stream = self.__wrapped - if 'PYCHARM_HOSTED' in os.environ: - if stream is not None and (stream is sys.__stdout__ or stream is sys.__stderr__): - return True + if ( + 'PYCHARM_HOSTED' in os.environ + and stream is not None + and (stream is sys.__stdout__ or stream is sys.__stderr__) + ): + return True try: stream_isatty = stream.isatty except AttributeError: @@ -170,7 +171,7 @@ def get_win32_calls(self): AnsiBack.LIGHTCYAN_EX: (winterm.back, WinColor.CYAN, True), AnsiBack.LIGHTWHITE_EX: (winterm.back, WinColor.GREY, True), } - return dict() + return {} def write(self, text): if self.strip or self.convert: @@ -225,7 +226,7 @@ def extract_params(self, command, paramstring): params = params + (1,) else: params = tuple(int(p) for p in paramstring.split(';') if len(p) != 0) - if len(params) == 0: + if not params: # defaults: if command in 'JKm': params = (0,) @@ -262,14 +263,13 @@ def convert_osc(self, text): start, end = match.span() text = text[:start] + text[end:] paramstring, command = match.groups() - if command == BEL: - if paramstring.count(";") == 1: - params = paramstring.split(";") - # 0 - change title and icon (we will only change title) - # 1 - change icon (we don't support this) - # 2 - change title - if params[0] in '02': - winterm.set_title(params[1]) + if command == BEL and paramstring.count(";") == 1: + params = paramstring.split(";") + # 0 - change title and icon (we will only change title) + # 1 - change icon (we don't support this) + # 2 - change title + if params[0] in '02': + winterm.set_title(params[1]) return text diff --git a/pipenv/patched/pip/_vendor/six.py b/pipenv/patched/pip/_vendor/six.py index 4e15675d8b..9244a1b926 100644 --- a/pipenv/patched/pip/_vendor/six.py +++ b/pipenv/patched/pip/_vendor/six.py @@ -20,6 +20,7 @@ """Utilities for writing code that runs on Python 2 and 3""" + from __future__ import absolute_import import functools @@ -35,7 +36,7 @@ # Useful for very coarse version differentiation. PY2 = sys.version_info[0] == 2 PY3 = sys.version_info[0] == 3 -PY34 = sys.version_info[0:2] >= (3, 4) +PY34 = sys.version_info[:2] >= (3, 4) if PY3: string_types = str, @@ -150,10 +151,7 @@ def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): new_mod = name self.mod = new_mod if new_attr is None: - if old_attr is None: - new_attr = name - else: - new_attr = old_attr + new_attr = name if old_attr is None else old_attr self.attr = new_attr else: self.mod = old_mod @@ -181,15 +179,13 @@ def __init__(self, six_module_name): def _add_module(self, mod, *fullnames): for fullname in fullnames: - self.known_modules[self.name + "." + fullname] = mod + self.known_modules[f"{self.name}.{fullname}"] = mod def _get_module(self, fullname): - return self.known_modules[self.name + "." + fullname] + return self.known_modules[f"{self.name}.{fullname}"] def find_module(self, fullname, path=None): - if fullname in self.known_modules: - return self - return None + return self if fullname in self.known_modules else None def find_spec(self, fullname, path, target=None): if fullname in self.known_modules: @@ -200,7 +196,7 @@ def __get_module(self, fullname): try: return self.known_modules[fullname] except KeyError: - raise ImportError("This loader does not know module " + fullname) + raise ImportError(f"This loader does not know module {fullname}") def load_module(self, fullname): try: @@ -251,7 +247,9 @@ class _MovedItems(_LazyModule): _moved_attributes = [ MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), - MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"), + MovedAttribute( + "filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse" + ), MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), MovedAttribute("intern", "__builtin__", "sys"), MovedAttribute("map", "itertools", "builtins", "imap", "map"), @@ -259,7 +257,12 @@ class _MovedItems(_LazyModule): MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"), MovedAttribute("getoutput", "commands", "subprocess"), MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"), - MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"), + MovedAttribute( + "reload_module", + "__builtin__", + "importlib" if PY34 else "imp", + "reload", + ), MovedAttribute("reduce", "__builtin__", "functools"), MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), MovedAttribute("StringIO", "StringIO", "io"), @@ -268,14 +271,24 @@ class _MovedItems(_LazyModule): MovedAttribute("UserString", "UserString", "collections"), MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), - MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), + MovedAttribute( + "zip_longest", "itertools", "itertools", "izip_longest", "zip_longest" + ), MovedModule("builtins", "__builtin__"), MovedModule("configparser", "ConfigParser"), - MovedModule("collections_abc", "collections", "collections.abc" if sys.version_info >= (3, 3) else "collections"), + MovedModule( + "collections_abc", + "collections", + "collections.abc" if sys.version_info >= (3, 3) else "collections", + ), MovedModule("copyreg", "copy_reg"), MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), MovedModule("dbm_ndbm", "dbm", "dbm.ndbm"), - MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread" if sys.version_info < (3, 9) else "_thread"), + MovedModule( + "_dummy_thread", + "dummy_thread", + "_dummy_thread" if sys.version_info < (3, 9) else "_thread", + ), MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), MovedModule("http_cookies", "Cookie", "http.cookies"), MovedModule("html_entities", "htmlentitydefs", "html.entities"), @@ -283,8 +296,14 @@ class _MovedItems(_LazyModule): MovedModule("http_client", "httplib", "http.client"), MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"), MovedModule("email_mime_image", "email.MIMEImage", "email.mime.image"), - MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), - MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"), + MovedModule( + "email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart" + ), + MovedModule( + "email_mime_nonmultipart", + "email.MIMENonMultipart", + "email.mime.nonmultipart", + ), MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), @@ -297,24 +316,37 @@ class _MovedItems(_LazyModule): MovedModule("tkinter", "Tkinter"), MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), - MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), - MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), + MovedModule( + "tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext" + ), + MovedModule( + "tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog" + ), MovedModule("tkinter_tix", "Tix", "tkinter.tix"), MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"), MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), - MovedModule("tkinter_colorchooser", "tkColorChooser", - "tkinter.colorchooser"), - MovedModule("tkinter_commondialog", "tkCommonDialog", - "tkinter.commondialog"), + MovedModule( + "tkinter_colorchooser", "tkColorChooser", "tkinter.colorchooser" + ), + MovedModule( + "tkinter_commondialog", "tkCommonDialog", "tkinter.commondialog" + ), MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), MovedModule("tkinter_font", "tkFont", "tkinter.font"), MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), - MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", - "tkinter.simpledialog"), - MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"), - MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"), - MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"), + MovedModule( + "tkinter_tksimpledialog", "tkSimpleDialog", "tkinter.simpledialog" + ), + MovedModule( + "urllib_parse", f"{__name__}.moves.urllib_parse", "urllib.parse" + ), + MovedModule( + "urllib_error", f"{__name__}.moves.urllib_error", "urllib.error" + ), + MovedModule( + "urllib", f"{__name__}.moves.urllib", f"{__name__}.moves.urllib" + ), MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"), @@ -328,20 +360,18 @@ class _MovedItems(_LazyModule): for attr in _moved_attributes: setattr(_MovedItems, attr.name, attr) if isinstance(attr, MovedModule): - _importer._add_module(attr, "moves." + attr.name) + _importer._add_module(attr, f"moves.{attr.name}") del attr _MovedItems._moved_attributes = _moved_attributes -moves = _MovedItems(__name__ + ".moves") +moves = _MovedItems(f"{__name__}.moves") _importer._add_module(moves, "moves") class Module_six_moves_urllib_parse(_LazyModule): """Lazy loading of moved objects in six.moves.urllib_parse""" - - _urllib_parse_moved_attributes = [ MovedAttribute("ParseResult", "urlparse", "urllib.parse"), MovedAttribute("SplitResult", "urlparse", "urllib.parse"), @@ -375,15 +405,16 @@ class Module_six_moves_urllib_parse(_LazyModule): Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes -_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"), - "moves.urllib_parse", "moves.urllib.parse") +_importer._add_module( + Module_six_moves_urllib_parse(f"{__name__}.moves.urllib_parse"), + "moves.urllib_parse", + "moves.urllib.parse", +) class Module_six_moves_urllib_error(_LazyModule): """Lazy loading of moved objects in six.moves.urllib_error""" - - _urllib_error_moved_attributes = [ MovedAttribute("URLError", "urllib2", "urllib.error"), MovedAttribute("HTTPError", "urllib2", "urllib.error"), @@ -395,15 +426,16 @@ class Module_six_moves_urllib_error(_LazyModule): Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes -_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"), - "moves.urllib_error", "moves.urllib.error") +_importer._add_module( + Module_six_moves_urllib_error(f"{__name__}.moves.urllib.error"), + "moves.urllib_error", + "moves.urllib.error", +) class Module_six_moves_urllib_request(_LazyModule): """Lazy loading of moved objects in six.moves.urllib_request""" - - _urllib_request_moved_attributes = [ MovedAttribute("urlopen", "urllib2", "urllib.request"), MovedAttribute("install_opener", "urllib2", "urllib.request"), @@ -447,15 +479,16 @@ class Module_six_moves_urllib_request(_LazyModule): Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes -_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"), - "moves.urllib_request", "moves.urllib.request") +_importer._add_module( + Module_six_moves_urllib_request(f"{__name__}.moves.urllib.request"), + "moves.urllib_request", + "moves.urllib.request", +) class Module_six_moves_urllib_response(_LazyModule): """Lazy loading of moved objects in six.moves.urllib_response""" - - _urllib_response_moved_attributes = [ MovedAttribute("addbase", "urllib", "urllib.response"), MovedAttribute("addclosehook", "urllib", "urllib.response"), @@ -468,15 +501,16 @@ class Module_six_moves_urllib_response(_LazyModule): Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes -_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"), - "moves.urllib_response", "moves.urllib.response") +_importer._add_module( + Module_six_moves_urllib_response(f"{__name__}.moves.urllib.response"), + "moves.urllib_response", + "moves.urllib.response", +) class Module_six_moves_urllib_robotparser(_LazyModule): """Lazy loading of moved objects in six.moves.urllib_robotparser""" - - _urllib_robotparser_moved_attributes = [ MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"), ] @@ -486,8 +520,13 @@ class Module_six_moves_urllib_robotparser(_LazyModule): Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes -_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"), - "moves.urllib_robotparser", "moves.urllib.robotparser") +_importer._add_module( + Module_six_moves_urllib_robotparser( + f"{__name__}.moves.urllib.robotparser" + ), + "moves.urllib_robotparser", + "moves.urllib.robotparser", +) class Module_six_moves_urllib(types.ModuleType): @@ -503,8 +542,9 @@ class Module_six_moves_urllib(types.ModuleType): def __dir__(self): return ['parse', 'error', 'request', 'response', 'robotparser'] -_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"), - "moves.urllib") +_importer._add_module( + Module_six_moves_urllib(f"{__name__}.moves.urllib"), "moves.urllib" +) def add_move(move): @@ -910,7 +950,7 @@ def ensure_binary(s, encoding='utf-8', errors='strict'): return s if isinstance(s, text_type): return s.encode(encoding, errors) - raise TypeError("not expecting type '%s'" % type(s)) + raise TypeError(f"not expecting type '{type(s)}'") def ensure_str(s, encoding='utf-8', errors='strict'): @@ -932,7 +972,7 @@ def ensure_str(s, encoding='utf-8', errors='strict'): elif PY3 and isinstance(s, binary_type): return s.decode(encoding, errors) elif not isinstance(s, (text_type, binary_type)): - raise TypeError("not expecting type '%s'" % type(s)) + raise TypeError(f"not expecting type '{type(s)}'") return s @@ -952,7 +992,7 @@ def ensure_text(s, encoding='utf-8', errors='strict'): elif isinstance(s, text_type): return s else: - raise TypeError("not expecting type '%s'" % type(s)) + raise TypeError(f"not expecting type '{type(s)}'") def python_2_unicode_compatible(klass): diff --git a/pipenv/patched/pip/_vendor/typing_extensions.py b/pipenv/patched/pip/_vendor/typing_extensions.py index 44f666d490..adac816f68 100644 --- a/pipenv/patched/pip/_vendor/typing_extensions.py +++ b/pipenv/patched/pip/_vendor/typing_extensions.py @@ -163,9 +163,7 @@ def __instancecheck__(self, obj): return super().__instancecheck__(obj) def __repr__(self): - if self is Any: - return "typing_extensions.Any" - return super().__repr__() + return "typing_extensions.Any" if self is Any else super().__repr__() class Any(metaclass=_AnyMeta): """Special type indicating an unconstrained type. @@ -193,7 +191,7 @@ def __new__(cls, *args, **kwargs): class _FinalForm(typing._SpecialForm, _root=True): def __repr__(self): - return 'typing_extensions.' + self._name + return f'typing_extensions.{self._name}' def __getitem__(self, parameters): item = typing._type_check(parameters, @@ -265,7 +263,7 @@ def IntVar(name): class _LiteralForm(typing._SpecialForm, _root=True): def __repr__(self): - return 'typing_extensions.' + self._name + return f'typing_extensions.{self._name}' def __getitem__(self, parameters): return typing._GenericAlias(self, parameters) @@ -474,12 +472,15 @@ def __instancecheck__(cls, instance): _is_callable_members_only(cls)) and issubclass(instance.__class__, cls)): return True - if cls._is_protocol: - if all(hasattr(instance, attr) and - (not callable(getattr(cls, attr, None)) or - getattr(instance, attr) is not None) - for attr in _get_protocol_attrs(cls)): - return True + if cls._is_protocol and all( + hasattr(instance, attr) + and ( + not callable(getattr(cls, attr, None)) + or getattr(instance, attr) is not None + ) + for attr in _get_protocol_attrs(cls) + ): + return True return super().__instancecheck__(instance) class Protocol(metaclass=_ProtocolMeta): @@ -760,7 +761,7 @@ def __new__(cls, name, bases, ns, total=True): optional_keys = set() for base in bases: - annotations.update(base.__dict__.get('__annotations__', {})) + annotations |= base.__dict__.get('__annotations__', {}) required_keys.update(base.__dict__.get('__required_keys__', ())) optional_keys.update(base.__dict__.get('__optional_keys__', ())) @@ -768,20 +769,18 @@ def __new__(cls, name, bases, ns, total=True): for annotation_key, annotation_type in own_annotations.items(): annotation_origin = get_origin(annotation_type) if annotation_origin is Annotated: - annotation_args = get_args(annotation_type) - if annotation_args: + if annotation_args := get_args(annotation_type): annotation_type = annotation_args[0] annotation_origin = get_origin(annotation_type) - if annotation_origin is Required: - required_keys.add(annotation_key) - elif annotation_origin is NotRequired: - optional_keys.add(annotation_key) - elif total: + if ( + annotation_origin is Required + or annotation_origin is not NotRequired + and total + ): required_keys.add(annotation_key) else: optional_keys.add(annotation_key) - tp_dict.__annotations__ = annotations tp_dict.__required_keys__ = frozenset(required_keys) tp_dict.__optional_keys__ = frozenset(optional_keys) @@ -877,9 +876,7 @@ def _strip_extras(t): return _strip_extras(t.__args__[0]) if isinstance(t, typing._GenericAlias): stripped_args = tuple(_strip_extras(a) for a in t.__args__) - if stripped_args == t.__args__: - return t - return t.copy_with(stripped_args) + return t if stripped_args == t.__args__ else t.copy_with(stripped_args) if hasattr(types, "GenericAlias") and isinstance(t, types.GenericAlias): stripped_args = tuple(_strip_extras(a) for a in t.__args__) if stripped_args == t.__args__: @@ -1080,9 +1077,7 @@ def get_origin(tp): if isinstance(tp, (typing._GenericAlias, _typing_GenericAlias, _BaseGenericAlias, ParamSpecArgs, ParamSpecKwargs)): return tp.__origin__ - if tp is typing.Generic: - return typing.Generic - return None + return typing.Generic if tp is typing.Generic else None def get_args(tp): """Get type arguments with all substitutions performed. @@ -1114,7 +1109,7 @@ def get_args(tp): elif sys.version_info[:2] >= (3, 9): class _TypeAliasForm(typing._SpecialForm, _root=True): def __repr__(self): - return 'typing_extensions.' + self._name + return f'typing_extensions.{self._name}' @_TypeAliasForm def TypeAlias(self, parameters): @@ -1133,7 +1128,7 @@ def TypeAlias(self, parameters): else: class _TypeAliasForm(typing._SpecialForm, _root=True): def __repr__(self): - return 'typing_extensions.' + self._name + return f'typing_extensions.{self._name}' TypeAlias = _TypeAliasForm('TypeAlias', doc="""Special marker indicating that an assignment should @@ -1221,9 +1216,11 @@ def __repr__(self): return f"{self.__origin__.__name__}.args" def __eq__(self, other): - if not isinstance(other, ParamSpecArgs): - return NotImplemented - return self.__origin__ == other.__origin__ + return ( + self.__origin__ == other.__origin__ + if isinstance(other, ParamSpecArgs) + else NotImplemented + ) class ParamSpecKwargs(_Immutable): """The kwargs for a ParamSpec object. @@ -1244,9 +1241,11 @@ def __repr__(self): return f"{self.__origin__.__name__}.kwargs" def __eq__(self, other): - if not isinstance(other, ParamSpecKwargs): - return NotImplemented - return self.__origin__ == other.__origin__ + return ( + self.__origin__ == other.__origin__ + if isinstance(other, ParamSpecKwargs) + else NotImplemented + ) # 3.10+ if hasattr(typing, 'ParamSpec'): @@ -1449,7 +1448,7 @@ def Concatenate(self, parameters): else: class _ConcatenateForm(typing._SpecialForm, _root=True): def __repr__(self): - return 'typing_extensions.' + self._name + return f'typing_extensions.{self._name}' def __getitem__(self, parameters): return _concatenate_getitem(self, parameters) @@ -1474,7 +1473,7 @@ def __getitem__(self, parameters): elif sys.version_info[:2] >= (3, 9): class _TypeGuardForm(typing._SpecialForm, _root=True): def __repr__(self): - return 'typing_extensions.' + self._name + return f'typing_extensions.{self._name}' @_TypeGuardForm def TypeGuard(self, parameters): @@ -1527,7 +1526,7 @@ def is_str(val: Union[str, float]): class _TypeGuardForm(typing._SpecialForm, _root=True): def __repr__(self): - return 'typing_extensions.' + self._name + return f'typing_extensions.{self._name}' def __getitem__(self, parameters): item = typing._type_check(parameters, @@ -1704,7 +1703,7 @@ def int_or_str(arg: int | str) -> None: elif sys.version_info[:2] >= (3, 9): class _ExtensionsSpecialForm(typing._SpecialForm, _root=True): def __repr__(self): - return 'typing_extensions.' + self._name + return f'typing_extensions.{self._name}' @_ExtensionsSpecialForm def Required(self, parameters): @@ -1746,7 +1745,7 @@ class Movie(TypedDict): else: class _RequiredForm(typing._SpecialForm, _root=True): def __repr__(self): - return 'typing_extensions.' + self._name + return f'typing_extensions.{self._name}' def __getitem__(self, parameters): item = typing._type_check(parameters, @@ -1791,7 +1790,7 @@ class Movie(TypedDict): elif sys.version_info[:2] >= (3, 9): class _UnpackSpecialForm(typing._SpecialForm, _root=True): def __repr__(self): - return 'typing_extensions.' + self._name + return f'typing_extensions.{self._name}' class _UnpackAlias(typing._GenericAlias, _root=True): __class__ = typing.TypeVar @@ -1820,7 +1819,7 @@ class _UnpackAlias(typing._GenericAlias, _root=True): class _UnpackForm(typing._SpecialForm, _root=True): def __repr__(self): - return 'typing_extensions.' + self._name + return f'typing_extensions.{self._name}' def __getitem__(self, parameters): item = typing._type_check(parameters, @@ -1939,7 +1938,7 @@ def __eq__(self, other): def __reduce__(self): return self.__name__ - def __init_subclass__(self, *args, **kwds): + def __init_subclass__(cls, *args, **kwds): if '_root' not in kwds: raise TypeError("Cannot subclass special typing classes") @@ -2178,7 +2177,7 @@ def __new__(cls, typename, bases, ns): # update from user namespace without overriding special namedtuple attributes for key in ns: if key in _prohibited_namedtuple_fields: - raise AttributeError("Cannot overwrite NamedTuple attribute " + key) + raise AttributeError(f"Cannot overwrite NamedTuple attribute {key}") elif key not in _special_namedtuple_fields and key not in nm_tpl._fields: setattr(nm_tpl, key, ns[key]) if typing.Generic in bases: diff --git a/pipenv/project.py b/pipenv/project.py index 34f2ad3a3f..800d51b902 100644 --- a/pipenv/project.py +++ b/pipenv/project.py @@ -98,9 +98,7 @@ def encode(self, obj): def preferred_newlines(f): - if isinstance(f.newlines, str): - return f.newlines - return DEFAULT_NEWLINES + return f.newlines if isinstance(f.newlines, str) else DEFAULT_NEWLINES # (path, file contents) => TOMLFile @@ -157,10 +155,7 @@ def __init__(self, python_version=None, chdir=True): def path_to(self, p: str) -> str: """Returns the absolute path to a given relative path.""" - if os.path.isabs(p): - return p - - return os.sep.join([self._original_dir, p]) + return p if os.path.isabs(p) else os.sep.join([self._original_dir, p]) def get_pipfile_section(self, section): """Returns the details from the section of the Project's Pipfile.""" @@ -215,10 +210,7 @@ def is_venv_in_project(self) -> bool: @property def virtualenv_exists(self) -> bool: if os.path.exists(self.virtualenv_location): - if os.name == "nt": - extra = ["Scripts", "activate.bat"] - else: - extra = ["bin", "activate"] + extra = ["Scripts", "activate.bat"] if os.name == "nt" else ["bin", "activate"] return os.path.isfile(os.sep.join([self.virtualenv_location] + extra)) return False @@ -303,8 +295,8 @@ def get_environment(self, allow_global: bool = False) -> Environment: else: prefix = self.virtualenv_location python = None - sources = self.sources if self.sources else [self.default_source] - environment = Environment( + sources = self.sources or [self.default_source] + return Environment( prefix=prefix, python=python, is_venv=is_venv, @@ -312,7 +304,6 @@ def get_environment(self, allow_global: bool = False) -> Environment: pipfile=self.parsed_pipfile, project=self, ) - return environment @property def environment(self) -> Environment: @@ -338,7 +329,7 @@ def _sanitize(cls, name: str) -> Tuple[str, str]: # https://www.gnu.org/software/bash/manual/html_node/Double-Quotes.html # http://www.tldp.org/LDP/abs/html/special-chars.html#FIELDREF # https://github.com/torvalds/linux/blob/2bfe01ef/include/uapi/linux/binfmts.h#L18 - return re.sub(r'[ &$`!*@"()\[\]\\\r\n\t]', "_", name)[0:42] + return re.sub(r'[ &$`!*@"()\[\]\\\r\n\t]', "_", name)[:42] def _get_virtualenv_hash(self, name: str) -> str: """Get the name of the virtualenv adjusted for windows if needed @@ -383,8 +374,7 @@ def get_name(name, location): @property def virtualenv_name(self) -> str: - custom_name = self.s.PIPENV_CUSTOM_VENV_NAME - if custom_name: + if custom_name := self.s.PIPENV_CUSTOM_VENV_NAME: return custom_name sanitized, encoded_hash = self._get_virtualenv_hash(self.name) suffix = "" @@ -396,7 +386,7 @@ def virtualenv_name(self) -> str: # If the pipfile was located at '/home/user/MY_PROJECT/Pipfile', # the name of its virtualenv will be 'my-project-wyUfYPqE' - return sanitized + "-" + encoded_hash + suffix + return f"{sanitized}-{encoded_hash}{suffix}" @property def virtualenv_location(self) -> str: @@ -602,8 +592,7 @@ def _lockfile(self, categories=None): def _pipfile(self): from .vendor.requirementslib.models.pipfile import Pipfile as ReqLibPipfile - pf = ReqLibPipfile.load(self.pipfile_location) - return pf + return ReqLibPipfile.load(self.pipfile_location) @property def lockfile_location(self): @@ -618,12 +607,11 @@ def lockfile_content(self): return self.load_lockfile() def get_editable_packages(self, category): - packages = { + return { k: v for k, v in self.parsed_pipfile.get(category, {}).items() if is_editable(v) } - return packages def _get_vcs_packages(self, dev=False): from pipenv.vendor.requirementslib.utils import is_vcs @@ -641,7 +629,7 @@ def all_packages(self): """Returns a list of all packages.""" packages = {} for category in self.get_package_categories(): - packages.update(self.parsed_pipfile.get(category, {})) + packages |= self.parsed_pipfile.get(category, {}) return packages @property @@ -656,13 +644,7 @@ def dev_packages(self): @property def pipfile_is_empty(self): - if not self.pipfile_exists: - return True - - if not self.read_pipfile(): - return True - - return False + return not self.read_pipfile() if self.pipfile_exists else True def create_pipfile(self, python=None): """Creates the Pipfile, filled with juicy defaults.""" @@ -674,7 +656,7 @@ def create_pipfile(self, python=None): if not index: continue - source_name = "pip_index_{}".format(i) + source_name = f"pip_index_{i}" verify_ssl = index.startswith("https") sources.append({"url": index, "verify_ssl": verify_ssl, "name": source_name}) @@ -716,12 +698,13 @@ def get_or_create_lockfile(self, categories, from_pipfile=False): ) if from_pipfile and self.pipfile_exists: - lockfile_dict = {} categories = self.get_package_categories(for_lockfile=True) _lockfile = self._lockfile(categories=categories) - for category in categories: - lockfile_dict[category] = _lockfile.get(category, {}).copy() - lockfile_dict.update({"_meta": self.get_lockfile_meta()}) + lockfile_dict = { + category: _lockfile.get(category, {}).copy() + for category in categories + } + lockfile_dict["_meta"] = self.get_lockfile_meta() lockfile = Req_Lockfile.from_data( path=self.lockfile_location, data=lockfile_dict, meta_from_project=False ) @@ -740,21 +723,20 @@ def get_or_create_lockfile(self, categories, from_pipfile=False): ) if lockfile._lockfile is not None: return lockfile - if self.lockfile_exists and self.lockfile_content: - lockfile_dict = self.lockfile_content.copy() - sources = lockfile_dict.get("_meta", {}).get("sources", []) - if not sources: - sources = self.pipfile_sources(expand_vars=False) - elif not isinstance(sources, list): - sources = [sources] - lockfile_dict["_meta"]["sources"] = [self.populate_source(s) for s in sources] - _created_lockfile = Req_Lockfile.from_data( - path=self.lockfile_location, data=lockfile_dict, meta_from_project=False - ) - lockfile._lockfile = lockfile.projectfile.model = _created_lockfile - return lockfile - else: + if not self.lockfile_exists or not self.lockfile_content: return self.get_or_create_lockfile(categories=categories, from_pipfile=True) + lockfile_dict = self.lockfile_content.copy() + sources = lockfile_dict.get("_meta", {}).get("sources", []) + if not sources: + sources = self.pipfile_sources(expand_vars=False) + elif not isinstance(sources, list): + sources = [sources] + lockfile_dict["_meta"]["sources"] = [self.populate_source(s) for s in sources] + _created_lockfile = Req_Lockfile.from_data( + path=self.lockfile_location, data=lockfile_dict, meta_from_project=False + ) + lockfile._lockfile = lockfile.projectfile.model = _created_lockfile + return lockfile def get_lockfile_meta(self): from .vendor.plette.lockfiles import PIPFILE_SPEC_CURRENT @@ -831,14 +813,11 @@ def pipfile_sources(self, expand_vars=True): @property def sources(self): - if self.lockfile_exists and hasattr(self.lockfile_content, "keys"): - meta_ = self.lockfile_content.get("_meta", {}) - sources_ = meta_.get("sources") - if sources_: - return sources_ - - else: + if not self.lockfile_exists or not hasattr(self.lockfile_content, "keys"): return self.pipfile_sources() + meta_ = self.lockfile_content.get("_meta", {}) + if sources_ := meta_.get("sources"): + return sources_ @property def sources_default(self): @@ -900,16 +879,16 @@ def get_package_name_in_pipfile(self, package_name, category): """Get the equivalent package name in pipfile""" section = self.parsed_pipfile.get(category, {}) package_name = pep423_name(package_name) - for name in section.keys(): - if pep423_name(name) == package_name: - return name - return None + return next( + (name for name in section.keys() if pep423_name(name) == package_name), + None, + ) def remove_package_from_pipfile(self, package_name, category): - # Read and append Pipfile. - name = self.get_package_name_in_pipfile(package_name, category=category) - p = self.parsed_pipfile - if name: + if name := self.get_package_name_in_pipfile( + package_name, category=category + ): + p = self.parsed_pipfile del p[category][name] self.write_toml(p) return True @@ -917,12 +896,12 @@ def remove_package_from_pipfile(self, package_name, category): def remove_packages_from_pipfile(self, packages): parsed = self.parsed_pipfile - packages = set([pep423_name(pkg) for pkg in packages]) + packages = {pep423_name(pkg) for pkg in packages} for category in self.get_package_categories(): pipfile_section = parsed.get(category, {}) - pipfile_packages = set( - [pep423_name(pkg_name) for pkg_name in pipfile_section.keys()] - ) + pipfile_packages = { + pep423_name(pkg_name) for pkg_name in pipfile_section.keys() + } to_remove = packages & pipfile_packages for pkg in to_remove: pkg_name = self.get_package_name_in_pipfile(pkg, category=category) @@ -938,7 +917,7 @@ def add_package_to_pipfile(self, package, dev=False, category=None): if not isinstance(package, Requirement): package = Requirement.from_line(package.strip()) req_name, converted = package.pipfile_entry - category = category if category else "dev-packages" if dev else "packages" + category = category or ("dev-packages" if dev else "packages") # Set empty group if it doesn't exist yet. if category not in p: p[category] = {} @@ -1092,11 +1071,10 @@ def finders(self): scripts_dirname = "Scripts" if os.name == "nt" else "bin" scripts_dir = os.path.join(self.virtualenv_location, scripts_dirname) - finders = [ + return [ Finder(path=scripts_dir, global_search=gs, system=False) for gs in (False, True) ] - return finders @property def finder(self): @@ -1107,9 +1085,8 @@ def which(self, search, as_path=True): result = next(iter(filter(None, (find(finder) for finder in self.finders))), None) if not result: result = self._which(search) - else: - if as_path: - result = str(result.path) + elif as_path: + result = str(result.path) return result def _which(self, command, location=None, allow_global=False): @@ -1121,16 +1098,16 @@ def _which(self, 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{}".format(".".join([str(v) for v in sys.version_info[:2]])) + version_str = f'python{".".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": - p = find_windows_executable(os.path.join(location, "Scripts"), command) - else: - p = os.path.join(location, "bin", command) - else: - if is_python: - p = sys.executable + p = ( + find_windows_executable(os.path.join(location, "Scripts"), command) + if os.name == "nt" + else os.path.join(location, "bin", command) + ) + elif is_python: + p = sys.executable if not os.path.exists(p): if is_python: p = sys.executable or system_which("python") diff --git a/pipenv/resolver.py b/pipenv/resolver.py index 8708177e98..1b53779601 100644 --- a/pipenv/resolver.py +++ b/pipenv/resolver.py @@ -193,8 +193,7 @@ def markers(self): @markers.setter def markers(self, markers): if not markers: - marker_str = self.marker_to_str(markers) - if marker_str: + if marker_str := self.marker_to_str(markers): self._entry = self.entry.merge_markers(marker_str) self._markers = self.marker_to_str(self._entry.markers) entry_dict = self.entry_dict.copy() @@ -225,9 +224,7 @@ def marker_to_str(marker): marker_str = " and ".join([normalize_marker_str(m) for m in marker if m]) elif isinstance(marker, str): marker_str = f"{normalize_marker_str(marker)}" - if isinstance(marker_str, str): - return marker_str - return None + return marker_str if isinstance(marker_str, str) else None def get_cleaned_dict(self, keep_outdated=False): if keep_outdated and self.is_updated: @@ -289,7 +286,7 @@ def pipfile_name(self): @property def is_in_pipfile(self): - return True if self.pipfile_name else False + return bool(self.pipfile_name) @property def pipfile_packages(self): @@ -323,7 +320,7 @@ def clean_specifier(specifier): return "*" specifier = f"=={specifier}" elif specifier.startswith("==") and specifier.count("=") > 3: - specifier = "=={}".format(specifier.lstrip("=")) + specifier = f'=={specifier.lstrip("=")}' return specifier @staticmethod @@ -458,11 +455,8 @@ def ensure_least_updates_possible(self): self.can_use_original = False if not constraint.specifier.contains(self.updated_version): self.can_use_updated = False - satisfied_by_value = getattr(constraint, "satisfied_by", None) - if satisfied_by_value: - satisfied_by = "{}".format( - self.clean_specifier(str(satisfied_by_value.version)) - ) + if satisfied_by_value := getattr(constraint, "satisfied_by", None): + satisfied_by = f"{self.clean_specifier(str(satisfied_by_value.version))}" satisfied_by_versions.add(satisfied_by) if can_use_original: self.entry_dict = self.lockfile_dict.copy() @@ -474,16 +468,16 @@ def ensure_least_updates_possible(self): hashes = None if self.lockfile_entry.specifiers == satisfied_by: ireq = self.lockfile_entry.as_ireq() - if ( - not self.lockfile_entry.hashes - and self.resolver._should_include_hash(ireq) - ): - hashes = self.resolver.get_hash(ireq) - else: - hashes = self.lockfile_entry.hashes - else: - if self.resolver._should_include_hash(constraint): - hashes = self.resolver.get_hash(constraint) + hashes = ( + self.resolver.get_hash(ireq) + if ( + not self.lockfile_entry.hashes + and self.resolver._should_include_hash(ireq) + ) + else self.lockfile_entry.hashes + ) + elif self.resolver._should_include_hash(constraint): + hashes = self.resolver.get_hash(constraint) if hashes: self.entry_dict["hashes"] = list(hashes) self._entry.hashes = frozenset(hashes) @@ -541,15 +535,7 @@ def validate_constraints(self): ): if self.project.s.is_verbose(): print(f"Tried constraint: {constraint!r}", file=sys.stderr) - msg = ( - "Cannot resolve conflicting version {}{} while {}{} is " - "locked.".format( - self.name, - constraint.req.specifier, - self.name, - self.updated_specifier, - ) - ) + msg = f"Cannot resolve conflicting version {self.name}{constraint.req.specifier} while {self.name}{self.updated_specifier} is locked." raise DependencyConflict(msg) return True @@ -560,16 +546,7 @@ def check_flattened_parents(self): if not parent.validate_specifiers(): from pipenv.exceptions import DependencyConflict - msg = ( - "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, - ) - ) + msg = f"Cannot resolve conflicting versions: (Root: {self.name}) {parent.pipfile_name}{parent.pipfile_entry.requirement.specifiers} (Pipfile) Incompatible with {parent.name}{parent.updated_specifiers} (resolved)\n" raise DependencyConflict(msg) def __getattribute__(self, key): @@ -656,9 +633,8 @@ def clean_outdated(results, resolver, project, category): if entry.was_editable and not entry.is_editable: continue lockfile_entry = lockfile[lockfile_section].get(name, None) - if not lockfile_entry: - if name in lockfile[lockfile_section]: - lockfile_entry = lockfile[lockfile_section][name] + if not lockfile_entry and name in lockfile[lockfile_section]: + lockfile_entry = lockfile[lockfile_section][name] if lockfile_entry and not entry.is_updated: old_markers = next( iter( diff --git a/pipenv/shells.py b/pipenv/shells.py index 02065e70f2..dfaf5ee50f 100644 --- a/pipenv/shells.py +++ b/pipenv/shells.py @@ -79,11 +79,9 @@ def __repr__(self): @contextlib.contextmanager def inject_path(self, venv): with temp_environ(): - os.environ["PATH"] = "{}{}{}".format( - os.pathsep.join(str(p.parent) for p in _iter_python(venv)), - os.pathsep, - os.environ["PATH"], - ) + os.environ[ + "PATH" + ] = f'{os.pathsep.join(str(p.parent) for p in _iter_python(venv))}{os.pathsep}{os.environ["PATH"]}' yield def fork(self, venv, cwd, args): @@ -92,9 +90,9 @@ def fork(self, venv, cwd, args): name = os.path.basename(venv) os.environ["VIRTUAL_ENV"] = str(venv) if "PROMPT" in os.environ: - os.environ["PROMPT"] = "({}) {}".format(name, os.environ["PROMPT"]) + os.environ["PROMPT"] = f'({name}) {os.environ["PROMPT"]}' if "PS1" in os.environ: - os.environ["PS1"] = "({}) {}".format(name, os.environ["PS1"]) + os.environ["PS1"] = f'({name}) {os.environ["PS1"]}' with self.inject_path(venv): os.chdir(cwd) _handover(self.cmd, self.args + list(args)) @@ -152,9 +150,7 @@ def inject_path(self, venv): base_rc_src = f'source "{bashrc_path.as_posix()}"\n' rcfile.write(base_rc_src) - export_path = 'export PATH="{}:$PATH"\n'.format( - ":".join(self._format_path(python) for python in _iter_python(venv)) - ) + export_path = f'export PATH="{":".join(self._format_path(python) for python in _iter_python(venv))}:$PATH"\n' rcfile.write(export_path) rcfile.flush() self.args.extend(["--rcfile", rcfile.name]) @@ -164,10 +160,7 @@ def inject_path(self, venv): class MsysBash(Bash): def _format_path(self, python): s = super()._format_path(python) - if not python.drive: - return s - # Convert "C:/something" to "/c/something". - return f"/{s[0].lower()}{s[2:]}" + return f"/{s[0].lower()}{s[2:]}" if python.drive else s class CmderEmulatedShell(Shell):