"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "poetry/mixology/failure.py" between
poetry-1.1.15.tar.gz and poetry-1.2.0.tar.gz

About: Poetry is a tool for dependency management and packaging in Python.

failure.py  (poetry-1.1.15):failure.py  (poetry-1.2.0)
from typing import Dict from __future__ import annotations
from typing import List
from typing import Tuple from typing import TYPE_CHECKING
from typing import cast
from poetry.core.semver import parse_constraint
from poetry.core.semver.helpers import parse_constraint
from .incompatibility import Incompatibility
from .incompatibility_cause import ConflictCause from poetry.mixology.incompatibility_cause import ConflictCause
from .incompatibility_cause import PythonCause from poetry.mixology.incompatibility_cause import PythonCause
if TYPE_CHECKING:
from poetry.mixology.incompatibility import Incompatibility
class SolveFailure(Exception): class SolveFailure(Exception):
def __init__(self, incompatibility): # type: (Incompatibility) -> None def __init__(self, incompatibility: Incompatibility) -> None:
self._incompatibility = incompatibility self._incompatibility = incompatibility
@property @property
def message(self): def message(self) -> str:
return str(self) return str(self)
def __str__(self): def __str__(self) -> str:
return _Writer(self._incompatibility).write() return _Writer(self._incompatibility).write()
class _Writer: class _Writer:
def __init__(self, root): # type: (Incompatibility) -> None def __init__(self, root: Incompatibility) -> None:
self._root = root self._root = root
self._derivations = {} # type: Dict[Incompatibility, int] self._derivations: dict[Incompatibility, int] = {}
self._lines = [] # type: List[Tuple[str, int]] self._lines: list[tuple[str, int | None]] = []
self._line_numbers = {} # type: Dict[Incompatibility, int] self._line_numbers: dict[Incompatibility, int] = {}
self._count_derivations(self._root) self._count_derivations(self._root)
def write(self): def write(self) -> str:
buffer = [] buffer = []
required_python_version_notification = False required_python_version_notification = False
for incompatibility in self._root.external_incompatibilities: for incompatibility in self._root.external_incompatibilities:
if isinstance(incompatibility.cause, PythonCause): if isinstance(incompatibility.cause, PythonCause):
if not required_python_version_notification: if not required_python_version_notification:
buffer.append( buffer.append(
"The current project's Python requirement ({}) " "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:".format( " compatible with some of the required packages Python"
incompatibility.cause.root_python_version " requirement:"
)
) )
required_python_version_notification = True required_python_version_notification = True
root_constraint = parse_constraint( root_constraint = parse_constraint(
incompatibility.cause.root_python_version incompatibility.cause.root_python_version
) )
constraint = parse_constraint(incompatibility.cause.python_versi on) constraint = parse_constraint(incompatibility.cause.python_versi on)
buffer.append( buffer.append(
" - {} requires Python {}, so it will not be satisfied for f" - {incompatibility.terms[0].dependency.name} requires Py
Python {}".format( thon"
incompatibility.terms[0].dependency.name, f" {incompatibility.cause.python_version}, so it will not be
incompatibility.cause.python_version, "
root_constraint.difference(constraint), f" satisfied for Python {root_constraint.difference(constrai
) nt)}"
) )
if required_python_version_notification: if required_python_version_notification:
buffer.append("") buffer.append("")
if isinstance(self._root.cause, ConflictCause): if isinstance(self._root.cause, ConflictCause):
self._visit(self._root, {}) self._visit(self._root)
else: else:
self._write( self._write(self._root, f"Because {self._root}, version solving fail
self._root, "Because {}, version solving failed.".format(self._r ed.")
oot)
)
padding = ( padding = (
0 0
if not self._line_numbers if not self._line_numbers
else len("({}) ".format(list(self._line_numbers.values())[-1])) else len(f"({list(self._line_numbers.values())[-1]}) ")
) )
last_was_empty = False last_was_empty = False
for line in self._lines: for line in self._lines:
message = line[0] message = line[0]
if not message: if not message:
if not last_was_empty: if not last_was_empty:
buffer.append("") buffer.append("")
last_was_empty = True last_was_empty = True
continue continue
last_was_empty = False last_was_empty = False
number = line[-1] number = line[-1]
if number is not None: if number is not None:
message = "({})".format(number).ljust(padding) + message message = f"({number})".ljust(padding) + message
else: else:
message = " " * padding + message message = " " * padding + message
buffer.append(message) buffer.append(message)
return "\n".join(buffer) return "\n".join(buffer)
def _write( def _write(
self, incompatibility, message, numbered=False self, incompatibility: Incompatibility, message: str, numbered: bool = F
): # type: (Incompatibility, str, bool) -> None alse
) -> None:
if numbered: if numbered:
number = len(self._line_numbers) + 1 number = len(self._line_numbers) + 1
self._line_numbers[incompatibility] = number self._line_numbers[incompatibility] = number
self._lines.append((message, number)) self._lines.append((message, number))
else: else:
self._lines.append((message, None)) self._lines.append((message, None))
def _visit( def _visit(
self, incompatibility, details_for_incompatibility, conclusion=False self,
): # type: (Incompatibility, Dict, bool) -> None incompatibility: Incompatibility,
conclusion: bool = False,
) -> None:
numbered = conclusion or self._derivations[incompatibility] > 1 numbered = conclusion or self._derivations[incompatibility] > 1
conjunction = "So," if conclusion or incompatibility == self._root else "And" conjunction = "So," if conclusion or incompatibility == self._root else "And"
incompatibility_string = str(incompatibility) incompatibility_string = str(incompatibility)
cause = incompatibility.cause # type: ConflictCause cause: ConflictCause = cast(ConflictCause, incompatibility.cause)
details_for_cause = {}
if isinstance(cause.conflict.cause, ConflictCause) and isinstance( if isinstance(cause.conflict.cause, ConflictCause) and isinstance(
cause.other.cause, ConflictCause cause.other.cause, ConflictCause
): ):
conflict_line = self._line_numbers.get(cause.conflict) conflict_line = self._line_numbers.get(cause.conflict)
other_line = self._line_numbers.get(cause.other) other_line = self._line_numbers.get(cause.other)
if conflict_line is not None and other_line is not None: if conflict_line is not None and other_line is not None:
reason = cause.conflict.and_to_string(
cause.other, conflict_line, other_line
)
self._write( self._write(
incompatibility, incompatibility,
"Because {}, {}.".format( f"Because {reason}, {incompatibility_string}.",
cause.conflict.and_to_string(
cause.other, details_for_cause, conflict_line, other
_line
),
incompatibility_string,
),
numbered=numbered, numbered=numbered,
) )
elif conflict_line is not None or other_line is not None: elif conflict_line is not None or other_line is not None:
if conflict_line is not None: if conflict_line is not None:
with_line = cause.conflict with_line = cause.conflict
without_line = cause.other without_line = cause.other
line = conflict_line line = conflict_line
else: elif other_line is not None:
with_line = cause.other with_line = cause.other
without_line = cause.conflict without_line = cause.conflict
line = other_line line = other_line
self._visit(without_line, details_for_cause) self._visit(without_line)
self._write( self._write(
incompatibility, incompatibility,
"{} because {} ({}), {}.".format( f"{conjunction} because {with_line!s} ({line}),"
conjunction, str(with_line), line, incompatibility_strin f" {incompatibility_string}.",
g
),
numbered=numbered, numbered=numbered,
) )
else: else:
single_line_conflict = self._is_single_line(cause.conflict.cause ) single_line_conflict = self._is_single_line(cause.conflict.cause )
single_line_other = self._is_single_line(cause.other.cause) single_line_other = self._is_single_line(cause.other.cause)
if single_line_other or single_line_conflict: if single_line_other or single_line_conflict:
first = cause.conflict if single_line_other else cause.other first = cause.conflict if single_line_other else cause.other
second = cause.other if single_line_other else cause.conflic t second = cause.other if single_line_other else cause.conflic t
self._visit(first, details_for_cause) self._visit(first)
self._visit(second, details_for_cause) self._visit(second)
self._write( self._write(
incompatibility, incompatibility,
"Thus, {}.".format(incompatibility_string), f"Thus, {incompatibility_string}.",
numbered=numbered, numbered=numbered,
) )
else: else:
self._visit(cause.conflict, {}, conclusion=True) self._visit(cause.conflict, conclusion=True)
self._lines.append(("", None)) self._lines.append(("", None))
self._visit(cause.other, details_for_cause) self._visit(cause.other)
self._write( self._write(
incompatibility, incompatibility,
"{} because {} ({}), {}".format( f"{conjunction} because"
conjunction, f" {cause.conflict!s} ({self._line_numbers[cause.conflic
str(cause.conflict), t]}),"
self._line_numbers[cause.conflict], f" {incompatibility_string}",
incompatibility_string,
),
numbered=numbered, numbered=numbered,
) )
elif isinstance(cause.conflict.cause, ConflictCause) or isinstance( elif isinstance(cause.conflict.cause, ConflictCause) or isinstance(
cause.other.cause, ConflictCause cause.other.cause, ConflictCause
): ):
derived = ( derived = (
cause.conflict cause.conflict
if isinstance(cause.conflict.cause, ConflictCause) if isinstance(cause.conflict.cause, ConflictCause)
else cause.other else cause.other
) )
ext = ( ext = (
cause.other cause.other
if isinstance(cause.conflict.cause, ConflictCause) if isinstance(cause.conflict.cause, ConflictCause)
else cause.conflict else cause.conflict
) )
derived_line = self._line_numbers.get(derived) derived_line = self._line_numbers.get(derived)
if derived_line is not None: if derived_line is not None:
reason = ext.and_to_string(derived, None, derived_line)
self._write( self._write(
incompatibility, incompatibility,
"Because {}, {}.".format( f"Because {reason}, {incompatibility_string}.",
ext.and_to_string(
derived, details_for_cause, None, derived_line
),
incompatibility_string,
),
numbered=numbered, numbered=numbered,
) )
elif self._is_collapsible(derived): elif self._is_collapsible(derived):
derived_cause = derived.cause # type: ConflictCause derived_cause: ConflictCause = cast(ConflictCause, derived.cause )
if isinstance(derived_cause.conflict.cause, ConflictCause): if isinstance(derived_cause.conflict.cause, ConflictCause):
collapsed_derived = derived_cause.conflict collapsed_derived = derived_cause.conflict
collapsed_ext = derived_cause.other
else: else:
collapsed_derived = derived_cause.other collapsed_derived = derived_cause.other
if isinstance(derived_cause.conflict.cause, ConflictCause):
collapsed_ext = derived_cause.other
else:
collapsed_ext = derived_cause.conflict collapsed_ext = derived_cause.conflict
details_for_cause = {} self._visit(collapsed_derived)
reason = collapsed_ext.and_to_string(ext, None, None)
self._visit(collapsed_derived, details_for_cause)
self._write( self._write(
incompatibility, incompatibility,
"{} because {}, {}.".format( f"{conjunction} because {reason}, {incompatibility_string}."
conjunction, ,
collapsed_ext.and_to_string(ext, details_for_cause, None
, None),
incompatibility_string,
),
numbered=numbered, numbered=numbered,
) )
else: else:
self._visit(derived, details_for_cause) self._visit(derived)
self._write( self._write(
incompatibility, incompatibility,
"{} because {}, {}.".format( f"{conjunction} because {ext!s}, {incompatibility_string}.",
conjunction, str(ext), incompatibility_string
),
numbered=numbered, numbered=numbered,
) )
else: else:
reason = cause.conflict.and_to_string(cause.other, None, None)
self._write( self._write(
incompatibility, incompatibility,
"Because {}, {}.".format( f"Because {reason}, {incompatibility_string}.",
cause.conflict.and_to_string(
cause.other, details_for_cause, None, None
),
incompatibility_string,
),
numbered=numbered, numbered=numbered,
) )
def _is_collapsible(self, incompatibility): # type: (Incompatibility) -> bo ol def _is_collapsible(self, incompatibility: Incompatibility) -> bool:
if self._derivations[incompatibility] > 1: if self._derivations[incompatibility] > 1:
return False return False
cause = incompatibility.cause # type: ConflictCause cause: ConflictCause = cast(ConflictCause, incompatibility.cause)
if isinstance(cause.conflict.cause, ConflictCause) and isinstance( if isinstance(cause.conflict.cause, ConflictCause) and isinstance(
cause.other.cause, ConflictCause cause.other.cause, ConflictCause
): ):
return False return False
if not isinstance(cause.conflict.cause, ConflictCause) and not isinstanc e( if not isinstance(cause.conflict.cause, ConflictCause) and not isinstanc e(
cause.other.cause, ConflictCause cause.other.cause, ConflictCause
): ):
return False return False
complex = ( complex = (
cause.conflict cause.conflict
if isinstance(cause.conflict.cause, ConflictCause) if isinstance(cause.conflict.cause, ConflictCause)
else cause.other else cause.other
) )
return complex not in self._line_numbers return complex not in self._line_numbers
def _is_single_line(self, cause): # type: (ConflictCause) -> bool def _is_single_line(self, cause: ConflictCause) -> bool:
return not isinstance(cause.conflict.cause, ConflictCause) and not isins tance( return not isinstance(cause.conflict.cause, ConflictCause) and not isins tance(
cause.other.cause, ConflictCause cause.other.cause, ConflictCause
) )
def _count_derivations(self, incompatibility): # type: (Incompatibility) -> None def _count_derivations(self, incompatibility: Incompatibility) -> None:
if incompatibility in self._derivations: if incompatibility in self._derivations:
self._derivations[incompatibility] += 1 self._derivations[incompatibility] += 1
else: else:
self._derivations[incompatibility] = 1 self._derivations[incompatibility] = 1
cause = incompatibility.cause cause = incompatibility.cause
if isinstance(cause, ConflictCause): if isinstance(cause, ConflictCause):
self._count_derivations(cause.conflict) self._count_derivations(cause.conflict)
self._count_derivations(cause.other) self._count_derivations(cause.other)
 End of changes. 41 change blocks. 
98 lines changed or deleted 77 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)