45 lines
1.2 KiB
Python
45 lines
1.2 KiB
Python
from tree import tree
|
|
|
|
SP = '\N{SPACE}'
|
|
HLIN = '\N{BOX DRAWINGS LIGHT HORIZONTAL}' * 2 + SP # ──
|
|
VLIN = '\N{BOX DRAWINGS LIGHT VERTICAL}' + SP * 3 # │
|
|
TEE = '\N{BOX DRAWINGS LIGHT VERTICAL AND RIGHT}' + HLIN # ├──
|
|
ELBOW = '\N{BOX DRAWINGS LIGHT UP AND RIGHT}' + HLIN # └──
|
|
|
|
|
|
def subclasses(cls):
|
|
try:
|
|
return cls.__subclasses__()
|
|
except TypeError: # handle the `type` type
|
|
return cls.__subclasses__(cls)
|
|
|
|
|
|
def tree(cls, level=0, last_sibling=True):
|
|
yield cls, level, last_sibling
|
|
children = subclasses(cls)
|
|
if children:
|
|
last = children[-1]
|
|
for child in children:
|
|
yield from tree(child, level+1, child is last)
|
|
|
|
|
|
def render_lines(tree_iter):
|
|
cls, _, _ = next(tree_iter)
|
|
yield cls.__name__
|
|
prefix = ''
|
|
|
|
for cls, level, last in tree_iter:
|
|
prefix = prefix[:4 * (level - 1)]
|
|
prefix = prefix.replace(TEE, VLIN).replace(ELBOW, SP * 4)
|
|
prefix += ELBOW if last else TEE
|
|
yield prefix + cls.__name__
|
|
|
|
|
|
def draw(cls):
|
|
for line in render_lines(tree(cls)):
|
|
print(line)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
draw(BaseException)
|