0
# Pyreverse (UML Generation)
1
2
UML diagram generation tool that analyzes Python code structure and creates class diagrams, package diagrams, and dependency visualizations in multiple formats. Pyreverse helps understand code architecture and relationships through visual representations.
3
4
## Capabilities
5
6
### Main Entry Point
7
8
Primary function for running pyreverse from Python code.
9
10
```python { .api }
11
def run_pyreverse(argv=None):
12
"""
13
Generate UML diagrams from Python code.
14
15
Args:
16
argv (list, optional): Command line arguments. If None, uses sys.argv[1:]
17
18
Example:
19
run_pyreverse(['mypackage/', '--output-format=svg'])
20
run_pyreverse(['--help'])
21
"""
22
```
23
24
### Command Line Interface
25
26
Main class for handling pyreverse command-line operations.
27
28
```python { .api }
29
class Run:
30
"""
31
Pyreverse command-line interface.
32
33
Processes command-line arguments, analyzes Python code,
34
and generates UML diagrams in various formats.
35
"""
36
37
def __init__(self, args):
38
"""
39
Initialize and run pyreverse.
40
41
Args:
42
args (list): Command line arguments
43
"""
44
```
45
46
### Diagram Definition System
47
48
Classes for defining and managing diagram structures and content.
49
50
```python { .api }
51
class DiadefsHandler:
52
"""
53
Diagram definition handler.
54
55
Manages the creation and organization of diagram definitions
56
based on code analysis results.
57
"""
58
59
def __init__(self, config):
60
"""
61
Initialize diagram handler.
62
63
Args:
64
config: Configuration object
65
"""
66
67
def get_diadefs(self, project, linker):
68
"""
69
Get diagram definitions for project.
70
71
Args:
72
project: Analyzed project object
73
linker: Object linking system
74
75
Returns:
76
list: Diagram definition objects
77
"""
78
79
class DiaDefGenerator:
80
"""
81
Diagram definition generator.
82
83
Generates diagram definitions by analyzing code structure
84
and relationships between classes and packages.
85
"""
86
87
def __init__(self, linker, handler):
88
"""
89
Initialize diagram generator.
90
91
Args:
92
linker: Object linking system
93
handler: Diagram handler
94
"""
95
96
def visit_project(self, node):
97
"""
98
Visit project node and generate diagrams.
99
100
Args:
101
node: Project AST node
102
"""
103
```
104
105
### Diagram Types
106
107
Classes representing different types of UML diagrams.
108
109
```python { .api }
110
class PackageDiagram:
111
"""
112
Package relationship diagrams.
113
114
Shows dependencies and relationships between packages
115
and modules in the analyzed code.
116
"""
117
118
def __init__(self, title, objects):
119
"""
120
Initialize package diagram.
121
122
Args:
123
title (str): Diagram title
124
objects (list): Objects to include in diagram
125
"""
126
127
def get_relationships(self):
128
"""
129
Get package relationships.
130
131
Returns:
132
list: Package relationship objects
133
"""
134
135
class ClassDiagram:
136
"""
137
Class relationship diagrams.
138
139
Shows inheritance hierarchies, associations, and
140
dependencies between classes.
141
"""
142
143
def __init__(self, title, objects):
144
"""
145
Initialize class diagram.
146
147
Args:
148
title (str): Diagram title
149
objects (list): Class objects to include
150
"""
151
152
def get_methods(self, node):
153
"""
154
Get methods for a class node.
155
156
Args:
157
node: Class AST node
158
159
Returns:
160
list: Method information
161
"""
162
163
def get_attrs(self, node):
164
"""
165
Get attributes for a class node.
166
167
Args:
168
node: Class AST node
169
170
Returns:
171
list: Attribute information
172
"""
173
```
174
175
### Output Writers
176
177
Classes for generating diagrams in different output formats.
178
179
```python { .api }
180
class DiagramWriter:
181
"""
182
Base diagram writer.
183
184
Abstract base class for all diagram output formats,
185
providing common functionality and interface.
186
"""
187
188
def __init__(self, config):
189
"""
190
Initialize diagram writer.
191
192
Args:
193
config: Configuration object
194
"""
195
196
def write(self, diadefs):
197
"""
198
Write diagrams to output.
199
200
Args:
201
diadefs (list): Diagram definitions to write
202
"""
203
204
class DotWriter(DiagramWriter):
205
"""
206
Graphviz DOT format writer.
207
208
Generates diagrams in DOT format for rendering
209
with Graphviz tools (dot, neato, circo, etc.).
210
"""
211
212
def __init__(self, config):
213
"""Initialize DOT writer."""
214
super().__init__(config)
215
216
def write_packages(self, diagram):
217
"""
218
Write package diagram in DOT format.
219
220
Args:
221
diagram: Package diagram object
222
"""
223
224
def write_classes(self, diagram):
225
"""
226
Write class diagram in DOT format.
227
228
Args:
229
diagram: Class diagram object
230
"""
231
232
class PlantUmlWriter(DiagramWriter):
233
"""
234
PlantUML format writer.
235
236
Generates diagrams in PlantUML format for rendering
237
with PlantUML tools and online services.
238
"""
239
240
def __init__(self, config):
241
"""Initialize PlantUML writer."""
242
super().__init__(config)
243
244
def write_packages(self, diagram):
245
"""
246
Write package diagram in PlantUML format.
247
248
Args:
249
diagram: Package diagram object
250
"""
251
252
def write_classes(self, diagram):
253
"""
254
Write class diagram in PlantUML format.
255
256
Args:
257
diagram: Class diagram object
258
"""
259
260
class MermaidWriter(DiagramWriter):
261
"""
262
Mermaid format writer.
263
264
Generates diagrams in Mermaid format for rendering
265
in Markdown, GitHub, and web applications.
266
"""
267
268
def __init__(self, config):
269
"""Initialize Mermaid writer."""
270
super().__init__(config)
271
272
def write_packages(self, diagram):
273
"""
274
Write package diagram in Mermaid format.
275
276
Args:
277
diagram: Package diagram object
278
"""
279
280
def write_classes(self, diagram):
281
"""
282
Write class diagram in Mermaid format.
283
284
Args:
285
diagram: Class diagram object
286
"""
287
```
288
289
## Usage Examples
290
291
### Basic Usage
292
293
```python
294
import pylint
295
296
# Generate class diagrams for a package
297
pylint.run_pyreverse(['mypackage/', '--output-format=png'])
298
299
# Generate both class and package diagrams
300
pylint.run_pyreverse([
301
'myproject/',
302
'--output-format=svg',
303
'--project=MyProject'
304
])
305
306
# Generate PlantUML format
307
pylint.run_pyreverse([
308
'src/',
309
'--output-format=plantuml',
310
'--output-directory=docs/diagrams/'
311
])
312
```
313
314
### Command Line Usage
315
316
```bash
317
# Basic class diagram generation
318
pyreverse mypackage/
319
320
# Specify output format and directory
321
pyreverse --output-format=svg --output-directory=docs/ mypackage/
322
323
# Generate both class and package diagrams
324
pyreverse --show-associated --show-builtin mypackage/
325
326
# Filter classes and show details
327
pyreverse --filter-mode=PUB_ONLY --show-ancestors=2 mypackage/
328
329
# Generate PlantUML format
330
pyreverse --output-format=plantuml --project=MyApp src/
331
332
# Generate Mermaid format
333
pyreverse --output-format=mermaid --colorized src/
334
```
335
336
### Programmatic Usage
337
338
```python
339
from pylint.pyreverse.main import Run
340
from pylint.pyreverse.diadefslib import DiadefsHandler, DiaDefGenerator
341
from pylint.pyreverse.writer import DotWriter, PlantUmlWriter
342
343
# Run pyreverse programmatically
344
args = [
345
'mypackage/',
346
'--output-format=svg',
347
'--project=MyProject',
348
'--output-directory=output/'
349
]
350
pyreverse_run = Run(args)
351
352
# Custom diagram generation
353
class CustomDiagramGenerator:
354
"""Custom diagram generation example."""
355
356
def __init__(self, package_path):
357
self.package_path = package_path
358
359
def generate_diagrams(self):
360
"""Generate custom diagrams."""
361
# This would involve using pyreverse internals
362
# to create custom diagram analysis and output
363
pass
364
```
365
366
### Advanced Configuration
367
368
```python
369
# Configure pyreverse options
370
config = {
371
'output_format': 'svg',
372
'output_directory': 'diagrams/',
373
'project': 'MyProject',
374
'show_ancestors': 2,
375
'show_associated': True,
376
'show_builtin': False,
377
'module_names': True,
378
'colorized': True,
379
'max_color_depth': 2,
380
'ignore': ['tests', '__pycache__'],
381
'filter_mode': 'PUB_ONLY' # Show only public members
382
}
383
384
# Apply configuration and run
385
args = []
386
for key, value in config.items():
387
if isinstance(value, bool) and value:
388
args.append(f'--{key.replace("_", "-")}')
389
elif not isinstance(value, bool):
390
args.extend([f'--{key.replace("_", "-")}', str(value)])
391
392
args.append('mypackage/')
393
pylint.run_pyreverse(args)
394
```
395
396
## Output Formats
397
398
### Graphviz DOT Format
399
400
```dot
401
digraph "classes" {
402
charset="utf-8"
403
rankdir=BT
404
"mypackage.MyClass" [label="{MyClass|data : str\lvalue : int\l|process()\lvalidate()\l}",shape="record"];
405
"mypackage.BaseClass" [label="{BaseClass|name : str\l|__init__()\l}",shape="record"];
406
"mypackage.MyClass" -> "mypackage.BaseClass" [arrowhead="empty",arrowtail="none"];
407
}
408
```
409
410
### PlantUML Format
411
412
```plantuml
413
@startuml classes
414
set namespaceSeparator none
415
class "mypackage.BaseClass" as mypackage.BaseClass {
416
name : str
417
__init__()
418
}
419
class "mypackage.MyClass" as mypackage.MyClass {
420
data : str
421
value : int
422
process()
423
validate()
424
}
425
mypackage.MyClass --|> mypackage.BaseClass
426
@enduml
427
```
428
429
### Mermaid Format
430
431
```mermaid
432
classDiagram
433
class BaseClass {
434
+str name
435
+__init__()
436
}
437
class MyClass {
438
+str data
439
+int value
440
+process()
441
+validate()
442
}
443
MyClass --|> BaseClass
444
```
445
446
## Configuration Options
447
448
### Diagram Content Options
449
450
```python { .api }
451
# Control what to show in diagrams
452
show_ancestors = 2 # Number of ancestor levels to show
453
show_associated = True # Show associated classes
454
show_builtin = False # Show built-in types
455
only_classnames = False # Show only class names, no details
456
module_names = True # Show module names in class labels
457
```
458
459
### Output Options
460
461
```python { .api }
462
# Output configuration
463
output_format = 'png' # png, svg, dot, plantuml, mermaid
464
output_directory = 'diagrams/' # Output directory
465
project = 'MyProject' # Project name for diagram titles
466
colorized = True # Use colors in diagrams
467
max_color_depth = 2 # Maximum color depth
468
```
469
470
### Filtering Options
471
472
```python { .api }
473
# Content filtering
474
filter_mode = 'PUB_ONLY' # PUB_ONLY, ALL, SPECIAL
475
ignore = ['tests', 'docs'] # Directories/files to ignore
476
class_names = ['MyClass', 'BaseClass'] # Specific classes to include
477
```
478
479
## Integration Examples
480
481
### CI/CD Integration
482
483
```yaml
484
# GitHub Actions example
485
name: Generate UML Diagrams
486
on: [push]
487
jobs:
488
diagrams:
489
runs-on: ubuntu-latest
490
steps:
491
- uses: actions/checkout@v2
492
- name: Setup Python
493
uses: actions/setup-python@v2
494
with:
495
python-version: '3.9'
496
- name: Install dependencies
497
run: |
498
pip install pylint graphviz
499
- name: Generate diagrams
500
run: |
501
pyreverse --output-format=svg --output-directory=docs/diagrams/ src/
502
- name: Commit diagrams
503
run: |
504
git add docs/diagrams/
505
git commit -m "Update UML diagrams" || exit 0
506
git push
507
```
508
509
### Documentation Integration
510
511
```python
512
# Sphinx integration example
513
def generate_uml_diagrams():
514
"""Generate UML diagrams for Sphinx documentation."""
515
import os
516
import pylint
517
518
# Create diagrams directory
519
diagrams_dir = 'docs/source/_static/diagrams'
520
os.makedirs(diagrams_dir, exist_ok=True)
521
522
# Generate SVG diagrams for web display
523
pylint.run_pyreverse([
524
'src/',
525
'--output-format=svg',
526
f'--output-directory={diagrams_dir}',
527
'--project=MyProject',
528
'--colorized'
529
])
530
531
print(f"UML diagrams generated in {diagrams_dir}")
532
533
# Add to Sphinx conf.py
534
def setup(app):
535
generate_uml_diagrams()
536
```
537
538
### Custom Analysis
539
540
```python
541
def analyze_class_complexity():
542
"""Analyze class complexity using pyreverse data."""
543
# This would involve extending pyreverse to collect
544
# additional metrics during diagram generation
545
546
# Example: Count methods, attributes, inheritance depth
547
class ComplexityAnalyzer:
548
def __init__(self):
549
self.metrics = {}
550
551
def visit_classdef(self, node):
552
"""Collect class complexity metrics."""
553
class_name = node.name
554
method_count = len([n for n in node.body
555
if n.__class__.__name__ == 'FunctionDef'])
556
attr_count = len([n for n in node.body
557
if n.__class__.__name__ == 'Assign'])
558
559
self.metrics[class_name] = {
560
'methods': method_count,
561
'attributes': attr_count,
562
'complexity': method_count + attr_count
563
}
564
565
def report(self):
566
"""Generate complexity report."""
567
for class_name, metrics in self.metrics.items():
568
print(f"{class_name}: {metrics['complexity']} complexity points")
569
```