Commit ecb030e1 by Stijn de Gooijer Committed by GitHub

Wrap long lines to comply with flake8 E501 (#4985)

* Update flake8 settings

* Add poetry to isort namespace packages

* Ignore flake8 E501 for long test names

* Run automatic string formatting on tests

* Run automatic string formatting on src

* Fix typo "already exits"

* Ignore long URLs, hashes, and paths

* Fix in-line comments

* Fix in-line comments in tests

* Fix docstrings

* Ignore misc

* Fix f-strings in src

* Fix f-strings in tests

* Fix multi-line strings in src

* Fix multi-line strings in tests

* Fix some oddly autoformatted code

* Replace some strings by multi-line strings

* Revert namespace change

* Add black string processing to pre-commit

* Move black pre-commit config to pyproject.toml

* Autoformat install scripts

* Manual line wrapping for install scripts

* Disable black formatting for expected strings

* Replace strings by constant
parent b5279e02
...@@ -12,8 +12,6 @@ enable-extensions = TC, TC2 ...@@ -12,8 +12,6 @@ enable-extensions = TC, TC2
type-checking-exempt-modules = typing, typing-extensions type-checking-exempt-modules = typing, typing-extensions
eradicate-whitelist-extend = ^-.*; eradicate-whitelist-extend = ^-.*;
extend-ignore = extend-ignore =
# E501: Line too long (FIXME: long string constants)
E501,
# E203: Whitespace before ':' (pycqa/pycodestyle#373) # E203: Whitespace before ':' (pycqa/pycodestyle#373)
E203, E203,
# SIM106: Handle error-cases first # SIM106: Handle error-cases first
......
...@@ -458,11 +458,11 @@ class Installer: ...@@ -458,11 +458,11 @@ class Installer:
print( print(
colorize( colorize(
"error", "error",
"Version {version} does not support this installation method. Please specify a version prior to " "Version {version} does not support this installation method."
"1.2.0a1 explicitly using the '--version' option.\n" " Please specify a version prior to 1.2.0a1 explicitly using the"
"Please see " " '--version' option.\nPlease see"
"https://python-poetry.org/blog/announcing-poetry-1-2-0a1.html#deprecation-of-the-get-poetry-py-script " " https://python-poetry.org/blog/announcing-poetry-1-2-0a1.html#deprecation-of-the-get-poetry-py-script"
"for more information.".format(version=version), " for more information.".format(version=version),
) )
) )
return None, None return None, None
...@@ -470,9 +470,9 @@ class Installer: ...@@ -470,9 +470,9 @@ class Installer:
print( print(
colorize( colorize(
"warning", "warning",
"This installer is deprecated. " "This installer is deprecated. Poetry versions installed using this"
"Poetry versions installed using this script will not be able to use 'self update' command to upgrade to " " script will not be able to use 'self update' command to upgrade to"
"1.2.0a1 or later.", " 1.2.0a1 or later.",
) )
) )
...@@ -685,7 +685,8 @@ class Installer: ...@@ -685,7 +685,8 @@ class Installer:
return executable return executable
if fallback is None: if fallback is None:
# keep this one as the fallback; it was the first valid executable we found. # keep this one as the fallback; it was the first valid executable we
# found.
fallback = executable fallback = executable
if fallback is None: if fallback is None:
...@@ -773,7 +774,8 @@ class Installer: ...@@ -773,7 +774,8 @@ class Installer:
print( print(
colorize( colorize(
"warning", "warning",
"\nUnable to get the PATH value. It will not be updated automatically.", "\nUnable to get the PATH value. It will not be updated"
" automatically.",
) )
) )
self._modify_path = False self._modify_path = False
...@@ -808,7 +810,8 @@ class Installer: ...@@ -808,7 +810,8 @@ class Installer:
print( print(
colorize( colorize(
"warning", "warning",
"Unable to get the PATH value. It will not be updated automatically", "Unable to get the PATH value. It will not be updated"
" automatically",
) )
) )
self._modify_path = False self._modify_path = False
...@@ -1074,8 +1077,10 @@ def main(): ...@@ -1074,8 +1077,10 @@ def main():
"--file", "--file",
dest="file", dest="file",
action="store", action="store",
help="Install from a local file instead of fetching the latest version " help=(
"of Poetry available online.", "Install from a local file instead of fetching the latest version "
"of Poetry available online."
),
) )
args = parser.parse_args() args = parser.parse_args()
......
...@@ -273,7 +273,8 @@ class PoetryInstallationError(RuntimeError): ...@@ -273,7 +273,8 @@ class PoetryInstallationError(RuntimeError):
class VirtualEnvironment: class VirtualEnvironment:
def __init__(self, path: Path) -> None: def __init__(self, path: Path) -> None:
self._path = path self._path = path
# str is required for compatibility with subprocess run on CPython <= 3.7 on Windows # str is required for compatibility with subprocess run on CPython <= 3.7 on
# Windows
self._python = str( self._python = str(
self._path.joinpath("Scripts/python.exe" if WINDOWS else "bin/python") self._path.joinpath("Scripts/python.exe" if WINDOWS else "bin/python")
) )
...@@ -313,7 +314,8 @@ class VirtualEnvironment: ...@@ -313,7 +314,8 @@ class VirtualEnvironment:
env = cls(target) env = cls(target)
# we do this here to ensure that outdated system default pip does not trigger older bugs # we do this here to ensure that outdated system default pip does not trigger
# older bugs
env.pip("install", "--disable-pip-version-check", "--upgrade", "pip") env.pip("install", "--disable-pip-version-check", "--upgrade", "pip")
return env return env
...@@ -480,7 +482,8 @@ class Installer: ...@@ -480,7 +482,8 @@ class Installer:
mx = self.VERSION_REGEX.match(x) mx = self.VERSION_REGEX.match(x)
if mx is None: if mx is None:
# the version is not semver, perhaps scm or file, we assume upgrade is supported # the version is not semver, perhaps scm or file, we assume upgrade is
# supported
return True return True
vx = tuple(int(p) for p in mx.groups()[:3]) + (mx.group(5),) vx = tuple(int(p) for p in mx.groups()[:3]) + (mx.group(5),)
...@@ -490,8 +493,9 @@ class Installer: ...@@ -490,8 +493,9 @@ class Installer:
self._write( self._write(
colorize( colorize(
"warning", "warning",
f"You are installing {version}. When using the current installer, this version does not support " f"You are installing {version}. When using the current installer,"
f"updating using the 'self update' command. Please use 1.1.7 or later.", " this version does not support updating using the 'self update'"
" command. Please use 1.1.7 or later.",
) )
) )
if not self._accept_all: if not self._accept_all:
...@@ -883,7 +887,10 @@ def main(): ...@@ -883,7 +887,10 @@ def main():
text=True, text=True,
) )
installer._write(colorize("error", f"See {path} for error logs.")) installer._write(colorize("error", f"See {path} for error logs."))
text = f"{e.log}\nTraceback:\n\n{''.join(traceback.format_tb(e.__traceback__))}" text = (
f"{e.log}\n"
f"Traceback:\n\n{''.join(traceback.format_tb(e.__traceback__))}"
)
Path(path).write_text(text) Path(path).write_text(text)
return e.return_code return e.return_code
...@@ -893,8 +900,9 @@ if __name__ == "__main__": ...@@ -893,8 +900,9 @@ if __name__ == "__main__":
sys.stdout.write( sys.stdout.write(
colorize( colorize(
"warning", "warning",
"The canonical source for Poetry's installation script is now https://install.python-poetry.org. " "The canonical source for Poetry's installation script is now"
"Please update your usage to reflect this.\n", " https://install.python-poetry.org. Please update your usage to reflect"
" this.\n",
) )
) )
sys.exit(main()) sys.exit(main())
...@@ -89,6 +89,7 @@ extend_skip = ["setup.py"] ...@@ -89,6 +89,7 @@ extend_skip = ["setup.py"]
[tool.black] [tool.black]
target-version = ['py36'] target-version = ['py36']
experimental_string_processing = true
force-exclude = ''' force-exclude = '''
.*/setup\.py$ .*/setup\.py$
''' '''
......
__path__ = __import__("pkgutil").extend_path(__path__, __name__) # type: ignore[has-type] __path__ = __import__("pkgutil").extend_path(__path__, __name__) # type: ignore[has-type] # noqa: E501
...@@ -353,7 +353,7 @@ class Application(BaseApplication): ...@@ -353,7 +353,7 @@ class Application(BaseApplication):
SolutionProviderRepository, SolutionProviderRepository,
) )
from poetry.mixology.solutions.providers.python_requirement_solution_provider import ( from poetry.mixology.solutions.providers.python_requirement_solution_provider import ( # noqa: E501
PythonRequirementSolutionProvider, PythonRequirementSolutionProvider,
) )
......
...@@ -9,8 +9,11 @@ class AboutCommand(Command): ...@@ -9,8 +9,11 @@ class AboutCommand(Command):
def handle(self) -> None: def handle(self) -> None:
self.line( self.line(
"""<info>Poetry - Package Management for Python</info> """\
<info>Poetry - Package Management for Python</info>
<comment>Poetry is a dependency manager tracking local dependencies of your projects and libraries. <comment>Poetry is a dependency manager tracking local dependencies of your projects\
See <fg=blue>https://github.com/python-poetry/poetry</> for more information.</comment>""" and libraries.
See <fg=blue>https://github.com/python-poetry/poetry</> for more information.</comment>\
"""
) )
...@@ -54,24 +54,31 @@ class AddCommand(InstallerCommand, InitCommand): ...@@ -54,24 +54,31 @@ class AddCommand(InstallerCommand, InitCommand):
option( option(
"dry-run", "dry-run",
None, None,
"Output the operations but do not execute anything (implicitly enables --verbose).", "Output the operations but do not execute anything (implicitly enables"
" --verbose).",
), ),
option("lock", None, "Do not perform operations (only update the lockfile)."), option("lock", None, "Do not perform operations (only update the lockfile)."),
] ]
help = ( help = """\
"The add command adds required packages to your <comment>pyproject.toml</> and installs them.\n\n" The add command adds required packages to your <comment>pyproject.toml</> and installs\
"If you do not specify a version constraint, poetry will choose a suitable one based on the available package versions.\n\n" them.
"You can specify a package in the following forms:\n"
" - A single name (<b>requests</b>)\n" If you do not specify a version constraint, poetry will choose a suitable one based on\
" - A name and a constraint (<b>requests@^2.23.0</b>)\n" the available package versions.
" - A git url (<b>git+https://github.com/python-poetry/poetry.git</b>)\n"
" - A git url with a revision (<b>git+https://github.com/python-poetry/poetry.git#develop</b>)\n" You can specify a package in the following forms:
" - A git SSH url (<b>git+ssh://github.com/python-poetry/poetry.git</b>)\n" - A single name (<b>requests</b>)
" - A git SSH url with a revision (<b>git+ssh://github.com/python-poetry/poetry.git#develop</b>)\n" - A name and a constraint (<b>requests@^2.23.0</b>)
" - A file path (<b>../my-package/my-package.whl</b>)\n" - A git url (<b>git+https://github.com/python-poetry/poetry.git</b>)
" - A directory (<b>../my-package/</b>)\n" - A git url with a revision\
" - A url (<b>https://example.com/packages/my-package-0.1.0.tar.gz</b>)\n" (<b>git+https://github.com/python-poetry/poetry.git#develop</b>)
) - A git SSH url (<b>git+ssh://github.com/python-poetry/poetry.git</b>)
- A git SSH url with a revision\
(<b>git+ssh://github.com/python-poetry/poetry.git#develop</b>)
- A file path (<b>../my-package/my-package.whl</b>)
- A directory (<b>../my-package/</b>)
- A url (<b>https://example.com/packages/my-package-0.1.0.tar.gz</b>)
"""
loggers = ["poetry.repositories.pypi_repository", "poetry.inspection.info"] loggers = ["poetry.repositories.pypi_repository", "poetry.inspection.info"]
...@@ -244,11 +251,13 @@ class AddCommand(InstallerCommand, InitCommand): ...@@ -244,11 +251,13 @@ class AddCommand(InstallerCommand, InitCommand):
def notify_about_existing_packages(self, existing_packages: List[str]) -> None: def notify_about_existing_packages(self, existing_packages: List[str]) -> None:
self.line( self.line(
"The following packages are already present in the pyproject.toml and will be skipped:\n" "The following packages are already present in the pyproject.toml and will"
" be skipped:\n"
) )
for name in existing_packages: for name in existing_packages:
self.line(f" • <c1>{name}</c1>") self.line(f" • <c1>{name}</c1>")
self.line( self.line(
"\nIf you want to update it to the latest compatible version, you can use `poetry update package`.\n" "\nIf you want to update it to the latest compatible version, you can use"
"If you prefer to upgrade it to the latest available version, you can use `poetry add package@latest`.\n" " `poetry update package`.\nIf you prefer to upgrade it to the latest"
" available version, you can use `poetry add package@latest`.\n"
) )
...@@ -42,8 +42,7 @@ class CacheClearCommand(Command): ...@@ -42,8 +42,7 @@ class CacheClearCommand(Command):
if len(parts) == 1: if len(parts) == 1:
if not self.option("all"): if not self.option("all"):
raise RuntimeError( raise RuntimeError(
"Add the --all option if you want to clear all " f"Add the --all option if you want to clear all {parts[0]} caches"
f"{parts[0]} caches"
) )
if not os.path.exists(str(cache_dir)): if not os.path.exists(str(cache_dir)):
......
...@@ -40,12 +40,15 @@ class EnvInfoCommand(Command): ...@@ -40,12 +40,15 @@ class EnvInfoCommand(Command):
listing = [ listing = [
f"<info>Python</info>: <comment>{env_python_version}</>", f"<info>Python</info>: <comment>{env_python_version}</>",
f"<info>Implementation</info>: <comment>{env.python_implementation}</>", f"<info>Implementation</info>: <comment>{env.python_implementation}</>",
f"<info>Path</info>: <comment>{env.path if env.is_venv() else 'NA'}</>", "<info>Path</info>: "
f"<info>Executable</info>: <comment>{env.python if env.is_venv() else 'NA'}</>", f" <comment>{env.path if env.is_venv() else 'NA'}</>",
"<info>Executable</info>: "
f" <comment>{env.python if env.is_venv() else 'NA'}</>",
] ]
if env.is_venv(): if env.is_venv():
listing.append( listing.append(
f"<info>Valid</info>: <{'comment' if env.is_sane() else 'error'}>{env.is_sane()}</>" "<info>Valid</info>: "
f" <{'comment' if env.is_sane() else 'error'}>{env.is_sane()}</>"
) )
self.line("\n".join(listing)) self.line("\n".join(listing))
......
...@@ -12,8 +12,8 @@ class EnvRemoveCommand(Command): ...@@ -12,8 +12,8 @@ class EnvRemoveCommand(Command):
arguments = [ arguments = [
argument( argument(
"python", "python",
"The python executables associated with, or names of the virtual environments which are to " "The python executables associated with, or names of the virtual"
"be removed.", " environments which are to be removed.",
optional=True, optional=True,
multiple=True, multiple=True,
) )
...@@ -21,8 +21,9 @@ class EnvRemoveCommand(Command): ...@@ -21,8 +21,9 @@ class EnvRemoveCommand(Command):
options = [ options = [
option( option(
"all", "all",
description="Remove all managed virtual environments associated with the " description=(
"project.", "Remove all managed virtual environments associated with the project."
),
), ),
] ]
......
...@@ -54,7 +54,8 @@ class InitCommand(Command): ...@@ -54,7 +54,8 @@ class InitCommand(Command):
] ]
help = """\ help = """\
The <c1>init</c1> command creates a basic <comment>pyproject.toml</> file in the current directory. The <c1>init</c1> command creates a basic <comment>pyproject.toml</> file in the\
current directory.
""" """
def __init__(self) -> None: def __init__(self) -> None:
...@@ -76,13 +77,15 @@ The <c1>init</c1> command creates a basic <comment>pyproject.toml</> file in the ...@@ -76,13 +77,15 @@ The <c1>init</c1> command creates a basic <comment>pyproject.toml</> file in the
if pyproject.file.exists(): if pyproject.file.exists():
if pyproject.is_poetry_project(): if pyproject.is_poetry_project():
self.line( self.line(
"<error>A pyproject.toml file with a poetry section already exists.</error>" "<error>A pyproject.toml file with a poetry section already"
" exists.</error>"
) )
return 1 return 1
if pyproject.data.get("build-system"): if pyproject.data.get("build-system"):
self.line( self.line(
"<error>A pyproject.toml file with a defined build-system already exists.</error>" "<error>A pyproject.toml file with a defined build-system already"
" exists.</error>"
) )
return 1 return 1
...@@ -91,7 +94,8 @@ The <c1>init</c1> command creates a basic <comment>pyproject.toml</> file in the ...@@ -91,7 +94,8 @@ The <c1>init</c1> command creates a basic <comment>pyproject.toml</> file in the
if self.io.is_interactive(): if self.io.is_interactive():
self.line("") self.line("")
self.line( self.line(
"This command will guide you through creating your <info>pyproject.toml</> config." "This command will guide you through creating your"
" <info>pyproject.toml</> config."
) )
self.line("") self.line("")
...@@ -165,16 +169,18 @@ The <c1>init</c1> command creates a basic <comment>pyproject.toml</> file in the ...@@ -165,16 +169,18 @@ The <c1>init</c1> command creates a basic <comment>pyproject.toml</> file in the
) )
question = "Would you like to define your main dependencies interactively?" question = "Would you like to define your main dependencies interactively?"
help_message = ( help_message = """\
"You can specify a package in the following forms:\n" You can specify a package in the following forms:
" - A single name (<b>requests</b>)\n" - A single name (<b>requests</b>)
" - A name and a constraint (<b>requests@^2.23.0</b>)\n" - A name and a constraint (<b>requests@^2.23.0</b>)
" - A git url (<b>git+https://github.com/python-poetry/poetry.git</b>)\n" - A git url (<b>git+https://github.com/python-poetry/poetry.git</b>)
" - A git url with a revision (<b>git+https://github.com/python-poetry/poetry.git#develop</b>)\n" - A git url with a revision\
" - A file path (<b>../my-package/my-package.whl</b>)\n" (<b>git+https://github.com/python-poetry/poetry.git#develop</b>)
" - A directory (<b>../my-package/</b>)\n" - A file path (<b>../my-package/my-package.whl</b>)
" - A url (<b>https://example.com/packages/my-package-0.1.0.tar.gz</b>)\n" - A directory (<b>../my-package/</b>)
) - A url (<b>https://example.com/packages/my-package-0.1.0.tar.gz</b>)
"""
help_displayed = False help_displayed = False
if self.confirm(question, True): if self.confirm(question, True):
if self.io.is_interactive(): if self.io.is_interactive():
...@@ -280,11 +286,13 @@ The <c1>init</c1> command creates a basic <comment>pyproject.toml</> file in the ...@@ -280,11 +286,13 @@ 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(
f"Found <info>{len(matches)}</info> packages matching <c1>{package}</c1>" f"Found <info>{len(matches)}</info> packages matching"
f" <c1>{package}</c1>"
) )
package = self.choice( package = self.choice(
"\nEnter package # to add, or the complete package name if it is not listed", "\nEnter package # to add, or the complete package name if it"
" is not listed",
choices, choices,
attempts=3, attempts=3,
) )
...@@ -310,7 +318,8 @@ The <c1>init</c1> command creates a basic <comment>pyproject.toml</> file in the ...@@ -310,7 +318,8 @@ The <c1>init</c1> command creates a basic <comment>pyproject.toml</> file in the
) )
self.line( self.line(
f"Using version <b>{package_constraint}</b> for <c1>{package}</c1>" f"Using version <b>{package_constraint}</b> for"
f" <c1>{package}</c1>"
) )
constraint["version"] = package_constraint constraint["version"] = package_constraint
......
...@@ -34,17 +34,20 @@ class InstallCommand(InstallerCommand): ...@@ -34,17 +34,20 @@ class InstallCommand(InstallerCommand):
option( option(
"no-dev", "no-dev",
None, None,
"Do not install the development dependencies. (<warning>Deprecated</warning>)", "Do not install the development dependencies."
" (<warning>Deprecated</warning>)",
), ),
option( option(
"dev-only", "dev-only",
None, None,
"Only install the development dependencies. (<warning>Deprecated</warning>)", "Only install the development dependencies."
" (<warning>Deprecated</warning>)",
), ),
option( option(
"sync", "sync",
None, None,
"Synchronize the environment with the locked packages and the specified groups.", "Synchronize the environment with the locked packages and the specified"
" groups.",
), ),
option( option(
"no-root", None, "Do not install the root package (the current project)." "no-root", None, "Do not install the root package (the current project)."
...@@ -108,14 +111,16 @@ dependencies and not including the current project, run the command with the ...@@ -108,14 +111,16 @@ dependencies and not including the current project, run the command with the
only_groups = [] only_groups = []
if self.option("no-dev"): if self.option("no-dev"):
self.line( self.line(
"<warning>The `<fg=yellow;options=bold>--no-dev</>` option is deprecated, " "<warning>The `<fg=yellow;options=bold>--no-dev</>` option is"
"use the `<fg=yellow;options=bold>--without dev</>` notation instead.</warning>" " deprecated, use the `<fg=yellow;options=bold>--without dev</>`"
" notation instead.</warning>"
) )
excluded_groups.append("dev") excluded_groups.append("dev")
elif self.option("dev-only"): elif self.option("dev-only"):
self.line( self.line(
"<warning>The `<fg=yellow;options=bold>--dev-only</>` option is deprecated, " "<warning>The `<fg=yellow;options=bold>--dev-only</>` option is"
"use the `<fg=yellow;options=bold>--only dev</>` notation instead.</warning>" " deprecated, use the `<fg=yellow;options=bold>--only dev</>` notation"
" instead.</warning>"
) )
only_groups.append("dev") only_groups.append("dev")
...@@ -147,8 +152,9 @@ dependencies and not including the current project, run the command with the ...@@ -147,8 +152,9 @@ dependencies and not including the current project, run the command with the
with_synchronization = self.option("sync") with_synchronization = self.option("sync")
if self.option("remove-untracked"): if self.option("remove-untracked"):
self.line( self.line(
"<warning>The `<fg=yellow;options=bold>--remove-untracked</>` option is deprecated, " "<warning>The `<fg=yellow;options=bold>--remove-untracked</>` option is"
"use the `<fg=yellow;options=bold>--sync</>` option instead.</warning>" " deprecated, use the `<fg=yellow;options=bold>--sync</>` option"
" instead.</warning>"
) )
with_synchronization = True with_synchronization = True
...@@ -177,8 +183,9 @@ dependencies and not including the current project, run the command with the ...@@ -177,8 +183,9 @@ dependencies and not including the current project, run the command with the
return 0 return 0
log_install = ( log_install = (
f"<b>Installing</> the current project: <c1>{self.poetry.package.pretty_name}</c1> " "<b>Installing</> the current project:"
f"(<{{tag}}>{self.poetry.package.pretty_version}</>)" f" <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() overwrite = self._io.output.is_decorated() and not self.io.is_debug()
self.line("") self.line("")
......
...@@ -15,14 +15,15 @@ class LockCommand(InstallerCommand): ...@@ -15,14 +15,15 @@ class LockCommand(InstallerCommand):
option( option(
"check", "check",
None, None,
"Check that the <comment>poetry.lock</> file corresponds to the current version " "Check that the <comment>poetry.lock</> file corresponds to the current"
"of <comment>pyproject.toml</>.", " version of <comment>pyproject.toml</>.",
), ),
] ]
help = """ help = """
The <info>lock</info> command reads the <comment>pyproject.toml</> file from the The <info>lock</info> command reads the <comment>pyproject.toml</> file from the
current directory, processes it, and locks the dependencies in the <comment>poetry.lock</> current directory, processes it, and locks the dependencies in the\
<comment>poetry.lock</>
file. file.
<info>poetry lock</info> <info>poetry lock</info>
......
...@@ -40,7 +40,8 @@ class NewCommand(Command): ...@@ -40,7 +40,8 @@ class NewCommand(Command):
path = Path(self.argument("path")) path = Path(self.argument("path"))
if not path.is_absolute(): if not path.is_absolute():
# we do not use resolve here due to compatibility issues for path.resolve(strict=False) # we do not use resolve here due to compatibility issues
# for path.resolve(strict=False)
path = Path.cwd().joinpath(path) path = Path.cwd().joinpath(path)
name = self.option("name") name = self.option("name")
...@@ -50,7 +51,7 @@ class NewCommand(Command): ...@@ -50,7 +51,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(
f"Destination <fg=yellow>{path}</> " "exists and is not empty" f"Destination <fg=yellow>{path}</> exists and is not empty"
) )
readme_format = self.option("readme") or "md" readme_format = self.option("readme") or "md"
...@@ -81,5 +82,6 @@ class NewCommand(Command): ...@@ -81,5 +82,6 @@ class NewCommand(Command):
path = path.relative_to(Path.cwd()) path = path.relative_to(Path.cwd())
self.line( self.line(
f"Created package <info>{layout_._package_name}</> in <fg=blue>{path.as_posix()}</>" f"Created package <info>{layout_._package_name}</> in"
f" <fg=blue>{path.as_posix()}</>"
) )
...@@ -26,7 +26,8 @@ class PluginAddCommand(InitCommand): ...@@ -26,7 +26,8 @@ class PluginAddCommand(InitCommand):
option( option(
"dry-run", "dry-run",
None, None,
"Output the operations but do not execute anything (implicitly enables --verbose).", "Output the operations but do not execute anything (implicitly enables"
" --verbose).",
) )
] ]
...@@ -35,16 +36,19 @@ The <c1>plugin add</c1> command installs Poetry plugins globally. ...@@ -35,16 +36,19 @@ The <c1>plugin add</c1> command installs Poetry plugins globally.
It works similarly to the <c1>add</c1> command: It works similarly to the <c1>add</c1> command:
If you do not specify a version constraint, poetry will choose a suitable one based on the available package versions. If you do not specify a version constraint, poetry will choose a suitable one based on\
the available package versions.
You can specify a package in the following forms: You can specify a package in the following forms:
- A single name (<b>requests</b>) - A single name (<b>requests</b>)
- A name and a constraint (<b>requests@^2.23.0</b>) - A name and a constraint (<b>requests@^2.23.0</b>)
- A git url (<b>git+https://github.com/python-poetry/poetry.git</b>) - A git url (<b>git+https://github.com/python-poetry/poetry.git</b>)
- A git url with a revision (<b>git+https://github.com/python-poetry/poetry.git#develop</b>) - A git url with a revision\
(<b>git+https://github.com/python-poetry/poetry.git#develop</b>)
- A git SSH url (<b>git+ssh://github.com/python-poetry/poetry.git</b>) - A git SSH url (<b>git+ssh://github.com/python-poetry/poetry.git</b>)
- A git SSH url with a revision (<b>git+ssh://github.com/python-poetry/poetry.git#develop</b>) - A git SSH url with a revision\
(<b>git+ssh://github.com/python-poetry/poetry.git#develop</b>)
- A file path (<b>../my-package/my-package.whl</b>) - A file path (<b>../my-package/my-package.whl</b>)
- A directory (<b>../my-package/</b>) - A directory (<b>../my-package/</b>)
- A url (<b>https://example.com/packages/my-package-0.1.0.tar.gz</b>)\ - A url (<b>https://example.com/packages/my-package-0.1.0.tar.gz</b>)\
...@@ -95,8 +99,9 @@ You can specify a package in the following forms: ...@@ -95,8 +99,9 @@ You can specify a package in the following forms:
# We retrieve the packages installed in the system environment. # We retrieve the packages installed in the system environment.
# We assume that this environment will be a self contained virtual environment # We assume that this environment will be a self contained virtual environment
# built by the official installer or by pipx. # built by the official installer or by pipx.
# If not, it might lead to side effects since other installed packages # If not, it might lead to side effects since other installed packages might not
# might not be required by Poetry but still taken into account when resolving dependencies. # be required by Poetry but still be taken into account when resolving
# dependencies.
installed_repository = InstalledRepository.load( installed_repository = InstalledRepository.load(
system_env, with_dependencies=True system_env, with_dependencies=True
) )
......
...@@ -24,7 +24,8 @@ class PluginRemoveCommand(Command): ...@@ -24,7 +24,8 @@ class PluginRemoveCommand(Command):
option( option(
"dry-run", "dry-run",
None, None,
"Output the operations but do not execute anything (implicitly enables --verbose).", "Output the operations but do not execute anything (implicitly enables"
" --verbose).",
) )
] ]
......
...@@ -82,7 +82,8 @@ class PluginShowCommand(Command): ...@@ -82,7 +82,8 @@ 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(
f" - {dependency.pretty_name} (<c2>{dependency.pretty_constraint}</c2>)" f" - {dependency.pretty_name}"
f" (<c2>{dependency.pretty_constraint}</c2>)"
) )
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(
f"There are <info>{len(publisher.files)}</info> files ready for publishing. " f"There are <info>{len(publisher.files)}</info> files ready for"
"Build anyway?" " publishing. Build anyway?"
): ):
self.line_error("<error>Aborted!</error>") self.line_error("<error>Aborted!</error>")
......
...@@ -36,7 +36,8 @@ class ShowCommand(EnvCommand): ...@@ -36,7 +36,8 @@ class ShowCommand(EnvCommand):
option( option(
"with", "with",
None, None,
"Show the information of the specified optional groups' dependencies as well.", "Show the information of the specified optional groups' dependencies as"
" well.",
flag=False, flag=False,
multiple=True, multiple=True,
), ),
...@@ -46,7 +47,8 @@ class ShowCommand(EnvCommand): ...@@ -46,7 +47,8 @@ class ShowCommand(EnvCommand):
option( option(
"only", "only",
None, None,
"Only show the information of dependencies belonging to the specified groups.", "Only show the information of dependencies belonging to the specified"
" groups.",
flag=False, flag=False,
multiple=True, multiple=True,
), ),
...@@ -97,8 +99,9 @@ lists all packages available.""" ...@@ -97,8 +99,9 @@ lists all packages available."""
only_groups = [] only_groups = []
if self.option("no-dev"): if self.option("no-dev"):
self.line( self.line(
"<warning>The `<fg=yellow;options=bold>--no-dev</>` option is deprecated, " "<warning>The `<fg=yellow;options=bold>--no-dev</>` option is"
"use the `<fg=yellow;options=bold>--without dev</>` notation instead.</warning>" " deprecated, use the `<fg=yellow;options=bold>--without dev</>`"
" notation instead.</warning>"
) )
excluded_groups.append("dev") excluded_groups.append("dev")
...@@ -201,7 +204,8 @@ lists all packages available.""" ...@@ -201,7 +204,8 @@ 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(
f" - <c1>{dependency.pretty_name}</c1> <b>{dependency.pretty_constraint}</b>" f" - <c1>{dependency.pretty_name}</c1>"
f" <b>{dependency.pretty_constraint}</b>"
) )
if required_by: if required_by:
...@@ -301,7 +305,10 @@ lists all packages available.""" ...@@ -301,7 +305,10 @@ lists all packages available."""
): ):
continue continue
line = f"<fg={color}>{name:{name_length - len(install_marker)}}{install_marker}</>" line = (
f"<fg={color}>"
f"{name:{name_length - len(install_marker)}}{install_marker}</>"
)
if write_version: if write_version:
version = get_package_version_display_string( version = get_package_version_display_string(
locked, root=self.poetry.file.parent locked, root=self.poetry.file.parent
...@@ -357,7 +364,10 @@ lists all packages available.""" ...@@ -357,7 +364,10 @@ lists all packages available."""
level = 1 level = 1
color = self.colors[level] color = self.colors[level]
info = f"{tree_bar}── <{color}>{dependency.name}</{color}> {dependency.pretty_constraint}" info = (
f"{tree_bar}── <{color}>{dependency.name}</{color}>"
f" {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("└", " ")
...@@ -400,7 +410,10 @@ lists all packages available.""" ...@@ -400,7 +410,10 @@ 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 = f"{tree_bar}── <{color}>{dependency.name}</{color}> {dependency.pretty_constraint} {circular_warn}" info = (
f"{tree_bar}── <{color}>{dependency.name}</{color}>"
f" {dependency.pretty_constraint} {circular_warn}"
)
self._write_tree_line(io, info) self._write_tree_line(io, info)
tree_bar = tree_bar.replace("└", " ") tree_bar = tree_bar.replace("└", " ")
......
...@@ -59,7 +59,8 @@ class SourceAddCommand(Command): ...@@ -59,7 +59,8 @@ class SourceAddCommand(Command):
if is_default and is_secondary: if is_default and is_secondary:
self.line_error( self.line_error(
"Cannot configure a source as both <c1>default</c1> and <c1>secondary</c1>." "Cannot configure a source as both <c1>default</c1> and"
" <c1>secondary</c1>."
) )
return 1 return 1
...@@ -73,18 +74,20 @@ class SourceAddCommand(Command): ...@@ -73,18 +74,20 @@ class SourceAddCommand(Command):
for source in existing_sources: for source in existing_sources:
if source == new_source: if source == new_source:
self.line( self.line(
f"Source with name <c1>{name}</c1> already exits. Skipping addition." f"Source with name <c1>{name}</c1> already exists. Skipping"
" addition."
) )
return 0 return 0
elif source.default and is_default: elif source.default and is_default:
self.line_error( self.line_error(
f"<error>Source with name <c1>{source.name}</c1> is already set to default. " f"<error>Source with name <c1>{source.name}</c1> is already set to"
f"Only one default source can be configured at a time.</error>" " default. Only one default source can be configured at a"
" time.</error>"
) )
return 1 return 1
if source.name == name: if source.name == name:
self.line(f"Source with name <c1>{name}</c1> already exits. Updating.") self.line(f"Source with name <c1>{name}</c1> already exists. Updating.")
source = new_source source = new_source
new_source = None new_source = None
......
...@@ -58,7 +58,8 @@ patch, minor, major, prepatch, preminor, premajor, prerelease. ...@@ -58,7 +58,8 @@ patch, minor, major, prepatch, preminor, premajor, prerelease.
self.line(version.to_string()) self.line(version.to_string())
else: else:
self.line( self.line(
f"Bumping version from <b>{self.poetry.package.pretty_version}</> to <fg=green>{version}</>" f"Bumping version from <b>{self.poetry.package.pretty_version}</>"
f" to <fg=green>{version}</>"
) )
content = self.poetry.file.read() content = self.poetry.file.read()
...@@ -71,7 +72,8 @@ patch, minor, major, prepatch, preminor, premajor, prerelease. ...@@ -71,7 +72,8 @@ patch, minor, major, prepatch, preminor, premajor, prerelease.
self.line(self.poetry.package.pretty_version) self.line(self.poetry.package.pretty_version)
else: else:
self.line( self.line(
f"<comment>{self.poetry.package.name}</> <info>{self.poetry.package.pretty_version}</>" f"<comment>{self.poetry.package.name}</>"
f" <info>{self.poetry.package.pretty_version}</>"
) )
def increment_version(self, version: str, rule: str) -> "Version": def increment_version(self, version: str, rule: str) -> "Version":
......
...@@ -112,7 +112,8 @@ class PackageInfo: ...@@ -112,7 +112,8 @@ class PackageInfo:
""" """
Helper method to load data from a dictionary produced by `PackageInfo.asdict()`. Helper method to load data from a dictionary produced by `PackageInfo.asdict()`.
:param data: Data to load. This is expected to be a `dict` object output by `asdict()`. :param data: Data to load. This is expected to be a `dict` object output by
`asdict()`.
""" """
cache_version = data.pop("_cache_version", None) cache_version = data.pop("_cache_version", None)
return cls(cache_version=cache_version, **data) return cls(cache_version=cache_version, **data)
...@@ -129,17 +130,20 @@ class PackageInfo: ...@@ -129,17 +130,20 @@ class PackageInfo:
root_dir: Optional[Path] = None, root_dir: Optional[Path] = None,
) -> Package: ) -> Package:
""" """
Create a new `poetry.core.packages.package.Package` instance using metadata from this instance. Create a new `poetry.core.packages.package.Package` instance using metadata from
this instance.
:param name: Name to use for the package, if not specified name from this instance is used. :param name: Name to use for the package, if not specified name from this
instance is used.
:param extras: Extras to activate for this package. :param extras: Extras to activate for this package.
:param root_dir: Optional root directory to use for the package. If set, dependency strings :param root_dir: Optional root directory to use for the package. If set,
will be parsed relative to this directory. dependency strings will be parsed relative to this directory.
""" """
name = name or self.name name = name or self.name
if not self.version: if not self.version:
# The version could not be determined, so we raise an error since it is mandatory. # The version could not be determined, so we raise an error since it is
# mandatory.
raise RuntimeError(f"Unable to retrieve the package version for {name}") raise RuntimeError(f"Unable to retrieve the package version for {name}")
package = Package( package = Package(
...@@ -155,8 +159,8 @@ class PackageInfo: ...@@ -155,8 +159,8 @@ class PackageInfo:
package.files = self.files package.files = self.files
if root_dir or (self._source_type in {"directory"} and self._source_url): if root_dir or (self._source_type in {"directory"} and self._source_url):
# this is a local poetry project, this means we can extract "richer" requirement information # this is a local poetry project, this means we can extract "richer"
# eg: development requirements etc. # requirement information, eg: development requirements etc.
poetry_package = self._get_poetry_package(path=root_dir or self._source_url) poetry_package = self._get_poetry_package(path=root_dir or self._source_url)
if poetry_package: if poetry_package:
package.extras = poetry_package.extras package.extras = poetry_package.extras
...@@ -178,8 +182,8 @@ class PackageInfo: ...@@ -178,8 +182,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(
f"Invalid constraint ({req}) found in {package.name}-{package.version} dependencies, " f"Invalid constraint ({req}) found in"
"skipping", f" {package.name}-{package.version} dependencies, skipping",
level="warning", level="warning",
) )
continue continue
...@@ -188,7 +192,8 @@ class PackageInfo: ...@@ -188,7 +192,8 @@ class PackageInfo:
# this dependency is required by an extra package # this dependency is required by an extra package
for extra in dependency.in_extras: for extra in dependency.in_extras:
if extra not in package.extras: if extra not in package.extras:
# this is the first time we encounter this extra for this package # this is the first time we encounter this extra for this
# package
package.extras[extra] = [] package.extras[extra] = []
package.extras[extra].append(dependency) package.extras[extra].append(dependency)
...@@ -206,7 +211,8 @@ class PackageInfo: ...@@ -206,7 +211,8 @@ class PackageInfo:
cls, dist: Union[pkginfo.BDist, pkginfo.SDist, pkginfo.Wheel] cls, dist: Union[pkginfo.BDist, pkginfo.SDist, pkginfo.Wheel]
) -> "PackageInfo": ) -> "PackageInfo":
""" """
Helper method to parse package information from a `pkginfo.Distribution` instance. Helper method to parse package information from a `pkginfo.Distribution`
instance.
:param dist: The distribution instance to parse information from. :param dist: The distribution instance to parse information from.
""" """
...@@ -237,9 +243,9 @@ class PackageInfo: ...@@ -237,9 +243,9 @@ class PackageInfo:
@classmethod @classmethod
def _from_sdist_file(cls, path: Path) -> "PackageInfo": def _from_sdist_file(cls, path: Path) -> "PackageInfo":
""" """
Helper method to parse package information from an sdist file. We attempt to first inspect the Helper method to parse package information from an sdist file. We attempt to
file using `pkginfo.SDist`. If this does not provide us with package requirements, we extract the first inspect the file using `pkginfo.SDist`. If this does not provide us with
source and handle it as a directory. package requirements, we extract the source and handle it as a directory.
:param path: The sdist file to parse information from. :param path: The sdist file to parse information from.
""" """
...@@ -302,9 +308,10 @@ class PackageInfo: ...@@ -302,9 +308,10 @@ class PackageInfo:
@classmethod @classmethod
def from_setup_files(cls, path: Path) -> "PackageInfo": def from_setup_files(cls, path: Path) -> "PackageInfo":
""" """
Mechanism to parse package information from a `setup.[py|cfg]` file. This uses the implementation Mechanism to parse package information from a `setup.[py|cfg]` file. This uses
at `poetry.utils.setup_reader.SetupReader` in order to parse the file. This is not reliable for the implementation at `poetry.utils.setup_reader.SetupReader` in order to parse
complex setup files and should only attempted as a fallback. the file. This is not reliable for complex setup files and should only attempted
as a fallback.
:param path: Path to `setup.py` file :param path: Path to `setup.py` file
""" """
...@@ -361,9 +368,9 @@ class PackageInfo: ...@@ -361,9 +368,9 @@ class PackageInfo:
:param path: Path to search. :param path: Path to search.
""" """
pattern = "**/*.*-info" pattern = "**/*.*-info"
# Sometimes pathlib will fail on recursive symbolic links, so we need to workaround it # Sometimes pathlib will fail on recursive symbolic links, so we need to work
# and use the glob module instead. Note that this does not happen with pathlib2 # around it and use the glob module instead. Note that this does not happen with
# so it's safe to use it for Python < 3.4. # pathlib2 so it's safe to use it for Python < 3.4.
directories = glob.iglob(path.joinpath(pattern).as_posix(), recursive=True) directories = glob.iglob(path.joinpath(pattern).as_posix(), recursive=True)
for d in directories: for d in directories:
...@@ -508,13 +515,14 @@ class PackageInfo: ...@@ -508,13 +515,14 @@ class PackageInfo:
@classmethod @classmethod
def from_directory(cls, path: Path, disable_build: bool = False) -> "PackageInfo": def from_directory(cls, path: Path, disable_build: bool = False) -> "PackageInfo":
""" """
Generate package information from a package source directory. If `disable_build` is not `True` and Generate package information from a package source directory. If `disable_build`
introspection of all available metadata fails, the package is attempted to be build in an isolated is not `True` and introspection of all available metadata fails, the package is
environment so as to generate required metadata. attempted to be built in an isolated environment so as to generate required
metadata.
:param path: Path to generate package information from. :param path: Path to generate package information from.
:param disable_build: If not `True` and setup reader fails, PEP 517 isolated build is attempted in :param disable_build: If not `True` and setup reader fails, PEP 517 isolated
order to gather metadata. build is attempted in order to gather metadata.
""" """
project_package = cls._get_poetry_package(path) project_package = cls._get_poetry_package(path)
if project_package: if project_package:
......
...@@ -112,7 +112,8 @@ class Chooser: ...@@ -112,7 +112,8 @@ class Chooser:
if links and not selected_links: if links and not selected_links:
raise RuntimeError( raise RuntimeError(
f"Retrieved digest for link {link.filename}({h}) not in poetry.lock metadata {hashes}" f"Retrieved digest for link {link.filename}({h}) not in poetry.lock"
f" metadata {hashes}"
) )
return selected_links return selected_links
......
...@@ -230,7 +230,8 @@ class Executor: ...@@ -230,7 +230,8 @@ 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(
f" <fg=blue;options=bold>•</> {op_message}: <fg=blue>Pending...</>" f" <fg=blue;options=bold>•</> {op_message}:"
" <fg=blue>Pending...</>"
) )
else: else:
if self._should_write_operation(operation): if self._should_write_operation(operation):
...@@ -266,7 +267,11 @@ class Executor: ...@@ -266,7 +267,11 @@ class Executor:
if not self.supports_fancy_output(): if not self.supports_fancy_output():
io = self._io io = self._io
else: else:
message = f" <error>•</error> {self.get_operation_message(operation, error=True)}: <error>Failed</error>" message = (
" <error>•</error>"
f" {self.get_operation_message(operation, error=True)}:"
" <error>Failed</error>"
)
self._write(operation, message) self._write(operation, message)
io = self._sections.get(id(operation), self._io) io = self._sections.get(id(operation), self._io)
...@@ -279,7 +284,11 @@ class Executor: ...@@ -279,7 +284,11 @@ class Executor:
self._shutdown = True self._shutdown = True
except KeyboardInterrupt: except KeyboardInterrupt:
try: try:
message = f" <warning>•</warning> {self.get_operation_message(operation, warning=True)}: <warning>Cancelled</warning>" message = (
" <warning>•</warning>"
f" {self.get_operation_message(operation, warning=True)}:"
" <warning>Cancelled</warning>"
)
if not self.supports_fancy_output(): if not self.supports_fancy_output():
self._io.write_line(message) self._io.write_line(message)
else: else:
...@@ -376,21 +385,26 @@ class Executor: ...@@ -376,21 +385,26 @@ class Executor:
if operation.job_type == "install": if operation.job_type == "install":
return ( return (
f"<{base_tag}>Installing <{package_color}>{operation.package.name}</{package_color}> " f"<{base_tag}>Installing"
f"(<{operation_color}>{operation.package.full_pretty_version}</>)</>" f" <{package_color}>{operation.package.name}</{package_color}>"
f" (<{operation_color}>{operation.package.full_pretty_version}</>)</>"
) )
if operation.job_type == "uninstall": if operation.job_type == "uninstall":
return ( return (
f"<{base_tag}>Removing <{package_color}>{operation.package.name}</{package_color}> " f"<{base_tag}>Removing"
f"(<{operation_color}>{operation.package.full_pretty_version}</>)</>" f" <{package_color}>{operation.package.name}</{package_color}>"
f" (<{operation_color}>{operation.package.full_pretty_version}</>)</>"
) )
if operation.job_type == "update": if operation.job_type == "update":
return ( return (
f"<{base_tag}>Updating <{package_color}>{operation.initial_package.name}</{package_color}> " f"<{base_tag}>Updating"
f"(<{source_operation_color}>{operation.initial_package.full_pretty_version}</{source_operation_color}> " f" <{package_color}>{operation.initial_package.name}</{package_color}> "
f"-> <{operation_color}>{operation.target_package.full_pretty_version}</>)</>" f"(<{source_operation_color}>"
f"{operation.initial_package.full_pretty_version}"
f"</{source_operation_color}> -> <{operation_color}>"
f"{operation.target_package.full_pretty_version}</>)</>"
) )
return "" return ""
...@@ -464,7 +478,10 @@ class Executor: ...@@ -464,7 +478,10 @@ 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 = f" <fg=blue;options=bold>•</> {operation_message}: <info>Installing...</info>" message = (
f" <fg=blue;options=bold>•</> {operation_message}:"
" <info>Installing...</info>"
)
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")
...@@ -492,7 +509,10 @@ class Executor: ...@@ -492,7 +509,10 @@ class Executor:
package = operation.package package = operation.package
operation_message = self.get_operation_message(operation) operation_message = self.get_operation_message(operation)
message = f" <fg=blue;options=bold>•</> {operation_message}: <info>Preparing...</info>" message = (
f" <fg=blue;options=bold>•</> {operation_message}:"
" <info>Preparing...</info>"
)
self._write(operation, message) self._write(operation, message)
archive = Path(package.source_url) archive = Path(package.source_url)
...@@ -509,7 +529,10 @@ class Executor: ...@@ -509,7 +529,10 @@ class Executor:
package = operation.package package = operation.package
operation_message = self.get_operation_message(operation) operation_message = self.get_operation_message(operation)
message = f" <fg=blue;options=bold>•</> {operation_message}: <info>Building...</info>" message = (
f" <fg=blue;options=bold>•</> {operation_message}:"
" <info>Building...</info>"
)
self._write(operation, message) self._write(operation, message)
if package.root_dir: if package.root_dir:
...@@ -644,7 +667,8 @@ class Executor: ...@@ -644,7 +667,8 @@ class Executor:
if archive_hash not in known_hashes: if archive_hash not in known_hashes:
raise RuntimeError( raise RuntimeError(
f"Hash for {package} from archive {archive_path.name} not found in known hashes (was: {archive_hash})" f"Hash for {package} from archive {archive_path.name} not found in"
f" known hashes (was: {archive_hash})"
) )
return archive_hash return archive_hash
......
...@@ -414,14 +414,16 @@ class Installer: ...@@ -414,14 +414,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(
f" - Skipping <c1>{target.pretty_name}</c1> (<c2>{target.full_pretty_version}</c2>) {operation.skip_reason}" f" - Skipping <c1>{target.pretty_name}</c1>"
f" (<c2>{target.full_pretty_version}</c2>) {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(
f" - Installing <c1>{target.pretty_name}</c1> (<c2>{target.full_pretty_version}</c2>)" f" - Installing <c1>{target.pretty_name}</c1>"
f" (<c2>{target.full_pretty_version}</c2>)"
) )
if not self._execute_operations: if not self._execute_operations:
...@@ -444,8 +446,9 @@ class Installer: ...@@ -444,8 +446,9 @@ class Installer:
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(
f" - Updating <c1>{target.pretty_name}</c1> " f" - Updating <c1>{target.pretty_name}</c1>"
f"(<c2>{source.full_pretty_version}</c2> -> <c2>{target.full_pretty_version}</c2>)" f" (<c2>{source.full_pretty_version}</c2> ->"
f" <c2>{target.full_pretty_version}</c2>)"
) )
if not self._execute_operations: if not self._execute_operations:
...@@ -458,14 +461,16 @@ class Installer: ...@@ -458,14 +461,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(
f" - Not removing <c1>{target.pretty_name}</c1> (<c2>{target.pretty_version}</c2>) {operation.skip_reason}" f" - Not removing <c1>{target.pretty_name}</c1>"
f" (<c2>{target.pretty_version}</c2>) {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(
f" - Removing <c1>{target.pretty_name}</c1> (<c2>{target.pretty_version}</c2>)" f" - Removing <c1>{target.pretty_name}</c1>"
f" (<c2>{target.pretty_version}</c2>)"
) )
if not self._execute_operations: if not self._execute_operations:
......
...@@ -25,7 +25,13 @@ class Install(Operation): ...@@ -25,7 +25,13 @@ class Install(Operation):
return "install" return "install"
def __str__(self) -> str: def __str__(self) -> str:
return f"Installing {self.package.pretty_name} ({self.format_version(self.package)})" return (
"Installing"
f" {self.package.pretty_name} ({self.format_version(self.package)})"
)
def __repr__(self) -> str: def __repr__(self) -> str:
return f"<Install {self.package.pretty_name} ({self.format_version(self.package)})>" return (
"<Install"
f" {self.package.pretty_name} ({self.format_version(self.package)})>"
)
...@@ -28,7 +28,13 @@ class Uninstall(Operation): ...@@ -28,7 +28,13 @@ class Uninstall(Operation):
return "uninstall" return "uninstall"
def __str__(self) -> str: def __str__(self) -> str:
return f"Uninstalling {self.package.pretty_name} ({self.format_version(self._package)})" return (
"Uninstalling"
f" {self.package.pretty_name} ({self.format_version(self._package)})"
)
def __repr__(self) -> str: def __repr__(self) -> str:
return f"<Uninstall {self.package.pretty_name} ({self.format_version(self.package)})>" return (
"<Uninstall"
f" {self.package.pretty_name} ({self.format_version(self.package)})>"
)
...@@ -52,7 +52,8 @@ class PipInstaller(BaseInstaller): ...@@ -52,7 +52,8 @@ 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(
f" <warning>Installing from unsecure host: {parsed.hostname}</warning>" " <warning>Installing from unsecure host:"
f" {parsed.hostname}</warning>"
) )
args += ["--trusted-host", parsed.hostname] args += ["--trusted-host", parsed.hostname]
...@@ -159,7 +160,10 @@ class PipInstaller(BaseInstaller): ...@@ -159,7 +160,10 @@ class PipInstaller(BaseInstaller):
return req return req
if package.source_type == "git": if package.source_type == "git":
req = f"git+{package.source_url}@{package.source_reference}#egg={package.name}" req = (
f"git+{package.source_url}@{package.source_reference}"
f"#egg={package.name}"
)
if package.develop: if package.develop:
req = ["-e", req] req = ["-e", req]
......
...@@ -63,7 +63,8 @@ class Layout: ...@@ -63,7 +63,8 @@ class Layout:
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) accepted_readme_formats = ", ".join(self.ACCEPTED_README_FORMATS)
raise ValueError( raise ValueError(
f"Invalid readme format '{readme_format}', use one of {accepted_readme_formats}." f"Invalid readme format '{readme_format}', use one of"
f" {accepted_readme_formats}."
) )
self._license = license self._license = license
......
...@@ -47,7 +47,8 @@ class EditableBuilder(Builder): ...@@ -47,7 +47,8 @@ class EditableBuilder(Builder):
def build(self) -> None: def build(self) -> None:
self._debug( self._debug(
f" - Building package <c1>{self._package.name}</c1> in <info>editable</info> mode" f" - Building package <c1>{self._package.name}</c1> in"
" <info>editable</info> mode"
) )
if self._package.build_script: if self._package.build_script:
...@@ -63,7 +64,8 @@ class EditableBuilder(Builder): ...@@ -63,7 +64,8 @@ class EditableBuilder(Builder):
distribution_name=self._package.name distribution_name=self._package.name
): ):
self._debug( self._debug(
f" - Removed <c2>{removed.name}</c2> directory from <b>{removed.parent}</b>" f" - Removed <c2>{removed.name}</c2> directory from"
f" <b>{removed.parent}</b>"
) )
added_files = [] added_files = []
...@@ -121,7 +123,8 @@ class EditableBuilder(Builder): ...@@ -121,7 +123,8 @@ 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(
f" - Removing existing <c2>{file.name}</c2> from <b>{file.parent}</b> for {self._poetry.file.parent}" f" - Removing existing <c2>{file.name}</c2> from <b>{file.parent}</b>"
f" for {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():
...@@ -132,13 +135,15 @@ class EditableBuilder(Builder): ...@@ -132,13 +135,15 @@ class EditableBuilder(Builder):
pth_file, content, encoding="utf-8" pth_file, content, encoding="utf-8"
) )
self._debug( self._debug(
f" - Adding <c2>{pth_file.name}</c2> to <b>{pth_file.parent}</b> for {self._poetry.file.parent}" f" - Adding <c2>{pth_file.name}</c2> to <b>{pth_file.parent}</b> for"
f" {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(
f" - Failed to create <c2>{pth_file.name}</c2> for {self._poetry.file.parent}" f" - Failed to create <c2>{pth_file.name}</c2> for"
f" {self._poetry.file.parent}"
) )
return [] return []
...@@ -151,7 +156,8 @@ class EditableBuilder(Builder): ...@@ -151,7 +156,8 @@ class EditableBuilder(Builder):
break break
else: else:
self._io.write_error_line( self._io.write_error_line(
f" - Failed to find a suitable script installation directory for {self._poetry.file.parent}" " - Failed to find a suitable script installation directory for"
f" {self._poetry.file.parent}"
) )
return [] return []
...@@ -185,7 +191,8 @@ class EditableBuilder(Builder): ...@@ -185,7 +191,8 @@ 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(
f" - Adding the <c2>{cmd_script.name}</c2> script wrapper to <b>{scripts_path}</b>" f" - Adding the <c2>{cmd_script.name}</c2> script wrapper to"
f" <b>{scripts_path}</b>"
) )
with cmd_script.open("w", encoding="utf-8") as f: with cmd_script.open("w", encoding="utf-8") as f:
...@@ -204,7 +211,8 @@ class EditableBuilder(Builder): ...@@ -204,7 +211,8 @@ 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(
f" - Adding the <c2>{dist_info.name}</c2> directory to <b>{dist_info.parent}</b>" f" - Adding the <c2>{dist_info.name}</c2> directory to"
f" <b>{dist_info.parent}</b>"
) )
with dist_info.joinpath("METADATA").open("w", encoding="utf-8") as f: with dist_info.joinpath("METADATA").open("w", encoding="utf-8") as f:
......
...@@ -43,9 +43,10 @@ class _Writer: ...@@ -43,9 +43,10 @@ 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(
f"The current project's Python requirement ({incompatibility.cause.root_python_version}) " "The current project's Python requirement"
"is not compatible with some of the required " f" ({incompatibility.cause.root_python_version}) is not"
"packages Python requirement:" " compatible with some of the required packages Python"
" requirement:"
) )
required_python_version_notification = True required_python_version_notification = True
...@@ -54,9 +55,9 @@ class _Writer: ...@@ -54,9 +55,9 @@ class _Writer:
) )
constraint = parse_constraint(incompatibility.cause.python_version) constraint = parse_constraint(incompatibility.cause.python_version)
buffer.append( buffer.append(
f" - {incompatibility.terms[0].dependency.name} requires Python " f" - {incompatibility.terms[0].dependency.name} requires Python"
f"{incompatibility.cause.python_version}, so it will not be satisfied " f" {incompatibility.cause.python_version}, so it will not be"
f"for Python {root_constraint.difference(constraint)}" f" satisfied for Python {root_constraint.difference(constraint)}"
) )
if required_python_version_notification: if required_python_version_notification:
...@@ -145,7 +146,8 @@ class _Writer: ...@@ -145,7 +146,8 @@ class _Writer:
self._visit(without_line, details_for_cause) self._visit(without_line, details_for_cause)
self._write( self._write(
incompatibility, incompatibility,
f"{conjunction} because {with_line!s} ({line}), {incompatibility_string}.", f"{conjunction} because {with_line!s} ({line}),"
f" {incompatibility_string}.",
numbered=numbered, numbered=numbered,
) )
else: else:
...@@ -170,7 +172,9 @@ class _Writer: ...@@ -170,7 +172,9 @@ class _Writer:
self._write( self._write(
incompatibility, incompatibility,
f"{conjunction} because {cause.conflict!s} ({self._line_numbers[cause.conflict]}), {incompatibility_string}", f"{conjunction} because"
f" {cause.conflict!s} ({self._line_numbers[cause.conflict]}),"
f" {incompatibility_string}",
numbered=numbered, numbered=numbered,
) )
elif isinstance(cause.conflict.cause, ConflictCause) or isinstance( elif isinstance(cause.conflict.cause, ConflictCause) or isinstance(
......
...@@ -54,11 +54,11 @@ class Incompatibility: ...@@ -54,11 +54,11 @@ class Incompatibility:
if ref in by_ref: if ref in by_ref:
by_ref[ref] = by_ref[ref].intersect(term) by_ref[ref] = by_ref[ref].intersect(term)
# If we have two terms that refer to the same package but have a null # If we have two terms that refer to the same package but have a
# intersection, they're mutually exclusive, making this incompatibility # null intersection, they're mutually exclusive, making this
# irrelevant, since we already know that mutually exclusive version # incompatibility irrelevant, since we already know that mutually
# ranges are incompatible. We should never derive an irrelevant # exclusive version ranges are incompatible. We should never derive
# incompatibility. # an irrelevant incompatibility.
assert by_ref[ref] is not None assert by_ref[ref] is not None
else: else:
by_ref[ref] = term by_ref[ref] = term
...@@ -127,7 +127,10 @@ class Incompatibility: ...@@ -127,7 +127,10 @@ class Incompatibility:
assert depender.is_positive() assert depender.is_positive()
assert not dependee.is_positive() assert not dependee.is_positive()
return f"{self._terse(depender, allow_every=True)} depends on {self._terse(dependee)}" return (
f"{self._terse(depender, allow_every=True)} depends on"
f" {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()
...@@ -150,7 +153,10 @@ class Incompatibility: ...@@ -150,7 +153,10 @@ 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 f"no versions of {self._terms[0].dependency.name} match {self._terms[0].constraint}" return (
f"no versions of {self._terms[0].dependency.name} match"
f" {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()
...@@ -161,7 +167,10 @@ class Incompatibility: ...@@ -161,7 +167,10 @@ 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 f"{self._terms[0].dependency.name} is {self._terms[0].dependency.constraint}" return (
f"{self._terms[0].dependency.name} is"
f" {self._terms[0].dependency.constraint}"
)
elif self.is_failure(): elif self.is_failure():
return "version solving failed" return "version solving failed"
...@@ -205,7 +214,10 @@ class Incompatibility: ...@@ -205,7 +214,10 @@ class Incompatibility:
return f"if {' and '.join(positive)} then {' or '.join(negative)}" return f"if {' and '.join(positive)} then {' or '.join(negative)}"
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 f"{self._terse(positive_term, allow_every=True)} requires {' or '.join(negative)}" return (
f"{self._terse(positive_term, allow_every=True)} requires"
f" {' or '.join(negative)}"
)
elif positive: elif positive:
return f"one of {' or '.join(positive)} must be false" return f"one of {' or '.join(positive)} must be false"
else: else:
......
...@@ -20,7 +20,8 @@ class PartialSolution: ...@@ -20,7 +20,8 @@ class PartialSolution:
# what's true for the eventual set of package versions that will comprise the # what's true for the eventual set of package versions that will comprise the
# total solution. # total solution.
# #
# See https://github.com/dart-lang/mixology/tree/master/doc/solver.md#partial-solution. # See:
# https://github.com/dart-lang/mixology/tree/master/doc/solver.md#partial-solution.
""" """
def __init__(self) -> None: def __init__(self) -> None:
......
...@@ -26,14 +26,17 @@ class PythonRequirementSolution(Solution): ...@@ -26,14 +26,17 @@ class PythonRequirementSolution(Solution):
constraint = parse_constraint(incompatibility.cause.python_version) constraint = parse_constraint(incompatibility.cause.python_version)
version_solutions.append( version_solutions.append(
f"For <fg=default;options=bold>{incompatibility.terms[0].dependency.name}</>, " "For <fg=default;options=bold>"
"a possible solution would be to set the `<fg=default;options=bold>python</>` " f"{incompatibility.terms[0].dependency.name}</>,"
f'property to <fg=yellow>"{root_constraint.intersect(constraint)}"</>' " a possible solution would be to set the"
" `<fg=default;options=bold>python</>` property to"
f' <fg=yellow>"{root_constraint.intersect(constraint)}"</>'
) )
description = ( description = (
"The Python requirement can be specified via the `<fg=default;options=bold>python</>` " "The Python requirement can be specified via the"
"or `<fg=default;options=bold>markers</>` properties" " `<fg=default;options=bold>python</>` or"
" `<fg=default;options=bold>markers</>` properties"
) )
if version_solutions: if version_solutions:
description += "\n\n" + "\n".join(version_solutions) description += "\n\n" + "\n".join(version_solutions)
...@@ -53,6 +56,6 @@ class PythonRequirementSolution(Solution): ...@@ -53,6 +56,6 @@ class PythonRequirementSolution(Solution):
@property @property
def documentation_links(self) -> List[str]: def documentation_links(self) -> List[str]:
return [ return [
"https://python-poetry.org/docs/dependency-specification/#python-restricted-dependencies", "https://python-poetry.org/docs/dependency-specification/#python-restricted-dependencies", # noqa: E501
"https://python-poetry.org/docs/dependency-specification/#using-environment-markers", "https://python-poetry.org/docs/dependency-specification/#using-environment-markers", # noqa: E501
] ]
...@@ -109,8 +109,8 @@ class VersionSolver: ...@@ -109,8 +109,8 @@ class VersionSolver:
if result is _conflict: if result is _conflict:
# If the incompatibility is satisfied by the solution, we use # If the incompatibility is satisfied by the solution, we use
# _resolve_conflict() to determine the root cause of the conflict as a # _resolve_conflict() to determine the root cause of the conflict as
# new incompatibility. # a new incompatibility.
# #
# It also backjumps to a point in the solution # It also backjumps to a point in the solution
# where that incompatibility will allow us to derive new assignments # where that incompatibility will allow us to derive new assignments
...@@ -180,13 +180,14 @@ class VersionSolver: ...@@ -180,13 +180,14 @@ class VersionSolver:
def _resolve_conflict(self, incompatibility: Incompatibility) -> Incompatibility: def _resolve_conflict(self, incompatibility: Incompatibility) -> Incompatibility:
""" """
Given an incompatibility that's satisfied by _solution, Given an incompatibility that's satisfied by _solution,
The `conflict resolution`_ constructs a new incompatibility that encapsulates the root The `conflict resolution`_ constructs a new incompatibility that encapsulates
cause of the conflict and backtracks _solution until the new the root cause of the conflict and backtracks _solution until the new
incompatibility will allow _propagate() to deduce new assignments. incompatibility will allow _propagate() to deduce new assignments.
Adds the new incompatibility to _incompatibilities and returns it. Adds the new incompatibility to _incompatibilities and returns it.
.. _conflict resolution: https://github.com/dart-lang/pub/tree/master/doc/solver.md#conflict-resolution .. _conflict resolution:
https://github.com/dart-lang/pub/tree/master/doc/solver.md#conflict-resolution
""" """
self._log(f"conflict: {incompatibility}") self._log(f"conflict: {incompatibility}")
...@@ -286,7 +287,8 @@ class VersionSolver: ...@@ -286,7 +287,8 @@ class VersionSolver:
# the incompatibility as well, See the `algorithm documentation`_ for # the incompatibility as well, See the `algorithm documentation`_ for
# details. # details.
# #
# .. _algorithm documentation: https://github.com/dart-lang/pub/tree/master/doc/solver.md#conflict-resolution # .. _algorithm documentation:
# https://github.com/dart-lang/pub/tree/master/doc/solver.md#conflict-resolution # noqa: E501
if difference is not None: if difference is not None:
new_terms.append(difference.inverse) new_terms.append(difference.inverse)
...@@ -297,7 +299,8 @@ class VersionSolver: ...@@ -297,7 +299,8 @@ class VersionSolver:
partially = "" if difference is None else " partially" partially = "" if difference is None else " partially"
self._log( self._log(
f"! {most_recent_term} is{partially} satisfied by {most_recent_satisfier}" f"! {most_recent_term} is{partially} satisfied by"
f" {most_recent_satisfier}"
) )
self._log(f'! which is caused by "{most_recent_satisfier.cause}"') self._log(f'! which is caused by "{most_recent_satisfier.cause}"')
self._log(f"! thus: {incompatibility}") self._log(f"! thus: {incompatibility}")
......
...@@ -179,7 +179,8 @@ class Locker: ...@@ -179,7 +179,8 @@ class Locker:
root_dir = self._lock.path.parent root_dir = self._lock.path.parent
if package.source_type == "directory": if package.source_type == "directory":
# root dir should be the source of the package relative to the lock path # root dir should be the source of the package relative to the lock
# path
root_dir = Path(package.source_url) root_dir = Path(package.source_url)
if isinstance(constraint, list): if isinstance(constraint, list):
...@@ -290,7 +291,8 @@ class Locker: ...@@ -290,7 +291,8 @@ class Locker:
pinned_versions: bool = False, pinned_versions: bool = False,
with_nested: bool = False, with_nested: bool = False,
) -> Iterable[Dependency]: ) -> Iterable[Dependency]:
# group packages entries by name, this is required because requirement might use different constraints # group packages entries by name, this is required because requirement might use
# different constraints
packages_by_name = {} packages_by_name = {}
for pkg in locked_packages: for pkg in locked_packages:
if pkg.name not in packages_by_name: if pkg.name not in packages_by_name:
...@@ -482,9 +484,10 @@ class Locker: ...@@ -482,9 +484,10 @@ class Locker:
lock_version_allowed = accepted_versions.allows(lock_version) lock_version_allowed = accepted_versions.allows(lock_version)
if lock_version_allowed and current_version < lock_version: if lock_version_allowed and current_version < lock_version:
logger.warning( logger.warning(
"The lock file might not be compatible with the current version of Poetry.\n" "The lock file might not be compatible with the current version of"
"Upgrade Poetry to ensure the lock file is read properly or, alternatively, " " Poetry.\nUpgrade Poetry to ensure the lock file is read properly or,"
"regenerate the lock file with the `poetry lock` command." " alternatively, regenerate the lock file with the `poetry lock`"
" command."
) )
elif not lock_version_allowed: elif not lock_version_allowed:
raise RuntimeError( raise RuntimeError(
......
...@@ -89,8 +89,9 @@ class Publisher: ...@@ -89,8 +89,9 @@ class Publisher:
if repository_name == "pypi": if repository_name == "pypi":
repository_name = "PyPI" repository_name = "PyPI"
self._io.write_line( self._io.write_line(
f"Publishing <c1>{self._package.pretty_name}</c1> (<c2>{self._package.pretty_version}</c2>) " f"Publishing <c1>{self._package.pretty_name}</c1>"
f"to <info>{repository_name}</info>" f" (<c2>{self._package.pretty_version}</c2>) to"
f" <info>{repository_name}</info>"
) )
self._uploader.upload( self._uploader.upload(
......
...@@ -83,7 +83,8 @@ class Uploader: ...@@ -83,7 +83,8 @@ class Uploader:
wheels = list( wheels = list(
dist.glob( dist.glob(
f"{escape_name(self._package.pretty_name)}-{escape_version(version)}-*.whl" f"{escape_name(self._package.pretty_name)}-{escape_version(version)}"
"-*.whl"
) )
) )
tars = list(dist.glob(f"{self._package.pretty_name}-{version}.tar.gz")) tars = list(dist.glob(f"{self._package.pretty_name}-{version}.tar.gz"))
...@@ -295,7 +296,7 @@ class Uploader: ...@@ -295,7 +296,7 @@ class Uploader:
dist = self._poetry.file.parent / "dist" dist = self._poetry.file.parent / "dist"
file = ( file = (
dist dist
/ f"{self._package.name}-{normalize_version(self._package.version.text)}.tar.gz" / f"{self._package.name}-{normalize_version(self._package.version.text)}.tar.gz" # noqa: E501
) )
if not file.exists(): if not file.exists():
......
...@@ -258,7 +258,8 @@ class Provider: ...@@ -258,7 +258,8 @@ 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(
f"The dependency name for {dependency.name} does not match the actual package's name: {package.name}" f"The dependency name for {dependency.name} does not match the actual"
f" package's name: {package.name}"
) )
if dependency.base is not None: if dependency.base is not None:
...@@ -318,7 +319,8 @@ class Provider: ...@@ -318,7 +319,8 @@ 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(
f"The dependency name for {name} does not match the actual package's name: {package.name}" f"The dependency name for {name} does not match the actual package's"
f" name: {package.name}"
) )
return package return package
...@@ -332,7 +334,8 @@ class Provider: ...@@ -332,7 +334,8 @@ 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(
f"The dependency name for {dependency.name} does not match the actual package's name: {package.name}" f"The dependency name for {dependency.name} does not match the actual"
f" package's name: {package.name}"
) )
for extra in dependency.extras: for extra in dependency.extras:
...@@ -631,8 +634,8 @@ class Provider: ...@@ -631,8 +634,8 @@ class Provider:
def fmt_warning(d: "Dependency") -> str: def fmt_warning(d: "Dependency") -> str:
marker = d.marker if not d.marker.is_any() else "*" marker = d.marker if not d.marker.is_any() else "*"
return ( return (
f"<c1>{d.name}</c1> <fg=default>(<c2>{d.pretty_constraint}</c2>)</> " f"<c1>{d.name}</c1> <fg=default>(<c2>{d.pretty_constraint}</c2>)</>"
f"with markers <b>{marker}</b>" f" with markers <b>{marker}</b>"
) )
warnings = ", ".join(fmt_warning(d) for d in _deps[:-1]) warnings = ", ".join(fmt_warning(d) for d in _deps[:-1])
...@@ -673,7 +676,8 @@ class Provider: ...@@ -673,7 +676,8 @@ class Provider:
dep_other.set_constraint( dep_other.set_constraint(
dep_other.constraint.intersect(dep_any.constraint) dep_other.constraint.intersect(dep_any.constraint)
) )
# TODO: Setting _pretty_constraint can be removed once the following issue has been fixed # TODO: Setting _pretty_constraint can be removed once the
# following issue has been fixed:
# https://github.com/python-poetry/poetry/issues/4589 # https://github.com/python-poetry/poetry/issues/4589
dep_other._pretty_constraint = str(dep_other.constraint) dep_other._pretty_constraint = str(dep_other.constraint)
...@@ -765,7 +769,10 @@ class Provider: ...@@ -765,7 +769,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 = f"<fg=blue>derived</>: <c1>{m.group(1)}</c1> (<c2>{m.group(2)}</c2>)" message = (
f"<fg=blue>derived</>: <c1>{m.group(1)}</c1>"
f" (<c2>{m.group(2)}</c2>)"
)
else: else:
message = ( message = (
f"<fg=blue>derived</>: <c1>{message.split('derived: ')[1]}</c1>" f"<fg=blue>derived</>: <c1>{message.split('derived: ')[1]}</c1>"
...@@ -786,7 +793,10 @@ class Provider: ...@@ -786,7 +793,10 @@ class Provider:
f"depends on <c1>{m.group(2)}</c1> (<c2>{m.group(3)}</c2>)" f"depends on <c1>{m.group(2)}</c1> (<c2>{m.group(3)}</c2>)"
) )
else: else:
message = f"<fg=red;options=bold>conflict</>: {message.split('conflict: ')[1]}" message = (
"<fg=red;options=bold>conflict</>:"
f" {message.split('conflict: ')[1]}"
)
message = message.replace("! ", "<error>!</error> ") message = message.replace("! ", "<error>!</error> ")
......
...@@ -78,10 +78,12 @@ class Solver: ...@@ -78,10 +78,12 @@ class Solver:
if len(self._overrides) > 1: if len(self._overrides) > 1:
self._provider.debug( self._provider.debug(
f"Complete version solving took {end - start:.3f} seconds with {len(self._overrides)} overrides" f"Complete version solving took {end - start:.3f} seconds with"
f" {len(self._overrides)} overrides"
) )
self._provider.debug( self._provider.debug(
f"Resolved with overrides: {', '.join(f'({b})' for b in self._overrides)}" "Resolved with overrides:"
f" {', '.join(f'({b})' for b in self._overrides)}"
) )
return Transaction( return Transaction(
...@@ -140,7 +142,8 @@ class Solver: ...@@ -140,7 +142,8 @@ class Solver:
except SolveFailure as e: except SolveFailure as e:
raise SolverProblemError(e) raise SolverProblemError(e)
# NOTE passing explicit empty array for seen to reset between invocations during update + install cycle # NOTE passing explicit empty array for seen to reset between invocations during
# update + install cycle
results = dict( results = dict(
depth_first_search( depth_first_search(
PackageNode(self._package, packages, seen=[]), aggregate_package_nodes PackageNode(self._package, packages, seen=[]), aggregate_package_nodes
......
...@@ -79,9 +79,9 @@ class Transaction: ...@@ -79,9 +79,9 @@ class Transaction:
current_package_names = { current_package_names = {
current_package.name for current_package in self._current_packages current_package.name for current_package in self._current_packages
} }
# We preserve pip/setuptools/wheel when not managed by poetry, this is done # We preserve pip/setuptools/wheel when not managed by poetry, this is
# to avoid externally managed virtual environments causing unnecessary # done to avoid externally managed virtual environments causing
# removals. # unnecessary removals.
preserved_package_names = { preserved_package_names = {
"pip", "pip",
"setuptools", "setuptools",
......
...@@ -49,8 +49,8 @@ class InstalledRepository(Repository): ...@@ -49,8 +49,8 @@ class InstalledRepository(Repository):
paths = set() paths = set()
# we identify the candidate pth files to check, this is done so to handle cases # we identify the candidate pth files to check, this is done so to handle cases
# where the pth file for foo-bar might have been installed as either foo-bar.pth or # where the pth file for foo-bar might have been installed as either foo-bar.pth
# foo_bar.pth (expected) in either pure or platform lib directories. # or foo_bar.pth (expected) in either pure or platform lib directories.
candidates = itertools.product( candidates = itertools.product(
{env.purelib, env.platlib}, {env.purelib, env.platlib},
{name, module_name(name)}, {name, module_name(name)},
......
...@@ -342,7 +342,8 @@ class LegacyRepository(PyPiRepository): ...@@ -342,7 +342,8 @@ 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(
f'No valid distribution links found for package: "{name}" version: "{version}"' f'No valid distribution links found for package: "{name}" version:'
f' "{version}"'
) )
urls = defaultdict(list) urls = defaultdict(list)
files = [] files = []
......
...@@ -121,7 +121,8 @@ class PyPiRepository(RemoteRepository): ...@@ -121,7 +121,8 @@ class PyPiRepository(RemoteRepository):
if not release: if not release:
# Bad release # Bad release
self._log( self._log(
f"No release information found for {dependency.name}-{version}, skipping", f"No release information found for {dependency.name}-{version},"
" skipping",
level="debug", level="debug",
) )
continue continue
...@@ -130,7 +131,8 @@ class PyPiRepository(RemoteRepository): ...@@ -130,7 +131,8 @@ class PyPiRepository(RemoteRepository):
package = Package(info["info"]["name"], version) package = Package(info["info"]["name"], version)
except InvalidVersion: except InvalidVersion:
self._log( self._log(
f'Unable to parse version "{version}" for the {dependency.name} package, skipping', f'Unable to parse version "{version}" for the'
f" {dependency.name} package, skipping",
level="debug", level="debug",
) )
continue continue
...@@ -183,7 +185,8 @@ class PyPiRepository(RemoteRepository): ...@@ -183,7 +185,8 @@ class PyPiRepository(RemoteRepository):
results.append(result) results.append(result)
except InvalidVersion: except InvalidVersion:
self._log( self._log(
f'Unable to parse version "{version}" for the {name} package, skipping', f'Unable to parse version "{version}" for the {name} package,'
" skipping",
level="debug", level="debug",
) )
......
...@@ -117,7 +117,9 @@ env = { ...@@ -117,7 +117,9 @@ env = {
"sys_platform": sys.platform, "sys_platform": sys.platform,
"version_info": tuple(sys.version_info), "version_info": tuple(sys.version_info),
# Extra information # Extra information
"interpreter_name": INTERPRETER_SHORT_NAMES.get(implementation_name, implementation_name), "interpreter_name": INTERPRETER_SHORT_NAMES.get(
implementation_name, implementation_name
),
"interpreter_version": interpreter_version(), "interpreter_version": interpreter_version(),
} }
...@@ -142,6 +144,10 @@ import sys ...@@ -142,6 +144,10 @@ import sys
print('.'.join([str(s) for s in sys.version_info[:3]])) print('.'.join([str(s) for s in sys.version_info[:3]]))
""" """
GET_PYTHON_VERSION_ONELINER = (
"\"import sys; print('.'.join([str(s) for s in sys.version_info[:3]]))\""
)
GET_SYS_PATH = """\ GET_SYS_PATH = """\
import json import json
import sys import sys
...@@ -262,7 +268,8 @@ class SitePackages: ...@@ -262,7 +268,8 @@ class SitePackages:
if not results and strict: if not results and strict:
raise RuntimeError( raise RuntimeError(
f'Unable to find a suitable destination for "{path}" in {paths_csv(self._candidates)}' f'Unable to find a suitable destination for "{path}" in'
f" {paths_csv(self._candidates)}"
) )
return results return results
...@@ -416,7 +423,10 @@ class EnvCommandError(EnvError): ...@@ -416,7 +423,10 @@ 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 = f"Command {e.cmd} errored with the following return code {e.returncode}, and output: \n{decode(e.output)}" message = (
f"Command {e.cmd} errored with the following return code {e.returncode},"
f" and output: \n{decode(e.output)}"
)
if input: if input:
message += f"input was : {input}" message += f"input was : {input}"
super().__init__(message) super().__init__(message)
...@@ -477,13 +487,7 @@ class EnvManager: ...@@ -477,13 +487,7 @@ class EnvManager:
try: try:
python_version = decode( python_version = decode(
subprocess.check_output( subprocess.check_output(
list_to_shell_command( list_to_shell_command([python, "-c", GET_PYTHON_VERSION_ONELINER]),
[
python,
"-c",
"\"import sys; print('.'.join([str(s) for s in sys.version_info[:3]]))\"",
]
),
shell=True, shell=True,
) )
) )
...@@ -723,13 +727,7 @@ class EnvManager: ...@@ -723,13 +727,7 @@ class EnvManager:
try: try:
python_version = decode( python_version = decode(
subprocess.check_output( subprocess.check_output(
list_to_shell_command( list_to_shell_command([python, "-c", GET_PYTHON_VERSION_ONELINER]),
[
python,
"-c",
"\"import sys; print('.'.join([str(s) for s in sys.version_info[:3]]))\"",
]
),
shell=True, shell=True,
) )
) )
...@@ -799,11 +797,7 @@ class EnvManager: ...@@ -799,11 +797,7 @@ class EnvManager:
python_patch = decode( python_patch = decode(
subprocess.check_output( subprocess.check_output(
list_to_shell_command( list_to_shell_command(
[ [executable, "-c", GET_PYTHON_VERSION_ONELINER]
executable,
"-c",
"\"import sys; print('.'.join([str(s) for s in sys.version_info[:3]]))\"",
]
), ),
shell=True, shell=True,
).strip() ).strip()
...@@ -824,8 +818,8 @@ class EnvManager: ...@@ -824,8 +818,8 @@ class EnvManager:
) )
io.write_line( io.write_line(
f"<warning>The currently activated Python version {python_patch} " f"<warning>The currently activated Python version {python_patch} is not"
f"is not supported by the project ({self._poetry.package.python_versions}).\n" f" supported by the project ({self._poetry.package.python_versions}).\n"
"Trying to find and use a compatible version.</warning> " "Trying to find and use a compatible version.</warning> "
) )
...@@ -853,11 +847,7 @@ class EnvManager: ...@@ -853,11 +847,7 @@ class EnvManager:
python_patch = decode( python_patch = decode(
subprocess.check_output( subprocess.check_output(
list_to_shell_command( list_to_shell_command(
[ [python, "-c", GET_PYTHON_VERSION_ONELINER]
python,
"-c",
"\"import sys; print('.'.join([str(s) for s in sys.version_info[:3]]))\"",
]
), ),
stderr=subprocess.STDOUT, stderr=subprocess.STDOUT,
shell=True, shell=True,
...@@ -904,7 +894,8 @@ class EnvManager: ...@@ -904,7 +894,8 @@ class EnvManager:
if force: if force:
if not env.is_sane(): if not env.is_sane():
io.write_line( io.write_line(
f"<warning>The virtual environment found in {env.path} seems to be broken.</warning>" f"<warning>The virtual environment found in {env.path} seems to"
" be broken.</warning>"
) )
io.write_line(f"Recreating virtualenv <c1>{name}</> in {venv!s}") io.write_line(f"Recreating virtualenv <c1>{name}</> in {venv!s}")
self.remove_venv(venv) self.remove_venv(venv)
...@@ -965,7 +956,8 @@ class EnvManager: ...@@ -965,7 +956,8 @@ class EnvManager:
else flags.pop("no-setuptools", True) else flags.pop("no-setuptools", True)
) )
# we want wheels to be enabled when pip is required and it has not been explicitly disabled # we want wheels to be enabled when pip is required and it has not been
# explicitly disabled
flags["no-wheel"] = ( flags["no-wheel"] = (
not with_wheel not with_wheel
if with_wheel is not None if with_wheel is not None
...@@ -1174,7 +1166,8 @@ class Env: ...@@ -1174,7 +1166,8 @@ class Env:
""" """
Path to current pip executable Path to current pip executable
""" """
# we do not use as_posix() here due to issues with windows pathlib2 implementation # we do not use as_posix() here due to issues with windows pathlib2
# implementation
path = self._bin(self._pip_executable) path = self._bin(self._pip_executable)
if not Path(path).exists(): if not Path(path).exists():
return str(self.pip_embedded) return str(self.pip_embedded)
......
...@@ -28,9 +28,10 @@ def pip_install( ...@@ -28,9 +28,10 @@ def pip_install(
path = url_to_path(path.url) if isinstance(path, Link) else path path = url_to_path(path.url) if isinstance(path, Link) else path
is_wheel = path.suffix == ".whl" is_wheel = path.suffix == ".whl"
# We disable version check here as we are already pinning to version available in either the # We disable version check here as we are already pinning to version available in
# virtual environment or the virtualenv package embedded wheel. Version checks are a wasteful # either the virtual environment or the virtualenv package embedded wheel. Version
# network call that adds a lot of wait time when installing a lot of packages. # checks are a wasteful network call that adds a lot of wait time when installing a
# lot of packages.
args = ["install", "--disable-pip-version-check", "--prefix", str(environment.path)] args = ["install", "--disable-pip-version-check", "--prefix", str(environment.path)]
if not is_wheel: if not is_wheel:
...@@ -55,8 +56,9 @@ def pip_install( ...@@ -55,8 +56,9 @@ def pip_install(
return environment.run_pip(*args) return environment.run_pip(*args)
except EnvCommandError as e: except EnvCommandError as e:
if sys.version_info < (3, 7) and not is_wheel: if sys.version_info < (3, 7) and not is_wheel:
# Under certain Python3.6 installs vendored pip wheel does not contain zip-safe # Under certain Python3.6 installs vendored pip wheel does not contain
# pep517 lib. In this cases we create an isolated ephemeral virtual environment. # zip-safe pep517 lib. In this cases we create an isolated ephemeral virtual
# environment.
with ephemeral_environment( with ephemeral_environment(
executable=environment.python, with_pip=True, with_setuptools=True executable=environment.python, with_pip=True, with_setuptools=True
) as env: ) as env:
......
...@@ -192,12 +192,15 @@ poetry-plugin = "^1.2.3" ...@@ -192,12 +192,15 @@ poetry-plugin = "^1.2.3"
tester.execute("poetry-plugin") tester.execute("poetry-plugin")
expected = """\ expected = """\
The following plugins are already present in the pyproject.toml file and will be skipped: The following plugins are already present in the pyproject.toml file and will be\
skipped:
• poetry-plugin • poetry-plugin
If you want to update it to the latest compatible version, you can use `poetry plugin update package`. If you want to update it to the latest compatible version,\
If you prefer to upgrade it to the latest available version, you can use `poetry plugin add package@latest`. you can use `poetry plugin update package`.
If you prefer to upgrade it to the latest available version,\
you can use `poetry plugin add package@latest`.
""" """
......
...@@ -78,7 +78,8 @@ def test_source_add_error_pypi(tester: "CommandTester"): ...@@ -78,7 +78,8 @@ def test_source_add_error_pypi(tester: "CommandTester"):
tester.execute("pypi https://test.pypi.org/simple/") tester.execute("pypi https://test.pypi.org/simple/")
assert ( assert (
tester.io.fetch_error().strip() tester.io.fetch_error().strip()
== "Failed to validate addition of pypi: The name [pypi] is reserved for repositories" == "Failed to validate addition of pypi: The name [pypi] is reserved for"
" repositories"
) )
assert tester.status_code == 1 assert tester.status_code == 1
...@@ -89,7 +90,7 @@ def test_source_add_existing( ...@@ -89,7 +90,7 @@ def test_source_add_existing(
tester.execute(f"--default {source_existing.name} {source_existing.url}") tester.execute(f"--default {source_existing.name} {source_existing.url}")
assert ( assert (
tester.io.fetch_output().strip() tester.io.fetch_output().strip()
== f"Source with name {source_existing.name} already exits. Updating." == f"Source with name {source_existing.name} already exists. Updating."
) )
poetry_with_source.pyproject.reload() poetry_with_source.pyproject.reload()
......
...@@ -19,7 +19,8 @@ def test_about(tester: "CommandTester"): ...@@ -19,7 +19,8 @@ def test_about(tester: "CommandTester"):
expected = """\ expected = """\
Poetry - Package Management for Python Poetry - Package Management for Python
Poetry is a dependency manager tracking local dependencies of your projects and libraries. Poetry is a dependency manager tracking local dependencies of your projects and\
libraries.
See https://github.com/python-poetry/poetry for more information. See https://github.com/python-poetry/poetry for more information.
""" """
......
...@@ -77,7 +77,8 @@ def test_add_no_constraint_editable_error( ...@@ -77,7 +77,8 @@ def test_add_no_constraint_editable_error(
tester.execute("-e cachy") tester.execute("-e cachy")
expected = """ expected = """
Failed to add packages. Only vcs/path dependencies support editable installs. cachy is neither. Failed to add packages. Only vcs/path dependencies support editable installs.\
cachy is neither.
No changes were applied. No changes were applied.
""" """
...@@ -565,7 +566,8 @@ Writing lock file ...@@ -565,7 +566,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 https://python-poetry.org/distributions/demo-0.1.0-py2.py3-none-any.whl) • Installing demo\
(0.1.0 https://python-poetry.org/distributions/demo-0.1.0-py2.py3-none-any.whl)
""" """
assert expected == tester.io.fetch_output() assert expected == tester.io.fetch_output()
...@@ -590,7 +592,8 @@ def test_add_url_constraint_wheel_with_extras( ...@@ -590,7 +592,8 @@ def test_add_url_constraint_wheel_with_extras(
repo.add_package(get_package("tomlkit", "0.5.5")) repo.add_package(get_package("tomlkit", "0.5.5"))
tester.execute( tester.execute(
"https://python-poetry.org/distributions/demo-0.1.0-py2.py3-none-any.whl[foo,bar]" "https://python-poetry.org/distributions/demo-0.1.0-py2.py3-none-any.whl"
"[foo,bar]"
) )
expected = """\ expected = """\
...@@ -605,7 +608,8 @@ Package operations: 4 installs, 0 updates, 0 removals ...@@ -605,7 +608,8 @@ Package operations: 4 installs, 0 updates, 0 removals
• Installing cleo (0.6.5) • Installing cleo (0.6.5)
• Installing pendulum (1.4.4) • Installing pendulum (1.4.4)
• Installing tomlkit (0.5.5) • Installing tomlkit (0.5.5)
• Installing demo (0.1.0 https://python-poetry.org/distributions/demo-0.1.0-py2.py3-none-any.whl) • Installing demo\
(0.1.0 https://python-poetry.org/distributions/demo-0.1.0-py2.py3-none-any.whl)
""" """
# Order might be different, split into lines and compare the overall output. # Order might be different, split into lines and compare the overall output.
expected = set(expected.splitlines()) expected = set(expected.splitlines())
...@@ -617,7 +621,9 @@ Package operations: 4 installs, 0 updates, 0 removals ...@@ -617,7 +621,9 @@ Package operations: 4 installs, 0 updates, 0 removals
assert "demo" in content["dependencies"] assert "demo" in content["dependencies"]
assert content["dependencies"]["demo"] == { assert content["dependencies"]["demo"] == {
"url": "https://python-poetry.org/distributions/demo-0.1.0-py2.py3-none-any.whl", "url": (
"https://python-poetry.org/distributions/demo-0.1.0-py2.py3-none-any.whl"
),
"extras": ["foo", "bar"], "extras": ["foo", "bar"],
} }
...@@ -873,8 +879,10 @@ The following packages are already present in the pyproject.toml and will be ski ...@@ -873,8 +879,10 @@ The following packages are already present in the pyproject.toml and will be ski
• foo • foo
If you want to update it to the latest compatible version, you can use `poetry update package`. If you want to update it to the latest compatible version,\
If you prefer to upgrade it to the latest available version, you can use `poetry add package@latest`. you can use `poetry update package`.
If you prefer to upgrade it to the latest available version,\
you can use `poetry add package@latest`.
""" """
assert expected in tester.io.fetch_output() assert expected in tester.io.fetch_output()
...@@ -1502,7 +1510,8 @@ Writing lock file ...@@ -1502,7 +1510,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 https://python-poetry.org/distributions/demo-0.1.0-py2.py3-none-any.whl) - Installing demo\
(0.1.0 https://python-poetry.org/distributions/demo-0.1.0-py2.py3-none-any.whl)
""" """
assert expected == old_tester.io.fetch_output() assert expected == old_tester.io.fetch_output()
...@@ -1528,7 +1537,8 @@ def test_add_url_constraint_wheel_with_extras_old_installer( ...@@ -1528,7 +1537,8 @@ def test_add_url_constraint_wheel_with_extras_old_installer(
repo.add_package(get_package("tomlkit", "0.5.5")) repo.add_package(get_package("tomlkit", "0.5.5"))
old_tester.execute( old_tester.execute(
"https://python-poetry.org/distributions/demo-0.1.0-py2.py3-none-any.whl[foo,bar]" "https://python-poetry.org/distributions/demo-0.1.0-py2.py3-none-any.whl"
"[foo,bar]"
) )
expected = """\ expected = """\
...@@ -1543,7 +1553,8 @@ Package operations: 4 installs, 0 updates, 0 removals ...@@ -1543,7 +1553,8 @@ Package operations: 4 installs, 0 updates, 0 removals
- Installing cleo (0.6.5) - Installing cleo (0.6.5)
- Installing pendulum (1.4.4) - Installing pendulum (1.4.4)
- Installing tomlkit (0.5.5) - Installing tomlkit (0.5.5)
- Installing demo (0.1.0 https://python-poetry.org/distributions/demo-0.1.0-py2.py3-none-any.whl) - Installing demo\
(0.1.0 https://python-poetry.org/distributions/demo-0.1.0-py2.py3-none-any.whl)
""" """
assert expected == old_tester.io.fetch_output() assert expected == old_tester.io.fetch_output()
...@@ -1554,7 +1565,9 @@ Package operations: 4 installs, 0 updates, 0 removals ...@@ -1554,7 +1565,9 @@ Package operations: 4 installs, 0 updates, 0 removals
assert "demo" in content["dependencies"] assert "demo" in content["dependencies"]
assert content["dependencies"]["demo"] == { assert content["dependencies"]["demo"] == {
"url": "https://python-poetry.org/distributions/demo-0.1.0-py2.py3-none-any.whl", "url": (
"https://python-poetry.org/distributions/demo-0.1.0-py2.py3-none-any.whl"
),
"extras": ["foo", "bar"], "extras": ["foo", "bar"],
} }
...@@ -1791,14 +1804,16 @@ The following packages are already present in the pyproject.toml and will be ski ...@@ -1791,14 +1804,16 @@ The following packages are already present in the pyproject.toml and will be ski
• foo • foo
If you want to update it to the latest compatible version, you can use `poetry update package`. If you want to update it to the latest compatible version,\
If you prefer to upgrade it to the latest available version, you can use `poetry add package@latest`. you can use `poetry update package`.
If you prefer to upgrade it to the latest available version,\
you can use `poetry add package@latest`.
""" """
assert expected in old_tester.io.fetch_output() assert expected in old_tester.io.fetch_output()
def test_add_should_work_when_adding_existing_package_with_latest_constraint_old_installer( def test_add_should_work_when_adding_existing_package_with_latest_constraint_old_installer( # noqa: E501
app: "PoetryTestApplication", app: "PoetryTestApplication",
repo: "TestRepository", repo: "TestRepository",
installer: "NoopInstaller", installer: "NoopInstaller",
......
...@@ -39,8 +39,10 @@ def test_check_invalid(mocker: "MockerFixture", tester: "CommandTester"): ...@@ -39,8 +39,10 @@ def test_check_invalid(mocker: "MockerFixture", tester: "CommandTester"):
expected = """\ expected = """\
Error: 'description' is a required property Error: 'description' is a required property
Warning: A wildcard Python dependency is ambiguous. Consider specifying a more explicit one. Warning: A wildcard Python dependency is ambiguous.\
Warning: The "pendulum" dependency specifies the "allows-prereleases" property, which is deprecated. Use "allow-prereleases" instead. Consider specifying a more explicit one.
Warning: The "pendulum" dependency specifies the "allows-prereleases" property,\
which is deprecated. Use "allow-prereleases" instead.
""" """
assert expected == tester.io.fetch_output() assert expected == tester.io.fetch_output()
...@@ -67,7 +67,8 @@ sqlalchemy-wrap (2.1.7) ...@@ -67,7 +67,8 @@ sqlalchemy-wrap (2.1.7)
Python wrapper for the CircleCI API Python wrapper for the CircleCI API
sqlalchemy-nav (0.0.2) sqlalchemy-nav (0.0.2)
SQLAlchemy-Nav provides SQLAlchemy Mixins for creating navigation bars compatible with Bootstrap SQLAlchemy-Nav provides SQLAlchemy Mixins for creating navigation bars compatible with\
Bootstrap
sqlalchemy-repr (0.0.1) sqlalchemy-repr (0.0.1)
Automatically generates pretty repr of a SQLAlchemy model. Automatically generates pretty repr of a SQLAlchemy model.
......
...@@ -386,8 +386,10 @@ def test_show_latest_decorated( ...@@ -386,8 +386,10 @@ def test_show_latest_decorated(
tester.execute("--latest", decorated=True) tester.execute("--latest", decorated=True)
expected = """\ expected = """\
\033[36mcachy \033[39m \033[39;1m0.1.0\033[39;22m \033[33m0.2.0\033[39m Cachy package \033[36mcachy \033[39m \033[39;1m0.1.0\033[39;22m\
\033[36mpendulum\033[39m \033[39;1m2.0.0\033[39;22m \033[31m2.0.1\033[39m Pendulum package \033[33m0.2.0\033[39m Cachy package
\033[36mpendulum\033[39m \033[39;1m2.0.0\033[39;22m\
\033[31m2.0.1\033[39m Pendulum package
""" """
assert expected == tester.io.fetch_output() assert expected == tester.io.fetch_output()
...@@ -898,7 +900,9 @@ def test_show_outdated_git_dev_dependency( ...@@ -898,7 +900,9 @@ def test_show_outdated_git_dev_dependency(
"source": { "source": {
"type": "git", "type": "git",
"reference": "9cf87a285a2d3fbb0b9fa621997b3acc3631ed24", "reference": "9cf87a285a2d3fbb0b9fa621997b3acc3631ed24",
"resolved_reference": "9cf87a285a2d3fbb0b9fa621997b3acc3631ed24", "resolved_reference": (
"9cf87a285a2d3fbb0b9fa621997b3acc3631ed24"
),
"url": "https://github.com/demo/demo.git", "url": "https://github.com/demo/demo.git",
}, },
}, },
......
...@@ -216,6 +216,7 @@ class TestRepository(Repository): ...@@ -216,6 +216,7 @@ 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(
f"https://foo.bar/files/{escape_name(package.name)}-{escape_version(package.version.text)}-py2.py3-none-any.whl" f"https://foo.bar/files/{escape_name(package.name)}"
f"-{escape_version(package.version.text)}-py2.py3-none-any.whl"
) )
] ]
...@@ -90,7 +90,7 @@ def demo_setup_complex(source_dir: Path) -> Path: ...@@ -90,7 +90,7 @@ def demo_setup_complex(source_dir: Path) -> Path:
def demo_setup_complex_pep517_legacy(demo_setup_complex: Path) -> Path: def demo_setup_complex_pep517_legacy(demo_setup_complex: Path) -> Path:
pyproject_toml = demo_setup_complex / "pyproject.toml" pyproject_toml = demo_setup_complex / "pyproject.toml"
pyproject_toml.write_text( pyproject_toml.write_text(
decode("[build-system]\n" 'requires = ["setuptools", "wheel"]') decode('[build-system]\nrequires = ["setuptools", "wheel"]')
) )
return demo_setup_complex return demo_setup_complex
......
...@@ -83,7 +83,8 @@ def test_get_cache_directory_for_link(config: "Config", config_cache_dir: Path): ...@@ -83,7 +83,8 @@ def test_get_cache_directory_for_link(config: "Config", config_cache_dir: Path):
) )
expected = Path( expected = Path(
f"{config_cache_dir.as_posix()}/artifacts/ba/63/13/283a3b3b7f95f05e9e6f84182d276f7bb0951d5b0cc24422b33f7a4648" f"{config_cache_dir.as_posix()}/artifacts/ba/63/13/"
"283a3b3b7f95f05e9e6f84182d276f7bb0951d5b0cc24422b33f7a4648"
) )
assert expected == directory assert expected == directory
...@@ -207,7 +207,7 @@ def test_chooser_chooses_distributions_that_match_the_package_hashes( ...@@ -207,7 +207,7 @@ def test_chooser_chooses_distributions_that_match_the_package_hashes(
package = Package("isort", "4.3.4") package = Package("isort", "4.3.4")
files = [ files = [
{ {
"hash": "sha256:b9c40e9750f3d77e6e4d441d8b0266cf555e7cdabdcff33c4fd06366ca761ef8", "hash": "sha256:b9c40e9750f3d77e6e4d441d8b0266cf555e7cdabdcff33c4fd06366ca761ef8", # noqa: E501
"filename": "isort-4.3.4.tar.gz", "filename": "isort-4.3.4.tar.gz",
} }
] ]
...@@ -240,7 +240,7 @@ def test_chooser_throws_an_error_if_package_hashes_do_not_match( ...@@ -240,7 +240,7 @@ def test_chooser_throws_an_error_if_package_hashes_do_not_match(
package = Package("isort", "4.3.4") package = Package("isort", "4.3.4")
files = [ files = [
{ {
"hash": "sha256:0000000000000000000000000000000000000000000000000000000000000000", "hash": "sha256:0000000000000000000000000000000000000000000000000000000000000000", # noqa: E501
"filename": "isort-4.3.4.tar.gz", "filename": "isort-4.3.4.tar.gz",
} }
] ]
......
...@@ -251,13 +251,16 @@ def test_execute_works_with_ansi_output( ...@@ -251,13 +251,16 @@ def test_execute_works_with_ansi_output(
) )
env._run.assert_called_once() env._run.assert_called_once()
# fmt: off
expected = [ expected = [
"\x1b[39;1mPackage operations\x1b[39;22m: \x1b[34m1\x1b[39m install, \x1b[34m0\x1b[39m updates, \x1b[34m0\x1b[39m removals", "\x1b[39;1mPackage operations\x1b[39;22m: \x1b[34m1\x1b[39m install, \x1b[34m0\x1b[39m updates, \x1b[34m0\x1b[39m removals", # noqa: E501
"\x1b[34;1m•\x1b[39;22m \x1b[39mInstalling \x1b[39m\x1b[36mpytest\x1b[39m\x1b[39m (\x1b[39m\x1b[39;1m3.5.2\x1b[39;22m\x1b[39m)\x1b[39m: \x1b[34mPending...\x1b[39m", "\x1b[34;1m•\x1b[39;22m \x1b[39mInstalling \x1b[39m\x1b[36mpytest\x1b[39m\x1b[39m (\x1b[39m\x1b[39;1m3.5.2\x1b[39;22m\x1b[39m)\x1b[39m: \x1b[34mPending...\x1b[39m", # noqa: E501
"\x1b[34;1m•\x1b[39;22m \x1b[39mInstalling \x1b[39m\x1b[36mpytest\x1b[39m\x1b[39m (\x1b[39m\x1b[39;1m3.5.2\x1b[39;22m\x1b[39m)\x1b[39m: \x1b[34mDownloading...\x1b[39m", "\x1b[34;1m•\x1b[39;22m \x1b[39mInstalling \x1b[39m\x1b[36mpytest\x1b[39m\x1b[39m (\x1b[39m\x1b[39;1m3.5.2\x1b[39;22m\x1b[39m)\x1b[39m: \x1b[34mDownloading...\x1b[39m", # noqa: E501
"\x1b[34;1m•\x1b[39;22m \x1b[39mInstalling \x1b[39m\x1b[36mpytest\x1b[39m\x1b[39m (\x1b[39m\x1b[39;1m3.5.2\x1b[39;22m\x1b[39m)\x1b[39m: \x1b[34mInstalling...\x1b[39m", "\x1b[34;1m•\x1b[39;22m \x1b[39mInstalling \x1b[39m\x1b[36mpytest\x1b[39m\x1b[39m (\x1b[39m\x1b[39;1m3.5.2\x1b[39;22m\x1b[39m)\x1b[39m: \x1b[34mInstalling...\x1b[39m", # noqa: E501
"\x1b[32;1m•\x1b[39;22m \x1b[39mInstalling \x1b[39m\x1b[36mpytest\x1b[39m\x1b[39m (\x1b[39m\x1b[32m3.5.2\x1b[39m\x1b[39m)\x1b[39m", # finished "\x1b[32;1m•\x1b[39;22m \x1b[39mInstalling \x1b[39m\x1b[36mpytest\x1b[39m\x1b[39m (\x1b[39m\x1b[32m3.5.2\x1b[39m\x1b[39m)\x1b[39m", # finished # noqa: E501
] ]
# fmt: on
output = io_decorated.fetch_output() output = io_decorated.fetch_output()
# hint: use print(repr(output)) if you need to debug this # hint: use print(repr(output)) if you need to debug this
...@@ -542,7 +545,7 @@ def test_executor_should_use_cached_link_and_hash( ...@@ -542,7 +545,7 @@ def test_executor_should_use_cached_link_and_hash(
package.files = [ package.files = [
{ {
"file": "demo-0.1.0-py2.py3-none-any.whl", "file": "demo-0.1.0-py2.py3-none-any.whl",
"hash": "sha256:70e704135718fffbcbf61ed1fc45933cfd86951a744b681000eaaa75da31f17a", "hash": "sha256:70e704135718fffbcbf61ed1fc45933cfd86951a744b681000eaaa75da31f17a", # noqa: E501
} }
] ]
......
...@@ -497,7 +497,7 @@ def test_run_install_does_not_remove_locked_packages_if_installed_but_not_requir ...@@ -497,7 +497,7 @@ def test_run_install_does_not_remove_locked_packages_if_installed_but_not_requir
assert installer.executor.removals_count == 0 assert installer.executor.removals_count == 0
def test_run_install_removes_locked_packages_if_installed_and_synchronization_is_required( def test_run_install_removes_locked_packages_if_installed_and_synchronization_is_required( # noqa: E501
installer: Installer, installer: Installer,
locker: Locker, locker: Locker,
repo: Repository, repo: Repository,
...@@ -1873,7 +1873,7 @@ def test_run_install_duplicate_dependencies_different_constraints_with_lock_upda ...@@ -1873,7 +1873,7 @@ def test_run_install_duplicate_dependencies_different_constraints_with_lock_upda
@pytest.mark.skip( @pytest.mark.skip(
"This is not working at the moment due to limitations in the resolver" "This is not working at the moment due to limitations in the resolver"
) )
def test_installer_test_solver_finds_compatible_package_for_dependency_python_not_fully_compatible_with_package_python( def test_installer_test_solver_finds_compatible_package_for_dependency_python_not_fully_compatible_with_package_python( # noqa: E501
installer: Installer, installer: Installer,
locker: Locker, locker: Locker,
repo: Repository, repo: Repository,
...@@ -1901,7 +1901,7 @@ def test_installer_test_solver_finds_compatible_package_for_dependency_python_no ...@@ -1901,7 +1901,7 @@ def test_installer_test_solver_finds_compatible_package_for_dependency_python_no
assert installer.executor.installations_count == 1 assert installer.executor.installations_count == 1
def test_installer_required_extras_should_not_be_removed_when_updating_single_dependency( def test_installer_required_extras_should_not_be_removed_when_updating_single_dependency( # noqa: E501
installer: Installer, installer: Installer,
locker: Locker, locker: Locker,
repo: Repository, repo: Repository,
...@@ -1968,7 +1968,7 @@ def test_installer_required_extras_should_not_be_removed_when_updating_single_de ...@@ -1968,7 +1968,7 @@ def test_installer_required_extras_should_not_be_removed_when_updating_single_de
assert installer.executor.removals_count == 0 assert installer.executor.removals_count == 0
def test_installer_required_extras_should_not_be_removed_when_updating_single_dependency_pypi_repository( def test_installer_required_extras_should_not_be_removed_when_updating_single_dependency_pypi_repository( # noqa: E501
locker: Locker, locker: Locker,
repo: Repository, repo: Repository,
package: ProjectPackage, package: ProjectPackage,
......
...@@ -1532,7 +1532,7 @@ def test_run_install_duplicate_dependencies_different_constraints_with_lock_upda ...@@ -1532,7 +1532,7 @@ def test_run_install_duplicate_dependencies_different_constraints_with_lock_upda
@pytest.mark.skip( @pytest.mark.skip(
"This is not working at the moment due to limitations in the resolver" "This is not working at the moment due to limitations in the resolver"
) )
def test_installer_test_solver_finds_compatible_package_for_dependency_python_not_fully_compatible_with_package_python( def test_installer_test_solver_finds_compatible_package_for_dependency_python_not_fully_compatible_with_package_python( # noqa: E501
installer: Installer, installer: Installer,
locker: Locker, locker: Locker,
repo: Repository, repo: Repository,
...@@ -1562,7 +1562,7 @@ def test_installer_test_solver_finds_compatible_package_for_dependency_python_no ...@@ -1562,7 +1562,7 @@ def test_installer_test_solver_finds_compatible_package_for_dependency_python_no
assert len(installs) == 1 assert len(installs) == 1
def test_installer_required_extras_should_not_be_removed_when_updating_single_dependency( def test_installer_required_extras_should_not_be_removed_when_updating_single_dependency( # noqa: E501
installer: Installer, installer: Installer,
locker: Locker, locker: Locker,
repo: Repository, repo: Repository,
...@@ -1621,7 +1621,7 @@ def test_installer_required_extras_should_not_be_removed_when_updating_single_de ...@@ -1621,7 +1621,7 @@ def test_installer_required_extras_should_not_be_removed_when_updating_single_de
assert len(installer.installer.removals) == 0 assert len(installer.installer.removals) == 0
def test_installer_required_extras_should_not_be_removed_when_updating_single_dependency_pypi_repository( def test_installer_required_extras_should_not_be_removed_when_updating_single_dependency_pypi_repository( # noqa: E501
locker: Locker, locker: Locker,
repo: Repository, repo: Repository,
package: ProjectPackage, package: ProjectPackage,
......
...@@ -104,7 +104,8 @@ def test_builder_installs_proper_files_for_standard_packages( ...@@ -104,7 +104,8 @@ def test_builder_installs_proper_files_for_standard_packages(
assert dist_info.joinpath("INSTALLER").read_text() == "poetry" assert dist_info.joinpath("INSTALLER").read_text() == "poetry"
assert ( assert (
dist_info.joinpath("entry_points.txt").read_text() dist_info.joinpath("entry_points.txt").read_text()
== "[console_scripts]\nbaz=bar:baz.boom.bim\nfoo=foo:bar\nfox=fuz.foo:bar.baz\n\n" == "[console_scripts]\nbaz=bar:baz.boom.bim\nfoo=foo:bar\n"
"fox=fuz.foo:bar.baz\n\n"
) )
metadata = """\ metadata = """\
......
...@@ -24,8 +24,8 @@ The Python requirement can be specified via the `python` or `markers` properties ...@@ -24,8 +24,8 @@ The Python requirement can be specified via the `python` or `markers` properties
For foo, a possible solution would be to set the `python` property to ">=3.6,<4.0"\ For foo, a possible solution would be to set the `python` property to ">=3.6,<4.0"\
""" """
links = [ links = [
"https://python-poetry.org/docs/dependency-specification/#python-restricted-dependencies", "https://python-poetry.org/docs/dependency-specification/#python-restricted-dependencies", # noqa: E501
"https://python-poetry.org/docs/dependency-specification/#using-environment-markers", "https://python-poetry.org/docs/dependency-specification/#using-environment-markers", # noqa: E501
] ]
assert title == solution.solution_title assert title == solution.solution_title
......
...@@ -19,7 +19,9 @@ def test_dependency_does_not_match_root_python_constraint( ...@@ -19,7 +19,9 @@ def test_dependency_does_not_match_root_python_constraint(
add_to_repo(repo, "foo", "1.0.0", python="<3.5") add_to_repo(repo, "foo", "1.0.0", python="<3.5")
error = """The current project's Python requirement (>=3.6,<4.0) is not compatible with some of the required packages Python requirement: error = """\
The current project's Python requirement (>=3.6,<4.0) is not compatible with some of\
the required packages Python requirement:
- foo requires Python <3.5, so it will not be satisfied for Python >=3.6,<4.0 - foo requires Python <3.5, so it will not be satisfied for Python >=3.6,<4.0
Because no versions of foo match !=1.0.0 Because no versions of foo match !=1.0.0
......
...@@ -42,9 +42,12 @@ def test_no_version_that_matches_combined_constraints( ...@@ -42,9 +42,12 @@ def test_no_version_that_matches_combined_constraints(
error = """\ error = """\
Because foo (1.0.0) depends on shared (>=2.0.0 <3.0.0) Because foo (1.0.0) depends on shared (>=2.0.0 <3.0.0)
and no versions of shared match >=2.9.0,<3.0.0, foo (1.0.0) requires shared (>=2.0.0,<2.9.0). and no versions of shared match >=2.9.0,<3.0.0,\
And because bar (1.0.0) depends on shared (>=2.9.0 <4.0.0), bar (1.0.0) is incompatible with foo (1.0.0). foo (1.0.0) requires shared (>=2.0.0,<2.9.0).
So, because myapp depends on both foo (1.0.0) and bar (1.0.0), version solving failed.""" And because bar (1.0.0) depends on shared (>=2.9.0 <4.0.0),\
bar (1.0.0) is incompatible with foo (1.0.0).
So, because myapp depends on both foo (1.0.0) and bar (1.0.0), version solving failed.\
"""
check_solver_result(root, provider, error=error) check_solver_result(root, provider, error=error)
...@@ -62,8 +65,10 @@ def test_disjoint_constraints( ...@@ -62,8 +65,10 @@ def test_disjoint_constraints(
error = """\ error = """\
Because bar (1.0.0) depends on shared (>3.0.0) Because bar (1.0.0) depends on shared (>3.0.0)
and foo (1.0.0) depends on shared (<=2.0.0), bar (1.0.0) is incompatible with foo (1.0.0). and foo (1.0.0) depends on shared (<=2.0.0),\
So, because myapp depends on both foo (1.0.0) and bar (1.0.0), version solving failed.""" bar (1.0.0) is incompatible with foo (1.0.0).
So, because myapp depends on both foo (1.0.0) and bar (1.0.0), version solving failed.\
"""
check_solver_result(root, provider, error=error) check_solver_result(root, provider, error=error)
check_solver_result(root, provider, error=error) check_solver_result(root, provider, error=error)
......
...@@ -73,7 +73,7 @@ def test_with_unrelated_locked_dependencies( ...@@ -73,7 +73,7 @@ def test_with_unrelated_locked_dependencies(
) )
def test_unlocks_dependencies_if_necessary_to_ensure_that_a_new_dependency_is_statisfied( def test_unlocks_dependencies_if_necessary_to_ensure_that_a_new_dependency_is_satisfied(
root: "ProjectPackage", provider: "Provider", repo: "Repository" root: "ProjectPackage", provider: "Provider", repo: "Repository"
): ):
root.add_dependency(Factory.create_dependency("foo", "*")) root.add_dependency(Factory.create_dependency("foo", "*"))
......
...@@ -514,7 +514,7 @@ A = [] ...@@ -514,7 +514,7 @@ A = []
assert expected == content assert expected == content
def test_locker_should_neither_emit_warnings_nor_raise_error_for_lower_compatible_versions( def test_locker_should_neither_emit_warnings_nor_raise_error_for_lower_compatible_versions( # noqa: E501
locker: Locker, caplog: "LogCaptureFixture" locker: Locker, caplog: "LogCaptureFixture"
): ):
current_version = Version.parse(Locker._VERSION) current_version = Version.parse(Locker._VERSION)
......
...@@ -964,7 +964,7 @@ def test_solver_with_dependency_in_both_default_and_dev_dependencies( ...@@ -964,7 +964,7 @@ def test_solver_with_dependency_in_both_default_and_dev_dependencies(
assert a.category == "main" assert a.category == "main"
def test_solver_with_dependency_in_both_main_and_dev_dependencies_with_one_more_dependent( def test_solver_with_dependency_in_both_main_and_dev_dependencies_with_one_more_dependent( # noqa: E501
solver: Solver, repo: Repository, package: Package solver: Solver, repo: Repository, package: Package
): ):
package.add_dependency(Factory.create_dependency("A", "*")) package.add_dependency(Factory.create_dependency("A", "*"))
...@@ -1466,7 +1466,7 @@ def test_solver_can_resolve_git_dependencies_with_ref( ...@@ -1466,7 +1466,7 @@ def test_solver_can_resolve_git_dependencies_with_ref(
assert op.package.source_resolved_reference.startswith("9cf87a2") assert op.package.source_resolved_reference.startswith("9cf87a2")
def test_solver_does_not_trigger_conflict_for_python_constraint_if_python_requirement_is_compatible( def test_solver_does_not_trigger_conflict_for_python_constraint_if_python_requirement_is_compatible( # noqa: E501
solver: Solver, repo: Repository, package: Package solver: Solver, repo: Repository, package: Package
): ):
solver.provider.set_package_python_versions("~2.7 || ^3.4") solver.provider.set_package_python_versions("~2.7 || ^3.4")
...@@ -1484,7 +1484,7 @@ def test_solver_does_not_trigger_conflict_for_python_constraint_if_python_requir ...@@ -1484,7 +1484,7 @@ def test_solver_does_not_trigger_conflict_for_python_constraint_if_python_requir
check_solver_result(transaction, [{"job": "install", "package": package_a}]) check_solver_result(transaction, [{"job": "install", "package": package_a}])
def test_solver_does_not_trigger_conflict_for_python_constraint_if_python_requirement_is_compatible_multiple( def test_solver_does_not_trigger_conflict_for_python_constraint_if_python_requirement_is_compatible_multiple( # noqa: E501
solver: Solver, repo: Repository, package: Package solver: Solver, repo: Repository, package: Package
): ):
solver.provider.set_package_python_versions("~2.7 || ^3.4") solver.provider.set_package_python_versions("~2.7 || ^3.4")
...@@ -1516,7 +1516,7 @@ def test_solver_does_not_trigger_conflict_for_python_constraint_if_python_requir ...@@ -1516,7 +1516,7 @@ def test_solver_does_not_trigger_conflict_for_python_constraint_if_python_requir
) )
def test_solver_triggers_conflict_for_dependency_python_not_fully_compatible_with_package_python( def test_solver_triggers_conflict_for_dependency_python_not_fully_compatible_with_package_python( # noqa: E501
solver: Solver, repo: Repository, package: Package solver: Solver, repo: Repository, package: Package
): ):
solver.provider.set_package_python_versions("~2.7 || ^3.4") solver.provider.set_package_python_versions("~2.7 || ^3.4")
...@@ -1533,7 +1533,7 @@ def test_solver_triggers_conflict_for_dependency_python_not_fully_compatible_wit ...@@ -1533,7 +1533,7 @@ def test_solver_triggers_conflict_for_dependency_python_not_fully_compatible_wit
solver.solve() solver.solve()
def test_solver_finds_compatible_package_for_dependency_python_not_fully_compatible_with_package_python( def test_solver_finds_compatible_package_for_dependency_python_not_fully_compatible_with_package_python( # noqa: E501
solver: Solver, repo: Repository, package: Package solver: Solver, repo: Repository, package: Package
): ):
solver.provider.set_package_python_versions("~2.7 || ^3.4") solver.provider.set_package_python_versions("~2.7 || ^3.4")
...@@ -1555,7 +1555,7 @@ def test_solver_finds_compatible_package_for_dependency_python_not_fully_compati ...@@ -1555,7 +1555,7 @@ def test_solver_finds_compatible_package_for_dependency_python_not_fully_compati
check_solver_result(transaction, [{"job": "install", "package": package_a100}]) check_solver_result(transaction, [{"job": "install", "package": package_a100}])
def test_solver_does_not_trigger_new_resolution_on_duplicate_dependencies_if_only_extras( def test_solver_does_not_trigger_new_resolution_on_duplicate_dependencies_if_only_extras( # noqa: E501
solver: Solver, repo: Repository, package: Package solver: Solver, repo: Repository, package: Package
): ):
dep1 = Dependency.create_from_pep_508('B (>=1.0); extra == "foo"') dep1 = Dependency.create_from_pep_508('B (>=1.0); extra == "foo"')
...@@ -1693,7 +1693,8 @@ def test_solver_ignores_dependencies_with_incompatible_python_full_version_marke ...@@ -1693,7 +1693,8 @@ def test_solver_ignores_dependencies_with_incompatible_python_full_version_marke
package_a = get_package("A", "1.0.0") package_a = get_package("A", "1.0.0")
package_a.add_dependency( package_a.add_dependency(
Dependency.create_from_pep_508( Dependency.create_from_pep_508(
'B (<2.0); platform_python_implementation == "PyPy" and python_full_version < "2.7.9"' 'B (<2.0); platform_python_implementation == "PyPy" and python_full_version'
' < "2.7.9"'
) )
) )
...@@ -1835,7 +1836,9 @@ def test_solver_git_dependencies_short_hash_update_skipped( ...@@ -1835,7 +1836,9 @@ def test_solver_git_dependencies_short_hash_update_skipped(
source_type="git", source_type="git",
source_url="https://github.com/demo/demo.git", source_url="https://github.com/demo/demo.git",
source_reference="9cf87a285a2d3fbb0b9fa621997b3acc3631ed24", source_reference="9cf87a285a2d3fbb0b9fa621997b3acc3631ed24",
source_resolved_reference="9cf87a285a2d3fbb0b9fa621997b3acc3631ed24", source_resolved_reference=(
"9cf87a285a2d3fbb0b9fa621997b3acc3631ed24"
),
), ),
"skipped": True, "skipped": True,
}, },
......
...@@ -283,11 +283,11 @@ def test_get_package_retrieves_non_sha256_hashes(): ...@@ -283,11 +283,11 @@ def test_get_package_retrieves_non_sha256_hashes():
expected = [ expected = [
{ {
"file": "ipython-7.5.0-py3-none-any.whl", "file": "ipython-7.5.0-py3-none-any.whl",
"hash": "sha256:78aea20b7991823f6a32d55f4e963a61590820e43f666ad95ad07c7f0c704efa", "hash": "sha256:78aea20b7991823f6a32d55f4e963a61590820e43f666ad95ad07c7f0c704efa", # noqa: E501
}, },
{ {
"file": "ipython-7.5.0.tar.gz", "file": "ipython-7.5.0.tar.gz",
"hash": "sha256:e840810029224b56cd0d9e7719dc3b39cf84d577f8ac686547c8ba7a06eeab26", "hash": "sha256:e840810029224b56cd0d9e7719dc3b39cf84d577f8ac686547c8ba7a06eeab26", # noqa: E501
}, },
] ]
...@@ -306,11 +306,11 @@ def test_get_package_retrieves_non_sha256_hashes_mismatching_known_hash(): ...@@ -306,11 +306,11 @@ def test_get_package_retrieves_non_sha256_hashes_mismatching_known_hash():
}, },
{ {
"file": "ipython-5.7.0-py3-none-any.whl", "file": "ipython-5.7.0-py3-none-any.whl",
"hash": "sha256:fc0464e68f9c65cd8c453474b4175432cc29ecb6c83775baedf6dbfcee9275ab", "hash": "sha256:fc0464e68f9c65cd8c453474b4175432cc29ecb6c83775baedf6dbfcee9275ab", # noqa: E501
}, },
{ {
"file": "ipython-5.7.0.tar.gz", "file": "ipython-5.7.0.tar.gz",
"hash": "sha256:8db43a7fb7619037c98626613ff08d03dda9d5d12c84814a4504c78c0da8323c", "hash": "sha256:8db43a7fb7619037c98626613ff08d03dda9d5d12c84814a4504c78c0da8323c", # noqa: E501
}, },
] ]
...@@ -325,7 +325,7 @@ def test_get_package_retrieves_packages_with_no_hashes(): ...@@ -325,7 +325,7 @@ def test_get_package_retrieves_packages_with_no_hashes():
assert [ assert [
{ {
"file": "jupyter-1.0.0.tar.gz", "file": "jupyter-1.0.0.tar.gz",
"hash": "sha256:d9dc4b3318f310e34c82951ea5d6683f67bed7def4b259fafbfe4f1beb1d8e5f", "hash": "sha256:d9dc4b3318f310e34c82951ea5d6683f67bed7def4b259fafbfe4f1beb1d8e5f", # noqa: E501
} }
] == package.files ] == package.files
......
...@@ -104,9 +104,10 @@ def test_package(): ...@@ -104,9 +104,10 @@ def test_package():
win_inet = package.extras["socks"][0] win_inet = package.extras["socks"][0]
assert win_inet.name == "win-inet-pton" assert win_inet.name == "win-inet-pton"
assert win_inet.python_versions == "~2.7 || ~2.6" assert win_inet.python_versions == "~2.7 || ~2.6"
assert str(win_inet.marker) == ( assert (
'sys_platform == "win32" and (python_version == "2.7" ' str(win_inet.marker)
'or python_version == "2.6") and extra == "socks"' == 'sys_platform == "win32" and (python_version == "2.7"'
' or python_version == "2.6") and extra == "socks"'
) )
......
...@@ -103,7 +103,8 @@ def test_create_poetry(): ...@@ -103,7 +103,8 @@ def test_create_poetry():
assert functools32.pretty_constraint == "^3.2.3" assert functools32.pretty_constraint == "^3.2.3"
assert ( assert (
str(functools32.marker) str(functools32.marker)
== 'python_version ~= "2.7" and sys_platform == "win32" or python_version in "3.4 3.5"' == 'python_version ~= "2.7" and sys_platform == "win32" or python_version in'
' "3.4 3.5"'
) )
assert "db" in package.extras assert "db" in package.extras
......
...@@ -795,7 +795,7 @@ def test_call_no_input_with_called_process_error( ...@@ -795,7 +795,7 @@ def test_call_no_input_with_called_process_error(
subprocess.call.assert_called_once() subprocess.call.assert_called_once()
def test_create_venv_tries_to_find_a_compatible_python_executable_using_generic_ones_first( def test_create_venv_tries_to_find_a_compatible_python_executable_using_generic_ones_first( # noqa: E501
manager: EnvManager, manager: EnvManager,
poetry: "Poetry", poetry: "Poetry",
config: "Config", config: "Config",
......
...@@ -276,8 +276,8 @@ def test_exporter_can_export_requirements_txt_poetry(tmp_dir: str, poetry: "Poet ...@@ -276,8 +276,8 @@ def test_exporter_can_export_requirements_txt_poetry(tmp_dir: str, poetry: "Poet
content = f.read() content = f.read()
# The dependency graph: # The dependency graph:
# junit-xml 1.9 Creates JUnit XML test result documents that can be read by tools such as Jenkins # junit-xml 1.9 Creates JUnit XML test result documents that can be read by tools
# └── six * # └── six * such as Jenkins
# poetry 1.1.4 Python dependency management and packaging made easy. # poetry 1.1.4 Python dependency management and packaging made easy.
# ├── keyring >=21.2.0,<22.0.0 # ├── keyring >=21.2.0,<22.0.0
# │ ├── importlib-metadata >=1 # │ ├── importlib-metadata >=1
...@@ -364,11 +364,12 @@ def test_exporter_can_export_requirements_txt_pyinstaller( ...@@ -364,11 +364,12 @@ def test_exporter_can_export_requirements_txt_pyinstaller(
content = f.read() content = f.read()
# Rationale for the results: # Rationale for the results:
# * PyInstaller has an explicit dependency on altgraph, so it must always be installed. # * PyInstaller has an explicit dependency on altgraph, so it must always be
# installed.
# * PyInstaller requires macholib on Darwin, which in turn requires altgraph. # * PyInstaller requires macholib on Darwin, which in turn requires altgraph.
# The dependency graph: # The dependency graph:
# pyinstaller 4.0 PyInstaller bundles a Python application and all its dependencies into a single package. # pyinstaller 4.0 PyInstaller bundles a Python application and all its
# ├── altgraph * # ├── altgraph * dependencies into a single package.
# ├── macholib >=1.8 -- only on Darwin # ├── macholib >=1.8 -- only on Darwin
# │ └── altgraph >=0.15 # │ └── altgraph >=0.15
expected = { expected = {
...@@ -453,7 +454,8 @@ def test_exporter_can_export_requirements_txt_with_nested_packages_and_markers( ...@@ -453,7 +454,8 @@ def test_exporter_can_export_requirements_txt_with_nested_packages_and_markers(
"c==7.8.9 ; sys_platform == 'win32' and python_version < '3.7'" "c==7.8.9 ; sys_platform == 'win32' and python_version < '3.7'"
), ),
"d": Dependency.create_from_pep_508( "d": Dependency.create_from_pep_508(
"d==0.0.1 ; platform_system == 'Windows' and python_version < '3.7' or sys_platform == 'win32' and python_version < '3.7'" "d==0.0.1 ; platform_system == 'Windows' and python_version < '3.7' or"
" sys_platform == 'win32' and python_version < '3.7'"
), ),
} }
...@@ -571,7 +573,7 @@ foo==1.2.3 \\ ...@@ -571,7 +573,7 @@ foo==1.2.3 \\
assert expected == content assert expected == content
def test_exporter_can_export_requirements_txt_with_standard_packages_and_hashes_disabled( def test_exporter_can_export_requirements_txt_with_standard_packages_and_hashes_disabled( # noqa: E501
tmp_dir: str, poetry: "Poetry" tmp_dir: str, poetry: "Poetry"
): ):
poetry.locker.mock_lock_data( poetry.locker.mock_lock_data(
...@@ -1158,7 +1160,7 @@ def test_exporter_can_export_requirements_txt_with_nested_directory_packages( ...@@ -1158,7 +1160,7 @@ def test_exporter_can_export_requirements_txt_with_nested_directory_packages(
"python-versions": "*", "python-versions": "*",
"source": { "source": {
"type": "directory", "type": "directory",
"url": "tests/fixtures/sample_project/../project_with_nested_local/bar", "url": "tests/fixtures/sample_project/../project_with_nested_local/bar", # noqa: E501
"reference": "", "reference": "",
}, },
}, },
...@@ -1170,7 +1172,7 @@ def test_exporter_can_export_requirements_txt_with_nested_directory_packages( ...@@ -1170,7 +1172,7 @@ def test_exporter_can_export_requirements_txt_with_nested_directory_packages(
"python-versions": "*", "python-versions": "*",
"source": { "source": {
"type": "directory", "type": "directory",
"url": "tests/fixtures/sample_project/../project_with_nested_local/bar/..", "url": "tests/fixtures/sample_project/../project_with_nested_local/bar/..", # noqa: E501
"reference": "", "reference": "",
}, },
}, },
...@@ -1237,7 +1239,8 @@ def test_exporter_can_export_requirements_txt_with_directory_packages_and_marker ...@@ -1237,7 +1239,8 @@ def test_exporter_can_export_requirements_txt_with_directory_packages_and_marker
content = f.read() content = f.read()
expected = f"""\ expected = f"""\
foo @ {working_directory.as_uri()}/tests/fixtures/sample_project ; python_version < "3.7" foo @ {working_directory.as_uri()}/tests/fixtures/sample_project\
; python_version < "3.7"
""" """
assert expected == content assert expected == content
...@@ -1322,7 +1325,8 @@ def test_exporter_can_export_requirements_txt_with_file_packages_and_markers( ...@@ -1322,7 +1325,8 @@ def test_exporter_can_export_requirements_txt_with_file_packages_and_markers(
content = f.read() content = f.read()
expected = f"""\ expected = f"""\
foo @ {working_directory.as_uri()}/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"
""" """
assert expected == content assert expected == content
......
...@@ -27,7 +27,8 @@ msgpack-python>=0.5.0.0,<0.6.0.0 ...@@ -27,7 +27,8 @@ msgpack-python>=0.5.0.0,<0.6.0.0
pyparsing>=2.2.0.0,<3.0.0.0 pyparsing>=2.2.0.0,<3.0.0.0
requests-toolbelt>=0.8.0.0,<0.9.0.0 requests-toolbelt>=0.8.0.0,<0.9.0.0
[:(python_version >= "2.7.0.0" and python_version < "2.8.0.0") or (python_version >= "3.4.0.0" and python_version < "3.5.0.0")] [:(python_version >= "2.7.0.0" and python_version < "2.8.0.0")\
or (python_version >= "3.4.0.0" and python_version < "3.5.0.0")]
typing>=3.6.0.0,<4.0.0.0 typing>=3.6.0.0,<4.0.0.0
[:python_version >= "2.7.0.0" and python_version < "2.8.0.0"] [:python_version >= "2.7.0.0" and python_version < "2.8.0.0"]
...@@ -39,8 +40,9 @@ zipfile36>=0.1.0.0,<0.2.0.0 ...@@ -39,8 +40,9 @@ zipfile36>=0.1.0.0,<0.2.0.0
[dev] [dev]
isort@ git+git://github.com/timothycrosley/isort.git@e63ae06ec7d70b06df9e528357650281a3d3ec22#egg=isort isort@ git+git://github.com/timothycrosley/isort.git@e63ae06ec7d70b06df9e528357650281a3d3ec22#egg=isort
""" """ # noqa: E501
result = parse_requires(requires) result = parse_requires(requires)
# fmt: off
expected = [ expected = [
"jsonschema>=2.6.0.0,<3.0.0.0", "jsonschema>=2.6.0.0,<3.0.0.0",
"lockfile>=0.12.0.0,<0.13.0.0", "lockfile>=0.12.0.0,<0.13.0.0",
...@@ -55,12 +57,13 @@ isort@ git+git://github.com/timothycrosley/isort.git@e63ae06ec7d70b06df9e5283576 ...@@ -55,12 +57,13 @@ isort@ git+git://github.com/timothycrosley/isort.git@e63ae06ec7d70b06df9e5283576
"msgpack-python>=0.5.0.0,<0.6.0.0", "msgpack-python>=0.5.0.0,<0.6.0.0",
"pyparsing>=2.2.0.0,<3.0.0.0", "pyparsing>=2.2.0.0,<3.0.0.0",
"requests-toolbelt>=0.8.0.0,<0.9.0.0", "requests-toolbelt>=0.8.0.0,<0.9.0.0",
'typing>=3.6.0.0,<4.0.0.0 ; (python_version >= "2.7.0.0" and python_version < "2.8.0.0") or (python_version >= "3.4.0.0" and python_version < "3.5.0.0")', 'typing>=3.6.0.0,<4.0.0.0 ; (python_version >= "2.7.0.0" and python_version < "2.8.0.0") or (python_version >= "3.4.0.0" and python_version < "3.5.0.0")', # noqa: E501
'virtualenv>=15.2.0.0,<16.0.0.0 ; python_version >= "2.7.0.0" and python_version < "2.8.0.0"', 'virtualenv>=15.2.0.0,<16.0.0.0 ; python_version >= "2.7.0.0" and python_version < "2.8.0.0"', # noqa: E501
'pathlib2>=2.3.0.0,<3.0.0.0 ; python_version >= "2.7.0.0" and python_version < "2.8.0.0"', 'pathlib2>=2.3.0.0,<3.0.0.0 ; python_version >= "2.7.0.0" and python_version < "2.8.0.0"', # noqa: E501
'zipfile36>=0.1.0.0,<0.2.0.0 ; python_version >= "3.4.0.0" and python_version < "3.6.0.0"', 'zipfile36>=0.1.0.0,<0.2.0.0 ; python_version >= "3.4.0.0" and python_version < "3.6.0.0"', # noqa: E501
'isort@ git+git://github.com/timothycrosley/isort.git@e63ae06ec7d70b06df9e528357650281a3d3ec22#egg=isort ; extra == "dev"', 'isort@ git+git://github.com/timothycrosley/isort.git@e63ae06ec7d70b06df9e528357650281a3d3ec22#egg=isort ; extra == "dev"', # noqa: E501
] ]
# fmt: on
assert result == expected assert result == expected
......
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