From af5fc28eabb2992421e5cf2320e63b0d35de3f76 Mon Sep 17 00:00:00 2001 From: Julfried <julian.grimm8@gmail.com> Date: Mon, 11 Nov 2024 15:57:11 +0100 Subject: [PATCH 01/20] Add command line option to limit depth --- pylint/pyreverse/main.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pylint/pyreverse/main.py b/pylint/pyreverse/main.py index 972a46741f..7538f9b533 100644 --- a/pylint/pyreverse/main.py +++ b/pylint/pyreverse/main.py @@ -192,6 +192,22 @@ "help": "Use colored output. Classes/modules of the same package get the same color.", }, ), + ( + "max-depth", + { + "dest": "max_depth", + "action": "store", + "default": None, + "metavar": "<depth>", + "type": "int", + "group": OPTIONS_GROUPS["DISPLAY"], + "help": ( + "Maximum depth in package/module hierarchy to display. A depth of 0 shows only " + "top-level packages, 1 shows one level of subpackages, etc. If not specified, " + "all packages/modules are shown." + ), + }, + ), ( "max-color-depth", { From 0c159a1d293e029df9ef90089969cbf2b1328877 Mon Sep 17 00:00:00 2001 From: Julfried <julian.grimm8@gmail.com> Date: Mon, 11 Nov 2024 16:27:40 +0100 Subject: [PATCH 02/20] Update writer to only show modules below max depth setting --- pylint/pyreverse/writer.py | 45 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/pylint/pyreverse/writer.py b/pylint/pyreverse/writer.py index 093c459598..efd6723696 100644 --- a/pylint/pyreverse/writer.py +++ b/pylint/pyreverse/writer.py @@ -35,6 +35,7 @@ def __init__(self, config: argparse.Namespace) -> None: self.printer: Printer # defined in set_printer self.file_name = "" # defined in set_printer self.depth = self.config.max_color_depth + self.max_depth = self.config.max_depth # default colors are an adaption of the seaborn colorblind palette self.available_colors = itertools.cycle(self.config.color_palette) self.used_colors: dict[str, str] = {} @@ -53,6 +54,15 @@ def write(self, diadefs: Iterable[ClassDiagram | PackageDiagram]) -> None: self.write_classes(diagram) self.save() + def should_show_node(self, qualified_name: str) -> bool: + """Determine if a node should be shown based on depth settings.""" + # If no depth limit is set ==> show all nodes + if self.max_depth is None: + return True + # Count dots to determine depth, subtract 1 since root counts as depth 0 + node_depth = qualified_name.count(".") + return bool(node_depth <= self.max_depth) + def write_packages(self, diagram: PackageDiagram) -> None: """Write a package diagram.""" module_info: dict[str, dict[str, int]] = {} @@ -61,6 +71,10 @@ def write_packages(self, diagram: PackageDiagram) -> None: for module in sorted(diagram.modules(), key=lambda x: x.title): module.fig_id = module.node.qname() + # Filter nodes based on depth + if not self.should_show_node(module.fig_id): + continue + if self.config.no_standalone and not any( module in (rel.from_object, rel.to_object) for rel in diagram.get_relationships("depends") @@ -83,6 +97,10 @@ def write_packages(self, diagram: PackageDiagram) -> None: from_id = rel.from_object.fig_id to_id = rel.to_object.fig_id + # Filter nodes based on depth ==> skip if either source or target nodes is beyond the max depth + if not self.should_show_node(from_id) or not self.should_show_node(to_id): + continue + self.printer.emit_edge( from_id, to_id, @@ -96,6 +114,10 @@ def write_packages(self, diagram: PackageDiagram) -> None: from_id = rel.from_object.fig_id to_id = rel.to_object.fig_id + # Filter nodes based on depth ==> skip if either source or target nodes is beyond the max depth + if not self.should_show_node(from_id) or not self.should_show_node(to_id): + continue + self.printer.emit_edge( from_id, to_id, @@ -115,6 +137,11 @@ def write_classes(self, diagram: ClassDiagram) -> None: # sorted to get predictable (hence testable) results for obj in sorted(diagram.objects, key=lambda x: x.title): obj.fig_id = obj.node.qname() + + # Filter class based on depth setting + if not self.should_show_node(obj.fig_id): + continue + if self.config.no_standalone and not any( obj in (rel.from_object, rel.to_object) for rel_type in ("specialization", "association", "aggregation") @@ -129,6 +156,12 @@ def write_classes(self, diagram: ClassDiagram) -> None: ) # inheritance links for rel in diagram.get_relationships("specialization"): + # Filter nodes based on depth setting + if not self.should_show_node( + rel.from_object.fig_id + ) or not self.should_show_node(rel.to_object.fig_id): + continue + self.printer.emit_edge( rel.from_object.fig_id, rel.to_object.fig_id, @@ -137,6 +170,12 @@ def write_classes(self, diagram: ClassDiagram) -> None: associations: dict[str, set[str]] = defaultdict(set) # generate associations for rel in diagram.get_relationships("association"): + # Filter nodes based on depth setting + if not self.should_show_node( + rel.from_object.fig_id + ) or not self.should_show_node(rel.to_object.fig_id): + continue + associations[rel.from_object.fig_id].add(rel.to_object.fig_id) self.printer.emit_edge( rel.from_object.fig_id, @@ -146,6 +185,12 @@ def write_classes(self, diagram: ClassDiagram) -> None: ) # generate aggregations for rel in diagram.get_relationships("aggregation"): + # Filter nodes based on depth setting + if not self.should_show_node( + rel.from_object.fig_id + ) or not self.should_show_node(rel.to_object.fig_id): + continue + if rel.to_object.fig_id in associations[rel.from_object.fig_id]: continue self.printer.emit_edge( From b421afa49652b0580c2e8df9ac7f3bb68730f58c Mon Sep 17 00:00:00 2001 From: Julfried <julian.grimm8@gmail.com> Date: Mon, 11 Nov 2024 16:39:16 +0100 Subject: [PATCH 03/20] Update PyreverseConfig in testutils --- pylint/testutils/pyreverse.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pylint/testutils/pyreverse.py b/pylint/testutils/pyreverse.py index 115eda416a..eddb8ab5bb 100644 --- a/pylint/testutils/pyreverse.py +++ b/pylint/testutils/pyreverse.py @@ -23,6 +23,7 @@ class PyreverseConfig( The default values correspond to the defaults of the options' parser. """ + # pylint: disable=too-many-locals def __init__( self, *, @@ -40,6 +41,7 @@ def __init__( output_format: str = "dot", colorized: bool = False, max_color_depth: int = 2, + max_depth: int | None = None, color_palette: tuple[str, ...] = DEFAULT_COLOR_PALETTE, ignore_list: tuple[str, ...] = tuple(), project: str = "", @@ -62,12 +64,15 @@ def __init__( self.only_classnames = only_classnames self.output_format = output_format self.colorized = colorized + self.max_depth = max_depth self.max_color_depth = max_color_depth self.color_palette = color_palette self.ignore_list = ignore_list self.project = project self.output_directory = output_directory + # pylint: enable=too-many-locals + class TestFileOptions(TypedDict): source_roots: list[str] From da496873fa338324984d704cfa261245c3d00ddb Mon Sep 17 00:00:00 2001 From: Julfried <julian.grimm8@gmail.com> Date: Mon, 11 Nov 2024 16:54:57 +0100 Subject: [PATCH 04/20] Improve depth logic for classes --- pylint/pyreverse/writer.py | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/pylint/pyreverse/writer.py b/pylint/pyreverse/writer.py index efd6723696..b88c056e21 100644 --- a/pylint/pyreverse/writer.py +++ b/pylint/pyreverse/writer.py @@ -54,12 +54,26 @@ def write(self, diadefs: Iterable[ClassDiagram | PackageDiagram]) -> None: self.write_classes(diagram) self.save() - def should_show_node(self, qualified_name: str) -> bool: + def should_show_node(self, qualified_name: str, is_class: bool = False) -> bool: """Determine if a node should be shown based on depth settings.""" # If no depth limit is set ==> show all nodes if self.max_depth is None: return True - # Count dots to determine depth, subtract 1 since root counts as depth 0 + + # For classes, we want to measure depth from their containing module + if is_class: + # Get the module part (everything before the last dot) + last_dot = qualified_name.rfind(".") + if last_dot == -1: + module_path = "" + else: + module_path = qualified_name[:last_dot] + + # Count module depth + module_depth = module_path.count(".") + return bool(module_depth <= self.max_depth) + + # For packages/modules, count full depth node_depth = qualified_name.count(".") return bool(node_depth <= self.max_depth) @@ -139,7 +153,7 @@ def write_classes(self, diagram: ClassDiagram) -> None: obj.fig_id = obj.node.qname() # Filter class based on depth setting - if not self.should_show_node(obj.fig_id): + if not self.should_show_node(obj.fig_id, is_class=True): continue if self.config.no_standalone and not any( @@ -158,8 +172,8 @@ def write_classes(self, diagram: ClassDiagram) -> None: for rel in diagram.get_relationships("specialization"): # Filter nodes based on depth setting if not self.should_show_node( - rel.from_object.fig_id - ) or not self.should_show_node(rel.to_object.fig_id): + rel.from_object.fig_id, is_class=True + ) or not self.should_show_node(rel.to_object.fig_id, is_class=True): continue self.printer.emit_edge( @@ -172,8 +186,8 @@ def write_classes(self, diagram: ClassDiagram) -> None: for rel in diagram.get_relationships("association"): # Filter nodes based on depth setting if not self.should_show_node( - rel.from_object.fig_id - ) or not self.should_show_node(rel.to_object.fig_id): + rel.from_object.fig_id, is_class=True + ) or not self.should_show_node(rel.to_object.fig_id, is_class=True): continue associations[rel.from_object.fig_id].add(rel.to_object.fig_id) @@ -187,8 +201,8 @@ def write_classes(self, diagram: ClassDiagram) -> None: for rel in diagram.get_relationships("aggregation"): # Filter nodes based on depth setting if not self.should_show_node( - rel.from_object.fig_id - ) or not self.should_show_node(rel.to_object.fig_id): + rel.from_object.fig_id, is_class=True + ) or not self.should_show_node(rel.to_object.fig_id, is_class=True): continue if rel.to_object.fig_id in associations[rel.from_object.fig_id]: From f35d82275eea8e5833d0ba83786c910552a9a2ce Mon Sep 17 00:00:00 2001 From: Julfried <julian.grimm8@gmail.com> Date: Mon, 11 Nov 2024 16:59:27 +0100 Subject: [PATCH 05/20] Update docs --- doc/additional_tools/pyreverse/configuration.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/additional_tools/pyreverse/configuration.rst b/doc/additional_tools/pyreverse/configuration.rst index 845386e533..f980e1ac4f 100644 --- a/doc/additional_tools/pyreverse/configuration.rst +++ b/doc/additional_tools/pyreverse/configuration.rst @@ -115,6 +115,13 @@ Display Options **Default:** ``2`` +--max-depth +----------- +*Maximum depth in package/module hierarchy to display. A depth of 0 shows only top-level packages, 1 shows one level of subpackages, etc. If not specified, all packages/modules are shown.* + +**Default:** ``None`` + + --module-names -------------- *Include module name in the representation of classes.* From 39e0eace1f00ecdc8d916357ba1f945c25a7b5d8 Mon Sep 17 00:00:00 2001 From: Julfried <51880314+Julfried@users.noreply.github.com> Date: Sat, 14 Dec 2024 13:38:12 +0100 Subject: [PATCH 06/20] Update docstring for the should_show_node function --- pylint/pyreverse/writer.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pylint/pyreverse/writer.py b/pylint/pyreverse/writer.py index b88c056e21..ffe7c8624c 100644 --- a/pylint/pyreverse/writer.py +++ b/pylint/pyreverse/writer.py @@ -55,7 +55,16 @@ def write(self, diadefs: Iterable[ClassDiagram | PackageDiagram]) -> None: self.save() def should_show_node(self, qualified_name: str, is_class: bool = False) -> bool: - """Determine if a node should be shown based on depth settings.""" + """Determine if a node should be shown based on depth settings. + + Depth is calculated by counting dots in the qualified name: + - depth 0: top-level packages (no dots) + - depth 1: first level subpackages (one dot) + - depth 2: second level subpackages (two dots) + + For classes, depth is measured from their containing module, excluding + the class name itself from the depth calculation. + """ # If no depth limit is set ==> show all nodes if self.max_depth is None: return True From f2a9299b08c4fc455f7204241441aea8a065a32f Mon Sep 17 00:00:00 2001 From: Julfried <51880314+Julfried@users.noreply.github.com> Date: Sat, 14 Dec 2024 14:46:18 +0100 Subject: [PATCH 07/20] Add tests for should_show_node method --- tests/pyreverse/test_writer.py | 81 ++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/tests/pyreverse/test_writer.py b/tests/pyreverse/test_writer.py index d3a2ce5aae..cb3aec164b 100644 --- a/tests/pyreverse/test_writer.py +++ b/tests/pyreverse/test_writer.py @@ -257,3 +257,84 @@ def test_package_name_with_slash(default_config: PyreverseConfig) -> None: writer.write([obj]) assert os.path.exists("test_package_name_with_slash_.dot") + + +def test_should_show_node_no_depth_limit(default_config: PyreverseConfig) -> None: + """Test that nodes are shown when no depth limit is set.""" + writer = DiagramWriter(default_config) + writer.max_depth = None + + assert writer.should_show_node("pkg") + assert writer.should_show_node("pkg.subpkg") + assert writer.should_show_node("pkg.subpkg.module") + assert writer.should_show_node("pkg.subpkg.module.submodule") + + +@pytest.mark.parametrize("max_depth", range(5)) +def test_should_show_node_with_depth_limit( + default_config: PyreverseConfig, max_depth: int +) -> None: + """Test that nodes are filtered correctly when depth limit is set. + + Depth counting is zero-based, determined by number of dots in path: + - pkg -> depth 0 (0 dots) + - pkg.subpkg -> depth 1 (1 dot) + - pkg.subpkg.module -> depth 2 (2 dots) + - pkg.subpkg.module.submodule -> depth 3 (3 dots) + """ + writer = DiagramWriter(default_config) + print("max_depth:", max_depth) + writer.max_depth = max_depth + + # Test cases for different depths + test_cases = [ + "pkg", + "pkg.subpkg", + "pkg.subpkg.module", + "pkg.subpkg.module.submodule", + ] + + # Test if nodes are shown based on their depth and max_depth setting + for i, path in enumerate(test_cases): + should_show = i <= max_depth + print( + f"Path {path} (depth {i}) with max_depth={max_depth} " + f"{'should show' if should_show else 'should not show'}:" + f"{writer.should_show_node(path, is_class=True)}" + ) + assert writer.should_show_node(path) == should_show + + +@pytest.mark.parametrize("max_depth", range(5)) +def test_should_show_node_classes( + default_config: PyreverseConfig, max_depth: int +) -> None: + """Test class visibility based on their containing module depth. + + Classes are filtered based on their containing module's depth: + - MyClass -> depth 0 (no module) + - pkg.MyClass -> depth 0 (module has no dots) + - pkg.subpkg.MyClass -> depth 1 (module has 1 dot) + - pkg.subpkg.mod.MyClass -> depth 2 (module has 2 dots) + """ + writer = DiagramWriter(default_config) + print("max_depth:", max_depth) + writer.max_depth = max_depth + + # Test cases for different depths + test_cases = [ + "MyClass", + "pkg.MyClass", + "pkg.subpkg.MyClass", + "pkg.subpkg.mod.MyClass", + ] + + # Test if nodes are shown based on their depth and max_depth setting + for i, path in enumerate(test_cases): + should_show = i - 1 <= max_depth # Subtract 1 to account for the class name + print( + f"Path {path} (depth {i}) with max_depth={max_depth} " + f"{'should show' if should_show else 'should not show'}:" + f"{writer.should_show_node(path, is_class=True)}" + ) + assert writer.should_show_node(path, is_class=True) == should_show From 1f31feb2f2cceef71499ad7fbbb2ec0f136da993 Mon Sep 17 00:00:00 2001 From: Julfried <51880314+Julfried@users.noreply.github.com> Date: Sat, 14 Dec 2024 15:51:27 +0100 Subject: [PATCH 08/20] Added a news fragment --- doc/whatsnew/fragments/10077.feature.rst | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 doc/whatsnew/fragments/10077.feature.rst diff --git a/doc/whatsnew/fragments/10077.feature.rst b/doc/whatsnew/fragments/10077.feature.rst new file mode 100644 index 0000000000..b8e748071b --- /dev/null +++ b/doc/whatsnew/fragments/10077.feature.rst @@ -0,0 +1,4 @@ +Add --max-depth option to pyreverse to control diagram complexity. A depth of 0 shows only top-level packages, 1 shows one level of subpackages, etc. +This helps manage visualization of large codebases by limiting the depth of displayed packages and classes. + +Refs #10077 From 2006bb7fac3152f654c9568cfdc925f39b4469f2 Mon Sep 17 00:00:00 2001 From: Julfried <51880314+Julfried@users.noreply.github.com> Date: Sat, 14 Dec 2024 17:38:08 +0100 Subject: [PATCH 09/20] Remove file extension --- doc/whatsnew/fragments/{10077.feature.rst => 10077.feature} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename doc/whatsnew/fragments/{10077.feature.rst => 10077.feature} (100%) diff --git a/doc/whatsnew/fragments/10077.feature.rst b/doc/whatsnew/fragments/10077.feature similarity index 100% rename from doc/whatsnew/fragments/10077.feature.rst rename to doc/whatsnew/fragments/10077.feature From 1c107ee16bd75c881b0239b8355101279f0c9f66 Mon Sep 17 00:00:00 2001 From: Julfried <51880314+Julfried@users.noreply.github.com> Date: Sun, 15 Dec 2024 00:36:00 +0100 Subject: [PATCH 10/20] Fix typo in docstring --- pylint/pyreverse/writer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pylint/pyreverse/writer.py b/pylint/pyreverse/writer.py index ffe7c8624c..a021b1b287 100644 --- a/pylint/pyreverse/writer.py +++ b/pylint/pyreverse/writer.py @@ -59,8 +59,8 @@ def should_show_node(self, qualified_name: str, is_class: bool = False) -> bool: Depth is calculated by counting dots in the qualified name: - depth 0: top-level packages (no dots) - - depth 1: first level subpackages (one dot) - - depth 2: second level subpackages (two dots) + - depth 1: first level sub-packages (one dot) + - depth 2: second level sub-packages (two dots) For classes, depth is measured from their containing module, excluding the class name itself from the depth calculation. From 4be3aa7fd47f96b61cda652e2d2cbae8d72c059c Mon Sep 17 00:00:00 2001 From: Pierre Sassoulas <pierre.sassoulas@gmail.com> Date: Wed, 25 Dec 2024 20:30:11 +0100 Subject: [PATCH 11/20] Update tests/pyreverse/test_writer.py --- tests/pyreverse/test_writer.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/pyreverse/test_writer.py b/tests/pyreverse/test_writer.py index cb3aec164b..a895f62b36 100644 --- a/tests/pyreverse/test_writer.py +++ b/tests/pyreverse/test_writer.py @@ -277,10 +277,10 @@ def test_should_show_node_with_depth_limit( """Test that nodes are filtered correctly when depth limit is set. Depth counting is zero-based, determined by number of dots in path: - - pkg -> depth 0 (0 dots) - - pkg.subpkg -> depth 1 (1 dot) - - pkg.subpkg.module -> depth 2 (2 dots) - - pkg.subpkg.module.submodule -> depth 3 (3 dots) + - 'pkg' -> depth 0 (0 dots) + - 'pkg.subpkg' -> depth 1 (1 dot) + - 'pkg.subpkg.module' -> depth 2 (2 dots) + - 'pkg.subpkg.module.submodule' -> depth 3 (3 dots) """ writer = DiagramWriter(default_config) print("max_depth:", max_depth) From 6defb5f81c2fa394a2ec6333849ce3f6bb22f9b6 Mon Sep 17 00:00:00 2001 From: Pierre Sassoulas <pierre.sassoulas@gmail.com> Date: Wed, 25 Dec 2024 20:30:52 +0100 Subject: [PATCH 12/20] Update tests/pyreverse/test_writer.py --- tests/pyreverse/test_writer.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/pyreverse/test_writer.py b/tests/pyreverse/test_writer.py index a895f62b36..07492f1d3e 100644 --- a/tests/pyreverse/test_writer.py +++ b/tests/pyreverse/test_writer.py @@ -312,10 +312,10 @@ def test_should_show_node_classes( """Test class visibility based on their containing module depth. Classes are filtered based on their containing module's depth: - - MyClass -> depth 0 (no module) - - pkg.MyClass -> depth 0 (module has no dots) - - pkg.subpkg.MyClass -> depth 1 (module has 1 dot) - - pkg.subpkg.mod.MyClass -> depth 2 (module has 2 dots) + - 'MyClass' -> depth 0 (no module) + - 'pkg.MyClass' -> depth 0 (module has no dots) + - 'pkg.subpkg.MyClass' -> depth 1 (module has 1 dot) + - 'pkg.subpkg.mod.MyClass' -> depth 2 (module has 2 dots) """ writer = DiagramWriter(default_config) print("max_depth:", max_depth) From 88f3a9dd8646a5462666cb73a9c848228422f59d Mon Sep 17 00:00:00 2001 From: Julfried <51880314+Julfried@users.noreply.github.com> Date: Thu, 26 Dec 2024 10:21:56 +0100 Subject: [PATCH 13/20] Try to increase test coverage --- tests/pyreverse/data/packages_depth_limited.dot | 9 +++++++++ tests/pyreverse/test_writer.py | 14 ++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 tests/pyreverse/data/packages_depth_limited.dot diff --git a/tests/pyreverse/data/packages_depth_limited.dot b/tests/pyreverse/data/packages_depth_limited.dot new file mode 100644 index 0000000000..8f8a231141 --- /dev/null +++ b/tests/pyreverse/data/packages_depth_limited.dot @@ -0,0 +1,9 @@ +digraph "packages_depth_limited" { +rankdir=BT +charset="utf-8" +"data" [color="black", label=<data>, shape="box", style="solid"]; +"data.clientmodule_test" [color="black", label=<data.clientmodule_test>, shape="box", style="solid"]; +"data.nullable_pattern" [color="black", label=<data.nullable_pattern>, shape="box", style="solid"]; +"data.property_pattern" [color="black", label=<data.property_pattern>, shape="box", style="solid"]; +"data.suppliermodule_test" [color="black", label=<data.suppliermodule_test>, shape="box", style="solid"]; +} diff --git a/tests/pyreverse/test_writer.py b/tests/pyreverse/test_writer.py index 07492f1d3e..4174880137 100644 --- a/tests/pyreverse/test_writer.py +++ b/tests/pyreverse/test_writer.py @@ -338,3 +338,17 @@ def test_should_show_node_classes( f"{writer.should_show_node(path, is_class=True)}" ) assert writer.should_show_node(path, is_class=True) == should_show + + +def test_depth_limited_write( + default_config: PyreverseConfig, get_project: GetProjectCallable +) -> None: + """Test package diagram generation with a depth limit of 1.""" + writer = DiagramWriter(default_config) + project = get_project(TEST_DATA_DIR, name="depth_limited") + linker = Linker(project) + handler = DiadefsHandler(default_config) + dd = DefaultDiadefGenerator(linker, handler).visit(project) + writer.max_depth = 1 + writer.write(dd) + _assert_files_are_equal("packages_depth_limited.dot") From 35c062cdf46dd07e8256dd0d3c5749e2415110ac Mon Sep 17 00:00:00 2001 From: Julfried <51880314+Julfried@users.noreply.github.com> Date: Sun, 5 Jan 2025 20:27:55 +0100 Subject: [PATCH 14/20] Refactor test_depth_limited_write to set max depth in default config --- tests/pyreverse/test_writer.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/pyreverse/test_writer.py b/tests/pyreverse/test_writer.py index 4174880137..e31ce11320 100644 --- a/tests/pyreverse/test_writer.py +++ b/tests/pyreverse/test_writer.py @@ -344,11 +344,13 @@ def test_depth_limited_write( default_config: PyreverseConfig, get_project: GetProjectCallable ) -> None: """Test package diagram generation with a depth limit of 1.""" + # Set max depth in default config instead of the writer instance + default_config.max_depth = 1 + writer = DiagramWriter(default_config) project = get_project(TEST_DATA_DIR, name="depth_limited") linker = Linker(project) handler = DiadefsHandler(default_config) dd = DefaultDiadefGenerator(linker, handler).visit(project) - writer.max_depth = 1 writer.write(dd) _assert_files_are_equal("packages_depth_limited.dot") From 907479bac796b56fc6a1deae0467e02efa0c13eb Mon Sep 17 00:00:00 2001 From: Julfried <51880314+Julfried@users.noreply.github.com> Date: Sun, 5 Jan 2025 22:08:08 +0100 Subject: [PATCH 15/20] Use proper fixtures to setup depth limited tests --- tests/pyreverse/conftest.py | 7 ++++ .../pyreverse/data/packages_depth_limited.dot | 3 +- tests/pyreverse/test_writer.py | 33 ++++++++++--------- 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/tests/pyreverse/conftest.py b/tests/pyreverse/conftest.py index ac63b2aeaa..2b05d4403b 100644 --- a/tests/pyreverse/conftest.py +++ b/tests/pyreverse/conftest.py @@ -67,6 +67,13 @@ def html_config() -> PyreverseConfig: ) +@pytest.fixture() +def depth_limited_config(default_max_depth: int) -> PyreverseConfig: + return PyreverseConfig( + max_depth=default_max_depth, + ) + + @pytest.fixture(scope="session") def get_project() -> GetProjectCallable: def _get_project(module: str, name: str | None = "No Name") -> Project: diff --git a/tests/pyreverse/data/packages_depth_limited.dot b/tests/pyreverse/data/packages_depth_limited.dot index 8f8a231141..553d7a9fbe 100644 --- a/tests/pyreverse/data/packages_depth_limited.dot +++ b/tests/pyreverse/data/packages_depth_limited.dot @@ -6,4 +6,5 @@ charset="utf-8" "data.nullable_pattern" [color="black", label=<data.nullable_pattern>, shape="box", style="solid"]; "data.property_pattern" [color="black", label=<data.property_pattern>, shape="box", style="solid"]; "data.suppliermodule_test" [color="black", label=<data.suppliermodule_test>, shape="box", style="solid"]; -} +"data.clientmodule_test" -> "data.suppliermodule_test" [arrowhead="open", arrowtail="none"]; +} diff --git a/tests/pyreverse/test_writer.py b/tests/pyreverse/test_writer.py index e31ce11320..15959b4f6c 100644 --- a/tests/pyreverse/test_writer.py +++ b/tests/pyreverse/test_writer.py @@ -160,6 +160,16 @@ def setup_html( yield from _setup(project, html_config, writer) +@pytest.fixture() +def setup_depth_limited( + depth_limited_config: PyreverseConfig, get_project: GetProjectCallable +) -> Iterator[None]: + writer = DiagramWriter(depth_limited_config) + + project = get_project(TEST_DATA_DIR, name="depth_limited") + yield from _setup(project, depth_limited_config, writer) + + def _setup( project: Project, config: PyreverseConfig, writer: DiagramWriter ) -> Iterator[None]: @@ -220,6 +230,13 @@ def test_colorized_puml_files(generated_file: str) -> None: _assert_files_are_equal(generated_file) +@pytest.mark.parametrize("default_max_depth", [1]) +@pytest.mark.usefixtures("setup_depth_limited") +def test_depth_limited_write() -> None: + """Test package diagram generation with a depth limit of 1.""" + _assert_files_are_equal("packages_depth_limited.dot") + + def _assert_files_are_equal(generated_file: str) -> None: expected_file = os.path.join(os.path.dirname(__file__), "data", generated_file) generated = _file_lines(generated_file) @@ -338,19 +355,3 @@ def test_should_show_node_classes( f"{writer.should_show_node(path, is_class=True)}" ) assert writer.should_show_node(path, is_class=True) == should_show - - -def test_depth_limited_write( - default_config: PyreverseConfig, get_project: GetProjectCallable -) -> None: - """Test package diagram generation with a depth limit of 1.""" - # Set max depth in default config instead of the writer instance - default_config.max_depth = 1 - - writer = DiagramWriter(default_config) - project = get_project(TEST_DATA_DIR, name="depth_limited") - linker = Linker(project) - handler = DiadefsHandler(default_config) - dd = DefaultDiadefGenerator(linker, handler).visit(project) - writer.write(dd) - _assert_files_are_equal("packages_depth_limited.dot") From 012d1361f661f6d754d6235cf0deb6c30765c428 Mon Sep 17 00:00:00 2001 From: Julfried <51880314+Julfried@users.noreply.github.com> Date: Sun, 5 Jan 2025 22:10:37 +0100 Subject: [PATCH 16/20] Also assert class diagram --- tests/pyreverse/data/classes_depth_limited.dot | 17 +++++++++++++++++ tests/pyreverse/test_writer.py | 1 + 2 files changed, 18 insertions(+) create mode 100644 tests/pyreverse/data/classes_depth_limited.dot diff --git a/tests/pyreverse/data/classes_depth_limited.dot b/tests/pyreverse/data/classes_depth_limited.dot new file mode 100644 index 0000000000..35c6fa2e5b --- /dev/null +++ b/tests/pyreverse/data/classes_depth_limited.dot @@ -0,0 +1,17 @@ +digraph "classes_depth_limited" { +rankdir=BT +charset="utf-8" +"data.clientmodule_test.Ancestor" [color="black", fontcolor="black", label=<{Ancestor|attr : str<br ALIGN="LEFT"/>cls_member<br ALIGN="LEFT"/>|get_value()<br ALIGN="LEFT"/>set_value(value)<br ALIGN="LEFT"/>}>, shape="record", style="solid"]; +"data.suppliermodule_test.CustomException" [color="black", fontcolor="red", label=<{CustomException|<br ALIGN="LEFT"/>|}>, shape="record", style="solid"]; +"data.suppliermodule_test.DoNothing" [color="black", fontcolor="black", label=<{DoNothing|<br ALIGN="LEFT"/>|}>, shape="record", style="solid"]; +"data.suppliermodule_test.DoNothing2" [color="black", fontcolor="black", label=<{DoNothing2|<br ALIGN="LEFT"/>|}>, shape="record", style="solid"]; +"data.suppliermodule_test.DoSomething" [color="black", fontcolor="black", label=<{DoSomething|my_int : Optional[int]<br ALIGN="LEFT"/>my_int_2 : Optional[int]<br ALIGN="LEFT"/>my_string : str<br ALIGN="LEFT"/>|do_it(new_int: int): int<br ALIGN="LEFT"/>}>, shape="record", style="solid"]; +"data.suppliermodule_test.Interface" [color="black", fontcolor="black", label=<{Interface|<br ALIGN="LEFT"/>|<I>get_value</I>()<br ALIGN="LEFT"/><I>set_value</I>(value)<br ALIGN="LEFT"/>}>, shape="record", style="solid"]; +"data.nullable_pattern.NullablePatterns" [color="black", fontcolor="black", label=<{NullablePatterns|<br ALIGN="LEFT"/>|<I>return_nullable_1</I>(): int \| None<br ALIGN="LEFT"/><I>return_nullable_2</I>(): Optional[int]<br ALIGN="LEFT"/>}>, shape="record", style="solid"]; +"data.property_pattern.PropertyPatterns" [color="black", fontcolor="black", label=<{PropertyPatterns|prop1<br ALIGN="LEFT"/>prop2<br ALIGN="LEFT"/>|}>, shape="record", style="solid"]; +"data.clientmodule_test.Specialization" [color="black", fontcolor="black", label=<{Specialization|TYPE : str<br ALIGN="LEFT"/>relation<br ALIGN="LEFT"/>relation2<br ALIGN="LEFT"/>top : str<br ALIGN="LEFT"/>|from_value(value: int)<br ALIGN="LEFT"/>increment_value(): None<br ALIGN="LEFT"/>transform_value(value: int): int<br ALIGN="LEFT"/>}>, shape="record", style="solid"]; +"data.clientmodule_test.Specialization" -> "data.clientmodule_test.Ancestor" [arrowhead="empty", arrowtail="none"]; +"data.suppliermodule_test.DoNothing" -> "data.clientmodule_test.Ancestor" [arrowhead="diamond", arrowtail="none", fontcolor="green", label="cls_member", style="solid"]; +"data.suppliermodule_test.DoNothing" -> "data.clientmodule_test.Specialization" [arrowhead="diamond", arrowtail="none", fontcolor="green", label="relation", style="solid"]; +"data.suppliermodule_test.DoNothing2" -> "data.clientmodule_test.Specialization" [arrowhead="odiamond", arrowtail="none", fontcolor="green", label="relation2", style="solid"]; +} diff --git a/tests/pyreverse/test_writer.py b/tests/pyreverse/test_writer.py index 15959b4f6c..9f13e5b6d3 100644 --- a/tests/pyreverse/test_writer.py +++ b/tests/pyreverse/test_writer.py @@ -235,6 +235,7 @@ def test_colorized_puml_files(generated_file: str) -> None: def test_depth_limited_write() -> None: """Test package diagram generation with a depth limit of 1.""" _assert_files_are_equal("packages_depth_limited.dot") + _assert_files_are_equal("classes_depth_limited.dot") def _assert_files_are_equal(generated_file: str) -> None: From 24fdc46edf3bf861f7a4b58cab266a7734ba05ab Mon Sep 17 00:00:00 2001 From: Julfried <51880314+Julfried@users.noreply.github.com> Date: Sun, 5 Jan 2025 22:15:07 +0100 Subject: [PATCH 17/20] Remove old test files --- tests/pyreverse/data/classes_depth_limited.dot | 17 ----------------- tests/pyreverse/data/packages_depth_limited.dot | 10 ---------- 2 files changed, 27 deletions(-) delete mode 100644 tests/pyreverse/data/classes_depth_limited.dot delete mode 100644 tests/pyreverse/data/packages_depth_limited.dot diff --git a/tests/pyreverse/data/classes_depth_limited.dot b/tests/pyreverse/data/classes_depth_limited.dot deleted file mode 100644 index 35c6fa2e5b..0000000000 --- a/tests/pyreverse/data/classes_depth_limited.dot +++ /dev/null @@ -1,17 +0,0 @@ -digraph "classes_depth_limited" { -rankdir=BT -charset="utf-8" -"data.clientmodule_test.Ancestor" [color="black", fontcolor="black", label=<{Ancestor|attr : str<br ALIGN="LEFT"/>cls_member<br ALIGN="LEFT"/>|get_value()<br ALIGN="LEFT"/>set_value(value)<br ALIGN="LEFT"/>}>, shape="record", style="solid"]; -"data.suppliermodule_test.CustomException" [color="black", fontcolor="red", label=<{CustomException|<br ALIGN="LEFT"/>|}>, shape="record", style="solid"]; -"data.suppliermodule_test.DoNothing" [color="black", fontcolor="black", label=<{DoNothing|<br ALIGN="LEFT"/>|}>, shape="record", style="solid"]; -"data.suppliermodule_test.DoNothing2" [color="black", fontcolor="black", label=<{DoNothing2|<br ALIGN="LEFT"/>|}>, shape="record", style="solid"]; -"data.suppliermodule_test.DoSomething" [color="black", fontcolor="black", label=<{DoSomething|my_int : Optional[int]<br ALIGN="LEFT"/>my_int_2 : Optional[int]<br ALIGN="LEFT"/>my_string : str<br ALIGN="LEFT"/>|do_it(new_int: int): int<br ALIGN="LEFT"/>}>, shape="record", style="solid"]; -"data.suppliermodule_test.Interface" [color="black", fontcolor="black", label=<{Interface|<br ALIGN="LEFT"/>|<I>get_value</I>()<br ALIGN="LEFT"/><I>set_value</I>(value)<br ALIGN="LEFT"/>}>, shape="record", style="solid"]; -"data.nullable_pattern.NullablePatterns" [color="black", fontcolor="black", label=<{NullablePatterns|<br ALIGN="LEFT"/>|<I>return_nullable_1</I>(): int \| None<br ALIGN="LEFT"/><I>return_nullable_2</I>(): Optional[int]<br ALIGN="LEFT"/>}>, shape="record", style="solid"]; -"data.property_pattern.PropertyPatterns" [color="black", fontcolor="black", label=<{PropertyPatterns|prop1<br ALIGN="LEFT"/>prop2<br ALIGN="LEFT"/>|}>, shape="record", style="solid"]; -"data.clientmodule_test.Specialization" [color="black", fontcolor="black", label=<{Specialization|TYPE : str<br ALIGN="LEFT"/>relation<br ALIGN="LEFT"/>relation2<br ALIGN="LEFT"/>top : str<br ALIGN="LEFT"/>|from_value(value: int)<br ALIGN="LEFT"/>increment_value(): None<br ALIGN="LEFT"/>transform_value(value: int): int<br ALIGN="LEFT"/>}>, shape="record", style="solid"]; -"data.clientmodule_test.Specialization" -> "data.clientmodule_test.Ancestor" [arrowhead="empty", arrowtail="none"]; -"data.suppliermodule_test.DoNothing" -> "data.clientmodule_test.Ancestor" [arrowhead="diamond", arrowtail="none", fontcolor="green", label="cls_member", style="solid"]; -"data.suppliermodule_test.DoNothing" -> "data.clientmodule_test.Specialization" [arrowhead="diamond", arrowtail="none", fontcolor="green", label="relation", style="solid"]; -"data.suppliermodule_test.DoNothing2" -> "data.clientmodule_test.Specialization" [arrowhead="odiamond", arrowtail="none", fontcolor="green", label="relation2", style="solid"]; -} diff --git a/tests/pyreverse/data/packages_depth_limited.dot b/tests/pyreverse/data/packages_depth_limited.dot deleted file mode 100644 index 553d7a9fbe..0000000000 --- a/tests/pyreverse/data/packages_depth_limited.dot +++ /dev/null @@ -1,10 +0,0 @@ -digraph "packages_depth_limited" { -rankdir=BT -charset="utf-8" -"data" [color="black", label=<data>, shape="box", style="solid"]; -"data.clientmodule_test" [color="black", label=<data.clientmodule_test>, shape="box", style="solid"]; -"data.nullable_pattern" [color="black", label=<data.nullable_pattern>, shape="box", style="solid"]; -"data.property_pattern" [color="black", label=<data.property_pattern>, shape="box", style="solid"]; -"data.suppliermodule_test" [color="black", label=<data.suppliermodule_test>, shape="box", style="solid"]; -"data.clientmodule_test" -> "data.suppliermodule_test" [arrowhead="open", arrowtail="none"]; -} From 59a720ee825f91cba92b3c0c7abf84b51ab748c2 Mon Sep 17 00:00:00 2001 From: Julfried <51880314+Julfried@users.noreply.github.com> Date: Sun, 5 Jan 2025 22:16:05 +0100 Subject: [PATCH 18/20] Test writer with multiple depth limits --- .../pyreverse/data/classes_depth_limited_0.dot | 4 ++++ .../pyreverse/data/classes_depth_limited_1.dot | 17 +++++++++++++++++ .../pyreverse/data/packages_depth_limited_0.dot | 5 +++++ .../pyreverse/data/packages_depth_limited_1.dot | 10 ++++++++++ tests/pyreverse/test_writer.py | 12 +++++++----- 5 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 tests/pyreverse/data/classes_depth_limited_0.dot create mode 100644 tests/pyreverse/data/classes_depth_limited_1.dot create mode 100644 tests/pyreverse/data/packages_depth_limited_0.dot create mode 100644 tests/pyreverse/data/packages_depth_limited_1.dot diff --git a/tests/pyreverse/data/classes_depth_limited_0.dot b/tests/pyreverse/data/classes_depth_limited_0.dot new file mode 100644 index 0000000000..94ce357f5d --- /dev/null +++ b/tests/pyreverse/data/classes_depth_limited_0.dot @@ -0,0 +1,4 @@ +digraph "classes_depth_limited_0" { +rankdir=BT +charset="utf-8" +} diff --git a/tests/pyreverse/data/classes_depth_limited_1.dot b/tests/pyreverse/data/classes_depth_limited_1.dot new file mode 100644 index 0000000000..d27c19aaad --- /dev/null +++ b/tests/pyreverse/data/classes_depth_limited_1.dot @@ -0,0 +1,17 @@ +digraph "classes_depth_limited_1" { +rankdir=BT +charset="utf-8" +"data.clientmodule_test.Ancestor" [color="black", fontcolor="black", label=<{Ancestor|attr : str<br ALIGN="LEFT"/>cls_member<br ALIGN="LEFT"/>|get_value()<br ALIGN="LEFT"/>set_value(value)<br ALIGN="LEFT"/>}>, shape="record", style="solid"]; +"data.suppliermodule_test.CustomException" [color="black", fontcolor="red", label=<{CustomException|<br ALIGN="LEFT"/>|}>, shape="record", style="solid"]; +"data.suppliermodule_test.DoNothing" [color="black", fontcolor="black", label=<{DoNothing|<br ALIGN="LEFT"/>|}>, shape="record", style="solid"]; +"data.suppliermodule_test.DoNothing2" [color="black", fontcolor="black", label=<{DoNothing2|<br ALIGN="LEFT"/>|}>, shape="record", style="solid"]; +"data.suppliermodule_test.DoSomething" [color="black", fontcolor="black", label=<{DoSomething|my_int : Optional[int]<br ALIGN="LEFT"/>my_int_2 : Optional[int]<br ALIGN="LEFT"/>my_string : str<br ALIGN="LEFT"/>|do_it(new_int: int): int<br ALIGN="LEFT"/>}>, shape="record", style="solid"]; +"data.suppliermodule_test.Interface" [color="black", fontcolor="black", label=<{Interface|<br ALIGN="LEFT"/>|<I>get_value</I>()<br ALIGN="LEFT"/><I>set_value</I>(value)<br ALIGN="LEFT"/>}>, shape="record", style="solid"]; +"data.nullable_pattern.NullablePatterns" [color="black", fontcolor="black", label=<{NullablePatterns|<br ALIGN="LEFT"/>|<I>return_nullable_1</I>(): int \| None<br ALIGN="LEFT"/><I>return_nullable_2</I>(): Optional[int]<br ALIGN="LEFT"/>}>, shape="record", style="solid"]; +"data.property_pattern.PropertyPatterns" [color="black", fontcolor="black", label=<{PropertyPatterns|prop1<br ALIGN="LEFT"/>prop2<br ALIGN="LEFT"/>|}>, shape="record", style="solid"]; +"data.clientmodule_test.Specialization" [color="black", fontcolor="black", label=<{Specialization|TYPE : str<br ALIGN="LEFT"/>relation<br ALIGN="LEFT"/>relation2<br ALIGN="LEFT"/>top : str<br ALIGN="LEFT"/>|from_value(value: int)<br ALIGN="LEFT"/>increment_value(): None<br ALIGN="LEFT"/>transform_value(value: int): int<br ALIGN="LEFT"/>}>, shape="record", style="solid"]; +"data.clientmodule_test.Specialization" -> "data.clientmodule_test.Ancestor" [arrowhead="empty", arrowtail="none"]; +"data.suppliermodule_test.DoNothing" -> "data.clientmodule_test.Ancestor" [arrowhead="diamond", arrowtail="none", fontcolor="green", label="cls_member", style="solid"]; +"data.suppliermodule_test.DoNothing" -> "data.clientmodule_test.Specialization" [arrowhead="diamond", arrowtail="none", fontcolor="green", label="relation", style="solid"]; +"data.suppliermodule_test.DoNothing2" -> "data.clientmodule_test.Specialization" [arrowhead="odiamond", arrowtail="none", fontcolor="green", label="relation2", style="solid"]; +} diff --git a/tests/pyreverse/data/packages_depth_limited_0.dot b/tests/pyreverse/data/packages_depth_limited_0.dot new file mode 100644 index 0000000000..9db6e81bb9 --- /dev/null +++ b/tests/pyreverse/data/packages_depth_limited_0.dot @@ -0,0 +1,5 @@ +digraph "packages_depth_limited_0" { +rankdir=BT +charset="utf-8" +"data" [color="black", label=<data>, shape="box", style="solid"]; +} diff --git a/tests/pyreverse/data/packages_depth_limited_1.dot b/tests/pyreverse/data/packages_depth_limited_1.dot new file mode 100644 index 0000000000..51c324d4e7 --- /dev/null +++ b/tests/pyreverse/data/packages_depth_limited_1.dot @@ -0,0 +1,10 @@ +digraph "packages_depth_limited_1" { +rankdir=BT +charset="utf-8" +"data" [color="black", label=<data>, shape="box", style="solid"]; +"data.clientmodule_test" [color="black", label=<data.clientmodule_test>, shape="box", style="solid"]; +"data.nullable_pattern" [color="black", label=<data.nullable_pattern>, shape="box", style="solid"]; +"data.property_pattern" [color="black", label=<data.property_pattern>, shape="box", style="solid"]; +"data.suppliermodule_test" [color="black", label=<data.suppliermodule_test>, shape="box", style="solid"]; +"data.clientmodule_test" -> "data.suppliermodule_test" [arrowhead="open", arrowtail="none"]; +} diff --git a/tests/pyreverse/test_writer.py b/tests/pyreverse/test_writer.py index 9f13e5b6d3..85596e1238 100644 --- a/tests/pyreverse/test_writer.py +++ b/tests/pyreverse/test_writer.py @@ -166,7 +166,9 @@ def setup_depth_limited( ) -> Iterator[None]: writer = DiagramWriter(depth_limited_config) - project = get_project(TEST_DATA_DIR, name="depth_limited") + project = get_project( + TEST_DATA_DIR, name=f"depth_limited_{depth_limited_config.max_depth}" + ) yield from _setup(project, depth_limited_config, writer) @@ -230,12 +232,12 @@ def test_colorized_puml_files(generated_file: str) -> None: _assert_files_are_equal(generated_file) -@pytest.mark.parametrize("default_max_depth", [1]) +@pytest.mark.parametrize("default_max_depth", [0, 1]) @pytest.mark.usefixtures("setup_depth_limited") -def test_depth_limited_write() -> None: +def test_depth_limited_write(default_max_depth: int) -> None: """Test package diagram generation with a depth limit of 1.""" - _assert_files_are_equal("packages_depth_limited.dot") - _assert_files_are_equal("classes_depth_limited.dot") + _assert_files_are_equal(f"packages_depth_limited_{default_max_depth}.dot") + _assert_files_are_equal(f"classes_depth_limited_{default_max_depth}.dot") def _assert_files_are_equal(generated_file: str) -> None: From 85722e60f78151fee410bef457d381be0ddbaf2d Mon Sep 17 00:00:00 2001 From: Julfried <51880314+Julfried@users.noreply.github.com> Date: Sun, 5 Jan 2025 23:38:48 +0100 Subject: [PATCH 19/20] Add subpkg and MyClass to spelling ignore list --- pylintrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pylintrc b/pylintrc index bd6e8a2e22..9eaa8cf007 100644 --- a/pylintrc +++ b/pylintrc @@ -393,7 +393,7 @@ missing-member-max-choices=1 spelling-dict= # List of comma separated words that should not be checked. -spelling-ignore-words= +spelling-ignore-words=subpkg,MyClass # List of comma separated words that should be considered directives if they # appear and the beginning of a comment and should not be checked. From 94a3898e20e6a8cbcbb9fd1d4f408a9ac828a441 Mon Sep 17 00:00:00 2001 From: Julfried <51880314+Julfried@users.noreply.github.com> Date: Sun, 19 Jan 2025 15:10:07 +0100 Subject: [PATCH 20/20] Move --max-depth option to option group "Filtering and Scope" --- .../pyreverse/configuration.rst | 14 ++++---- pylint/pyreverse/main.py | 32 +++++++++---------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/doc/additional_tools/pyreverse/configuration.rst b/doc/additional_tools/pyreverse/configuration.rst index f980e1ac4f..231defa1c3 100644 --- a/doc/additional_tools/pyreverse/configuration.rst +++ b/doc/additional_tools/pyreverse/configuration.rst @@ -58,6 +58,13 @@ Filtering and Scope **Default:** ``PUB_ONLY`` +--max-depth +----------- +*Maximum depth in package/module hierarchy to display. A depth of 0 shows only top-level packages, 1 shows one level of subpackages, etc. If not specified, all packages/modules are shown.* + +**Default:** ``None`` + + --show-ancestors ---------------- *Show <ancestor> generations of ancestor classes not in <projects>.* @@ -115,13 +122,6 @@ Display Options **Default:** ``2`` ---max-depth ------------ -*Maximum depth in package/module hierarchy to display. A depth of 0 shows only top-level packages, 1 shows one level of subpackages, etc. If not specified, all packages/modules are shown.* - -**Default:** ``None`` - - --module-names -------------- *Include module name in the representation of classes.* diff --git a/pylint/pyreverse/main.py b/pylint/pyreverse/main.py index 7538f9b533..f297856c63 100644 --- a/pylint/pyreverse/main.py +++ b/pylint/pyreverse/main.py @@ -151,6 +151,22 @@ "help": "Include standard library objects in representation of classes.", }, ), + ( + "max-depth", + { + "dest": "max_depth", + "action": "store", + "default": None, + "metavar": "<depth>", + "type": "int", + "group": OPTIONS_GROUPS["FILTERING"], + "help": ( + "Maximum depth in package/module hierarchy to display. A depth of 0 shows only " + "top-level packages, 1 shows one level of subpackages, etc. If not specified, " + "all packages/modules are shown." + ), + }, + ), # Display Options ( "module-names", @@ -192,22 +208,6 @@ "help": "Use colored output. Classes/modules of the same package get the same color.", }, ), - ( - "max-depth", - { - "dest": "max_depth", - "action": "store", - "default": None, - "metavar": "<depth>", - "type": "int", - "group": OPTIONS_GROUPS["DISPLAY"], - "help": ( - "Maximum depth in package/module hierarchy to display. A depth of 0 shows only " - "top-level packages, 1 shows one level of subpackages, etc. If not specified, " - "all packages/modules are shown." - ), - }, - ), ( "max-color-depth", {