Skip to content

Commit d708fac

Browse files
authored
fix(compoundtypesplitter): handle class names with digits (#36)
* fix(compoundtypesplitter): handle class names with digits fixes #35 * docs(readme): fixed version of previous change
1 parent 4787c5d commit d708fac

File tree

8 files changed

+64
-17
lines changed

8 files changed

+64
-17
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ poetry run python -m pytest -v --cov=py2puml --cov-branch --cov-report term-miss
181181

182182
# Changelog
183183

184+
* `0.6.1`: handle class names with digits
184185
* `0.6.0`: handle abstract classes
185186
* `0.5.4`: fixed the packaging so that the contribution guide is included in the published package
186187
* `0.5.3`: handle constructors decorated by wrapping decorators (decorators making uses of `functools.wrap`)

py2puml/cli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
def run():
1010
argparser = ArgumentParser(description='Generate PlantUML class diagrams to document your Python application.')
1111

12-
argparser.add_argument('-v', '--version', action='version', version='py2puml 0.6.0')
12+
argparser.add_argument('-v', '--version', action='version', version='py2puml 0.6.1')
1313
argparser.add_argument('path', metavar='path', type=str, help='the path of the domain')
1414
argparser.add_argument('module', metavar='module', type=str, help='the module of the domain', default=None)
1515

py2puml/parsing/compoundtypesplitter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from re import compile, Pattern
33
from typing import List, Tuple
44

5-
IS_COMPOUND_TYPE: Pattern = compile('^[a-z|A-Z|\\[|\\]|\\.|,|\\s|_]+$')
5+
IS_COMPOUND_TYPE: Pattern = compile('^[a-z|A-Z|0-9|\\[|\\]|\\.|,|\\s|_]+$')
66
SPLITTING_CHARACTERS = ('[', ']', ',')
77

88
class CompoundTypeSplitter(object):

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "py2puml"
3-
version = "0.6.0"
3+
version = "0.6.1"
44
description = "Generate PlantUML class diagrams to document your Python application."
55
keywords = ["class diagram", "PlantUML", "documentation", "inspection", "AST"]
66
readme = "README.md"
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from typing import List
2+
3+
4+
class IPv6:
5+
'''class name with digits'''
6+
def __init__(self, address: str) -> None:
7+
self.address: str = address
8+
9+
class Multicast:
10+
def __init__(self, address: IPv6, repetition: int):
11+
# List[IPv6] must be parsed
12+
self.addresses: List[IPv6] = [address] * repetition

tests/py2puml/inspection/test_inspectclass.py

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11

2-
from typing import Dict, List
2+
from typing import Dict, List, Tuple
33
from importlib import import_module
44

5+
from pytest import fixture
6+
57
from py2puml.domain.umlitem import UmlItem
68
from py2puml.domain.umlclass import UmlClass, UmlAttribute
79
from py2puml.domain.umlrelation import UmlRelation, RelType
@@ -14,9 +16,17 @@
1416
from tests.asserts.relation import assert_relation
1517

1618

17-
def test_inspect_module_should_find_static_and_instance_attributes():
18-
domain_items_by_fqn: Dict[str, UmlItem] = {}
19-
domain_relations: List[UmlRelation] = []
19+
@fixture(scope='function')
20+
def domain_items_by_fqn() -> Dict[str, UmlItem]:
21+
return {}
22+
23+
@fixture(scope='function')
24+
def domain_relations() -> List[UmlRelation]:
25+
return []
26+
27+
def test_inspect_module_should_find_static_and_instance_attributes(
28+
domain_items_by_fqn: Dict[str, UmlItem], domain_relations: List[UmlRelation]
29+
):
2030
inspect_module(
2131
import_module('tests.modules.withconstructor'),
2232
'tests.modules.withconstructor',
@@ -70,9 +80,9 @@ def test_inspect_module_should_find_static_and_instance_attributes():
7080
RelType.COMPOSITION
7181
)
7282

73-
def test_inspect_module_should_find_abstract_class():
74-
domain_items_by_fqn: Dict[str, UmlItem] = {}
75-
domain_relations: List[UmlRelation] = []
83+
def test_inspect_module_should_find_abstract_class(
84+
domain_items_by_fqn: Dict[str, UmlItem], domain_relations: List[UmlRelation]
85+
):
7686
inspect_module(
7787
import_module('tests.modules.withabstract'),
7888
'tests.modules.withabstract',
@@ -91,9 +101,9 @@ def test_inspect_module_should_find_abstract_class():
91101
assert domain_relations[0].source_fqn == 'tests.modules.withabstract.ClassTemplate'
92102
assert domain_relations[0].target_fqn == 'tests.modules.withabstract.ConcreteClass'
93103

94-
def test_inspect_module_parse_class_constructor_should_not_process_inherited_constructor():
95-
domain_items_by_fqn: Dict[str, UmlItem] = {}
96-
domain_relations: List[UmlRelation] = []
104+
def test_inspect_module_parse_class_constructor_should_not_process_inherited_constructor(
105+
domain_items_by_fqn: Dict[str, UmlItem], domain_relations: List[UmlRelation]
106+
):
97107
# inspects the two sub-modules
98108
inspect_module(
99109
import_module('tests.modules.withinheritedconstructor.point'),
@@ -127,9 +137,9 @@ def test_inspect_module_parse_class_constructor_should_not_process_inherited_con
127137
unit_attribute = metric_origin_umlitem.attributes[0]
128138
assert_attribute(unit_attribute, 'unit', 'str', expected_staticity=True)
129139

130-
def test_inspect_module_should_unwrap_decorated_constructor():
131-
domain_items_by_fqn: Dict[str, UmlItem] = {}
132-
domain_relations: List[UmlRelation] = []
140+
def test_inspect_module_should_unwrap_decorated_constructor(
141+
domain_items_by_fqn: Dict[str, UmlItem], domain_relations: List[UmlRelation]
142+
):
133143
inspect_module(
134144
import_module('tests.modules.withwrappedconstructor'),
135145
'tests.modules.withwrappedconstructor',
@@ -148,3 +158,26 @@ def test_inspect_module_should_unwrap_decorated_constructor():
148158
# PointDecoratedWithoutWrapping UmlClass
149159
point_without_wrapping_umlitem: UmlClass = domain_items_by_fqn['tests.modules.withwrappedconstructor.PointDecoratedWithoutWrapping']
150160
assert len(point_without_wrapping_umlitem.attributes) == 0, 'the attributes of the original constructor could not be found, the constructor was not wrapped by the decorator'
161+
162+
def test_inspect_module_should_handle_compound_types_with_numbers_in_their_name(
163+
domain_items_by_fqn: Dict[str, UmlItem], domain_relations: List[UmlRelation]
164+
):
165+
fqdn = 'tests.modules.withcompoundtypewithdigits'
166+
inspect_module(
167+
import_module(fqdn), fqdn,
168+
domain_items_by_fqn, domain_relations
169+
)
170+
171+
assert len(domain_items_by_fqn) == 2, 'two classes must be inspected'
172+
173+
# IPv6 UmlClass
174+
ipv6_umlitem: UmlClass = domain_items_by_fqn[f'{fqdn}.IPv6']
175+
assert len(ipv6_umlitem.attributes) == 1, '1 attributes of IPv6 must be inspected'
176+
address_attribute = ipv6_umlitem.attributes[0]
177+
assert_attribute(address_attribute, 'address', 'str', expected_staticity=False)
178+
179+
# Multicast UmlClass
180+
multicast_umlitem: UmlClass = domain_items_by_fqn[f'{fqdn}.Multicast']
181+
assert len(multicast_umlitem.attributes) == 1, '1 attributes of Multicast must be inspected'
182+
address_attribute = multicast_umlitem.attributes[0]
183+
assert_attribute(address_attribute, 'addresses', 'List[IPv6]', expected_staticity=False)

tests/py2puml/parsing/test_compoundtypesplitter.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ def test_CompoundTypeSplitter_from_invalid_types(type_annotation: str):
3434
('_ast.Name', ('_ast.Name',)),
3535
('Tuple[str, withenum.TimeUnit]', ('Tuple', '[', 'str', ',', 'withenum.TimeUnit', ']')),
3636
('List[datetime.date]', ('List', '[', 'datetime.date', ']')),
37+
('List[IPv6]', ('List', '[', 'IPv6', ']')),
3738
('modules.withenum.TimeUnit', ('modules.withenum.TimeUnit',)),
3839
('Dict[str, Dict[str,builtins.float]]', ('Dict', '[', 'str', ',', 'Dict', '[', 'str', ',', 'builtins.float', ']', ']')),
3940
])

tests/py2puml/test__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
# Ensures the library version is modified in the pyproject.toml file when upgrading it (pull request)
44
def test_version():
5-
assert __version__ == '0.6.0'
5+
assert __version__ == '0.6.1'
66

77
# Description also output in the CLI
88
def test_description():

0 commit comments

Comments
 (0)