1- from ..library import Class
1+ from ..library import Class , Method
22
33
4- indent = " " * 4
4+ # define this here so we know what "1" indent is and can remove it for inner
5+ # class declarations
6+ DEFAULT_INDENT_WIDTH = 4
57
68
7- def attributes (attributes ) :
9+ def attributes (attributes , indent ) -> str :
810 attrs = []
911 for name , definitions in attributes .items ():
1012 value = definitions [- 1 ].value
1113 attrs .append (f"{ indent } { name } = { value } \n " )
1214 return "" .join (attrs )
1315
1416
15- def declaration ( name , parents ) :
16- parents = ", " . join ([ p . __name__ for p in parents ])
17- return f"class { name } ( { parents } ):"
17+ def classes ( classes , indent ) -> str :
18+ content = [ to_string ( c , indent = indent + indent ) for c in classes ]
19+ return "" . join ( content )
1820
1921
20- def docstring (docstring ):
22+ def declaration (name , parents , indent ) -> str :
23+ indent = indent [:- DEFAULT_INDENT_WIDTH ]
24+ content = f"{ indent } class { name } "
25+
26+ if parents :
27+ parents = ", " .join ([p .__name__ for p in parents ])
28+ content = f"{ content } ({ parents } )"
29+
30+ return f"{ content } :"
31+
32+
33+ def docstring (docstring , indent ) -> str :
2134 if not docstring :
2235 return ""
2336
@@ -27,23 +40,31 @@ def docstring(docstring):
2740 return f"{ quotes } { block } { quotes } "
2841
2942
30- def methods (methods ) :
43+ def methods (methods : dict [ str , list [ Method ]], indent ) -> str :
3144 content = ""
3245 for definitions in methods .values ():
33- for d in definitions :
34- lines = d .code .split ("\n " )[:- 1 ]
46+ for i , method in enumerate (definitions ):
47+ if len (definitions ) > 1 and i == 0 :
48+ content += f"{ indent } # Defined on: { method .defining_class } \n "
49+ lines = method .code .split ("\n " )[:- 1 ]
3550 for line in lines :
51+ # TODO: dedent code at source so defined indent isn't tied to
52+ # presentation indent
3653 content += f"{ indent } { line [4 :]} \n "
3754 content += "\n "
38- return content
55+
56+ # add strip to remove the trailing newline, rather than polluting the loop
57+ # with logic to work out if we're on the final loop iteration
58+ return content .strip ("\n " )
3959
4060
41- def to_string (structure : Class ) -> str :
42- content = declaration (structure .name , structure .parents )
61+ def to_string (structure : Class , indent : str = " " * DEFAULT_INDENT_WIDTH ) -> str :
62+ content = declaration (structure .name , structure .parents , indent )
4363 content += "\n "
44- content += docstring (structure .docstring ) if docstring else ""
45- content += attributes (structure .attributes )
64+ content += docstring (structure .docstring , indent ) if docstring else ""
65+ content += attributes (structure .attributes , indent )
4666 content += "\n "
47- content += methods (structure .methods )
67+ content += classes (structure .classes , indent )
68+ content += methods (structure .methods , indent )
4869
4970 return content
0 commit comments