Skip to content

Commit 15a5ac0

Browse files
Add detailed documentation for Pyreverse options and fix __init__ (#10045)
* Add comprehensive documentation for Pyreverse command-line options * Add configuration section to Pyreverse documentation * Also make sure that `Run.__init__` doesn't return `NoReturn` Co-authored-by: Daniël van Noord <[email protected]>
1 parent da0d3fc commit 15a5ac0

File tree

12 files changed

+371
-95
lines changed

12 files changed

+371
-95
lines changed
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
.. This file is auto-generated. Make any changes to the associated
2+
.. docs extension in 'doc/exts/pyreverse_configuration.py'.
3+
4+
5+
6+
Pyreverse Configuration
7+
^^^^^^^^^^^^^^^^^^^^^^^
8+
9+
10+
Filtering and Scope
11+
-------------------
12+
13+
--all-ancestors
14+
"""""""""""""""
15+
*Show all ancestors of all classes in <projects>.*
16+
17+
**Default:** ``None``
18+
19+
20+
--all-associated
21+
""""""""""""""""
22+
*Show all classes associated with the target classes, including indirect associations.*
23+
24+
**Default:** ``None``
25+
26+
27+
--class
28+
"""""""
29+
*Create a class diagram with all classes related to <class>; this uses by default the options -ASmy*
30+
31+
**Default:** ``None``
32+
33+
34+
--filter-mode
35+
"""""""""""""
36+
*Filter attributes and functions according to <mode>. Correct modes are:
37+
'PUB_ONLY' filter all non public attributes [DEFAULT], equivalent to PRIVATE+SPECIAL
38+
'ALL' no filter
39+
'SPECIAL' filter Python special functions except constructor
40+
'OTHER' filter protected and private attributes*
41+
42+
**Default:** ``PUB_ONLY``
43+
44+
45+
--show-ancestors
46+
""""""""""""""""
47+
*Show <ancestor> generations of ancestor classes not in <projects>.*
48+
49+
**Default:** ``None``
50+
51+
52+
--show-associated
53+
"""""""""""""""""
54+
*Show <association_level> levels of associated classes not in <projects>.*
55+
56+
**Default:** ``None``
57+
58+
59+
--show-builtin
60+
""""""""""""""
61+
*Include builtin objects in representation of classes.*
62+
63+
**Default:** ``False``
64+
65+
66+
--show-stdlib
67+
"""""""""""""
68+
*Include standard library objects in representation of classes.*
69+
70+
**Default:** ``False``
71+
72+
73+
74+
75+
Display Options
76+
---------------
77+
78+
--color-palette
79+
"""""""""""""""
80+
*Comma separated list of colors to use for the package depth coloring.*
81+
82+
**Default:** ``('#77AADD', '#99DDFF', '#44BB99', '#BBCC33', '#AAAA00', '#EEDD88', '#EE8866', '#FFAABB', '#DDDDDD')``
83+
84+
85+
--colorized
86+
"""""""""""
87+
*Use colored output. Classes/modules of the same package get the same color.*
88+
89+
**Default:** ``False``
90+
91+
92+
--max-color-depth
93+
"""""""""""""""""
94+
*Use separate colors up to package depth of <depth>. Higher depths will reuse colors.*
95+
96+
**Default:** ``2``
97+
98+
99+
--module-names
100+
""""""""""""""
101+
*Include module name in the representation of classes.*
102+
103+
**Default:** ``None``
104+
105+
106+
--no-standalone
107+
"""""""""""""""
108+
*Only show nodes with connections.*
109+
110+
**Default:** ``False``
111+
112+
113+
--only-classnames
114+
"""""""""""""""""
115+
*Don't show attributes and methods in the class boxes; this disables -f values.*
116+
117+
**Default:** ``False``
118+
119+
120+
121+
122+
Output Control
123+
--------------
124+
125+
--output
126+
""""""""
127+
*Create a *.<format> output file if format is available. Available formats are: .dot, .puml, .plantuml, .mmd, .html. Any other format will be tried to be created by using the 'dot' command line tool, which requires a graphviz installation. In this case, these additional formats are available (see `Graphviz output formats <https://graphviz.org/docs/outputs/>`_).*
128+
129+
**Default:** ``dot``
130+
131+
132+
--output-directory
133+
""""""""""""""""""
134+
*Set the output directory path.*
135+
136+
**Default:** ``""``
137+
138+
139+
140+
141+
Project Configuration
142+
---------------------
143+
144+
--ignore
145+
""""""""
146+
*Files or directories to be skipped. They should be base names, not paths.*
147+
148+
**Default:** ``('CVS',)``
149+
150+
151+
--project
152+
"""""""""
153+
*Set the project name. This will later be appended to the output file names.*
154+
155+
**Default:** ``""``
156+
157+
158+
--source-roots
159+
""""""""""""""
160+
*Add paths to the list of the source roots. Supports globbing patterns. The source root is an absolute path or a path relative to the current working directory used to determine a package namespace for modules located under the source root.*
161+
162+
**Default:** ``()``
163+
164+
165+
--verbose
166+
"""""""""
167+
*Makes pyreverse more verbose/talkative. Mostly useful for debugging.*
168+
169+
**Default:** ``False``

doc/pyreverse.rst renamed to doc/additional_tools/pyreverse/index.rst

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ To see a full list of the available options, run::
2222

2323
pyreverse -h
2424

25-
2625
Example Output
2726
''''''''''''''
2827

@@ -31,7 +30,7 @@ Example diagrams generated with the ``.puml`` output format are shown below.
3130
Class Diagram
3231
.............
3332

34-
.. image:: media/pyreverse_example_classes.png
33+
.. image:: ../../media/pyreverse_example_classes.png
3534
:width: 625
3635
:height: 589
3736
:alt: Class diagram generated by pyreverse
@@ -41,7 +40,7 @@ Class Diagram
4140
Package Diagram
4241
...............
4342

44-
.. image:: media/pyreverse_example_packages.png
43+
.. image:: ../../media/pyreverse_example_packages.png
4544
:width: 344
4645
:height: 177
4746
:alt: Package diagram generated by pyreverse
@@ -60,8 +59,14 @@ For example, running::
6059

6160
will generate the full class and package diagrams for ``pylint``, but will additionally generate a file ``pylint.checkers.classes.ClassChecker.dot``:
6261

63-
.. image:: media/ClassChecker_diagram.png
62+
.. image:: ../../media/ClassChecker_diagram.png
6463
:width: 757
6564
:height: 1452
6665
:alt: Package diagram generated by pyreverse
6766
:align: center
67+
68+
.. toctree::
69+
:maxdepth: 1
70+
:hidden:
71+
72+
configuration
File renamed without changes.

doc/conf.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
"pylint_extensions",
4545
"pylint_messages",
4646
"pylint_options",
47+
"pyreverse_configuration",
4748
"sphinx.ext.autosectionlabel",
4849
"sphinx.ext.intersphinx",
4950
"sphinx_reredirects",

doc/exts/pyreverse_configuration.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
2+
# For details: https://github.com/pylint-dev/pylint/blob/main/LICENSE
3+
# Copyright (c) https://github.com/pylint-dev/pylint/blob/main/CONTRIBUTORS.txt
4+
5+
"""Script used to generate the pyreverse configuration page."""
6+
7+
from __future__ import annotations
8+
9+
from pathlib import Path
10+
from typing import NamedTuple
11+
12+
from sphinx.application import Sphinx
13+
14+
from pylint.pyreverse.main import OPTIONS_GROUPS, Run
15+
from pylint.typing import OptionDict
16+
from pylint.utils import get_rst_title
17+
18+
19+
class OptionsData(NamedTuple):
20+
name: str
21+
optdict: OptionDict
22+
23+
24+
PYREVERSE_PATH = (
25+
Path(__file__).resolve().parent.parent / "additional_tools" / "pyreverse"
26+
)
27+
"""Path to the pyreverse documentation folder."""
28+
29+
30+
def _write_config_page(run: Run) -> None:
31+
"""Create or overwrite the configuration page."""
32+
sections: list[str] = [
33+
".. This file is auto-generated. Make any changes to the associated\n"
34+
".. docs extension in 'doc/exts/pyreverse_configuration.py'.\n\n",
35+
get_rst_title("Pyreverse Configuration", "^"),
36+
]
37+
38+
options: list[OptionsData] = [OptionsData(name, info) for name, info in run.options]
39+
option_groups: dict[str, list[str]] = {g: [] for g in OPTIONS_GROUPS.values()}
40+
41+
for option in sorted(options, key=lambda x: x.name):
42+
option_string = get_rst_title(f"--{option.name}", '"')
43+
option_string += f"*{option.optdict.get('help')}*\n\n"
44+
45+
if option.optdict.get("default") == "":
46+
option_string += '**Default:** ``""``\n\n\n'
47+
else:
48+
option_string += f"**Default:** ``{option.optdict.get('default')}``\n\n\n"
49+
50+
option_groups[str(option.optdict.get("group"))].append(option_string)
51+
52+
for group_title in OPTIONS_GROUPS.values():
53+
sections.append(
54+
get_rst_title(group_title, "-") + "\n" + "".join(option_groups[group_title])
55+
)
56+
57+
# Join all sections and remove the final two newlines
58+
final_page = "\n\n".join(sections)[:-2]
59+
60+
with open(PYREVERSE_PATH / "configuration.rst", "w", encoding="utf-8") as stream:
61+
stream.write(final_page)
62+
63+
64+
# pylint: disable-next=unused-argument
65+
def build_options_page(app: Sphinx | None) -> None:
66+
# Write configuration page
67+
_write_config_page(Run([]))
68+
69+
70+
def setup(app: Sphinx) -> dict[str, bool]:
71+
"""Connects the extension to the Sphinx process."""
72+
# Register callback at the builder-inited Sphinx event
73+
# See https://www.sphinx-doc.org/en/master/extdev/appapi.html
74+
app.connect("builder-inited", build_options_page)
75+
return {"parallel_read_safe": True}

doc/index.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@
3333
:titlesonly:
3434
:hidden:
3535

36-
pyreverse
37-
symilar
36+
additional_tools/pyreverse/index
37+
additional_tools/symilar/index
3838

3939
.. toctree::
4040
:caption: Changelog

doc/whatsnew/fragments/9689.breaking

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
`pyreverse` `Run` was changed to no longer call `sys.exit()` in its `__init__`.
2+
You should now call `Run(args).run()` which will return the exit code instead.
3+
Having a class that always raised a `SystemExit` exception was considered a bug.
4+
5+
Normal usage of pyreverse through the CLI will not be affected by this change.
6+
7+
Refs #9689

pylint/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def run_pyreverse(argv: Sequence[str] | None = None) -> NoReturn:
5353
"""
5454
from pylint.pyreverse.main import Run as PyreverseRun
5555

56-
PyreverseRun(argv or sys.argv[1:])
56+
sys.exit(PyreverseRun(argv or sys.argv[1:]).run())
5757

5858

5959
def run_symilar(argv: Sequence[str] | None = None) -> NoReturn:

pylint/pyreverse/inspector.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import os
1414
import traceback
1515
from abc import ABC, abstractmethod
16-
from collections.abc import Callable
16+
from collections.abc import Callable, Sequence
1717
from typing import Optional
1818

1919
import astroid
@@ -346,7 +346,7 @@ def handle(self, node: nodes.AssignAttr, parent: nodes.ClassDef) -> None:
346346

347347

348348
def project_from_files(
349-
files: list[str],
349+
files: Sequence[str],
350350
func_wrapper: _WrapperFuncT = _astroid_wrapper,
351351
project_name: str = "no name",
352352
black_list: tuple[str, ...] = constants.DEFAULT_IGNORE_LIST,

0 commit comments

Comments
 (0)