11
2- from inspect import isabstract
2+ from inspect import isabstract , signature
3+ import inspect
34from typing import Type , List , Dict
45
56from re import compile
67from dataclasses import dataclass
78
89from py2puml .domain .umlitem import UmlItem
9- from py2puml .domain .umlclass import UmlClass , UmlAttribute
10+ from py2puml .domain .umlclass import UmlClass , UmlAttribute , UmlMethod
1011from py2puml .domain .umlrelation import UmlRelation , RelType
1112from py2puml .parsing .parseclassconstructor import parse_class_constructor
12- from py2puml .utils import inspect_domain_definition
1313
1414CONCRETE_TYPE_PATTERN = compile ("^<(?:class|enum) '([\\ .|\\ w]+)'>$" )
1515
@@ -33,20 +33,12 @@ def handle_inheritance_relation(
3333 )
3434
3535def inspect_static_attributes (
36- class_type : Type ,
3736 class_type_fqn : str ,
37+ definition_attrs : List [UmlAttribute ],
38+ class_type : Type ,
3839 root_module_name : str ,
39- domain_items_by_fqn : Dict [str , UmlItem ],
4040 domain_relations : List [UmlRelation ]
4141) -> List [UmlAttribute ]:
42- definition_attrs : List [UmlAttribute ] = []
43- uml_class = UmlClass (
44- name = class_type .__name__ ,
45- fqn = class_type_fqn ,
46- attributes = definition_attrs ,
47- is_abstract = isabstract (class_type )
48- )
49- domain_items_by_fqn [class_type_fqn ] = uml_class
5042 # inspect_domain_definition(class_type)
5143 type_annotations = getattr (class_type , '__annotations__' , None )
5244 if type_annotations is not None :
@@ -58,7 +50,7 @@ def inspect_static_attributes(
5850 if attr_class .__module__ .startswith (root_module_name ):
5951 attr_type = attr_class .__name__
6052 domain_relations .append (
61- UmlRelation (uml_class . fqn , f'{ attr_class .__module__ } .{ attr_class .__name__ } ' , RelType .COMPOSITION )
53+ UmlRelation (class_type_fqn , f'{ attr_class .__module__ } .{ attr_class .__name__ } ' , RelType .COMPOSITION )
6254 )
6355 else :
6456 attr_type = concrete_type
@@ -73,7 +65,7 @@ def inspect_static_attributes(
7365 if getattr (component_class , '__name__' , None ) is not None
7466 ]
7567 domain_relations .extend ([
76- UmlRelation (uml_class . fqn , f'{ component_class .__module__ } .{ component_class .__name__ } ' , RelType .COMPOSITION )
68+ UmlRelation (class_type_fqn , f'{ component_class .__module__ } .{ component_class .__name__ } ' , RelType .COMPOSITION )
7769 for component_class in component_classes
7870 if component_class .__module__ .startswith (root_module_name )
7971 ])
@@ -85,16 +77,50 @@ def inspect_static_attributes(
8577
8678 return definition_attrs
8779
80+ def inspect_methods (
81+ definition_methods , class_type ,
82+ ):
83+ no_dunder = lambda x : not (x [0 ].startswith ('__' ) or x [0 ].endswith ('__' ))
84+ methods = filter (no_dunder , inspect .getmembers (class_type , callable ))
85+ for name , method in methods :
86+ signature = inspect .signature (method )
87+ uml_method = UmlMethod (
88+ name = name ,
89+ signature = str (signature ),
90+ )
91+ definition_methods .append (uml_method )
92+
93+
94+ def handle_class_type (
95+ class_type : Type ,
96+ class_type_fqn : str ,
97+ domain_items_by_fqn : Dict [str , UmlItem ],
98+ ) -> UmlClass :
99+ definition_attrs : List [UmlAttribute ] = []
100+ definition_methods : List [UmlMethod ] = []
101+ uml_class = UmlClass (
102+ name = class_type .__name__ ,
103+ fqn = class_type_fqn ,
104+ attributes = definition_attrs ,
105+ methods = definition_methods ,
106+ is_abstract = isabstract (class_type )
107+ )
108+ domain_items_by_fqn [class_type_fqn ] = uml_class
109+ return uml_class
110+
88111def inspect_class_type (
89112 class_type : Type ,
90113 class_type_fqn : str ,
91114 root_module_name : str ,
92115 domain_items_by_fqn : Dict [str , UmlItem ],
93116 domain_relations : List [UmlRelation ]
94117):
118+ uml_class = handle_class_type (class_type , class_type_fqn , domain_items_by_fqn )
95119 attributes = inspect_static_attributes (
96- class_type , class_type_fqn , root_module_name ,
97- domain_items_by_fqn , domain_relations
120+ class_type_fqn , uml_class .attributes , class_type , root_module_name , domain_relations
121+ )
122+ inspect_methods (
123+ uml_class .methods , class_type
98124 )
99125 instance_attributes , compositions = parse_class_constructor (class_type , class_type_fqn , root_module_name )
100126 attributes .extend (instance_attributes )
@@ -103,19 +129,20 @@ def inspect_class_type(
103129 handle_inheritance_relation (class_type , class_type_fqn , root_module_name , domain_relations )
104130
105131def inspect_dataclass_type (
106- class_type : Type [ dataclass ] ,
132+ class_type : Type ,
107133 class_type_fqn : str ,
108134 root_module_name : str ,
109135 domain_items_by_fqn : Dict [str , UmlItem ],
110136 domain_relations : List [UmlRelation ]
111137):
112- for attribute in inspect_static_attributes (
113- class_type ,
114- class_type_fqn ,
115- root_module_name ,
116- domain_items_by_fqn ,
117- domain_relations
118- ):
138+ uml_class = handle_class_type (class_type , class_type_fqn , domain_items_by_fqn )
139+ attributes = inspect_static_attributes (
140+ class_type_fqn , uml_class .attributes , class_type , root_module_name , domain_relations
141+ )
142+ inspect_methods (
143+ uml_class .methods , class_type
144+ )
145+ for attribute in attributes :
119146 attribute .static = False
120147
121148 handle_inheritance_relation (class_type , class_type_fqn , root_module_name , domain_relations )
0 commit comments