From 2d3aadd9890821451faa6d14e4df1592d77158b7 Mon Sep 17 00:00:00 2001 From: Nick Drozd Date: Sat, 2 Sep 2023 07:22:38 -0400 Subject: [PATCH] Fix Pyreverse line break bug (#8988) * Elaborate line break test * Fix Pyreverse line break bug --- doc/whatsnew/fragments/8671.bugfix | 3 +++ pylint/pyreverse/dot_printer.py | 4 ++-- .../functional/class_diagrams/annotations/line_breaks.dot | 2 +- .../functional/class_diagrams/annotations/line_breaks.mmd | 3 ++- .../functional/class_diagrams/annotations/line_breaks.puml | 3 ++- .../functional/class_diagrams/annotations/line_breaks.py | 7 ++++++- 6 files changed, 16 insertions(+), 6 deletions(-) create mode 100644 doc/whatsnew/fragments/8671.bugfix diff --git a/doc/whatsnew/fragments/8671.bugfix b/doc/whatsnew/fragments/8671.bugfix new file mode 100644 index 0000000000..5177a567ba --- /dev/null +++ b/doc/whatsnew/fragments/8671.bugfix @@ -0,0 +1,3 @@ +Fix a line break error in Pyreverse dot output. + +Closes #8671 diff --git a/pylint/pyreverse/dot_printer.py b/pylint/pyreverse/dot_printer.py index ddd895d309..4baed6c3c2 100644 --- a/pylint/pyreverse/dot_printer.py +++ b/pylint/pyreverse/dot_printer.py @@ -118,11 +118,11 @@ def _build_label_for_node(self, properties: NodeProperties) -> str: # Add class methods methods: list[nodes.FunctionDef] = properties.methods or [] for func in methods: - args = self._get_method_arguments(func) + args = ", ".join(self._get_method_arguments(func)).replace("|", r"\|") method_name = ( f"{func.name}" if func.is_abstract() else f"{func.name}" ) - label += rf"{method_name}({', '.join(args)})" + label += rf"{method_name}({args})" if func.returns: annotation_label = get_annotation_label(func.returns) label += ": " + self._escape_annotation_label(annotation_label) diff --git a/tests/pyreverse/functional/class_diagrams/annotations/line_breaks.dot b/tests/pyreverse/functional/class_diagrams/annotations/line_breaks.dot index f5c42258f3..673e30cb6a 100644 --- a/tests/pyreverse/functional/class_diagrams/annotations/line_breaks.dot +++ b/tests/pyreverse/functional/class_diagrams/annotations/line_breaks.dot @@ -1,5 +1,5 @@ digraph "classes" { rankdir=BT charset="utf-8" -"line_breaks.A" [color="black", fontcolor="black", label=<{A|
|f(x: str | None)
}>, shape="record", style="solid"]; +"line_breaks.A" [color="black", fontcolor="black", label=<{A|p : int \| None
|f(x: str \| None \| (list[A] \| list[int]), y: A \| (int \| str) \| None): int \| str \| list[A \| int]
}>, shape="record", style="solid"]; } diff --git a/tests/pyreverse/functional/class_diagrams/annotations/line_breaks.mmd b/tests/pyreverse/functional/class_diagrams/annotations/line_breaks.mmd index 0abb8eeb76..13328bd4f9 100644 --- a/tests/pyreverse/functional/class_diagrams/annotations/line_breaks.mmd +++ b/tests/pyreverse/functional/class_diagrams/annotations/line_breaks.mmd @@ -1,4 +1,5 @@ classDiagram class A { - f(x: str | None)* + p : int | None + f(x: str | None | (list[A] | list[int]), y: A | (int | str) | None)* int | str | list[A | int] } diff --git a/tests/pyreverse/functional/class_diagrams/annotations/line_breaks.puml b/tests/pyreverse/functional/class_diagrams/annotations/line_breaks.puml index 1515ea001e..ed054490f0 100644 --- a/tests/pyreverse/functional/class_diagrams/annotations/line_breaks.puml +++ b/tests/pyreverse/functional/class_diagrams/annotations/line_breaks.puml @@ -1,6 +1,7 @@ @startuml classes set namespaceSeparator none class "A" as line_breaks.A { - {abstract}f(x: str | None) + p : int | None + {abstract}f(x: str | None | (list[A] | list[int]), y: A | (int | str) | None) -> int | str | list[A | int] } @enduml diff --git a/tests/pyreverse/functional/class_diagrams/annotations/line_breaks.py b/tests/pyreverse/functional/class_diagrams/annotations/line_breaks.py index 2c084cebd2..3710638d6f 100644 --- a/tests/pyreverse/functional/class_diagrams/annotations/line_breaks.py +++ b/tests/pyreverse/functional/class_diagrams/annotations/line_breaks.py @@ -1,5 +1,10 @@ # OPEN BUG: https://github.com/pylint-dev/pylint/issues/8671 class A: - def f(self, x: str | None): + p: int | None + + def f(self, + x: (str | None) | (list[A] | list[int]), + y: A | (int | str) | None, + ) -> int | str | list[A | int]: pass