You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* upgraded to python 3.8 to have get_source_segment, WIP of constructor's code parsing
* fixed documentation link to poetry, closes#13
* handle non/typed and tuple assignment (to improve)
* properly handle type aliasing
* handle composition relationships
* refactored inspection and AST parsing code, bump to version 0.5.0
* added code-coverage plugin for unit tests
* WIP added UmlAttribute staticity. Some attributes are detected twice
* skipped subscriptable assignment and fixed attribute naming
* updated documentation (inspection and AST parsing)
* code clean-up
* added test case with multiple assignments
* removed obsolete test case
* fixed unit tests + code refactoring
* added unit tests on astvisitors
* fixed variable name
* fixes after @jjherphan code review
* code review of @jjerphan and @doyou89 (thanks!)
Copy file name to clipboardExpand all lines: README.md
+60-31Lines changed: 60 additions & 31 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -9,44 +9,46 @@
9
9
<h1>Python to PlantUML</h1>
10
10
</div>
11
11
12
-
Generate Plantuml diagrams to document your python code
12
+
Generate PlantUML class diagrams to document your Python application.
13
13
14
14
# How it works
15
15
16
-
## Features
17
-
18
-
From a given path corresponding to a folder containing python code, `py2puml` loads each file as a module and generate a class diagram with the [PlantUML](https://plantuml.com/en/class-diagram) using:
16
+
`py2puml` produces a class diagram [PlantUML script](https://plantuml.com/en/class-diagram) representing classes properties (static and instance attributes) and their relations (composition and inheritance relationships).
19
17
20
-
* inspection to detect the classes to document (see the [inspect](https://docs.python.org/3/library/inspect.html) module)
21
-
* annotations (the python type hinting syntax) to detect the attributes and their types (see the [typing](https://docs.python.org/3/library/typing.html) module)
22
-
* fields for classes derived from namedtuples
23
-
* composition and inheritance relationships are drawn only between the domain classes (this is designed on purpose, for documentation sake)
18
+
`py2puml` internally uses code [inspection](https://docs.python.org/3/library/inspect.html) (also called *reflexion* in other programming languages) and [abstract tree parsing](https://docs.python.org/3/library/ast.html) to retrieve relevant information.
24
19
25
-
## Current limitations
20
+
## Features
26
21
27
-
* type hinting is optional when writing Python code and discarded when it is executed, as mentionned in the [typing official documentation](https://docs.python.org/3/library/typing.html). The quality of the diagram output by `py2puml` depends on the reliability with which the type annotations were written
22
+
From a given path corresponding to a folder containing Python code, `py2puml` processes each file as a module and generates a [PlantUML script](https://plantuml.com/en/class-diagram)of its classe-like definitions using:
28
23
29
-
> The Python runtime does not enforce function and variable type annotations. They can be used by third party tools such as type checkers, IDEs, linters, etc.
24
+
***[inspection](https://docs.python.org/3/library/inspect.html)** and [type annotations](https://docs.python.org/3/library/typing.html) to detect:
25
+
* static class attributes and [dataclass](https://docs.python.org/3/library/dataclasses.html) fields
26
+
* fields of [namedtuples](https://docs.python.org/3/library/collections.html#collections.namedtuple)
27
+
* members of [enumerations](https://docs.python.org/3/library/enum.html)
28
+
* composition and inheritance relationships (between your domain classes only, for documentation sake)
30
29
31
-
*complex type hints with more than one level of genericity are not properly handled for the moment: `List[MyClass]` or `Dict[str, MyClass]` are handled properly, `Dict[str, List[MyClass]]` is not. If your domain classes (also called business objects or DTOs) have attributes with complex type hints, it may be a code smell indicating that you should write a class which would better represent the business logic. But I may improve this part of the library as well 😀
30
+
*parsing [abstract syntax trees](https://docs.python.org/3/library/ast.html#ast.NodeVisitor) to detect the instance attributes defined in `__init__` constructors
32
31
33
-
*`py2puml` outputs diagrams in PlantUML syntax, which can be saved in text files along your python code and versioned with them. To generate image files, use the PlantUML runtime or a docker image (see [think/plantuml](https://hub.docker.com/r/think/plantuml))
32
+
`py2puml` outputs diagrams in PlantUML syntax, which can be:
33
+
* versioned along your code with a unit-test ensuring its consistency (see the [test_py2puml.py's test_py2puml_model_on_py2uml_domain](tests/py2puml/test_py2puml.py) example)
34
+
* generated and hosted along other code documentation (better option: generated documentation should not be versioned with the codebase)
34
35
35
-
*`py2puml` uses features of python 3 (generators for example) and thus won't work with python 2 runtimes. It relies on native python modules and uses no 3rd-party library, except [pytest](https://docs.pytest.org/en/latest/) as a development dependency for running the unit-tests
36
+
To generate image files, use the PlantUML runtime, a docker image of the runtime (see [think/plantuml](https://hub.docker.com/r/think/plantuml)) or of a server (see the CLI documentation below)
36
37
37
-
If you like tools around PlantUML, you may also be interested in this [lucsorel/plantuml-file-loader](https://github.com/lucsorel/plantuml-file-loader) project: A webpack loader which converts PlantUML files into images during the webpack processing (useful to [include PlantUML diagrams in your slides](https://github.com/lucsorel/markdown-image-loader/blob/master/README.md#web-based-slideshows) with RevealJS or RemarkJS).
38
+
If you like tools related with PlantUML, you may also be interested in this [lucsorel/plantuml-file-loader](https://github.com/lucsorel/plantuml-file-loader) project:
39
+
a webpack loader which converts PlantUML files into images during the webpack processing (useful to [include PlantUML diagrams in your slides](https://github.com/lucsorel/markdown-image-loader/blob/master/README.md#web-based-slideshows) with RevealJS or RemarkJS).
38
40
39
41
# Install
40
42
41
-
Install from PyPI:
43
+
Install from [PyPI](https://pypi.org/project/py2puml/):
42
44
43
45
* with `pip`:
44
46
45
47
```sh
46
48
pip install py2puml
47
49
```
48
50
49
-
* with [poetry](https://pipenv.readthedocs.io/en/latest/):
51
+
* with [poetry](https://python-poetry.org/docs/):
50
52
51
53
```sh
52
54
poetry add py2puml
@@ -64,25 +66,27 @@ pipenv install py2puml
64
66
65
67
Once `py2puml` is installed at the system level, an eponymous command is available in your environment shell.
66
68
67
-
For example, to create the diagram of the classes used by `py2puml`, one can use:
69
+
For example, to create the diagram of the classes used by `py2puml`, run:
70
+
68
71
```sh
69
72
py2puml py2puml/domain py2puml.domain
70
73
```
71
74
72
-
This will output the following PlantUML script:
75
+
This outputs the following PlantUML script:
73
76
74
77
```plantuml
75
78
@startuml
76
79
class py2puml.domain.umlclass.UmlAttribute {
77
80
name: str
78
81
type: str
82
+
static: bool
79
83
}
80
84
class py2puml.domain.umlclass.UmlClass {
81
85
attributes: List[UmlAttribute]
82
86
}
83
87
class py2puml.domain.umlitem.UmlItem {
84
88
name: str
85
-
fqdn: str
89
+
fqn: str
86
90
}
87
91
class py2puml.domain.umlenum.Member {
88
92
name: str
@@ -92,12 +96,12 @@ class py2puml.domain.umlenum.UmlEnum {
*`0.5.0`: handle instance attributes in class constructors, add code coverage of unit tests
172
183
*`0.4.0`: add a simple CLI
173
184
*`0.3.1`: inspect sub-folders recursively
174
-
*`0.3.0`: handle classes derived from namedtuples (attribute types are `any`)
175
-
*`0.2.0`: handle inheritance relationships and enums. Unit tested
176
-
*`0.1.3`: first release, handle all module of a folder and compositions of domain classes
185
+
*`0.3.0`: handle classes derived from namedtuples (attribute types are `Any`)
186
+
*`0.2.0`: handle inheritance relationships and enums
187
+
*`0.1.3`: first release, handle all modules of a folder and compositions of domain classes
177
188
178
189
# Licence
179
190
@@ -187,6 +198,24 @@ Unless stated otherwise all works are licensed under the [MIT license](http://sp
187
198
188
199
Pull-requests are welcome and will be processed on a best-effort basis.
189
200
201
+
# Current limitations
202
+
203
+
* regarding **inspection**
204
+
205
+
* type hinting is optional when writing Python code and discarded when it is executed, as mentionned in the [typing official documentation](https://docs.python.org/3/library/typing.html). The quality of the diagram output by `py2puml` depends on the reliability with which the type annotations were written
206
+
207
+
> The Python runtime does not enforce function and variable type annotations. They can be used by third party tools such as type checkers, IDEs, linters, etc.
208
+
209
+
* complex type hints with more than one level of genericity are not properly handled for the moment: `List[MyClass]` or `Dict[str, MyClass]` are handled properly, `Dict[str, List[MyClass]]` is not.
210
+
If your domain classes (also called business objects or DTOs) have attributes with complex type hints, it may be a code smell indicating that you should write a class which would better represent the business logic.
211
+
But I may improve this part of the library as well 😀
212
+
213
+
* regarding the detection of instance attributes with **AST parsing**:
214
+
* only constructors are visited, attributes assigned in other functions won't be documented
215
+
* attribute types are inferred from type annotations:
216
+
* of the attribute itself
217
+
* of the variable assigned to the attribute: a signature parameter or a locale variable
218
+
* to avoid side-effects, no code is executed nor interpreted
0 commit comments