Commit 5814e335 by Branch Vincent Committed by Bjorn Neergaard

chore: use fstrings

parent 3fae3702
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
min_python_version = 3.6.0 min_python_version = 3.6.0
max-line-length = 88 max-line-length = 88
ban-relative-imports = true ban-relative-imports = true
# flake8-use-fstring: https://github.com/MichaelKim0407/flake8-use-fstring#--percent-greedy-and---format-greedy
format-greedy = 1
inline-quotes = double inline-quotes = double
# Allow omission of a return type hint for __init__ if at least one argument is annotated # Allow omission of a return type hint for __init__ if at least one argument is annotated
# used by flake8-annotations # used by flake8-annotations
......
...@@ -42,6 +42,7 @@ repos: ...@@ -42,6 +42,7 @@ repos:
- flake8-tidy-imports==4.5.0 - flake8-tidy-imports==4.5.0
- flake8-type-checking==1.1.0 - flake8-type-checking==1.1.0
- flake8-typing-imports==1.11.0 - flake8-typing-imports==1.11.0
- flake8-use-fstring==1.3
- pep8-naming==0.12.1 - pep8-naming==0.12.1
- repo: https://github.com/asottile/pyupgrade - repo: https://github.com/asottile/pyupgrade
......
...@@ -111,9 +111,7 @@ class Config: ...@@ -111,9 +111,7 @@ class Config:
# Looking in the environment if the setting # Looking in the environment if the setting
# is set via a POETRY_* environment variable # is set via a POETRY_* environment variable
if self._use_environment: if self._use_environment:
env = "POETRY_{}".format( env = "POETRY_" + "_".join(k.upper().replace("-", "_") for k in keys)
"_".join(k.upper().replace("-", "_") for k in keys)
)
env_value = os.getenv(env) env_value = os.getenv(env)
if env_value is not None: if env_value is not None:
return self.process(self._get_normalizer(setting_name)(env_value)) return self.process(self._get_normalizer(setting_name)(env_value))
......
...@@ -39,13 +39,9 @@ if TYPE_CHECKING: ...@@ -39,13 +39,9 @@ if TYPE_CHECKING:
def load_command(name: str) -> Callable: def load_command(name: str) -> Callable:
def _load() -> Type[Command]: def _load() -> Type[Command]:
module = import_module( words = name.split(" ")
"poetry.console.commands.{}".format(".".join(name.split(" "))) module = import_module("poetry.console.commands." + ".".join(words))
) command_class = getattr(module, "".join(c.title() for c in words) + "Command")
command_class = getattr(
module, "{}Command".format("".join(c.title() for c in name.split(" ")))
)
return command_class() return command_class()
return _load return _load
......
...@@ -27,9 +27,7 @@ class BuildCommand(EnvCommand): ...@@ -27,9 +27,7 @@ class BuildCommand(EnvCommand):
package = self.poetry.package package = self.poetry.package
self.line( self.line(
"Building <c1>{}</c1> (<c2>{}</c2>)".format( f"Building <c1>{package.pretty_name}</c1> (<c2>{package.version}</c2>)"
package.pretty_name, package.version
)
) )
builder = Builder(self.poetry) builder = Builder(self.poetry)
......
...@@ -43,7 +43,7 @@ class CacheClearCommand(Command): ...@@ -43,7 +43,7 @@ class CacheClearCommand(Command):
if not self.option("all"): if not self.option("all"):
raise RuntimeError( raise RuntimeError(
"Add the --all option if you want to clear all " "Add the --all option if you want to clear all "
"{} caches".format(parts[0]) f"{parts[0]} caches"
) )
if not os.path.exists(str(cache_dir)): if not os.path.exists(str(cache_dir)):
......
...@@ -230,7 +230,7 @@ To remove a repository (repo is a short alias for repositories): ...@@ -230,7 +230,7 @@ To remove a repository (repo is a short alias for repositories):
elif len(values) != 2: elif len(values) != 2:
raise ValueError( raise ValueError(
"Expected one or two arguments " "Expected one or two arguments "
"(username, password), got {}".format(len(values)) f"(username, password), got {len(values)}"
) )
else: else:
username = values[0] username = values[0]
...@@ -270,7 +270,7 @@ To remove a repository (repo is a short alias for repositories): ...@@ -270,7 +270,7 @@ To remove a repository (repo is a short alias for repositories):
return 0 return 0
raise ValueError("Setting {} does not exist".format(self.argument("key"))) raise ValueError(f"Setting {self.argument('key')} does not exist")
def _handle_single_value( def _handle_single_value(
self, self,
...@@ -307,19 +307,16 @@ To remove a repository (repo is a short alias for repositories): ...@@ -307,19 +307,16 @@ To remove a repository (repo is a short alias for repositories):
continue continue
elif isinstance(value, list): elif isinstance(value, list):
value = [ value = ", ".join(
json.dumps(val) if isinstance(val, list) else val for val in value json.dumps(val) if isinstance(val, list) else val for val in value
] )
value = f"[{value}]"
value = "[{}]".format(", ".join(value))
if k.startswith("repositories."): if k.startswith("repositories."):
message = "<c1>{}</c1> = <c2>{}</c2>".format( message = f"<c1>{k + key}</c1> = <c2>{json.dumps(raw_val)}</c2>"
k + key, json.dumps(raw_val)
)
elif isinstance(raw_val, str) and raw_val != value: elif isinstance(raw_val, str) and raw_val != value:
message = "<c1>{}</c1> = <c2>{}</c2> # {}".format( message = (
k + key, json.dumps(raw_val), value f"<c1>{k + key}</c1> = <c2>{json.dumps(raw_val)}</c2> # {value}"
) )
else: else:
message = f"<c1>{k + key}</c1> = <c2>{json.dumps(value)}</c2>" message = f"<c1>{k + key}</c1> = <c2>{json.dumps(value)}</c2>"
...@@ -361,12 +358,11 @@ To remove a repository (repo is a short alias for repositories): ...@@ -361,12 +358,11 @@ To remove a repository (repo is a short alias for repositories):
continue continue
if isinstance(value, list): if isinstance(value, list):
value = [ value = ", ".join(
json.dumps(val) if isinstance(val, list) else val json.dumps(val) if isinstance(val, list) else val
for val in value for val in value
] )
value = f"[{value}]"
value = "[{}]".format(", ".join(value))
value = json.dumps(value) value = json.dumps(value)
......
...@@ -17,9 +17,7 @@ class DebugInfoCommand(Command): ...@@ -17,9 +17,7 @@ class DebugInfoCommand(Command):
"\n".join( "\n".join(
[ [
f"<info>Version</info>: <comment>{self.poetry.VERSION}</>", f"<info>Version</info>: <comment>{self.poetry.VERSION}</>",
"<info>Python</info>: <comment>{}</>".format( f"<info>Python</info>: <comment>{poetry_python_version}</>",
poetry_python_version
),
] ]
) )
) )
......
...@@ -52,15 +52,14 @@ class EnvInfoCommand(Command): ...@@ -52,15 +52,14 @@ class EnvInfoCommand(Command):
self.line("") self.line("")
system_env = env.parent_env system_env = env.parent_env
python = ".".join(str(v) for v in system_env.version_info[:3])
self.line("<b>System</b>") self.line("<b>System</b>")
self.line( self.line(
"\n".join( "\n".join(
[ [
f"<info>Platform</info>: <comment>{env.platform}</>", f"<info>Platform</info>: <comment>{env.platform}</>",
f"<info>OS</info>: <comment>{env.os}</>", f"<info>OS</info>: <comment>{env.os}</>",
"<info>Python</info>: <comment>{}</>".format( f"<info>Python</info>: <comment>{python}</>",
".".join(str(v) for v in system_env.version_info[:3])
),
f"<info>Path</info>: <comment>{system_env.path}</>", f"<info>Path</info>: <comment>{system_env.path}</>",
f"<info>Executable</info>: <comment>{system_env.python}</>", f"<info>Executable</info>: <comment>{system_env.python}</>",
] ]
......
...@@ -146,13 +146,11 @@ The <c1>init</c1> command creates a basic <comment>pyproject.toml</> file in the ...@@ -146,13 +146,11 @@ The <c1>init</c1> command creates a basic <comment>pyproject.toml</> file in the
python = self.option("python") python = self.option("python")
if not python: if not python:
current_env = SystemEnv(Path(sys.executable)) current_env = SystemEnv(Path(sys.executable))
default_python = "^{}".format( default_python = "^" + ".".join(
".".join(str(v) for v in current_env.version_info[:2]) str(v) for v in current_env.version_info[:2]
) )
question = self.create_question( question = self.create_question(
"Compatible Python versions [<comment>{}</comment>]: ".format( f"Compatible Python versions [<comment>{default_python}</comment>]: ",
default_python
),
default=default_python, default=default_python,
) )
python = self.ask(question) python = self.ask(question)
...@@ -282,9 +280,7 @@ The <c1>init</c1> command creates a basic <comment>pyproject.toml</> file in the ...@@ -282,9 +280,7 @@ The <c1>init</c1> command creates a basic <comment>pyproject.toml</> file in the
choices.append(found_package.pretty_name) choices.append(found_package.pretty_name)
self.line( self.line(
"Found <info>{}</info> packages matching <c1>{}</c1>".format( f"Found <info>{len(matches)}</info> packages matching <c1>{package}</c1>"
len(matches), package
)
) )
package = self.choice( package = self.choice(
...@@ -314,9 +310,7 @@ The <c1>init</c1> command creates a basic <comment>pyproject.toml</> file in the ...@@ -314,9 +310,7 @@ The <c1>init</c1> command creates a basic <comment>pyproject.toml</> file in the
) )
self.line( self.line(
"Using version <b>{}</b> for <c1>{}</c1>".format( f"Using version <b>{package_constraint}</b> for <c1>{package}</c1>"
package_constraint, package
)
) )
constraint["version"] = package_constraint constraint["version"] = package_constraint
......
...@@ -176,19 +176,15 @@ dependencies and not including the current project, run the command with the ...@@ -176,19 +176,15 @@ dependencies and not including the current project, run the command with the
# If this is a true error it will be picked up later by build anyway. # If this is a true error it will be picked up later by build anyway.
return 0 return 0
log_install = (
f"<b>Installing</> the current project: <c1>{self.poetry.package.pretty_name}</c1> "
f"(<{{tag}}>{self.poetry.package.pretty_version}</>)"
)
overwrite = self._io.output.is_decorated() and not self.io.is_debug()
self.line("") self.line("")
if not self._io.output.is_decorated() or self.io.is_debug(): self.write(log_install.format(tag="c2"))
self.line( if not overwrite:
"<b>Installing</> the current project: <c1>{}</c1> (<c2>{}</c2>)".format( self.line("")
self.poetry.package.pretty_name, self.poetry.package.pretty_version
)
)
else:
self.write(
"<b>Installing</> the current project: <c1>{}</c1> (<c2>{}</c2>)".format(
self.poetry.package.pretty_name, self.poetry.package.pretty_version
)
)
if self.option("dry-run"): if self.option("dry-run"):
self.line("") self.line("")
...@@ -196,12 +192,8 @@ dependencies and not including the current project, run the command with the ...@@ -196,12 +192,8 @@ dependencies and not including the current project, run the command with the
builder.build() builder.build()
if self._io.output.is_decorated() and not self.io.is_debug(): if overwrite:
self.overwrite( self.overwrite(log_install.format(tag="success"))
"<b>Installing</> the current project: <c1>{}</c1> (<success>{}</success>)".format(
self.poetry.package.pretty_name, self.poetry.package.pretty_version
)
)
self.line("") self.line("")
return 0 return 0
...@@ -50,7 +50,7 @@ class NewCommand(Command): ...@@ -50,7 +50,7 @@ class NewCommand(Command):
if path.exists() and list(path.glob("*")): if path.exists() and list(path.glob("*")):
# Directory is not empty. Aborting. # Directory is not empty. Aborting.
raise RuntimeError( raise RuntimeError(
"Destination <fg=yellow>{}</> " "exists and is not empty".format(path) f"Destination <fg=yellow>{path}</> " "exists and is not empty"
) )
readme_format = self.option("readme") or "md" readme_format = self.option("readme") or "md"
...@@ -64,9 +64,7 @@ class NewCommand(Command): ...@@ -64,9 +64,7 @@ class NewCommand(Command):
author += f" <{author_email}>" author += f" <{author_email}>"
current_env = SystemEnv(Path(sys.executable)) current_env = SystemEnv(Path(sys.executable))
default_python = "^{}".format( default_python = "^" + ".".join(str(v) for v in current_env.version_info[:2])
".".join(str(v) for v in current_env.version_info[:2])
)
layout_ = layout_( layout_ = layout_(
name, name,
...@@ -83,7 +81,5 @@ class NewCommand(Command): ...@@ -83,7 +81,5 @@ class NewCommand(Command):
path = path.relative_to(Path.cwd()) path = path.relative_to(Path.cwd())
self.line( self.line(
"Created package <info>{}</> in <fg=blue>{}</>".format( f"Created package <info>{layout_._package_name}</> in <fg=blue>{path.as_posix()}</>"
layout_._package_name, path.as_posix()
)
) )
...@@ -24,6 +24,7 @@ class PluginShowCommand(Command): ...@@ -24,6 +24,7 @@ class PluginShowCommand(Command):
from poetry.repositories.installed_repository import InstalledRepository from poetry.repositories.installed_repository import InstalledRepository
from poetry.utils.env import EnvManager from poetry.utils.env import EnvManager
from poetry.utils.helpers import canonicalize_name from poetry.utils.helpers import canonicalize_name
from poetry.utils.helpers import pluralize
plugins: DefaultDict[str, Dict[str, Union["Package", List[str]]]] = defaultdict( plugins: DefaultDict[str, Dict[str, Union["Package", List[str]]]] = defaultdict(
lambda: { lambda: {
...@@ -57,27 +58,21 @@ class PluginShowCommand(Command): ...@@ -57,27 +58,21 @@ class PluginShowCommand(Command):
for name, info in plugins.items(): for name, info in plugins.items():
package = info["package"] package = info["package"]
description = " " + package.description if package.description else ""
self.line("") self.line("")
self.line( self.line(f" • <c1>{name}</c1> (<c2>{package.version}</c2>){description}")
" • <c1>{}</c1> (<c2>{}</c2>){}".format(
name,
package.version,
" " + package.description if package.description else "",
)
)
provide_line = " " provide_line = " "
if info["plugins"]: if info["plugins"]:
provide_line += " <info>{}</info> plugin{}".format( count = len(info["plugins"])
len(info["plugins"]), "s" if len(info["plugins"]) > 1 else "" provide_line += f" <info>{count}</info> plugin{pluralize(count)}"
)
if info["application_plugins"]: if info["application_plugins"]:
if info["plugins"]: if info["plugins"]:
provide_line += " and" provide_line += " and"
provide_line += " <info>{}</info> application plugin{}".format( count = len(info["application_plugins"])
len(info["application_plugins"]), provide_line += (
"s" if len(info["application_plugins"]) > 1 else "", f" <info>{count}</info> application plugin{pluralize(count)}"
) )
self.line(provide_line) self.line(provide_line)
...@@ -87,9 +82,7 @@ class PluginShowCommand(Command): ...@@ -87,9 +82,7 @@ class PluginShowCommand(Command):
self.line(" <info>Dependencies</info>") self.line(" <info>Dependencies</info>")
for dependency in package.requires: for dependency in package.requires:
self.line( self.line(
" - {} (<c2>{}</c2>)".format( f" - {dependency.pretty_name} (<c2>{dependency.pretty_constraint}</c2>)"
dependency.pretty_name, dependency.pretty_constraint
)
) )
return 0 return 0
...@@ -49,8 +49,8 @@ the config command. ...@@ -49,8 +49,8 @@ the config command.
# Building package first, if told # Building package first, if told
if self.option("build"): if self.option("build"):
if publisher.files and not self.confirm( if publisher.files and not self.confirm(
"There are <info>{}</info> files ready for publishing. " f"There are <info>{len(publisher.files)}</info> files ready for publishing. "
"Build anyway?".format(len(publisher.files)) "Build anyway?"
): ):
self.line_error("<error>Aborted!</error>") self.line_error("<error>Aborted!</error>")
......
...@@ -88,9 +88,7 @@ list of installed packages ...@@ -88,9 +88,7 @@ list of installed packages
not_found = set(packages).difference(removed) not_found = set(packages).difference(removed)
if not_found: if not_found:
raise ValueError( raise ValueError(
"The following packages were not found: {}".format( "The following packages were not found: " + ", ".join(sorted(not_found))
", ".join(sorted(not_found))
)
) )
# Refresh the locker # Refresh the locker
......
...@@ -54,8 +54,8 @@ class RunCommand(EnvCommand): ...@@ -54,8 +54,8 @@ class RunCommand(EnvCommand):
cmd += [ cmd += [
"import sys; " "import sys; "
"from importlib import import_module; " "from importlib import import_module; "
"sys.argv = {!r}; {}" f"sys.argv = {args!r}; {src_in_sys_path}"
"import_module('{}').{}()".format(args, src_in_sys_path, module, callable_) f"import_module('{module}').{callable_}()"
] ]
return self.env.execute(*cmd) return self.env.execute(*cmd)
...@@ -139,9 +139,7 @@ class SelfUpdateCommand(Command): ...@@ -139,9 +139,7 @@ class SelfUpdateCommand(Command):
self.line("") self.line("")
self.line( self.line(
"<c1>Poetry</c1> (<c2>{}</c2>) is installed now. Great!".format( f"<c1>Poetry</c1> (<c2>{release.version}</c2>) is installed now. Great!"
release.version
)
) )
return 0 return 0
......
...@@ -25,8 +25,7 @@ If one doesn't exist yet, it will be created. ...@@ -25,8 +25,7 @@ If one doesn't exist yet, it will be created.
) == str(self.env.path) ) == str(self.env.path)
if venv_activated: if venv_activated:
self.line( self.line(
"Virtual environment already activated: " f"Virtual environment already activated: <info>{self.env.path}</>"
"<info>{}</>".format(self.env.path)
) )
return return
......
...@@ -201,9 +201,7 @@ lists all packages available.""" ...@@ -201,9 +201,7 @@ lists all packages available."""
self.line("<info>dependencies</info>") self.line("<info>dependencies</info>")
for dependency in pkg.requires: for dependency in pkg.requires:
self.line( self.line(
" - <c1>{}</c1> <b>{}</b>".format( f" - <c1>{dependency.pretty_name}</c1> <b>{dependency.pretty_constraint}</b>"
dependency.pretty_name, dependency.pretty_constraint
)
) )
if required_by: if required_by:
...@@ -303,16 +301,12 @@ lists all packages available.""" ...@@ -303,16 +301,12 @@ lists all packages available."""
): ):
continue continue
line = "<fg={}>{:{}}{}</>".format( line = f"<fg={color}>{name:{name_length - len(install_marker)}}{install_marker}</>"
color, name, name_length - len(install_marker), install_marker
)
if write_version: if write_version:
line += " <b>{:{}}</b>".format( version = get_package_version_display_string(
get_package_version_display_string( locked, root=self.poetry.file.parent
locked, root=self.poetry.file.parent
),
version_length,
) )
line += f" <b>{version:{version_length}}</b>"
if show_latest: if show_latest:
latest = latest_packages[locked.pretty_name] latest = latest_packages[locked.pretty_name]
update_status = latest_statuses[locked.pretty_name] update_status = latest_statuses[locked.pretty_name]
...@@ -324,13 +318,10 @@ lists all packages available.""" ...@@ -324,13 +318,10 @@ lists all packages available."""
elif update_status == "update-possible": elif update_status == "update-possible":
color = "yellow" color = "yellow"
line += " <fg={}>{:{}}</>".format( version = get_package_version_display_string(
color, latest, root=self.poetry.file.parent
get_package_version_display_string(
latest, root=self.poetry.file.parent
),
latest_length,
) )
line += f" <fg={color}>{version:{latest_length}}</>"
if write_description: if write_description:
description = locked.description description = locked.description
...@@ -366,12 +357,7 @@ lists all packages available.""" ...@@ -366,12 +357,7 @@ lists all packages available."""
level = 1 level = 1
color = self.colors[level] color = self.colors[level]
info = "{tree_bar}── <{color}>{name}</{color}> {constraint}".format( info = f"{tree_bar}── <{color}>{dependency.name}</{color}> {dependency.pretty_constraint}"
tree_bar=tree_bar,
color=color,
name=dependency.name,
constraint=dependency.pretty_constraint,
)
self._write_tree_line(io, info) self._write_tree_line(io, info)
tree_bar = tree_bar.replace("└", " ") tree_bar = tree_bar.replace("└", " ")
...@@ -414,13 +400,7 @@ lists all packages available.""" ...@@ -414,13 +400,7 @@ lists all packages available."""
if dependency.name in current_tree: if dependency.name in current_tree:
circular_warn = "(circular dependency aborted here)" circular_warn = "(circular dependency aborted here)"
info = "{tree_bar}── <{color}>{name}</{color}> {constraint} {warn}".format( info = f"{tree_bar}── <{color}>{dependency.name}</{color}> {dependency.pretty_constraint} {circular_warn}"
tree_bar=tree_bar,
color=color,
name=dependency.name,
constraint=dependency.pretty_constraint,
warn=circular_warn,
)
self._write_tree_line(io, info) self._write_tree_line(io, info)
tree_bar = tree_bar.replace("└", " ") tree_bar = tree_bar.replace("└", " ")
......
...@@ -58,9 +58,7 @@ patch, minor, major, prepatch, preminor, premajor, prerelease. ...@@ -58,9 +58,7 @@ patch, minor, major, prepatch, preminor, premajor, prerelease.
self.line(version.to_string()) self.line(version.to_string())
else: else:
self.line( self.line(
"Bumping version from <b>{}</> to <fg=green>{}</>".format( f"Bumping version from <b>{self.poetry.package.pretty_version}</> to <fg=green>{version}</>"
self.poetry.package.pretty_version, version
)
) )
content = self.poetry.file.read() content = self.poetry.file.read()
......
...@@ -100,9 +100,7 @@ class Factory(BaseFactory): ...@@ -100,9 +100,7 @@ class Factory(BaseFactory):
if config_file.exists(): if config_file.exists():
if io.is_debug(): if io.is_debug():
io.write_line( io.write_line(
"<debug>Loading configuration file {}</debug>".format( f"<debug>Loading configuration file {config_file.path}</debug>"
config_file.path
)
) )
config.merge(config_file.read()) config.merge(config_file.read())
...@@ -114,9 +112,7 @@ class Factory(BaseFactory): ...@@ -114,9 +112,7 @@ class Factory(BaseFactory):
if auth_config_file.exists(): if auth_config_file.exists():
if io.is_debug(): if io.is_debug():
io.write_line( io.write_line(
"<debug>Loading configuration file {}</debug>".format( f"<debug>Loading configuration file {auth_config_file.path}</debug>"
auth_config_file.path
)
) )
config.merge(auth_config_file.read()) config.merge(auth_config_file.read())
...@@ -134,9 +130,7 @@ class Factory(BaseFactory): ...@@ -134,9 +130,7 @@ class Factory(BaseFactory):
is_default = source.get("default", False) is_default = source.get("default", False)
is_secondary = source.get("secondary", False) is_secondary = source.get("secondary", False)
if io.is_debug(): if io.is_debug():
message = "Adding repository {} ({})".format( message = f"Adding repository {repository.name} ({repository.url})"
repository.name, repository.url
)
if is_default: if is_default:
message += " and setting it as the default one" message += " and setting it as the default one"
elif is_secondary: elif is_secondary:
......
...@@ -49,7 +49,7 @@ class PackageInfoError(ValueError): ...@@ -49,7 +49,7 @@ class PackageInfoError(ValueError):
def __init__( def __init__(
self, path: Union[Path, str], *reasons: Union[BaseException, str] self, path: Union[Path, str], *reasons: Union[BaseException, str]
) -> None: ) -> None:
reasons = (f"Unable to determine package info for path: {str(path)}",) + reasons reasons = (f"Unable to determine package info for path: {path!s}",) + reasons
super().__init__("\n\n".join(str(msg).strip() for msg in reasons if msg)) super().__init__("\n\n".join(str(msg).strip() for msg in reasons if msg))
...@@ -178,8 +178,8 @@ class PackageInfo: ...@@ -178,8 +178,8 @@ class PackageInfo:
except ValueError: except ValueError:
# Likely unable to parse constraint so we skip it # Likely unable to parse constraint so we skip it
self._log( self._log(
"Invalid constraint ({}) found in {}-{} dependencies, " f"Invalid constraint ({req}) found in {package.name}-{package.version} dependencies, "
"skipping".format(req, package.name, package.version), "skipping",
level="warning", level="warning",
) )
continue continue
...@@ -460,6 +460,10 @@ class PackageInfo: ...@@ -460,6 +460,10 @@ class PackageInfo:
dest_dir = venv.path.parent / "dist" dest_dir = venv.path.parent / "dist"
dest_dir.mkdir() dest_dir.mkdir()
pep517_meta_build_script = PEP517_META_BUILD.format(
source=path.as_posix(), dest=dest_dir.as_posix()
)
try: try:
venv.run_pip( venv.run_pip(
"install", "install",
...@@ -470,9 +474,7 @@ class PackageInfo: ...@@ -470,9 +474,7 @@ class PackageInfo:
venv.run( venv.run(
"python", "python",
"-", "-",
input_=PEP517_META_BUILD.format( input_=pep517_meta_build_script,
source=path.as_posix(), dest=dest_dir.as_posix()
),
) )
return cls.from_metadata(dest_dir) return cls.from_metadata(dest_dir)
except EnvCommandError as e: except EnvCommandError as e:
......
...@@ -149,8 +149,8 @@ class Chooser: ...@@ -149,8 +149,8 @@ class Chooser:
wheel = Wheel(link.filename) wheel = Wheel(link.filename)
if not wheel.is_supported_by_environment(self._env): if not wheel.is_supported_by_environment(self._env):
raise RuntimeError( raise RuntimeError(
"{} is not a supported wheel for this platform. It " f"{wheel.filename} is not a supported wheel for this platform. It "
"can't be sorted.".format(wheel.filename) "can't be sorted."
) )
# TODO: Binary preference # TODO: Binary preference
......
...@@ -26,6 +26,7 @@ from poetry.installation.chooser import Chooser ...@@ -26,6 +26,7 @@ from poetry.installation.chooser import Chooser
from poetry.utils._compat import decode from poetry.utils._compat import decode
from poetry.utils.authenticator import Authenticator from poetry.utils.authenticator import Authenticator
from poetry.utils.env import EnvCommandError from poetry.utils.env import EnvCommandError
from poetry.utils.helpers import pluralize
from poetry.utils.helpers import safe_rmtree from poetry.utils.helpers import safe_rmtree
from poetry.utils.pip import pip_editable_install from poetry.utils.pip import pip_editable_install
from poetry.utils.pip import pip_install from poetry.utils.pip import pip_install
...@@ -221,6 +222,7 @@ class Executor: ...@@ -221,6 +222,7 @@ class Executor:
def _execute_operation(self, operation: "OperationTypes") -> None: def _execute_operation(self, operation: "OperationTypes") -> None:
try: try:
op_message = self.get_operation_message(operation)
if self.supports_fancy_output(): if self.supports_fancy_output():
if id(operation) not in self._sections and self._should_write_operation( if id(operation) not in self._sections and self._should_write_operation(
operation operation
...@@ -228,27 +230,20 @@ class Executor: ...@@ -228,27 +230,20 @@ class Executor:
with self._lock: with self._lock:
self._sections[id(operation)] = self._io.section() self._sections[id(operation)] = self._io.section()
self._sections[id(operation)].write_line( self._sections[id(operation)].write_line(
" <fg=blue;options=bold>•</> {message}: <fg=blue>Pending...</>".format( f" <fg=blue;options=bold>•</> {op_message}: <fg=blue>Pending...</>"
message=self.get_operation_message(operation),
),
) )
else: else:
if self._should_write_operation(operation): if self._should_write_operation(operation):
if not operation.skipped: if not operation.skipped:
self._io.write_line( self._io.write_line(
" <fg=blue;options=bold>•</> {message}".format( f" <fg=blue;options=bold>•</> {op_message}"
message=self.get_operation_message(operation),
),
) )
else: else:
self._io.write_line( self._io.write_line(
" <fg=default;options=bold,dark>•</> {message}: " f" <fg=default;options=bold,dark>•</> {op_message}: "
"<fg=default;options=bold,dark>Skipped</> " "<fg=default;options=bold,dark>Skipped</> "
"<fg=default;options=dark>for the following reason:</> " "<fg=default;options=dark>for the following reason:</> "
"<fg=default;options=bold,dark>{reason}</>".format( f"<fg=default;options=bold,dark>{operation.skip_reason}</>"
message=self.get_operation_message(operation),
reason=operation.skip_reason,
)
) )
try: try:
...@@ -271,11 +266,7 @@ class Executor: ...@@ -271,11 +266,7 @@ class Executor:
if not self.supports_fancy_output(): if not self.supports_fancy_output():
io = self._io io = self._io
else: else:
message = ( message = f" <error>•</error> {self.get_operation_message(operation, error=True)}: <error>Failed</error>"
" <error>•</error> {message}: <error>Failed</error>".format(
message=self.get_operation_message(operation, error=True),
)
)
self._write(operation, message) self._write(operation, message)
io = self._sections.get(id(operation), self._io) io = self._sections.get(id(operation), self._io)
...@@ -288,9 +279,7 @@ class Executor: ...@@ -288,9 +279,7 @@ class Executor:
self._shutdown = True self._shutdown = True
except KeyboardInterrupt: except KeyboardInterrupt:
try: try:
message = " <warning>•</warning> {message}: <warning>Cancelled</warning>".format( message = f" <warning>•</warning> {self.get_operation_message(operation, warning=True)}: <warning>Cancelled</warning>"
message=self.get_operation_message(operation, warning=True),
)
if not self.supports_fancy_output(): if not self.supports_fancy_output():
self._io.write_line(message) self._io.write_line(message)
else: else:
...@@ -307,13 +296,10 @@ class Executor: ...@@ -307,13 +296,10 @@ class Executor:
if self.supports_fancy_output(): if self.supports_fancy_output():
self._write( self._write(
operation, operation,
" <fg=default;options=bold,dark>•</> {message}: " f" <fg=default;options=bold,dark>•</> {operation_message}: "
"<fg=default;options=bold,dark>Skipped</> " "<fg=default;options=bold,dark>Skipped</> "
"<fg=default;options=dark>for the following reason:</> " "<fg=default;options=dark>for the following reason:</> "
"<fg=default;options=bold,dark>{reason}</>".format( f"<fg=default;options=bold,dark>{operation.skip_reason}</>",
message=operation_message,
reason=operation.skip_reason,
),
) )
self._skipped[operation.job_type] += 1 self._skipped[operation.job_type] += 1
...@@ -321,11 +307,7 @@ class Executor: ...@@ -321,11 +307,7 @@ class Executor:
return 0 return 0
if not self._enabled or self._dry_run: if not self._enabled or self._dry_run:
self._io.write_line( self._io.write_line(f" <fg=blue;options=bold>•</> {operation_message}")
" <fg=blue;options=bold>•</> {message}".format(
message=operation_message,
)
)
return 0 return 0
...@@ -334,9 +316,8 @@ class Executor: ...@@ -334,9 +316,8 @@ class Executor:
if result != 0: if result != 0:
return result return result
message = " <fg=green;options=bold>•</> {message}".format( operation_message = self.get_operation_message(operation, done=True)
message=self.get_operation_message(operation, done=True), message = f" <fg=green;options=bold>•</> {operation_message}"
)
self._write(operation, message) self._write(operation, message)
self._increment_operations_count(operation, True) self._increment_operations_count(operation, True)
...@@ -394,38 +375,23 @@ class Executor: ...@@ -394,38 +375,23 @@ class Executor:
package_color += "_dark" package_color += "_dark"
if operation.job_type == "install": if operation.job_type == "install":
return "<{}>Installing <{}>{}</{}> (<{}>{}</>)</>".format( return (
base_tag, f"<{base_tag}>Installing <{package_color}>{operation.package.name}</{package_color}> "
package_color, f"(<{operation_color}>{operation.package.full_pretty_version}</>)</>"
operation.package.name,
package_color,
operation_color,
operation.package.full_pretty_version,
) )
if operation.job_type == "uninstall": if operation.job_type == "uninstall":
return "<{}>Removing <{}>{}</{}> (<{}>{}</>)</>".format( return (
base_tag, f"<{base_tag}>Removing <{package_color}>{operation.package.name}</{package_color}> "
package_color, f"(<{operation_color}>{operation.package.full_pretty_version}</>)</>"
operation.package.name,
package_color,
operation_color,
operation.package.full_pretty_version,
) )
if operation.job_type == "update": if operation.job_type == "update":
return "<{}>Updating <{}>{}</{}> (<{}>{}</{}> -> <{}>{}</>)</>".format( return (
base_tag, f"<{base_tag}>Updating <{package_color}>{operation.initial_package.name}</{package_color}> "
package_color, f"(<{source_operation_color}>{operation.initial_package.full_pretty_version}</{source_operation_color}> "
operation.initial_package.name, f"-> <{operation_color}>{operation.target_package.full_pretty_version}</>)</>"
package_color,
source_operation_color,
operation.initial_package.full_pretty_version,
source_operation_color,
operation_color,
operation.target_package.full_pretty_version,
) )
return "" return ""
def _display_summary(self, operations: List["OperationTypes"]) -> None: def _display_summary(self, operations: List["OperationTypes"]) -> None:
...@@ -452,21 +418,13 @@ class Executor: ...@@ -452,21 +418,13 @@ class Executor:
return return
self._io.write_line("") self._io.write_line("")
self._io.write_line( self._io.write("<b>Package operations</b>: ")
"<b>Package operations</b>: " self._io.write(f"<info>{installs}</> install{pluralize(installs)}, ")
"<info>{}</> install{}, " self._io.write(f"<info>{updates}</> update{pluralize(updates)}, ")
"<info>{}</> update{}, " self._io.write(f"<info>{uninstalls}</> removal{pluralize(uninstalls)}")
"<info>{}</> removal{}" if skipped and self._verbose:
"{}".format( self._io.write(f", <info>{skipped}</> skipped")
installs, self._io.write_line("")
"" if installs == 1 else "s",
updates,
"" if updates == 1 else "s",
uninstalls,
"" if uninstalls == 1 else "s",
f", <info>{skipped}</> skipped" if skipped and self._verbose else "",
)
)
self._io.write_line("") self._io.write_line("")
def _execute_install(self, operation: Union["Install", "Update"]) -> int: def _execute_install(self, operation: Union["Install", "Update"]) -> int:
...@@ -484,11 +442,8 @@ class Executor: ...@@ -484,11 +442,8 @@ class Executor:
return status_code return status_code
def _execute_uninstall(self, operation: "Uninstall") -> int: def _execute_uninstall(self, operation: "Uninstall") -> int:
message = ( op_msg = self.get_operation_message(operation)
" <fg=blue;options=bold>•</> {message}: <info>Removing...</info>".format( message = f" <fg=blue;options=bold>•</> {op_msg}: <info>Removing...</info>"
message=self.get_operation_message(operation),
)
)
self._write(operation, message) self._write(operation, message)
return self._remove(operation) return self._remove(operation)
...@@ -509,11 +464,7 @@ class Executor: ...@@ -509,11 +464,7 @@ class Executor:
archive = self._download(operation) archive = self._download(operation)
operation_message = self.get_operation_message(operation) operation_message = self.get_operation_message(operation)
message = ( message = f" <fg=blue;options=bold>•</> {operation_message}: <info>Installing...</info>"
" <fg=blue;options=bold>•</> {message}: <info>Installing...</info>".format(
message=operation_message,
)
)
self._write(operation, message) self._write(operation, message)
return self.pip_install(archive, upgrade=operation.job_type == "update") return self.pip_install(archive, upgrade=operation.job_type == "update")
...@@ -539,12 +490,9 @@ class Executor: ...@@ -539,12 +490,9 @@ class Executor:
def _prepare_file(self, operation: Union["Install", "Update"]) -> Path: def _prepare_file(self, operation: Union["Install", "Update"]) -> Path:
package = operation.package package = operation.package
operation_message = self.get_operation_message(operation)
message = ( message = f" <fg=blue;options=bold>•</> {operation_message}: <info>Preparing...</info>"
" <fg=blue;options=bold>•</> {message}: <info>Preparing...</info>".format(
message=self.get_operation_message(operation),
)
)
self._write(operation, message) self._write(operation, message)
archive = Path(package.source_url) archive = Path(package.source_url)
...@@ -561,11 +509,7 @@ class Executor: ...@@ -561,11 +509,7 @@ class Executor:
package = operation.package package = operation.package
operation_message = self.get_operation_message(operation) operation_message = self.get_operation_message(operation)
message = ( message = f" <fg=blue;options=bold>•</> {operation_message}: <info>Building...</info>"
" <fg=blue;options=bold>•</> {message}: <info>Building...</info>".format(
message=operation_message,
)
)
self._write(operation, message) self._write(operation, message)
if package.root_dir: if package.root_dir:
...@@ -622,9 +566,7 @@ class Executor: ...@@ -622,9 +566,7 @@ class Executor:
operation_message = self.get_operation_message(operation) operation_message = self.get_operation_message(operation)
message = ( message = (
" <fg=blue;options=bold>•</> {message}: <info>Cloning...</info>".format( f" <fg=blue;options=bold>•</> {operation_message}: <info>Cloning...</info>"
message=operation_message,
)
) )
self._write(operation, message) self._write(operation, message)
...@@ -716,9 +658,7 @@ class Executor: ...@@ -716,9 +658,7 @@ class Executor:
wheel_size = response.headers.get("content-length") wheel_size = response.headers.get("content-length")
operation_message = self.get_operation_message(operation) operation_message = self.get_operation_message(operation)
message = ( message = (
" <fg=blue;options=bold>•</> {message}: <info>Downloading...</>".format( f" <fg=blue;options=bold>•</> {operation_message}: <info>Downloading...</>"
message=operation_message,
)
) )
progress = None progress = None
if self.supports_fancy_output(): if self.supports_fancy_output():
......
...@@ -17,6 +17,7 @@ from poetry.repositories import Repository ...@@ -17,6 +17,7 @@ from poetry.repositories import Repository
from poetry.repositories.installed_repository import InstalledRepository from poetry.repositories.installed_repository import InstalledRepository
from poetry.utils.extras import get_extra_package_names from poetry.utils.extras import get_extra_package_names
from poetry.utils.helpers import canonicalize_name from poetry.utils.helpers import canonicalize_name
from poetry.utils.helpers import pluralize
if TYPE_CHECKING: if TYPE_CHECKING:
...@@ -385,23 +386,13 @@ class Installer: ...@@ -385,23 +386,13 @@ class Installer:
uninstalls += 1 uninstalls += 1
self._io.write_line("") self._io.write_line("")
self._io.write_line( self._io.write("Package operations: ")
"Package operations: " self._io.write(f"<info>{installs}</> install{pluralize(installs)}, ")
"<info>{}</> install{}, " self._io.write(f"<info>{updates}</> update{pluralize(updates)}, ")
"<info>{}</> update{}, " self._io.write(f"<info>{uninstalls}</> removal{pluralize(uninstalls)}")
"<info>{}</> removal{}" if skipped and self.is_verbose():
"{}".format( self._io.write(f", <info>{skipped}</> skipped")
installs, self._io.write_line("")
"" if installs == 1 else "s",
updates,
"" if updates == 1 else "s",
uninstalls,
"" if uninstalls == 1 else "s",
f", <info>{skipped}</> skipped"
if skipped and self.is_verbose()
else "",
)
)
self._io.write_line("") self._io.write_line("")
...@@ -419,23 +410,18 @@ class Installer: ...@@ -419,23 +410,18 @@ class Installer:
getattr(self, f"_execute_{method}")(operation) getattr(self, f"_execute_{method}")(operation)
def _execute_install(self, operation: Install) -> None: def _execute_install(self, operation: Install) -> None:
target = operation.package
if operation.skipped: if operation.skipped:
if self.is_verbose() and (self._execute_operations or self.is_dry_run()): if self.is_verbose() and (self._execute_operations or self.is_dry_run()):
self._io.write_line( self._io.write_line(
" - Skipping <c1>{}</c1> (<c2>{}</c2>) {}".format( f" - Skipping <c1>{target.pretty_name}</c1> (<c2>{target.full_pretty_version}</c2>) {operation.skip_reason}"
operation.package.pretty_name,
operation.package.full_pretty_version,
operation.skip_reason,
)
) )
return return
if self._execute_operations or self.is_dry_run(): if self._execute_operations or self.is_dry_run():
self._io.write_line( self._io.write_line(
" - Installing <c1>{}</c1> (<c2>{}</c2>)".format( f" - Installing <c1>{target.pretty_name}</c1> (<c2>{target.full_pretty_version}</c2>)"
operation.package.pretty_name, operation.package.full_pretty_version
)
) )
if not self._execute_operations: if not self._execute_operations:
...@@ -450,22 +436,16 @@ class Installer: ...@@ -450,22 +436,16 @@ class Installer:
if operation.skipped: if operation.skipped:
if self.is_verbose() and (self._execute_operations or self.is_dry_run()): if self.is_verbose() and (self._execute_operations or self.is_dry_run()):
self._io.write_line( self._io.write_line(
" - Skipping <c1>{}</c1> (<c2>{}</c2>) {}".format( f" - Skipping <c1>{target.pretty_name}</c1> "
target.pretty_name, f"(<c2>{target.full_pretty_version}</c2>) {operation.skip_reason}"
target.full_pretty_version,
operation.skip_reason,
)
) )
return return
if self._execute_operations or self.is_dry_run(): if self._execute_operations or self.is_dry_run():
self._io.write_line( self._io.write_line(
" - Updating <c1>{}</c1> (<c2>{}</c2> -> <c2>{}</c2>)".format( f" - Updating <c1>{target.pretty_name}</c1> "
target.pretty_name, f"(<c2>{source.full_pretty_version}</c2> -> <c2>{target.full_pretty_version}</c2>)"
source.full_pretty_version,
target.full_pretty_version,
)
) )
if not self._execute_operations: if not self._execute_operations:
...@@ -474,23 +454,18 @@ class Installer: ...@@ -474,23 +454,18 @@ class Installer:
self._installer.update(source, target) self._installer.update(source, target)
def _execute_uninstall(self, operation: Uninstall) -> None: def _execute_uninstall(self, operation: Uninstall) -> None:
target = operation.package
if operation.skipped: if operation.skipped:
if self.is_verbose() and (self._execute_operations or self.is_dry_run()): if self.is_verbose() and (self._execute_operations or self.is_dry_run()):
self._io.write_line( self._io.write_line(
" - Not removing <c1>{}</c1> (<c2>{}</c2>) {}".format( f" - Not removing <c1>{target.pretty_name}</c1> (<c2>{target.pretty_version}</c2>) {operation.skip_reason}"
operation.package.pretty_name,
operation.package.full_pretty_version,
operation.skip_reason,
)
) )
return return
if self._execute_operations or self.is_dry_run(): if self._execute_operations or self.is_dry_run():
self._io.write_line( self._io.write_line(
" - Removing <c1>{}</c1> (<c2>{}</c2>)".format( f" - Removing <c1>{target.pretty_name}</c1> (<c2>{target.pretty_version}</c2>)"
operation.package.pretty_name, operation.package.full_pretty_version
)
) )
if not self._execute_operations: if not self._execute_operations:
......
...@@ -25,11 +25,7 @@ class Install(Operation): ...@@ -25,11 +25,7 @@ class Install(Operation):
return "install" return "install"
def __str__(self) -> str: def __str__(self) -> str:
return "Installing {} ({})".format( return f"Installing {self.package.pretty_name} ({self.format_version(self.package)})"
self.package.pretty_name, self.format_version(self.package)
)
def __repr__(self) -> str: def __repr__(self) -> str:
return "<Install {} ({})>".format( return f"<Install {self.package.pretty_name} ({self.format_version(self.package)})>"
self.package.pretty_name, self.format_version(self.package)
)
...@@ -28,11 +28,7 @@ class Uninstall(Operation): ...@@ -28,11 +28,7 @@ class Uninstall(Operation):
return "uninstall" return "uninstall"
def __str__(self) -> str: def __str__(self) -> str:
return "Uninstalling {} ({})".format( return f"Uninstalling {self.package.pretty_name} ({self.format_version(self._package)})"
self.package.pretty_name, self.format_version(self._package)
)
def __repr__(self) -> str: def __repr__(self) -> str:
return "<Uninstall {} ({})>".format( return f"<Uninstall {self.package.pretty_name} ({self.format_version(self.package)})>"
self.package.pretty_name, self.format_version(self.package)
)
...@@ -38,17 +38,17 @@ class Update(Operation): ...@@ -38,17 +38,17 @@ class Update(Operation):
return "update" return "update"
def __str__(self) -> str: def __str__(self) -> str:
return "Updating {} ({}) to {} ({})".format( init_version = self.format_version(self.initial_package)
self.initial_package.pretty_name, target_version = self.format_version(self.target_package)
self.format_version(self.initial_package), return (
self.target_package.pretty_name, f"Updating {self.initial_package.pretty_name} ({init_version}) "
self.format_version(self.target_package), f"to {self.target_package.pretty_name} ({target_version})"
) )
def __repr__(self) -> str: def __repr__(self) -> str:
return "<Update {} ({}) to {} ({})>".format( init_version = self.format_version(self.initial_package)
self.initial_package.pretty_name, target_version = self.format_version(self.target_package)
self.format_version(self.initial_package), return (
self.target_package.pretty_name, f"<Update {self.initial_package.pretty_name} ({init_version}) "
self.format_version(self.target_package), f"to {self.target_package.pretty_name} ({target_version})>"
) )
...@@ -52,9 +52,7 @@ class PipInstaller(BaseInstaller): ...@@ -52,9 +52,7 @@ class PipInstaller(BaseInstaller):
parsed = urllib.parse.urlparse(package.source_url) parsed = urllib.parse.urlparse(package.source_url)
if parsed.scheme == "http": if parsed.scheme == "http":
self._io.write_error( self._io.write_error(
" <warning>Installing from unsecure host: {}</warning>".format( f" <warning>Installing from unsecure host: {parsed.hostname}</warning>"
parsed.hostname
)
) )
args += ["--trusted-host", parsed.hostname] args += ["--trusted-host", parsed.hostname]
...@@ -161,9 +159,7 @@ class PipInstaller(BaseInstaller): ...@@ -161,9 +159,7 @@ class PipInstaller(BaseInstaller):
return req return req
if package.source_type == "git": if package.source_type == "git":
req = "git+{}@{}#egg={}".format( req = f"git+{package.source_url}@{package.source_reference}#egg={package.name}"
package.source_url, package.source_reference, package.name
)
if package.develop: if package.develop:
req = ["-e", req] req = ["-e", req]
......
...@@ -31,9 +31,8 @@ def validate_object(obj: dict, schema_name: str) -> List[str]: ...@@ -31,9 +31,8 @@ def validate_object(obj: dict, schema_name: str) -> List[str]:
for error in validation_errors: for error in validation_errors:
message = error.message message = error.message
if error.path: if error.path:
message = "[{}] {}".format( path = ".".join(str(x) for x in error.absolute_path)
".".join(str(x) for x in error.absolute_path), message message = f"[{path}] {message}"
)
errors.append(message) errors.append(message)
......
...@@ -61,10 +61,9 @@ class Layout: ...@@ -61,10 +61,9 @@ class Layout:
self._readme_format = readme_format.lower() self._readme_format = readme_format.lower()
if self._readme_format not in self.ACCEPTED_README_FORMATS: if self._readme_format not in self.ACCEPTED_README_FORMATS:
accepted_readme_formats = ", ".join(self.ACCEPTED_README_FORMATS)
raise ValueError( raise ValueError(
"Invalid readme format '{}', use one of {}.".format( f"Invalid readme format '{readme_format}', use one of {accepted_readme_formats}."
readme_format, ", ".join(self.ACCEPTED_README_FORMATS)
)
) )
self._license = license self._license = license
......
...@@ -47,9 +47,7 @@ class EditableBuilder(Builder): ...@@ -47,9 +47,7 @@ class EditableBuilder(Builder):
def build(self) -> None: def build(self) -> None:
self._debug( self._debug(
" - Building package <c1>{}</c1> in <info>editable</info> mode".format( f" - Building package <c1>{self._package.name}</c1> in <info>editable</info> mode"
self._package.name
)
) )
if self._package.build_script: if self._package.build_script:
...@@ -65,9 +63,7 @@ class EditableBuilder(Builder): ...@@ -65,9 +63,7 @@ class EditableBuilder(Builder):
distribution_name=self._package.name distribution_name=self._package.name
): ):
self._debug( self._debug(
" - Removed <c2>{}</c2> directory from <b>{}</b>".format( f" - Removed <c2>{removed.name}</c2> directory from <b>{removed.parent}</b>"
removed.name, removed.parent
)
) )
added_files = [] added_files = []
...@@ -128,9 +124,7 @@ class EditableBuilder(Builder): ...@@ -128,9 +124,7 @@ class EditableBuilder(Builder):
# remove any pre-existing pth files for this package # remove any pre-existing pth files for this package
for file in self._env.site_packages.find(path=pth_file, writable_only=True): for file in self._env.site_packages.find(path=pth_file, writable_only=True):
self._debug( self._debug(
" - Removing existing <c2>{}</c2> from <b>{}</b> for {}".format( f" - Removing existing <c2>{file.name}</c2> from <b>{file.parent}</b> for {self._poetry.file.parent}"
file.name, file.parent, self._poetry.file.parent
)
) )
# We can't use unlink(missing_ok=True) because it's not always available # We can't use unlink(missing_ok=True) because it's not always available
if file.exists(): if file.exists():
...@@ -141,17 +135,13 @@ class EditableBuilder(Builder): ...@@ -141,17 +135,13 @@ class EditableBuilder(Builder):
pth_file, content, encoding="utf-8" pth_file, content, encoding="utf-8"
) )
self._debug( self._debug(
" - Adding <c2>{}</c2> to <b>{}</b> for {}".format( f" - Adding <c2>{pth_file.name}</c2> to <b>{pth_file.parent}</b> for {self._poetry.file.parent}"
pth_file.name, pth_file.parent, self._poetry.file.parent
)
) )
return [pth_file] return [pth_file]
except OSError: except OSError:
# TODO: Replace with PermissionError # TODO: Replace with PermissionError
self._io.write_error_line( self._io.write_error_line(
" - Failed to create <c2>{}</c2> for {}".format( f" - Failed to create <c2>{pth_file.name}</c2> for {self._poetry.file.parent}"
pth_file.name, self._poetry.file.parent
)
) )
return [] return []
...@@ -164,9 +154,7 @@ class EditableBuilder(Builder): ...@@ -164,9 +154,7 @@ class EditableBuilder(Builder):
break break
else: else:
self._io.write_error_line( self._io.write_error_line(
" - Failed to find a suitable script installation directory for {}".format( f" - Failed to find a suitable script installation directory for {self._poetry.file.parent}"
self._poetry.file.parent
)
) )
return [] return []
...@@ -178,9 +166,7 @@ class EditableBuilder(Builder): ...@@ -178,9 +166,7 @@ class EditableBuilder(Builder):
script_file = scripts_path.joinpath(name) script_file = scripts_path.joinpath(name)
self._debug( self._debug(
" - Adding the <c2>{}</c2> script to <b>{}</b>".format( f" - Adding the <c2>{name}</c2> script to <b>{scripts_path}</b>"
name, scripts_path
)
) )
with script_file.open("w", encoding="utf-8") as f: with script_file.open("w", encoding="utf-8") as f:
f.write( f.write(
...@@ -202,9 +188,7 @@ class EditableBuilder(Builder): ...@@ -202,9 +188,7 @@ class EditableBuilder(Builder):
cmd_script = script_file.with_suffix(".cmd") cmd_script = script_file.with_suffix(".cmd")
cmd = WINDOWS_CMD_TEMPLATE.format(python=self._env.python, script=name) cmd = WINDOWS_CMD_TEMPLATE.format(python=self._env.python, script=name)
self._debug( self._debug(
" - Adding the <c2>{}</c2> script wrapper to <b>{}</b>".format( f" - Adding the <c2>{cmd_script.name}</c2> script wrapper to <b>{scripts_path}</b>"
cmd_script.name, scripts_path
)
) )
with cmd_script.open("w", encoding="utf-8") as f: with cmd_script.open("w", encoding="utf-8") as f:
...@@ -223,9 +207,7 @@ class EditableBuilder(Builder): ...@@ -223,9 +207,7 @@ class EditableBuilder(Builder):
dist_info = self._env.site_packages.mkdir(Path(builder.dist_info)) dist_info = self._env.site_packages.mkdir(Path(builder.dist_info))
self._debug( self._debug(
" - Adding the <c2>{}</c2> directory to <b>{}</b>".format( f" - Adding the <c2>{dist_info.name}</c2> directory to <b>{dist_info.parent}</b>"
dist_info.name, dist_info.parent
)
) )
with dist_info.joinpath("METADATA").open("w", encoding="utf-8") as f: with dist_info.joinpath("METADATA").open("w", encoding="utf-8") as f:
...@@ -246,14 +228,15 @@ class EditableBuilder(Builder): ...@@ -246,14 +228,15 @@ class EditableBuilder(Builder):
added_files.append(dist_info.joinpath("entry_points.txt")) added_files.append(dist_info.joinpath("entry_points.txt"))
with dist_info.joinpath("RECORD").open("w", encoding="utf-8") as f: record = dist_info.joinpath("RECORD")
with record.open("w", encoding="utf-8") as f:
for path in added_files: for path in added_files:
hash = self._get_file_hash(path) hash = self._get_file_hash(path)
size = path.stat().st_size size = path.stat().st_size
f.write(f"{str(path)},sha256={hash},{size}\n") f.write(f"{path!s},sha256={hash},{size}\n")
# RECORD itself is recorded with no hash or size # RECORD itself is recorded with no hash or size
f.write("{},,\n".format(dist_info.joinpath("RECORD"))) f.write(f"{record},,\n")
def _get_file_hash(self, filepath: Path) -> str: def _get_file_hash(self, filepath: Path) -> str:
hashsum = hashlib.sha256() hashsum = hashlib.sha256()
......
...@@ -43,11 +43,9 @@ class _Writer: ...@@ -43,11 +43,9 @@ class _Writer:
if isinstance(incompatibility.cause, PythonCause): if isinstance(incompatibility.cause, PythonCause):
if not required_python_version_notification: if not required_python_version_notification:
buffer.append( buffer.append(
"The current project's Python requirement ({}) " f"The current project's Python requirement ({incompatibility.cause.root_python_version}) "
"is not compatible with some of the required " "is not compatible with some of the required "
"packages Python requirement:".format( "packages Python requirement:"
incompatibility.cause.root_python_version
)
) )
required_python_version_notification = True required_python_version_notification = True
...@@ -56,11 +54,9 @@ class _Writer: ...@@ -56,11 +54,9 @@ class _Writer:
) )
constraint = parse_constraint(incompatibility.cause.python_version) constraint = parse_constraint(incompatibility.cause.python_version)
buffer.append( buffer.append(
" - {} requires Python {}, so it will not be satisfied for Python {}".format( f" - {incompatibility.terms[0].dependency.name} requires Python "
incompatibility.terms[0].dependency.name, f"{incompatibility.cause.python_version}, so it will not be satisfied "
incompatibility.cause.python_version, f"for Python {root_constraint.difference(constraint)}"
root_constraint.difference(constraint),
)
) )
if required_python_version_notification: if required_python_version_notification:
...@@ -128,14 +124,12 @@ class _Writer: ...@@ -128,14 +124,12 @@ class _Writer:
other_line = self._line_numbers.get(cause.other) other_line = self._line_numbers.get(cause.other)
if conflict_line is not None and other_line is not None: if conflict_line is not None and other_line is not None:
reason = cause.conflict.and_to_string(
cause.other, details_for_cause, conflict_line, other_line
)
self._write( self._write(
incompatibility, incompatibility,
"Because {}, {}.".format( f"Because {reason}, {incompatibility_string}.",
cause.conflict.and_to_string(
cause.other, details_for_cause, conflict_line, other_line
),
incompatibility_string,
),
numbered=numbered, numbered=numbered,
) )
elif conflict_line is not None or other_line is not None: elif conflict_line is not None or other_line is not None:
...@@ -151,9 +145,7 @@ class _Writer: ...@@ -151,9 +145,7 @@ class _Writer:
self._visit(without_line, details_for_cause) self._visit(without_line, details_for_cause)
self._write( self._write(
incompatibility, incompatibility,
"{} because {} ({}), {}.".format( f"{conjunction} because {with_line!s} ({line}), {incompatibility_string}.",
conjunction, str(with_line), line, incompatibility_string
),
numbered=numbered, numbered=numbered,
) )
else: else:
...@@ -178,12 +170,7 @@ class _Writer: ...@@ -178,12 +170,7 @@ class _Writer:
self._write( self._write(
incompatibility, incompatibility,
"{} because {} ({}), {}".format( f"{conjunction} because {cause.conflict!s} ({self._line_numbers[cause.conflict]}), {incompatibility_string}",
conjunction,
str(cause.conflict),
self._line_numbers[cause.conflict],
incompatibility_string,
),
numbered=numbered, numbered=numbered,
) )
elif isinstance(cause.conflict.cause, ConflictCause) or isinstance( elif isinstance(cause.conflict.cause, ConflictCause) or isinstance(
...@@ -202,14 +189,12 @@ class _Writer: ...@@ -202,14 +189,12 @@ class _Writer:
derived_line = self._line_numbers.get(derived) derived_line = self._line_numbers.get(derived)
if derived_line is not None: if derived_line is not None:
reason = ext.and_to_string(
derived, details_for_cause, None, derived_line
)
self._write( self._write(
incompatibility, incompatibility,
"Because {}, {}.".format( f"Because {reason}, {incompatibility_string}.",
ext.and_to_string(
derived, details_for_cause, None, derived_line
),
incompatibility_string,
),
numbered=numbered, numbered=numbered,
) )
elif self._is_collapsible(derived): elif self._is_collapsible(derived):
...@@ -227,33 +212,26 @@ class _Writer: ...@@ -227,33 +212,26 @@ class _Writer:
details_for_cause = {} details_for_cause = {}
self._visit(collapsed_derived, details_for_cause) self._visit(collapsed_derived, details_for_cause)
reason = collapsed_ext.and_to_string(ext, details_for_cause, None, None)
self._write( self._write(
incompatibility, incompatibility,
"{} because {}, {}.".format( f"{conjunction} because {reason}, {incompatibility_string}.",
conjunction,
collapsed_ext.and_to_string(ext, details_for_cause, None, None),
incompatibility_string,
),
numbered=numbered, numbered=numbered,
) )
else: else:
self._visit(derived, details_for_cause) self._visit(derived, details_for_cause)
self._write( self._write(
incompatibility, incompatibility,
"{} because {}, {}.".format( f"{conjunction} because {ext!s}, {incompatibility_string}.",
conjunction, str(ext), incompatibility_string
),
numbered=numbered, numbered=numbered,
) )
else: else:
reason = cause.conflict.and_to_string(
cause.other, details_for_cause, None, None
)
self._write( self._write(
incompatibility, incompatibility,
"Because {}, {}.".format( f"Because {reason}, {incompatibility_string}.",
cause.conflict.and_to_string(
cause.other, details_for_cause, None, None
),
incompatibility_string,
),
numbered=numbered, numbered=numbered,
) )
......
...@@ -130,9 +130,7 @@ class Incompatibility: ...@@ -130,9 +130,7 @@ class Incompatibility:
assert depender.is_positive() assert depender.is_positive()
assert not dependee.is_positive() assert not dependee.is_positive()
return "{} depends on {}".format( return f"{self._terse(depender, allow_every=True)} depends on {self._terse(dependee)}"
self._terse(depender, allow_every=True), self._terse(dependee)
)
elif isinstance(self._cause, PythonCause): elif isinstance(self._cause, PythonCause):
assert len(self._terms) == 1 assert len(self._terms) == 1
assert self._terms[0].is_positive() assert self._terms[0].is_positive()
...@@ -155,9 +153,7 @@ class Incompatibility: ...@@ -155,9 +153,7 @@ class Incompatibility:
assert len(self._terms) == 1 assert len(self._terms) == 1
assert self._terms[0].is_positive() assert self._terms[0].is_positive()
return "no versions of {} match {}".format( return f"no versions of {self._terms[0].dependency.name} match {self._terms[0].constraint}"
self._terms[0].dependency.name, self._terms[0].constraint
)
elif isinstance(self._cause, PackageNotFoundCause): elif isinstance(self._cause, PackageNotFoundCause):
assert len(self._terms) == 1 assert len(self._terms) == 1
assert self._terms[0].is_positive() assert self._terms[0].is_positive()
...@@ -168,18 +164,14 @@ class Incompatibility: ...@@ -168,18 +164,14 @@ class Incompatibility:
assert not self._terms[0].is_positive() assert not self._terms[0].is_positive()
assert self._terms[0].dependency.is_root assert self._terms[0].dependency.is_root
return "{} is {}".format( return f"{self._terms[0].dependency.name} is {self._terms[0].dependency.constraint}"
self._terms[0].dependency.name, self._terms[0].dependency.constraint
)
elif self.is_failure(): elif self.is_failure():
return "version solving failed" return "version solving failed"
if len(self._terms) == 1: if len(self._terms) == 1:
term = self._terms[0] term = self._terms[0]
return "{} is {}".format( verb = "forbidden" if term.is_positive() else "required"
term.dependency.name, return f"{term.dependency.name} is {verb}"
"forbidden" if term.is_positive() else "required",
)
if len(self._terms) == 2: if len(self._terms) == 2:
term1 = self._terms[0] term1 = self._terms[0]
...@@ -200,9 +192,7 @@ class Incompatibility: ...@@ -200,9 +192,7 @@ class Incompatibility:
return f"{package1} is incompatible with {package2}" return f"{package1} is incompatible with {package2}"
else: else:
return "either {} or {}".format( return f"either {self._terse(term1)} or {self._terse(term2)}"
self._terse(term1), self._terse(term2)
)
positive = [] positive = []
negative = [] negative = []
...@@ -217,17 +207,13 @@ class Incompatibility: ...@@ -217,17 +207,13 @@ class Incompatibility:
if len(positive) == 1: if len(positive) == 1:
positive_term = [term for term in self._terms if term.is_positive()][0] positive_term = [term for term in self._terms if term.is_positive()][0]
return "{} requires {}".format( return f"{self._terse(positive_term, allow_every=True)} requires {' or '.join(negative)}"
self._terse(positive_term, allow_every=True), " or ".join(negative)
)
else: else:
return "if {} then {}".format( return f"if {' and '.join(positive)} then {' or '.join(negative)}"
" and ".join(positive), " or ".join(negative)
)
elif positive: elif positive:
return "one of {} must be false".format(" or ".join(positive)) return f"one of {' or '.join(positive)} must be false"
else: else:
return "one of {} must be true".format(" or ".join(negative)) return f"one of {' or '.join(negative)} must be true"
def and_to_string( def and_to_string(
self, self,
...@@ -254,12 +240,12 @@ class Incompatibility: ...@@ -254,12 +240,12 @@ class Incompatibility:
buffer = [str(self)] buffer = [str(self)]
if this_line is not None: if this_line is not None:
buffer.append(" " + str(this_line)) buffer.append(f" {this_line!s}")
buffer.append(f" and {str(other)}") buffer.append(f" and {other!s}")
if other_line is not None: if other_line is not None:
buffer.append(" " + str(other_line)) buffer.append(f" {other_line!s}")
return "\n".join(buffer) return "\n".join(buffer)
...@@ -454,9 +440,7 @@ class Incompatibility: ...@@ -454,9 +440,7 @@ class Incompatibility:
if term.dependency.is_root: if term.dependency.is_root:
return term.dependency.pretty_name return term.dependency.pretty_name
return "{} ({})".format( return f"{term.dependency.pretty_name} ({term.dependency.pretty_constraint})"
term.dependency.pretty_name, term.dependency.pretty_constraint
)
def _single_term_where( def _single_term_where(
self, callable: Callable[["Term"], bool] self, callable: Callable[["Term"], bool]
...@@ -474,4 +458,4 @@ class Incompatibility: ...@@ -474,4 +458,4 @@ class Incompatibility:
return found return found
def __repr__(self) -> str: def __repr__(self) -> str:
return f"<Incompatibility {str(self)}>" return f"<Incompatibility {self!s}>"
...@@ -26,11 +26,9 @@ class PythonRequirementSolution(Solution): ...@@ -26,11 +26,9 @@ class PythonRequirementSolution(Solution):
constraint = parse_constraint(incompatibility.cause.python_version) constraint = parse_constraint(incompatibility.cause.python_version)
version_solutions.append( version_solutions.append(
"For <fg=default;options=bold>{}</>, a possible solution would be " f"For <fg=default;options=bold>{incompatibility.terms[0].dependency.name}</>, "
'to set the `<fg=default;options=bold>python</>` property to <fg=yellow>"{}"</>'.format( "a possible solution would be to set the `<fg=default;options=bold>python</>` "
incompatibility.terms[0].dependency.name, f'property to <fg=yellow>"{root_constraint.intersect(constraint)}"</>'
root_constraint.intersect(constraint),
)
) )
description = ( description = (
......
...@@ -162,7 +162,8 @@ class Term: ...@@ -162,7 +162,8 @@ class Term:
return Term(self.dependency.with_constraint(constraint), is_positive) return Term(self.dependency.with_constraint(constraint), is_positive)
def __str__(self) -> str: def __str__(self) -> str:
return "{}{}".format("not " if not self.is_positive() else "", self._dependency) prefix = "not " if not self.is_positive() else ""
return f"{prefix}{self._dependency}"
def __repr__(self) -> str: def __repr__(self) -> str:
return f"<Term {str(self)}>" return f"<Term {self!s}>"
...@@ -87,10 +87,8 @@ class VersionSolver: ...@@ -87,10 +87,8 @@ class VersionSolver:
raise raise
finally: finally:
self._log( self._log(
"Version solving took {:.3f} seconds.\n" f"Version solving took {time.time() - start:.3f} seconds.\n"
"Tried {} solutions.".format( f"Tried {self._solution.attempted_solutions} solutions."
time.time() - start, self._solution.attempted_solutions
)
) )
def _propagate(self, package: str) -> None: def _propagate(self, package: str) -> None:
...@@ -172,11 +170,8 @@ class VersionSolver: ...@@ -172,11 +170,8 @@ class VersionSolver:
if unsatisfied is None: if unsatisfied is None:
return _conflict return _conflict
self._log( adverb = "not " if unsatisfied.is_positive() else ""
"derived: {}{}".format( self._log(f"derived: {adverb}{unsatisfied.dependency}")
"not " if unsatisfied.is_positive() else "", unsatisfied.dependency
)
)
self._solution.derive( self._solution.derive(
unsatisfied.dependency, not unsatisfied.is_positive(), incompatibility unsatisfied.dependency, not unsatisfied.is_positive(), incompatibility
...@@ -304,14 +299,11 @@ class VersionSolver: ...@@ -304,14 +299,11 @@ class VersionSolver:
new_incompatibility = True new_incompatibility = True
partially = "" if difference is None else " partially" partially = "" if difference is None else " partially"
bang = "!"
self._log( self._log(
"{} {} is{} satisfied by {}".format( f"! {most_recent_term} is{partially} satisfied by {most_recent_satisfier}"
bang, most_recent_term, partially, most_recent_satisfier
)
) )
self._log(f'{bang} which is caused by "{most_recent_satisfier.cause}"') self._log(f'! which is caused by "{most_recent_satisfier.cause}"')
self._log(f"{bang} thus: {incompatibility}") self._log(f"! thus: {incompatibility}")
raise SolveFailure(incompatibility) raise SolveFailure(incompatibility)
...@@ -412,9 +404,7 @@ class VersionSolver: ...@@ -412,9 +404,7 @@ class VersionSolver:
if not conflict: if not conflict:
self._solution.decide(version) self._solution.decide(version)
self._log( self._log(
"selecting {} ({})".format( f"selecting {version.complete_name} ({version.full_pretty_version})"
version.complete_name, version.full_pretty_version
)
) )
return dependency.complete_name return dependency.complete_name
......
...@@ -67,9 +67,7 @@ class Publisher: ...@@ -67,9 +67,7 @@ class Publisher:
auth = self._authenticator.get_http_auth(repository_name) auth = self._authenticator.get_http_auth(repository_name)
if auth: if auth:
logger.debug( logger.debug(
"Found authentication information for {}.".format( f"Found authentication information for {repository_name}."
repository_name
)
) )
username = auth["username"] username = auth["username"]
password = auth["password"] password = auth["password"]
...@@ -88,13 +86,11 @@ class Publisher: ...@@ -88,13 +86,11 @@ class Publisher:
self._uploader.auth(username, password) self._uploader.auth(username, password)
if repository_name == "pypi":
repository_name = "PyPI"
self._io.write_line( self._io.write_line(
"Publishing <c1>{}</c1> (<c2>{}</c2>) " f"Publishing <c1>{self._package.pretty_name}</c1> (<c2>{self._package.pretty_version}</c2>) "
"to <info>{}</info>".format( f"to <info>{repository_name}</info>"
self._package.pretty_name,
self._package.pretty_version,
"PyPI" if repository_name == "pypi" else repository_name,
)
) )
self._uploader.upload( self._uploader.upload(
......
...@@ -335,4 +335,4 @@ class Uploader: ...@@ -335,4 +335,4 @@ class Uploader:
elif len(exts) >= 2 and "".join(exts[-2:]) == ".tar.gz": elif len(exts) >= 2 and "".join(exts[-2:]) == ".tar.gz":
return "sdist" return "sdist"
raise ValueError("Unknown distribution format {}".format("".join(exts))) raise ValueError("Unknown distribution format " + "".join(exts))
...@@ -216,9 +216,8 @@ class Provider: ...@@ -216,9 +216,8 @@ class Provider:
if vcs != "git": if vcs != "git":
raise ValueError(f"Unsupported VCS dependency {vcs}") raise ValueError(f"Unsupported VCS dependency {vcs}")
tmp_dir = Path( suffix = url.split("/")[-1].rstrip(".git")
mkdtemp(prefix="pypoetry-git-{}".format(url.split("/")[-1].rstrip(".git"))) tmp_dir = Path(mkdtemp(prefix=f"pypoetry-git-{suffix}"))
)
try: try:
git = Git() git = Git()
...@@ -259,9 +258,7 @@ class Provider: ...@@ -259,9 +258,7 @@ class Provider:
if dependency.name != package.name: if dependency.name != package.name:
# For now, the dependency's name must match the actual package's name # For now, the dependency's name must match the actual package's name
raise RuntimeError( raise RuntimeError(
"The dependency name for {} does not match the actual package's name: {}".format( f"The dependency name for {dependency.name} does not match the actual package's name: {package.name}"
dependency.name, package.name
)
) )
if dependency.base is not None: if dependency.base is not None:
...@@ -321,9 +318,7 @@ class Provider: ...@@ -321,9 +318,7 @@ class Provider:
if name and name != package.name: if name and name != package.name:
# For now, the dependency's name must match the actual package's name # For now, the dependency's name must match the actual package's name
raise RuntimeError( raise RuntimeError(
"The dependency name for {} does not match the actual package's name: {}".format( f"The dependency name for {name} does not match the actual package's name: {package.name}"
name, package.name
)
) )
return package return package
...@@ -337,9 +332,7 @@ class Provider: ...@@ -337,9 +332,7 @@ class Provider:
if dependency.name != package.name: if dependency.name != package.name:
# For now, the dependency's name must match the actual package's name # For now, the dependency's name must match the actual package's name
raise RuntimeError( raise RuntimeError(
"The dependency name for {} does not match the actual package's name: {}".format( f"The dependency name for {dependency.name} does not match the actual package's name: {package.name}"
dependency.name, package.name
)
) )
for extra in dependency.extras: for extra in dependency.extras:
...@@ -596,7 +589,7 @@ class Provider: ...@@ -596,7 +589,7 @@ class Provider:
continue continue
if len(by_constraint) == 1: if len(by_constraint) == 1:
self.debug(f"<debug>Merging requirements for {str(deps[0])}</debug>") self.debug(f"<debug>Merging requirements for {deps[0]!s}</debug>")
dependencies.append(list(by_constraint.values())[0][0]) dependencies.append(list(by_constraint.values())[0][0])
continue continue
...@@ -633,28 +626,19 @@ class Provider: ...@@ -633,28 +626,19 @@ class Provider:
# with the following overrides: # with the following overrides:
# - {<Package foo (1.2.3): {"bar": <Dependency bar (>=2.0)>} # - {<Package foo (1.2.3): {"bar": <Dependency bar (>=2.0)>}
# - {<Package foo (1.2.3): {"bar": <Dependency bar (<2.0)>} # - {<Package foo (1.2.3): {"bar": <Dependency bar (<2.0)>}
markers = []
for deps in by_constraint.values():
markers.append(deps[0].marker)
_deps = [_dep[0] for _dep in by_constraint.values()] _deps = [_dep[0] for _dep in by_constraint.values()]
self.debug(
"<warning>Different requirements found for {}.</warning>".format( def fmt_warning(d: "Dependency") -> str:
", ".join( marker = d.marker if not d.marker.is_any() else "*"
"<c1>{}</c1> <fg=default>(<c2>{}</c2>)</> with markers <b>{}</b>".format( return (
d.name, f"<c1>{d.name}</c1> <fg=default>(<c2>{d.pretty_constraint}</c2>)</> "
d.pretty_constraint, f"with markers <b>{marker}</b>"
d.marker if not d.marker.is_any() else "*",
)
for d in _deps[:-1]
)
+ " and "
+ "<c1>{}</c1> <fg=default>(<c2>{}</c2>)</> with markers <b>{}</b>".format(
_deps[-1].name,
_deps[-1].pretty_constraint,
_deps[-1].marker if not _deps[-1].marker.is_any() else "*",
)
) )
warnings = ", ".join(fmt_warning(d) for d in _deps[:-1])
warnings += f" and {fmt_warning(_deps[-1])}"
self.debug(
f"<warning>Different requirements found for {warnings}.</warning>"
) )
# We need to check if one of the duplicate dependencies # We need to check if one of the duplicate dependencies
...@@ -758,10 +742,8 @@ class Provider: ...@@ -758,10 +742,8 @@ class Provider:
version = "" version = ""
message = ( message = (
"<fg=blue>fact</>: <c1>{}</c1>{} " f"<fg=blue>fact</>: <c1>{name}</c1>{version} "
"depends on <c1>{}</c1> (<c2>{}</c2>)".format( f"depends on <c1>{m.group(2)}</c1> (<c2>{m.group(3)}</c2>)"
name, version, m.group(2), m.group(3)
)
) )
elif " is " in message: elif " is " in message:
message = re.sub( message = re.sub(
...@@ -773,7 +755,7 @@ class Provider: ...@@ -773,7 +755,7 @@ class Provider:
message = re.sub( message = re.sub(
r"(?<=: )(.+?) \((.+?)\)", "<c1>\\1</c1> (<c2>\\2</c2>)", message r"(?<=: )(.+?) \((.+?)\)", "<c1>\\1</c1> (<c2>\\2</c2>)", message
) )
message = "<fg=blue>fact</>: {}".format(message.split("fact: ")[1]) message = f"<fg=blue>fact</>: {message.split('fact: ')[1]}"
elif message.startswith("selecting "): elif message.startswith("selecting "):
message = re.sub( message = re.sub(
r"selecting (.+?) \((.+?)\)", r"selecting (.+?) \((.+?)\)",
...@@ -783,12 +765,10 @@ class Provider: ...@@ -783,12 +765,10 @@ class Provider:
elif message.startswith("derived:"): elif message.startswith("derived:"):
m = re.match(r"derived: (.+?) \((.+?)\)$", message) m = re.match(r"derived: (.+?) \((.+?)\)$", message)
if m: if m:
message = "<fg=blue>derived</>: <c1>{}</c1> (<c2>{}</c2>)".format( message = f"<fg=blue>derived</>: <c1>{m.group(1)}</c1> (<c2>{m.group(2)}</c2>)"
m.group(1), m.group(2)
)
else: else:
message = "<fg=blue>derived</>: <c1>{}</c1>".format( message = (
message.split("derived: ")[1] f"<fg=blue>derived</>: <c1>{message.split('derived: ')[1]}</c1>"
) )
elif message.startswith("conflict:"): elif message.startswith("conflict:"):
m = re.match(r"conflict: (.+?) depends on (.+?) \((.+?)\)", message) m = re.match(r"conflict: (.+?) depends on (.+?) \((.+?)\)", message)
...@@ -802,15 +782,11 @@ class Provider: ...@@ -802,15 +782,11 @@ class Provider:
version = "" version = ""
message = ( message = (
"<fg=red;options=bold>conflict</>: <c1>{}</c1>{} " f"<fg=red;options=bold>conflict</>: <c1>{name}</c1>{version} "
"depends on <c1>{}</c1> (<c2>{}</c2>)".format( f"depends on <c1>{m.group(2)}</c1> (<c2>{m.group(3)}</c2>)"
name, version, m.group(2), m.group(3)
)
) )
else: else:
message = "<fg=red;options=bold>conflict</>: {}".format( message = f"<fg=red;options=bold>conflict</>: {message.split('conflict: ')[1]}"
message.split("conflict: ")[1]
)
message = message.replace("! ", "<error>!</error> ") message = message.replace("! ", "<error>!</error> ")
......
...@@ -78,9 +78,7 @@ class Solver: ...@@ -78,9 +78,7 @@ class Solver:
if len(self._overrides) > 1: if len(self._overrides) > 1:
self._provider.debug( self._provider.debug(
"Complete version solving took {:.3f} seconds with {} overrides".format( f"Complete version solving took {end - start:.3f} seconds with {len(self._overrides)} overrides"
end - start, len(self._overrides)
)
) )
self._provider.debug( self._provider.debug(
f"Resolved with overrides: {', '.join(f'({b})' for b in self._overrides)}" f"Resolved with overrides: {', '.join(f'({b})' for b in self._overrides)}"
......
...@@ -145,7 +145,7 @@ class Page: ...@@ -145,7 +145,7 @@ class Page:
"""Makes sure a link is fully encoded. That is, if a ' ' shows up in """Makes sure a link is fully encoded. That is, if a ' ' shows up in
the link, it will be rewritten to %20 (while not over-quoting the link, it will be rewritten to %20 (while not over-quoting
% or other characters).""" % or other characters)."""
return self._clean_re.sub(lambda match: "%%%2x" % ord(match.group(0)), url) return self._clean_re.sub(lambda match: f"%{match.group(0):2x}", url)
# TODO: revisit whether the LegacyRepository should inherit from PyPiRepository. # TODO: revisit whether the LegacyRepository should inherit from PyPiRepository.
...@@ -217,14 +217,10 @@ class LegacyRepository(PyPiRepository): ...@@ -217,14 +217,10 @@ class LegacyRepository(PyPiRepository):
return self.url return self.url
parsed = urllib.parse.urlparse(self.url) parsed = urllib.parse.urlparse(self.url)
username = quote(self._session.auth.username, safe="")
password = quote(self._session.auth.password, safe="")
return "{scheme}://{username}:{password}@{netloc}{path}".format( return f"{parsed.scheme}://{username}:{password}@{parsed.netloc}{parsed.path}"
scheme=parsed.scheme,
username=quote(self._session.auth.username, safe=""),
password=quote(self._session.auth.password, safe=""),
netloc=parsed.netloc,
path=parsed.path,
)
def find_packages(self, dependency: "Dependency") -> List[Package]: def find_packages(self, dependency: "Dependency") -> List[Package]:
packages = [] packages = []
...@@ -247,14 +243,14 @@ class LegacyRepository(PyPiRepository): ...@@ -247,14 +243,14 @@ class LegacyRepository(PyPiRepository):
key = dependency.name key = dependency.name
if not constraint.is_any(): if not constraint.is_any():
key = f"{key}:{str(constraint)}" key = f"{key}:{constraint!s}"
ignored_pre_release_versions = [] ignored_pre_release_versions = []
if self._cache.store("matches").has(key): if self._cache.store("matches").has(key):
versions = self._cache.store("matches").get(key) versions = self._cache.store("matches").get(key)
else: else:
page = self._get_page("/{}/".format(dependency.name.replace(".", "-"))) page = self._get_page(f"/{dependency.name.replace('.', '-')}/")
if page is None: if page is None:
return [] return []
...@@ -284,9 +280,7 @@ class LegacyRepository(PyPiRepository): ...@@ -284,9 +280,7 @@ class LegacyRepository(PyPiRepository):
packages.append(package) packages.append(package)
self._log( self._log(
"{} packages found for {} {}".format( f"{len(packages)} packages found for {dependency.name} {constraint!s}",
len(packages), dependency.name, str(constraint)
),
level="debug", level="debug",
) )
...@@ -323,14 +317,14 @@ class LegacyRepository(PyPiRepository): ...@@ -323,14 +317,14 @@ class LegacyRepository(PyPiRepository):
return package return package
def find_links_for_package(self, package: Package) -> List[Link]: def find_links_for_package(self, package: Package) -> List[Link]:
page = self._get_page("/{}/".format(package.name.replace(".", "-"))) page = self._get_page(f"/{package.name.replace('.', '-')}/")
if page is None: if page is None:
return [] return []
return list(page.links_for_version(package.version)) return list(page.links_for_version(package.version))
def _get_release_info(self, name: str, version: str) -> dict: def _get_release_info(self, name: str, version: str) -> dict:
page = self._get_page("/{}/".format(canonicalize_name(name).replace(".", "-"))) page = self._get_page(f"/{canonicalize_name(name).replace('.', '-')}/")
if page is None: if page is None:
raise PackageNotFound(f'No package named "{name}"') raise PackageNotFound(f'No package named "{name}"')
...@@ -348,9 +342,7 @@ class LegacyRepository(PyPiRepository): ...@@ -348,9 +342,7 @@ class LegacyRepository(PyPiRepository):
links = list(page.links_for_version(Version.parse(version))) links = list(page.links_for_version(Version.parse(version)))
if not links: if not links:
raise PackageNotFound( raise PackageNotFound(
'No valid distribution links found for package: "{}" version: "{}"'.format( f'No valid distribution links found for package: "{name}" version: "{version}"'
name, version
)
) )
urls = defaultdict(list) urls = defaultdict(list)
files = [] files = []
...@@ -388,9 +380,7 @@ class LegacyRepository(PyPiRepository): ...@@ -388,9 +380,7 @@ class LegacyRepository(PyPiRepository):
required_hash.update(chunk) required_hash.update(chunk)
if not known_hash or known_hash.hexdigest() == link.hash: if not known_hash or known_hash.hexdigest() == link.hash:
file_hash = "{}:{}".format( file_hash = f"{required_hash.name}:{required_hash.hexdigest()}"
required_hash.name, required_hash.hexdigest()
)
files.append({"file": link.filename, "hash": file_hash}) files.append({"file": link.filename, "hash": file_hash})
...@@ -422,9 +412,7 @@ class LegacyRepository(PyPiRepository): ...@@ -422,9 +412,7 @@ class LegacyRepository(PyPiRepository):
if response.url != url: if response.url != url:
self._log( self._log(
"Response URL {response_url} differs from request URL {url}".format( f"Response URL {response.url} differs from request URL {url}",
response_url=response.url, url=url
),
level="debug", level="debug",
) )
......
...@@ -109,7 +109,7 @@ class PyPiRepository(RemoteRepository): ...@@ -109,7 +109,7 @@ class PyPiRepository(RemoteRepository):
info = self.get_package_info(dependency.name) info = self.get_package_info(dependency.name)
except PackageNotFound: except PackageNotFound:
self._log( self._log(
f"No packages found for {dependency.name} {str(constraint)}", f"No packages found for {dependency.name} {constraint!s}",
level="debug", level="debug",
) )
return [] return []
...@@ -121,9 +121,7 @@ class PyPiRepository(RemoteRepository): ...@@ -121,9 +121,7 @@ class PyPiRepository(RemoteRepository):
if not release: if not release:
# Bad release # Bad release
self._log( self._log(
"No release information found for {}-{}, skipping".format( f"No release information found for {dependency.name}-{version}, skipping",
dependency.name, version
),
level="debug", level="debug",
) )
continue continue
...@@ -132,9 +130,7 @@ class PyPiRepository(RemoteRepository): ...@@ -132,9 +130,7 @@ class PyPiRepository(RemoteRepository):
package = Package(info["info"]["name"], version) package = Package(info["info"]["name"], version)
except InvalidVersion: except InvalidVersion:
self._log( self._log(
'Unable to parse version "{}" for the {} package, skipping'.format( f'Unable to parse version "{version}" for the {dependency.name} package, skipping',
version, dependency.name
),
level="debug", level="debug",
) )
continue continue
...@@ -149,9 +145,7 @@ class PyPiRepository(RemoteRepository): ...@@ -149,9 +145,7 @@ class PyPiRepository(RemoteRepository):
packages.append(package) packages.append(package)
self._log( self._log(
"{} packages found for {} {}".format( f"{len(packages)} packages found for {dependency.name} {constraint!s}",
len(packages), dependency.name, str(constraint)
),
level="debug", level="debug",
) )
...@@ -189,9 +183,7 @@ class PyPiRepository(RemoteRepository): ...@@ -189,9 +183,7 @@ class PyPiRepository(RemoteRepository):
results.append(result) results.append(result)
except InvalidVersion: except InvalidVersion:
self._log( self._log(
'Unable to parse version "{}" for the {} package, skipping'.format( f'Unable to parse version "{version}" for the {name} package, skipping',
version, name
),
level="debug", level="debug",
) )
...@@ -254,7 +246,7 @@ class PyPiRepository(RemoteRepository): ...@@ -254,7 +246,7 @@ class PyPiRepository(RemoteRepository):
links = [] links = []
for url in json_data["urls"]: for url in json_data["urls"]:
h = "sha256={}".format(url["digests"]["sha256"]) h = f"sha256={url['digests']['sha256']}"
links.append(Link(url["url"] + "#" + h)) links.append(Link(url["url"] + "#" + h))
return links return links
...@@ -433,14 +425,9 @@ class PyPiRepository(RemoteRepository): ...@@ -433,14 +425,9 @@ class PyPiRepository(RemoteRepository):
def _get_info_from_wheel(self, url: str) -> "PackageInfo": def _get_info_from_wheel(self, url: str) -> "PackageInfo":
from poetry.inspection.info import PackageInfo from poetry.inspection.info import PackageInfo
self._log( wheel_name = urllib.parse.urlparse(url).path.rsplit("/")[-1]
"Downloading wheel: {}".format( self._log(f"Downloading wheel: {wheel_name}", level="debug")
urllib.parse.urlparse(url).path.rsplit("/")[-1] filename = os.path.basename(wheel_name)
),
level="debug",
)
filename = os.path.basename(urllib.parse.urlparse(url).path.rsplit("/")[-1])
with temporary_directory() as temp_dir: with temporary_directory() as temp_dir:
filepath = Path(temp_dir) / filename filepath = Path(temp_dir) / filename
...@@ -451,14 +438,9 @@ class PyPiRepository(RemoteRepository): ...@@ -451,14 +438,9 @@ class PyPiRepository(RemoteRepository):
def _get_info_from_sdist(self, url: str) -> "PackageInfo": def _get_info_from_sdist(self, url: str) -> "PackageInfo":
from poetry.inspection.info import PackageInfo from poetry.inspection.info import PackageInfo
self._log( sdist_name = urllib.parse.urlparse(url).path
"Downloading sdist: {}".format( self._log(f"Downloading sdist: {sdist_name.rsplit('/')[-1]}", level="debug")
urllib.parse.urlparse(url).path.rsplit("/")[-1] filename = os.path.basename(sdist_name)
),
level="debug",
)
filename = os.path.basename(urllib.parse.urlparse(url).path)
with temporary_directory() as temp_dir: with temporary_directory() as temp_dir:
filepath = Path(temp_dir) / filename filepath = Path(temp_dir) / filename
......
...@@ -35,11 +35,7 @@ class Authenticator: ...@@ -35,11 +35,7 @@ class Authenticator:
def _log(self, message: str, level: str = "debug") -> None: def _log(self, message: str, level: str = "debug") -> None:
if self._io is not None: if self._io is not None:
self._io.write_line( self._io.write_line(f"<{level}>{message}</{level}>")
"<{level:s}>{message:s}</{level:s}>".format(
message=message, level=level
)
)
else: else:
getattr(logger, level, logger.debug)(message) getattr(logger, level, logger.debug)(message)
......
...@@ -254,19 +254,16 @@ class SitePackages: ...@@ -254,19 +254,16 @@ class SitePackages:
except ValueError: except ValueError:
pass pass
else: else:
site_type = "writable " if writable_only else ""
raise ValueError( raise ValueError(
"{} is not relative to any discovered {}sites".format( f"{path} is not relative to any discovered {site_type}sites"
path, "writable " if writable_only else ""
)
) )
results = [candidate / path for candidate in candidates if candidate] results = [candidate / path for candidate in candidates if candidate]
if not results and strict: if not results and strict:
raise RuntimeError( raise RuntimeError(
'Unable to find a suitable destination for "{}" in {}'.format( f'Unable to find a suitable destination for "{path}" in {paths_csv(self._candidates)}'
str(path), paths_csv(self._candidates)
)
) )
return results return results
...@@ -421,9 +418,7 @@ class EnvCommandError(EnvError): ...@@ -421,9 +418,7 @@ class EnvCommandError(EnvError):
def __init__(self, e: CalledProcessError, input: Optional[str] = None) -> None: def __init__(self, e: CalledProcessError, input: Optional[str] = None) -> None:
self.e = e self.e = e
message = "Command {} errored with the following return code {}, and output: \n{}".format( message = f"Command {e.cmd} errored with the following return code {e.returncode}, and output: \n{decode(e.output)}"
e.cmd, e.returncode, decode(e.output)
)
if input: if input:
message += f"input was : {input}" message += f"input was : {input}"
super().__init__(message) super().__init__(message)
...@@ -433,11 +428,11 @@ class NoCompatiblePythonVersionFound(EnvError): ...@@ -433,11 +428,11 @@ class NoCompatiblePythonVersionFound(EnvError):
def __init__(self, expected: str, given: Optional[str] = None) -> None: def __init__(self, expected: str, given: Optional[str] = None) -> None:
if given: if given:
message = ( message = (
"The specified Python version ({}) " f"The specified Python version ({given}) "
"is not supported by the project ({}).\n" f"is not supported by the project ({expected}).\n"
"Please choose a compatible version " "Please choose a compatible version "
"or loosen the python constraint specified " "or loosen the python constraint specified "
"in the pyproject.toml file.".format(given, expected) "in the pyproject.toml file."
) )
else: else:
message = ( message = (
...@@ -573,11 +568,8 @@ class EnvManager: ...@@ -573,11 +568,8 @@ class EnvManager:
envs = envs_file.read() envs = envs_file.read()
env = envs.get(name) env = envs.get(name)
if env is not None: if env is not None:
io.write_line( venv = venv_path / f"{name}-py{env['minor']}"
"Deactivating virtualenv: <comment>{}</comment>".format( io.write_line(f"Deactivating virtualenv: <comment>{venv}</comment>")
venv_path / (name + "-py{}".format(env["minor"]))
)
)
del envs[name] del envs[name]
envs_file.write(envs) envs_file.write(envs)
...@@ -834,11 +826,9 @@ class EnvManager: ...@@ -834,11 +826,9 @@ class EnvManager:
) )
io.write_line( io.write_line(
"<warning>The currently activated Python version {} " f"<warning>The currently activated Python version {python_patch} "
"is not supported by the project ({}).\n" f"is not supported by the project ({self._poetry.package.python_versions}).\n"
"Trying to find and use a compatible version.</warning> ".format( "Trying to find and use a compatible version.</warning> "
python_patch, self._poetry.package.python_versions
)
) )
for python_to_try in sorted( for python_to_try in sorted(
...@@ -910,17 +900,15 @@ class EnvManager: ...@@ -910,17 +900,15 @@ class EnvManager:
return self.get_system_env() return self.get_system_env()
io.write_line(f"Creating virtualenv <c1>{name}</> in {str(venv_path)}") io.write_line(f"Creating virtualenv <c1>{name}</> in {venv_path!s}")
else: else:
create_venv = False create_venv = False
if force: if force:
if not env.is_sane(): if not env.is_sane():
io.write_line( io.write_line(
"<warning>The virtual environment found in {} seems to be broken.</warning>".format( f"<warning>The virtual environment found in {env.path} seems to be broken.</warning>"
env.path
)
) )
io.write_line(f"Recreating virtualenv <c1>{name}</> in {str(venv)}") io.write_line(f"Recreating virtualenv <c1>{name}</> in {venv!s}")
self.remove_venv(venv) self.remove_venv(venv)
create_venv = True create_venv = True
elif io.is_very_verbose(): elif io.is_very_verbose():
...@@ -1493,7 +1481,7 @@ class SystemEnv(Env): ...@@ -1493,7 +1481,7 @@ class SystemEnv(Env):
def get_marker_env(self) -> Dict[str, Any]: def get_marker_env(self) -> Dict[str, Any]:
if hasattr(sys, "implementation"): if hasattr(sys, "implementation"):
info = sys.implementation.version info = sys.implementation.version
iver = "{0.major}.{0.minor}.{0.micro}".format(info) iver = f"{info.major}.{info.minor}.{info.micro}"
kind = info.releaselevel kind = info.releaselevel
if kind != "final": if kind != "final":
iver += kind[0] + str(info.serial) iver += kind[0] + str(info.serial)
...@@ -1678,8 +1666,8 @@ class GenericEnv(VirtualEnv): ...@@ -1678,8 +1666,8 @@ class GenericEnv(VirtualEnv):
patterns = [("python*", "pip*")] patterns = [("python*", "pip*")]
if self._child_env: if self._child_env:
minor_version = "{}.{}".format( minor_version = (
self._child_env.version_info[0], self._child_env.version_info[1] f"{self._child_env.version_info[0]}.{self._child_env.version_info[1]}"
) )
major_version = f"{self._child_env.version_info[0]}" major_version = f"{self._child_env.version_info[0]}"
patterns = [ patterns = [
......
...@@ -45,7 +45,7 @@ class Exporter: ...@@ -45,7 +45,7 @@ class Exporter:
if fmt not in self.ACCEPTED_FORMATS: if fmt not in self.ACCEPTED_FORMATS:
raise ValueError(f"Invalid export format: {fmt}") raise ValueError(f"Invalid export format: {fmt}")
getattr(self, "_export_{}".format(fmt.replace(".", "_")))( getattr(self, "_export_" + fmt.replace(".", "_"))(
cwd, cwd,
output, output,
with_hashes=with_hashes, with_hashes=with_hashes,
...@@ -120,11 +120,8 @@ class Exporter: ...@@ -120,11 +120,8 @@ class Exporter:
hashes.append(f"{algorithm}:{h}") hashes.append(f"{algorithm}:{h}")
if hashes: if hashes:
line += " \\\n" sep = " \\\n"
for i, h in enumerate(hashes): line += sep + sep.join(f" --hash={h}" for h in hashes)
line += " --hash={}{}".format(
h, " \\\n" if i < len(hashes) - 1 else ""
)
dependency_lines.add(line) dependency_lines.add(line)
content += "\n".join(sorted(dependency_lines)) content += "\n".join(sorted(dependency_lines))
......
...@@ -110,16 +110,14 @@ def get_package_version_display_string( ...@@ -110,16 +110,14 @@ def get_package_version_display_string(
package: "Package", root: Optional[Path] = None package: "Package", root: Optional[Path] = None
) -> str: ) -> str:
if package.source_type in ["file", "directory"] and root: if package.source_type in ["file", "directory"] and root:
return "{} {}".format( path = Path(os.path.relpath(package.source_url, root.as_posix())).as_posix()
package.version, return f"{package.version} {path}"
Path(os.path.relpath(package.source_url, root.as_posix())).as_posix(),
)
return package.full_pretty_version return package.full_pretty_version
def paths_csv(paths: List[Path]) -> str: def paths_csv(paths: List[Path]) -> str:
return ", ".join(f'"{str(c)}"' for c in paths) return ", ".join(f'"{c!s}"' for c in paths)
def is_dir_writable(path: Path, create: bool = False) -> bool: def is_dir_writable(path: Path, create: bool = False) -> bool:
...@@ -135,3 +133,9 @@ def is_dir_writable(path: Path, create: bool = False) -> bool: ...@@ -135,3 +133,9 @@ def is_dir_writable(path: Path, create: bool = False) -> bool:
return False return False
else: else:
return True return True
def pluralize(count: int, word: str = "") -> str:
if count == 1:
return word
return word + "s"
...@@ -61,9 +61,7 @@ class KeyRing: ...@@ -61,9 +61,7 @@ class KeyRing:
keyring.set_password(name, username, password) keyring.set_password(name, username, password)
except (RuntimeError, keyring.errors.KeyringError) as e: except (RuntimeError, keyring.errors.KeyringError) as e:
raise KeyRingError( raise KeyRingError(
"Unable to store the password for {} in the key ring: {}".format( f"Unable to store the password for {name} in the key ring: {e}"
name, str(e)
)
) )
def delete_password(self, name: str, username: str) -> None: def delete_password(self, name: str, username: str) -> None:
...@@ -89,7 +87,7 @@ class KeyRing: ...@@ -89,7 +87,7 @@ class KeyRing:
try: try:
import keyring import keyring
except Exception as e: except Exception as e:
logger.debug(f"An error occurred while importing keyring: {str(e)}") logger.debug(f"An error occurred while importing keyring: {e!s}")
self._is_available = False self._is_available = False
return return
......
...@@ -41,9 +41,8 @@ class SetupReader: ...@@ -41,9 +41,8 @@ class SetupReader:
if not filepath.exists(): if not filepath.exists():
continue continue
new_result = getattr(cls(), "read_{}".format(filename.replace(".", "_")))( read_file_func = getattr(cls(), "read_" + filename.replace(".", "_"))
filepath new_result = read_file_func(filepath)
)
for key in result.keys(): for key in result.keys():
if new_result[key]: if new_result[key]:
......
...@@ -309,7 +309,7 @@ def current_python(current_env: SystemEnv) -> Tuple[int, int, int]: ...@@ -309,7 +309,7 @@ def current_python(current_env: SystemEnv) -> Tuple[int, int, int]:
@pytest.fixture(scope="session") @pytest.fixture(scope="session")
def default_python(current_python: Tuple[int, int, int]) -> str: def default_python(current_python: Tuple[int, int, int]) -> str:
return "^{}".format(".".join(str(v) for v in current_python[:2])) return "^" + ".".join(str(v) for v in current_python[:2])
@pytest.fixture @pytest.fixture
......
...@@ -33,27 +33,21 @@ def tester(command_tester_factory: "CommandTesterFactory") -> "CommandTester": ...@@ -33,27 +33,21 @@ def tester(command_tester_factory: "CommandTesterFactory") -> "CommandTester":
def test_env_info_displays_complete_info(tester: "CommandTester"): def test_env_info_displays_complete_info(tester: "CommandTester"):
tester.execute() tester.execute()
expected = """ expected = f"""
Virtualenv Virtualenv
Python: 3.7.0 Python: 3.7.0
Implementation: CPython Implementation: CPython
Path: {prefix} Path: {Path('/prefix')}
Executable: {executable} Executable: {sys.executable}
Valid: True Valid: True
System System
Platform: darwin Platform: darwin
OS: posix OS: posix
Python: {base_version} Python: {'.'.join(str(v) for v in sys.version_info[:3])}
Path: {base_prefix} Path: {Path('/base/prefix')}
Executable: {base_executable} Executable: python
""".format( """
prefix=str(Path("/prefix")),
base_prefix=str(Path("/base/prefix")),
base_version=".".join(str(v) for v in sys.version_info[:3]),
executable=sys.executable,
base_executable="python",
)
assert expected == tester.io.fetch_output() assert expected == tester.io.fetch_output()
......
...@@ -82,14 +82,10 @@ def test_activate_activates_non_existing_virtualenv_no_envs_file( ...@@ -82,14 +82,10 @@ def test_activate_activates_non_existing_virtualenv_no_envs_file(
assert envs[venv_name]["minor"] == "3.7" assert envs[venv_name]["minor"] == "3.7"
assert envs[venv_name]["patch"] == "3.7.1" assert envs[venv_name]["patch"] == "3.7.1"
expected = """\ expected = f"""\
Creating virtualenv {} in {} Creating virtualenv {venv_py37.name} in {venv_py37.parent}
Using virtualenv: {} Using virtualenv: {venv_py37}
""".format( """
venv_py37.name,
venv_py37.parent,
venv_py37,
)
assert expected == tester.io.fetch_output() assert expected == tester.io.fetch_output()
...@@ -115,11 +111,9 @@ def test_get_prefers_explicitly_activated_virtualenvs_over_env_var( ...@@ -115,11 +111,9 @@ def test_get_prefers_explicitly_activated_virtualenvs_over_env_var(
tester.execute(python_minor) tester.execute(python_minor)
expected = """\ expected = f"""\
Using virtualenv: {} Using virtualenv: {venv_dir}
""".format( """
venv_dir
)
assert expected == tester.io.fetch_output() assert expected == tester.io.fetch_output()
...@@ -151,13 +145,9 @@ def test_get_prefers_explicitly_activated_non_existing_virtualenvs_over_env_var( ...@@ -151,13 +145,9 @@ def test_get_prefers_explicitly_activated_non_existing_virtualenvs_over_env_var(
tester.execute(python_minor) tester.execute(python_minor)
expected = """\ expected = f"""\
Creating virtualenv {} in {} Creating virtualenv {venv_dir.name} in {venv_dir.parent}
Using virtualenv: {} Using virtualenv: {venv_dir}
""".format( """
venv_dir.name,
venv_dir.parent,
venv_dir,
)
assert expected == tester.io.fetch_output() assert expected == tester.io.fetch_output()
...@@ -70,7 +70,7 @@ def test_self_update_can_update_from_recommended_installation( ...@@ -70,7 +70,7 @@ def test_self_update_can_update_from_recommended_installation(
tester.execute() tester.execute()
expected_output = """\ expected_output = f"""\
Updating Poetry to 1.2.0 Updating Poetry to 1.2.0
Updating dependencies Updating dependencies
...@@ -79,14 +79,12 @@ Resolving dependencies... ...@@ -79,14 +79,12 @@ Resolving dependencies...
Package operations: 0 installs, 2 updates, 0 removals Package operations: 0 installs, 2 updates, 0 removals
- Updating cleo (0.8.2 -> 1.0.0) - Updating cleo (0.8.2 -> 1.0.0)
- Updating poetry ({} -> {}) - Updating poetry ({__version__} -> {new_version})
Updating the poetry script Updating the poetry script
Poetry ({}) is installed now. Great! Poetry ({new_version}) is installed now. Great!
""".format( """
__version__, new_version, new_version
)
assert tester.io.fetch_output() == expected_output assert tester.io.fetch_output() == expected_output
......
...@@ -366,7 +366,7 @@ def test_add_directory_constraint( ...@@ -366,7 +366,7 @@ def test_add_directory_constraint(
path = "../git/github.com/demo/demo" path = "../git/github.com/demo/demo"
tester.execute(f"{path}" if not editable else f"-e {path}") tester.execute(f"{path}" if not editable else f"-e {path}")
expected = """\ expected = f"""\
Updating dependencies Updating dependencies
Resolving dependencies... Resolving dependencies...
...@@ -376,10 +376,8 @@ Writing lock file ...@@ -376,10 +376,8 @@ Writing lock file
Package operations: 2 installs, 0 updates, 0 removals Package operations: 2 installs, 0 updates, 0 removals
• Installing pendulum (1.4.4) • Installing pendulum (1.4.4)
• Installing demo (0.1.2 {}) • Installing demo (0.1.2 {app.poetry.file.parent.joinpath(path).resolve().as_posix()})
""".format( """
app.poetry.file.parent.joinpath(path).resolve().as_posix()
)
assert expected == tester.io.fetch_output() assert expected == tester.io.fetch_output()
assert tester.command.installer.executor.installations_count == 2 assert tester.command.installer.executor.installations_count == 2
...@@ -409,7 +407,7 @@ def test_add_directory_with_poetry( ...@@ -409,7 +407,7 @@ def test_add_directory_with_poetry(
path = "../git/github.com/demo/pyproject-demo" path = "../git/github.com/demo/pyproject-demo"
tester.execute(f"{path}") tester.execute(f"{path}")
expected = """\ expected = f"""\
Updating dependencies Updating dependencies
Resolving dependencies... Resolving dependencies...
...@@ -419,10 +417,8 @@ Writing lock file ...@@ -419,10 +417,8 @@ Writing lock file
Package operations: 2 installs, 0 updates, 0 removals Package operations: 2 installs, 0 updates, 0 removals
• Installing pendulum (1.4.4) • Installing pendulum (1.4.4)
• Installing demo (0.1.2 {}) • Installing demo (0.1.2 {app.poetry.file.parent.joinpath(path).resolve().as_posix()})
""".format( """
app.poetry.file.parent.joinpath(path).resolve().as_posix()
)
assert expected == tester.io.fetch_output() assert expected == tester.io.fetch_output()
assert tester.command.installer.executor.installations_count == 2 assert tester.command.installer.executor.installations_count == 2
...@@ -443,7 +439,7 @@ def test_add_file_constraint_wheel( ...@@ -443,7 +439,7 @@ def test_add_file_constraint_wheel(
path = "../distributions/demo-0.1.0-py2.py3-none-any.whl" path = "../distributions/demo-0.1.0-py2.py3-none-any.whl"
tester.execute(f"{path}") tester.execute(f"{path}")
expected = """\ expected = f"""\
Updating dependencies Updating dependencies
Resolving dependencies... Resolving dependencies...
...@@ -453,10 +449,8 @@ Writing lock file ...@@ -453,10 +449,8 @@ Writing lock file
Package operations: 2 installs, 0 updates, 0 removals Package operations: 2 installs, 0 updates, 0 removals
• Installing pendulum (1.4.4) • Installing pendulum (1.4.4)
• Installing demo (0.1.0 {}) • Installing demo (0.1.0 {app.poetry.file.parent.joinpath(path).resolve().as_posix()})
""".format( """
app.poetry.file.parent.joinpath(path).resolve().as_posix()
)
assert expected == tester.io.fetch_output() assert expected == tester.io.fetch_output()
assert tester.command.installer.executor.installations_count == 2 assert tester.command.installer.executor.installations_count == 2
...@@ -483,7 +477,7 @@ def test_add_file_constraint_sdist( ...@@ -483,7 +477,7 @@ def test_add_file_constraint_sdist(
path = "../distributions/demo-0.1.0.tar.gz" path = "../distributions/demo-0.1.0.tar.gz"
tester.execute(f"{path}") tester.execute(f"{path}")
expected = """\ expected = f"""\
Updating dependencies Updating dependencies
Resolving dependencies... Resolving dependencies...
...@@ -493,10 +487,8 @@ Writing lock file ...@@ -493,10 +487,8 @@ Writing lock file
Package operations: 2 installs, 0 updates, 0 removals Package operations: 2 installs, 0 updates, 0 removals
• Installing pendulum (1.4.4) • Installing pendulum (1.4.4)
• Installing demo (0.1.0 {}) • Installing demo (0.1.0 {app.poetry.file.parent.joinpath(path).resolve().as_posix()})
""".format( """
app.poetry.file.parent.joinpath(path).resolve().as_posix()
)
assert expected == tester.io.fetch_output() assert expected == tester.io.fetch_output()
assert tester.command.installer.executor.installations_count == 2 assert tester.command.installer.executor.installations_count == 2
...@@ -1305,7 +1297,7 @@ def test_add_directory_constraint_old_installer( ...@@ -1305,7 +1297,7 @@ def test_add_directory_constraint_old_installer(
path = "../git/github.com/demo/demo" path = "../git/github.com/demo/demo"
old_tester.execute(f"{path}") old_tester.execute(f"{path}")
expected = """\ expected = f"""\
Updating dependencies Updating dependencies
Resolving dependencies... Resolving dependencies...
...@@ -1315,10 +1307,8 @@ Writing lock file ...@@ -1315,10 +1307,8 @@ Writing lock file
Package operations: 2 installs, 0 updates, 0 removals Package operations: 2 installs, 0 updates, 0 removals
- Installing pendulum (1.4.4) - Installing pendulum (1.4.4)
- Installing demo (0.1.2 {}) - Installing demo (0.1.2 {app.poetry.file.parent.joinpath(path).resolve().as_posix()})
""".format( """
app.poetry.file.parent.joinpath(path).resolve().as_posix()
)
assert expected == old_tester.io.fetch_output() assert expected == old_tester.io.fetch_output()
...@@ -1345,7 +1335,7 @@ def test_add_directory_with_poetry_old_installer( ...@@ -1345,7 +1335,7 @@ def test_add_directory_with_poetry_old_installer(
path = "../git/github.com/demo/pyproject-demo" path = "../git/github.com/demo/pyproject-demo"
old_tester.execute(f"{path}") old_tester.execute(f"{path}")
expected = """\ expected = f"""\
Updating dependencies Updating dependencies
Resolving dependencies... Resolving dependencies...
...@@ -1355,10 +1345,8 @@ Writing lock file ...@@ -1355,10 +1345,8 @@ Writing lock file
Package operations: 2 installs, 0 updates, 0 removals Package operations: 2 installs, 0 updates, 0 removals
- Installing pendulum (1.4.4) - Installing pendulum (1.4.4)
- Installing demo (0.1.2 {}) - Installing demo (0.1.2 {app.poetry.file.parent.joinpath(path).resolve().as_posix()})
""".format( """
app.poetry.file.parent.joinpath(path).resolve().as_posix()
)
assert expected == old_tester.io.fetch_output() assert expected == old_tester.io.fetch_output()
...@@ -1380,7 +1368,7 @@ def test_add_file_constraint_wheel_old_installer( ...@@ -1380,7 +1368,7 @@ def test_add_file_constraint_wheel_old_installer(
path = "../distributions/demo-0.1.0-py2.py3-none-any.whl" path = "../distributions/demo-0.1.0-py2.py3-none-any.whl"
old_tester.execute(f"{path}") old_tester.execute(f"{path}")
expected = """\ expected = f"""\
Updating dependencies Updating dependencies
Resolving dependencies... Resolving dependencies...
...@@ -1390,10 +1378,8 @@ Writing lock file ...@@ -1390,10 +1378,8 @@ Writing lock file
Package operations: 2 installs, 0 updates, 0 removals Package operations: 2 installs, 0 updates, 0 removals
- Installing pendulum (1.4.4) - Installing pendulum (1.4.4)
- Installing demo (0.1.0 {}) - Installing demo (0.1.0 {app.poetry.file.parent.joinpath(path).resolve().as_posix()})
""".format( """
app.poetry.file.parent.joinpath(path).resolve().as_posix()
)
assert expected == old_tester.io.fetch_output() assert expected == old_tester.io.fetch_output()
...@@ -1422,7 +1408,7 @@ def test_add_file_constraint_sdist_old_installer( ...@@ -1422,7 +1408,7 @@ def test_add_file_constraint_sdist_old_installer(
path = "../distributions/demo-0.1.0.tar.gz" path = "../distributions/demo-0.1.0.tar.gz"
old_tester.execute(f"{path}") old_tester.execute(f"{path}")
expected = """\ expected = f"""\
Updating dependencies Updating dependencies
Resolving dependencies... Resolving dependencies...
...@@ -1432,10 +1418,8 @@ Writing lock file ...@@ -1432,10 +1418,8 @@ Writing lock file
Package operations: 2 installs, 0 updates, 0 removals Package operations: 2 installs, 0 updates, 0 removals
- Installing pendulum (1.4.4) - Installing pendulum (1.4.4)
- Installing demo (0.1.0 {}) - Installing demo (0.1.0 {app.poetry.file.parent.joinpath(path).resolve().as_posix()})
""".format( """
app.poetry.file.parent.joinpath(path).resolve().as_posix()
)
assert expected == old_tester.io.fetch_output() assert expected == old_tester.io.fetch_output()
......
...@@ -53,12 +53,10 @@ def test_cache_list( ...@@ -53,12 +53,10 @@ def test_cache_list(
): ):
tester.execute() tester.execute()
expected = """\ expected = f"""\
{} {repository_one}
{} {repository_two}
""".format( """
repository_one, repository_two
)
assert expected == tester.io.fetch_output() assert expected == tester.io.fetch_output()
......
...@@ -45,7 +45,9 @@ def test_list_displays_default_value_if_not_set( ...@@ -45,7 +45,9 @@ def test_list_displays_default_value_if_not_set(
): ):
tester.execute("--list") tester.execute("--list")
expected = """cache-dir = {cache} cache_dir = json.dumps(str(config_cache_dir))
venv_path = json.dumps(os.path.join("{cache-dir}", "virtualenvs"))
expected = f"""cache-dir = {cache_dir}
experimental.new-installer = true experimental.new-installer = true
installer.max-workers = null installer.max-workers = null
installer.parallel = true installer.parallel = true
...@@ -53,12 +55,8 @@ virtualenvs.create = true ...@@ -53,12 +55,8 @@ virtualenvs.create = true
virtualenvs.in-project = null virtualenvs.in-project = null
virtualenvs.options.always-copy = false virtualenvs.options.always-copy = false
virtualenvs.options.system-site-packages = false virtualenvs.options.system-site-packages = false
virtualenvs.path = {path} # {virtualenvs} virtualenvs.path = {venv_path} # {config_cache_dir / 'virtualenvs'}
""".format( """
cache=json.dumps(str(config_cache_dir)),
path=json.dumps(os.path.join("{cache-dir}", "virtualenvs")),
virtualenvs=str(config_cache_dir / "virtualenvs"),
)
assert expected == tester.io.fetch_output() assert expected == tester.io.fetch_output()
...@@ -70,7 +68,9 @@ def test_list_displays_set_get_setting( ...@@ -70,7 +68,9 @@ def test_list_displays_set_get_setting(
tester.execute("--list") tester.execute("--list")
expected = """cache-dir = {cache} cache_dir = json.dumps(str(config_cache_dir))
venv_path = json.dumps(os.path.join("{cache-dir}", "virtualenvs"))
expected = f"""cache-dir = {cache_dir}
experimental.new-installer = true experimental.new-installer = true
installer.max-workers = null installer.max-workers = null
installer.parallel = true installer.parallel = true
...@@ -78,12 +78,8 @@ virtualenvs.create = false ...@@ -78,12 +78,8 @@ virtualenvs.create = false
virtualenvs.in-project = null virtualenvs.in-project = null
virtualenvs.options.always-copy = false virtualenvs.options.always-copy = false
virtualenvs.options.system-site-packages = false virtualenvs.options.system-site-packages = false
virtualenvs.path = {path} # {virtualenvs} virtualenvs.path = {venv_path} # {config_cache_dir / 'virtualenvs'}
""".format( """
cache=json.dumps(str(config_cache_dir)),
path=json.dumps(os.path.join("{cache-dir}", "virtualenvs")),
virtualenvs=str(config_cache_dir / "virtualenvs"),
)
assert config.set_config_source.call_count == 0 assert config.set_config_source.call_count == 0
assert expected == tester.io.fetch_output() assert expected == tester.io.fetch_output()
...@@ -119,7 +115,9 @@ def test_list_displays_set_get_local_setting( ...@@ -119,7 +115,9 @@ def test_list_displays_set_get_local_setting(
tester.execute("--list") tester.execute("--list")
expected = """cache-dir = {cache} cache_dir = json.dumps(str(config_cache_dir))
venv_path = json.dumps(os.path.join("{cache-dir}", "virtualenvs"))
expected = f"""cache-dir = {cache_dir}
experimental.new-installer = true experimental.new-installer = true
installer.max-workers = null installer.max-workers = null
installer.parallel = true installer.parallel = true
...@@ -127,12 +125,8 @@ virtualenvs.create = false ...@@ -127,12 +125,8 @@ virtualenvs.create = false
virtualenvs.in-project = null virtualenvs.in-project = null
virtualenvs.options.always-copy = false virtualenvs.options.always-copy = false
virtualenvs.options.system-site-packages = false virtualenvs.options.system-site-packages = false
virtualenvs.path = {path} # {virtualenvs} virtualenvs.path = {venv_path} # {config_cache_dir / 'virtualenvs'}
""".format( """
cache=json.dumps(str(config_cache_dir)),
path=json.dumps(os.path.join("{cache-dir}", "virtualenvs")),
virtualenvs=str(config_cache_dir / "virtualenvs"),
)
assert config.set_config_source.call_count == 1 assert config.set_config_source.call_count == 1
assert expected == tester.io.fetch_output() assert expected == tester.io.fetch_output()
......
...@@ -180,7 +180,8 @@ def test_empty_license(tester: CommandTester): ...@@ -180,7 +180,8 @@ def test_empty_license(tester: CommandTester):
] ]
tester.execute(inputs="\n".join(inputs)) tester.execute(inputs="\n".join(inputs))
expected = """\ python = ".".join(str(c) for c in sys.version_info[:2])
expected = f"""\
[tool.poetry] [tool.poetry]
name = "my-package" name = "my-package"
version = "1.2.3" version = "1.2.3"
...@@ -191,9 +192,7 @@ packages = [{{include = "my_package"}}] ...@@ -191,9 +192,7 @@ packages = [{{include = "my_package"}}]
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = "^{python}" python = "^{python}"
""".format( """
python=".".join(str(c) for c in sys.version_info[:2])
)
assert expected in tester.io.fetch_output() assert expected in tester.io.fetch_output()
......
...@@ -216,8 +216,6 @@ class TestRepository(Repository): ...@@ -216,8 +216,6 @@ class TestRepository(Repository):
def find_links_for_package(self, package: Package) -> List[Link]: def find_links_for_package(self, package: Package) -> List[Link]:
return [ return [
Link( Link(
"https://foo.bar/files/{}-{}-py2.py3-none-any.whl".format( f"https://foo.bar/files/{escape_name(package.name)}-{escape_version(package.version.text)}-py2.py3-none-any.whl"
escape_name(package.name), escape_version(package.version.text)
)
) )
] ]
...@@ -83,9 +83,7 @@ def test_get_cache_directory_for_link(config: "Config", config_cache_dir: Path): ...@@ -83,9 +83,7 @@ def test_get_cache_directory_for_link(config: "Config", config_cache_dir: Path):
) )
expected = Path( expected = Path(
"{}/artifacts/ba/63/13/283a3b3b7f95f05e9e6f84182d276f7bb0951d5b0cc24422b33f7a4648".format( f"{config_cache_dir.as_posix()}/artifacts/ba/63/13/283a3b3b7f95f05e9e6f84182d276f7bb0951d5b0cc24422b33f7a4648"
config_cache_dir.as_posix()
)
) )
assert expected == directory assert expected == directory
...@@ -161,18 +161,16 @@ def test_execute_executes_a_batch_of_operations( ...@@ -161,18 +161,16 @@ def test_execute_executes_a_batch_of_operations(
] ]
) )
expected = """ expected = f"""
Package operations: 4 installs, 1 update, 1 removal Package operations: 4 installs, 1 update, 1 removal
• Installing pytest (3.5.2) • Installing pytest (3.5.2)
• Removing attrs (17.4.0) • Removing attrs (17.4.0)
• Updating requests (2.18.3 -> 2.18.4) • Updating requests (2.18.3 -> 2.18.4)
• Installing demo (0.1.0 {}) • Installing demo (0.1.0 {file_package.source_url})
• Installing simple-project (1.2.3 {}) • Installing simple-project (1.2.3 {directory_package.source_url})
• Installing demo (0.1.0 master) • Installing demo (0.1.0 master)
""".format( """
file_package.source_url, directory_package.source_url
)
expected = set(expected.splitlines()) expected = set(expected.splitlines())
output = set(io.fetch_output().splitlines()) output = set(io.fetch_output().splitlines())
......
...@@ -152,42 +152,36 @@ My Package ...@@ -152,42 +152,36 @@ My Package
assert str(dist_info.joinpath("entry_points.txt")) in records assert str(dist_info.joinpath("entry_points.txt")) in records
assert str(dist_info.joinpath("RECORD")) in records assert str(dist_info.joinpath("RECORD")) in records
baz_script = """\ baz_script = f"""\
#!{python} #!{tmp_venv.python}
import sys import sys
from bar import baz from bar import baz
if __name__ == '__main__': if __name__ == '__main__':
sys.exit(baz.boom.bim()) sys.exit(baz.boom.bim())
""".format( """
python=tmp_venv.python
)
assert baz_script == tmp_venv._bin_dir.joinpath("baz").read_text() assert baz_script == tmp_venv._bin_dir.joinpath("baz").read_text()
foo_script = """\ foo_script = f"""\
#!{python} #!{tmp_venv.python}
import sys import sys
from foo import bar from foo import bar
if __name__ == '__main__': if __name__ == '__main__':
sys.exit(bar()) sys.exit(bar())
""".format( """
python=tmp_venv.python
)
assert foo_script == tmp_venv._bin_dir.joinpath("foo").read_text() assert foo_script == tmp_venv._bin_dir.joinpath("foo").read_text()
fox_script = """\ fox_script = f"""\
#!{python} #!{tmp_venv.python}
import sys import sys
from fuz.foo import bar from fuz.foo import bar
if __name__ == '__main__': if __name__ == '__main__':
sys.exit(bar.baz()) sys.exit(bar.baz())
""".format( """
python=tmp_venv.python
)
assert fox_script == tmp_venv._bin_dir.joinpath("fox").read_text() assert fox_script == tmp_venv._bin_dir.joinpath("fox").read_text()
......
...@@ -430,18 +430,15 @@ A = [] ...@@ -430,18 +430,15 @@ A = []
def test_locker_should_emit_warnings_if_lock_version_is_newer_but_allowed( def test_locker_should_emit_warnings_if_lock_version_is_newer_but_allowed(
locker: Locker, caplog: "LogCaptureFixture" locker: Locker, caplog: "LogCaptureFixture"
): ):
content = """\ version = ".".join(Version.parse(Locker._VERSION).next_minor().text.split(".")[:2])
content = f"""\
[metadata] [metadata]
lock-version = "{version}" lock-version = "{version}"
python-versions = "~2.7 || ^3.4" python-versions = "~2.7 || ^3.4"
content-hash = "c3d07fca33fba542ef2b2a4d75bf5b48d892d21a830e2ad9c952ba5123a52f77" content-hash = "c3d07fca33fba542ef2b2a4d75bf5b48d892d21a830e2ad9c952ba5123a52f77"
[metadata.files] [metadata.files]
""".format( """
version=".".join(
Version.parse(Locker._VERSION).next_minor().text.split(".")[:2]
)
)
caplog.set_level(logging.WARNING, logger="poetry.packages.locker") caplog.set_level(logging.WARNING, logger="poetry.packages.locker")
locker.lock.write(tomlkit.parse(content)) locker.lock.write(tomlkit.parse(content))
...@@ -524,16 +521,14 @@ def test_locker_should_neither_emit_warnings_nor_raise_error_for_lower_compatibl ...@@ -524,16 +521,14 @@ def test_locker_should_neither_emit_warnings_nor_raise_error_for_lower_compatibl
older_version = ".".join( older_version = ".".join(
[str(current_version.major), str(current_version.minor - 1)] [str(current_version.major), str(current_version.minor - 1)]
) )
content = """\ content = f"""\
[metadata] [metadata]
lock-version = "{version}" lock-version = "{older_version}"
python-versions = "~2.7 || ^3.4" python-versions = "~2.7 || ^3.4"
content-hash = "c3d07fca33fba542ef2b2a4d75bf5b48d892d21a830e2ad9c952ba5123a52f77" content-hash = "c3d07fca33fba542ef2b2a4d75bf5b48d892d21a830e2ad9c952ba5123a52f77"
[metadata.files] [metadata.files]
""".format( """
version=older_version
)
caplog.set_level(logging.WARNING, logger="poetry.packages.locker") caplog.set_level(logging.WARNING, logger="poetry.packages.locker")
locker.lock.write(tomlkit.parse(content)) locker.lock.write(tomlkit.parse(content))
......
...@@ -207,7 +207,7 @@ def test_authenticator_request_retries_on_exception( ...@@ -207,7 +207,7 @@ def test_authenticator_request_retries_on_exception(
mocker: "MockerFixture", config: "Config", http: Type[httpretty.httpretty] mocker: "MockerFixture", config: "Config", http: Type[httpretty.httpretty]
): ):
sleep = mocker.patch("time.sleep") sleep = mocker.patch("time.sleep")
sdist_uri = f"https://foo.bar/files/{str(uuid.uuid4())}/foo-0.1.0.tar.gz" sdist_uri = f"https://foo.bar/files/{uuid.uuid4()!s}/foo-0.1.0.tar.gz"
content = str(uuid.uuid4()) content = str(uuid.uuid4())
seen = [] seen = []
...@@ -232,7 +232,7 @@ def test_authenticator_request_raises_exception_when_attempts_exhausted( ...@@ -232,7 +232,7 @@ def test_authenticator_request_raises_exception_when_attempts_exhausted(
mocker: "MockerFixture", config: "Config", http: Type[httpretty.httpretty] mocker: "MockerFixture", config: "Config", http: Type[httpretty.httpretty]
): ):
sleep = mocker.patch("time.sleep") sleep = mocker.patch("time.sleep")
sdist_uri = f"https://foo.bar/files/{str(uuid.uuid4())}/foo-0.1.0.tar.gz" sdist_uri = f"https://foo.bar/files/{uuid.uuid4()!s}/foo-0.1.0.tar.gz"
def callback(*_: Any, **___: Any) -> None: def callback(*_: Any, **___: Any) -> None:
raise requests.exceptions.ConnectionError(str(uuid.uuid4())) raise requests.exceptions.ConnectionError(str(uuid.uuid4()))
...@@ -267,7 +267,7 @@ def test_authenticator_request_retries_on_status_code( ...@@ -267,7 +267,7 @@ def test_authenticator_request_retries_on_status_code(
attempts: int, attempts: int,
): ):
sleep = mocker.patch("time.sleep") sleep = mocker.patch("time.sleep")
sdist_uri = f"https://foo.bar/files/{str(uuid.uuid4())}/foo-0.1.0.tar.gz" sdist_uri = f"https://foo.bar/files/{uuid.uuid4()!s}/foo-0.1.0.tar.gz"
content = str(uuid.uuid4()) content = str(uuid.uuid4())
def callback( def callback(
......
...@@ -470,10 +470,8 @@ def test_deactivate_non_activated_but_existing( ...@@ -470,10 +470,8 @@ def test_deactivate_non_activated_but_existing(
venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent)) venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent))
( python = ".".join(str(c) for c in sys.version_info[:2])
Path(tmp_dir) (Path(tmp_dir) / f"{venv_name}-py{python}").mkdir()
/ "{}-py{}".format(venv_name, ".".join(str(c) for c in sys.version_info[:2]))
).mkdir()
config.merge({"virtualenvs": {"path": str(tmp_dir)}}) config.merge({"virtualenvs": {"path": str(tmp_dir)}})
...@@ -485,9 +483,7 @@ def test_deactivate_non_activated_but_existing( ...@@ -485,9 +483,7 @@ def test_deactivate_non_activated_but_existing(
manager.deactivate(NullIO()) manager.deactivate(NullIO())
env = manager.get() env = manager.get()
assert env.path == Path(tmp_dir) / "{}-py{}".format( assert env.path == Path(tmp_dir) / f"{venv_name}-py{python}"
venv_name, ".".join(str(c) for c in sys.version_info[:2])
)
assert Path("/prefix") assert Path("/prefix")
...@@ -502,7 +498,7 @@ def test_deactivate_activated( ...@@ -502,7 +498,7 @@ def test_deactivate_activated(
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent)) venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent))
version = Version.parse(".".join(str(c) for c in sys.version_info[:3])) version = Version.from_parts(*sys.version_info[:3])
other_version = Version.parse("3.4") if version.major == 2 else version.next_minor() other_version = Version.parse("3.4") if version.major == 2 else version.next_minor()
(Path(tmp_dir) / f"{venv_name}-py{version.major}.{version.minor}").mkdir() (Path(tmp_dir) / f"{venv_name}-py{version.major}.{version.minor}").mkdir()
( (
...@@ -527,9 +523,7 @@ def test_deactivate_activated( ...@@ -527,9 +523,7 @@ def test_deactivate_activated(
manager.deactivate(NullIO()) manager.deactivate(NullIO())
env = manager.get() env = manager.get()
assert env.path == Path(tmp_dir) / "{}-py{}.{}".format( assert env.path == Path(tmp_dir) / f"{venv_name}-py{version.major}.{version.minor}"
venv_name, version.major, version.minor
)
assert Path("/prefix") assert Path("/prefix")
envs = envs_file.read() envs = envs_file.read()
...@@ -928,9 +922,9 @@ def test_create_venv_uses_patch_version_to_detect_compatibility( ...@@ -928,9 +922,9 @@ def test_create_venv_uses_patch_version_to_detect_compatibility(
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
version = Version.parse(".".join(str(c) for c in sys.version_info[:3])) version = Version.from_parts(*sys.version_info[:3])
poetry.package.python_versions = "^{}".format( poetry.package.python_versions = "^" + ".".join(
".".join(str(c) for c in sys.version_info[:3]) str(c) for c in sys.version_info[:3]
) )
venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent)) venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent))
...@@ -966,10 +960,8 @@ def test_create_venv_uses_patch_version_to_detect_compatibility_with_executable( ...@@ -966,10 +960,8 @@ def test_create_venv_uses_patch_version_to_detect_compatibility_with_executable(
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
version = Version.parse(".".join(str(c) for c in sys.version_info[:3])) version = Version.from_parts(*sys.version_info[:3])
poetry.package.python_versions = "~{}".format( poetry.package.python_versions = f"~{version.major}.{version.minor-1}.0"
".".join(str(c) for c in (version.major, version.minor - 1, 0))
)
venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent)) venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent))
check_output = mocker.patch( check_output = mocker.patch(
...@@ -1087,16 +1079,10 @@ def test_env_finds_the_correct_executables(tmp_dir: str, manager: EnvManager): ...@@ -1087,16 +1079,10 @@ def test_env_finds_the_correct_executables(tmp_dir: str, manager: EnvManager):
manager.build_venv(str(venv_path), with_pip=True) manager.build_venv(str(venv_path), with_pip=True)
venv = VirtualEnv(venv_path) venv = VirtualEnv(venv_path)
default_executable = expected_executable = "python" + (".exe" if WINDOWS else "") default_executable = expected_executable = f"python{'.exe' if WINDOWS else ''}"
default_pip_executable = expected_pip_executable = "pip" + ( default_pip_executable = expected_pip_executable = f"pip{'.exe' if WINDOWS else ''}"
".exe" if WINDOWS else "" major_executable = f"python{sys.version_info[0]}{'.exe' if WINDOWS else ''}"
) major_pip_executable = f"pip{sys.version_info[0]}{'.exe' if WINDOWS else ''}"
major_executable = "python{}{}".format(
sys.version_info[0], ".exe" if WINDOWS else ""
)
major_pip_executable = "pip{}{}".format(
sys.version_info[0], ".exe" if WINDOWS else ""
)
if ( if (
venv._bin_dir.joinpath(default_executable).exists() venv._bin_dir.joinpath(default_executable).exists()
...@@ -1130,11 +1116,11 @@ def test_env_finds_the_correct_executables_for_generic_env( ...@@ -1130,11 +1116,11 @@ def test_env_finds_the_correct_executables_for_generic_env(
) )
venv = GenericEnv(parent_venv.path, child_env=VirtualEnv(child_venv_path)) venv = GenericEnv(parent_venv.path, child_env=VirtualEnv(child_venv_path))
expected_executable = "python{}.{}{}".format( expected_executable = (
sys.version_info[0], sys.version_info[1], ".exe" if WINDOWS else "" f"python{sys.version_info[0]}.{sys.version_info[1]}{'.exe' if WINDOWS else ''}"
) )
expected_pip_executable = "pip{}.{}{}".format( expected_pip_executable = (
sys.version_info[0], sys.version_info[1], ".exe" if WINDOWS else "" f"pip{sys.version_info[0]}.{sys.version_info[1]}{'.exe' if WINDOWS else ''}"
) )
if WINDOWS: if WINDOWS:
...@@ -1157,12 +1143,10 @@ def test_env_finds_fallback_executables_for_generic_env( ...@@ -1157,12 +1143,10 @@ def test_env_finds_fallback_executables_for_generic_env(
) )
venv = GenericEnv(parent_venv.path, child_env=VirtualEnv(child_venv_path)) venv = GenericEnv(parent_venv.path, child_env=VirtualEnv(child_venv_path))
default_executable = "python" + (".exe" if WINDOWS else "") default_executable = f"python{'.exe' if WINDOWS else ''}"
major_executable = "python{}{}".format( major_executable = f"python{sys.version_info[0]}{'.exe' if WINDOWS else ''}"
sys.version_info[0], ".exe" if WINDOWS else "" minor_executable = (
) f"python{sys.version_info[0]}.{sys.version_info[1]}{'.exe' if WINDOWS else ''}"
minor_executable = "python{}.{}{}".format(
sys.version_info[0], sys.version_info[1], ".exe" if WINDOWS else ""
) )
expected_executable = minor_executable expected_executable = minor_executable
if ( if (
...@@ -1179,12 +1163,10 @@ def test_env_finds_fallback_executables_for_generic_env( ...@@ -1179,12 +1163,10 @@ def test_env_finds_fallback_executables_for_generic_env(
venv._bin_dir.joinpath(expected_executable).unlink() venv._bin_dir.joinpath(expected_executable).unlink()
expected_executable = default_executable expected_executable = default_executable
default_pip_executable = "pip" + (".exe" if WINDOWS else "") default_pip_executable = f"pip{'.exe' if WINDOWS else ''}"
major_pip_executable = "pip{}{}".format( major_pip_executable = f"pip{sys.version_info[0]}{'.exe' if WINDOWS else ''}"
sys.version_info[0], ".exe" if WINDOWS else "" minor_pip_executable = (
) f"pip{sys.version_info[0]}.{sys.version_info[1]}{'.exe' if WINDOWS else ''}"
minor_pip_executable = "pip{}.{}{}".format(
sys.version_info[0], sys.version_info[1], ".exe" if WINDOWS else ""
) )
expected_pip_executable = minor_pip_executable expected_pip_executable = minor_pip_executable
if ( if (
......
...@@ -1125,11 +1125,9 @@ def test_exporter_can_export_requirements_txt_with_directory_packages( ...@@ -1125,11 +1125,9 @@ def test_exporter_can_export_requirements_txt_with_directory_packages(
with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f: with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
content = f.read() content = f.read()
expected = """\ expected = f"""\
foo @ {}/tests/fixtures/sample_project foo @ {working_directory.as_uri()}/tests/fixtures/sample_project
""".format( """
working_directory.as_uri()
)
assert expected == content assert expected == content
...@@ -1193,15 +1191,11 @@ def test_exporter_can_export_requirements_txt_with_nested_directory_packages( ...@@ -1193,15 +1191,11 @@ def test_exporter_can_export_requirements_txt_with_nested_directory_packages(
with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f: with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
content = f.read() content = f.read()
expected = """\ expected = f"""\
bar @ {}/tests/fixtures/project_with_nested_local/bar bar @ {working_directory.as_uri()}/tests/fixtures/project_with_nested_local/bar
baz @ {}/tests/fixtures/project_with_nested_local baz @ {working_directory.as_uri()}/tests/fixtures/project_with_nested_local
foo @ {}/tests/fixtures/sample_project foo @ {working_directory.as_uri()}/tests/fixtures/sample_project
""".format( """
working_directory.as_uri(),
working_directory.as_uri(),
working_directory.as_uri(),
)
assert expected == content assert expected == content
...@@ -1242,11 +1236,9 @@ def test_exporter_can_export_requirements_txt_with_directory_packages_and_marker ...@@ -1242,11 +1236,9 @@ def test_exporter_can_export_requirements_txt_with_directory_packages_and_marker
with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f: with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
content = f.read() content = f.read()
expected = """\ expected = f"""\
foo @ {}/tests/fixtures/sample_project ; python_version < "3.7" foo @ {working_directory.as_uri()}/tests/fixtures/sample_project ; python_version < "3.7"
""".format( """
working_directory.as_uri()
)
assert expected == content assert expected == content
...@@ -1286,11 +1278,9 @@ def test_exporter_can_export_requirements_txt_with_file_packages( ...@@ -1286,11 +1278,9 @@ def test_exporter_can_export_requirements_txt_with_file_packages(
with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f: with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
content = f.read() content = f.read()
expected = """\ expected = f"""\
foo @ {}/tests/fixtures/distributions/demo-0.1.0.tar.gz foo @ {working_directory.as_uri()}/tests/fixtures/distributions/demo-0.1.0.tar.gz
""".format( """
working_directory.as_uri()
)
assert expected == content assert expected == content
...@@ -1331,11 +1321,9 @@ def test_exporter_can_export_requirements_txt_with_file_packages_and_markers( ...@@ -1331,11 +1321,9 @@ def test_exporter_can_export_requirements_txt_with_file_packages_and_markers(
with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f: with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
content = f.read() content = f.read()
expected = """\ expected = f"""\
foo @ {}/tests/fixtures/distributions/demo-0.1.0.tar.gz ; python_version < "3.7" foo @ {working_directory.as_uri()}/tests/fixtures/distributions/demo-0.1.0.tar.gz ; python_version < "3.7"
""".format( """
working_directory.as_uri()
)
assert expected == content assert expected == content
...@@ -1570,7 +1558,7 @@ def test_exporter_exports_requirements_txt_with_dev_extras( ...@@ -1570,7 +1558,7 @@ def test_exporter_exports_requirements_txt_with_dev_extras(
with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f: with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
content = f.read() content = f.read()
assert content == "{}\n".format("\n".join(expected)) assert content == "\n".join(expected) + "\n"
def test_exporter_exports_requirements_txt_with_legacy_packages_and_duplicate_sources( def test_exporter_exports_requirements_txt_with_legacy_packages_and_duplicate_sources(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment