ch17: update from book draft
This commit is contained in:
7
17-it-generator/tree/4steps/tree_step0.py
Normal file
7
17-it-generator/tree/4steps/tree_step0.py
Normal file
@@ -0,0 +1,7 @@
|
||||
def tree(cls):
|
||||
yield cls.__name__
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
for cls_name in tree(BaseException):
|
||||
print(cls_name)
|
||||
10
17-it-generator/tree/4steps/tree_step1.py
Normal file
10
17-it-generator/tree/4steps/tree_step1.py
Normal file
@@ -0,0 +1,10 @@
|
||||
def tree(cls):
|
||||
yield cls.__name__, 0
|
||||
for sub_cls in cls.__subclasses__():
|
||||
yield sub_cls.__name__, 1
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
for cls_name, level in tree(BaseException):
|
||||
indent = ' ' * 4 * level
|
||||
print(f'{indent}{cls_name}')
|
||||
12
17-it-generator/tree/4steps/tree_step2.py
Normal file
12
17-it-generator/tree/4steps/tree_step2.py
Normal file
@@ -0,0 +1,12 @@
|
||||
def tree(cls):
|
||||
yield cls.__name__, 0
|
||||
for sub_cls in cls.__subclasses__():
|
||||
yield sub_cls.__name__, 1
|
||||
for sub_sub_cls in sub_cls.__subclasses__():
|
||||
yield sub_sub_cls.__name__, 2
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
for cls_name, level in tree(BaseException):
|
||||
indent = ' ' * 4 * level
|
||||
print(f'{indent}{cls_name}')
|
||||
10
17-it-generator/tree/4steps/tree_step3.py
Normal file
10
17-it-generator/tree/4steps/tree_step3.py
Normal file
@@ -0,0 +1,10 @@
|
||||
def tree(cls, level=0):
|
||||
yield cls.__name__, level
|
||||
for sub_cls in cls.__subclasses__():
|
||||
yield from tree(sub_cls, level + 1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
for cls_name, level in tree(BaseException):
|
||||
indent = ' ' * 4 * level
|
||||
print(f'{indent}{cls_name}')
|
||||
31
17-it-generator/tree/extra/pretty_tree.py
Normal file
31
17-it-generator/tree/extra/pretty_tree.py
Normal file
@@ -0,0 +1,31 @@
|
||||
from tree import tree
|
||||
|
||||
SPACES = ' ' * 4
|
||||
HLINE = '\u2500' # ─ BOX DRAWINGS LIGHT HORIZONTAL
|
||||
HLINE2 = HLINE * 2
|
||||
ELBOW = f'\u2514{HLINE2} ' # └ BOX DRAWINGS LIGHT UP AND RIGHT
|
||||
TEE = f'\u251C{HLINE2} ' # ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT
|
||||
PIPE = f'\u2502 ' # │ BOX DRAWINGS LIGHT VERTICAL
|
||||
|
||||
|
||||
def render_lines(tree_iter):
|
||||
name, _, _ = next(tree_iter)
|
||||
yield name
|
||||
prefix = ''
|
||||
|
||||
for name, level, last in tree_iter:
|
||||
if last:
|
||||
connector = ELBOW
|
||||
else:
|
||||
connector = TEE
|
||||
|
||||
prefix = prefix[:4 * (level-1)]
|
||||
prefix = prefix.replace(TEE, PIPE).replace(ELBOW, SPACES)
|
||||
prefix += connector
|
||||
|
||||
yield prefix + name
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
for line in render_lines(tree(BaseException)):
|
||||
print(line)
|
||||
105
17-it-generator/tree/extra/test_pretty_tree.py
Normal file
105
17-it-generator/tree/extra/test_pretty_tree.py
Normal file
@@ -0,0 +1,105 @@
|
||||
import pytest
|
||||
|
||||
from pretty_tree import tree, render_lines
|
||||
|
||||
def test_1_level():
|
||||
result = list(render_lines(tree(BrokenPipeError)))
|
||||
expected = [
|
||||
'BrokenPipeError',
|
||||
]
|
||||
assert expected == result
|
||||
|
||||
|
||||
def test_2_levels_1_leaf():
|
||||
result = list(render_lines(tree(IndentationError)))
|
||||
expected = [
|
||||
'IndentationError',
|
||||
'└── TabError',
|
||||
]
|
||||
assert expected == result
|
||||
|
||||
|
||||
def test_3_levels_1_leaf():
|
||||
class X: pass
|
||||
class Y(X): pass
|
||||
class Z(Y): pass
|
||||
result = list(render_lines(tree(X)))
|
||||
expected = [
|
||||
'X',
|
||||
'└── Y',
|
||||
' └── Z',
|
||||
]
|
||||
assert expected == result
|
||||
|
||||
|
||||
def test_4_levels_1_leaf():
|
||||
class Level0: pass
|
||||
class Level1(Level0): pass
|
||||
class Level2(Level1): pass
|
||||
class Level3(Level2): pass
|
||||
|
||||
result = list(render_lines(tree(Level0)))
|
||||
expected = [
|
||||
'Level0',
|
||||
'└── Level1',
|
||||
' └── Level2',
|
||||
' └── Level3',
|
||||
]
|
||||
assert expected == result
|
||||
|
||||
|
||||
def test_2_levels_4_leaves():
|
||||
class Branch: pass
|
||||
class Leaf1(Branch): pass
|
||||
class Leaf2(Branch): pass
|
||||
class Leaf3(Branch): pass
|
||||
class Leaf4(Branch): pass
|
||||
result = list(render_lines(tree(Branch)))
|
||||
expected = [
|
||||
'Branch',
|
||||
'├── Leaf1',
|
||||
'├── Leaf2',
|
||||
'├── Leaf3',
|
||||
'└── Leaf4',
|
||||
]
|
||||
assert expected == result
|
||||
|
||||
|
||||
def test_3_levels_2_leaves():
|
||||
class A: pass
|
||||
class B(A): pass
|
||||
class C(B): pass
|
||||
class D(A): pass
|
||||
class E(D): pass
|
||||
|
||||
result = list(render_lines(tree(A)))
|
||||
expected = [
|
||||
'A',
|
||||
'├── B',
|
||||
'│ └── C',
|
||||
'└── D',
|
||||
' └── E',
|
||||
]
|
||||
assert expected == result
|
||||
|
||||
|
||||
def test_4_levels_4_leaves():
|
||||
class A: pass
|
||||
class B1(A): pass
|
||||
class C1(B1): pass
|
||||
class D1(C1): pass
|
||||
class D2(C1): pass
|
||||
class C2(B1): pass
|
||||
class B2(A): pass
|
||||
expected = [
|
||||
'A',
|
||||
'├── B1',
|
||||
'│ ├── C1',
|
||||
'│ │ ├── D1',
|
||||
'│ │ └── D2',
|
||||
'│ └── C2',
|
||||
'└── B2',
|
||||
]
|
||||
|
||||
result = list(render_lines(tree(A)))
|
||||
assert expected == result
|
||||
94
17-it-generator/tree/extra/test_tree.py
Normal file
94
17-it-generator/tree/extra/test_tree.py
Normal file
@@ -0,0 +1,94 @@
|
||||
from tree import tree
|
||||
|
||||
|
||||
def test_1_level():
|
||||
class One: pass
|
||||
expected = [('One', 0, True)]
|
||||
result = list(tree(One))
|
||||
assert expected == result
|
||||
|
||||
|
||||
def test_2_levels_4_leaves():
|
||||
class Branch: pass
|
||||
class Leaf1(Branch): pass
|
||||
class Leaf2(Branch): pass
|
||||
class Leaf3(Branch): pass
|
||||
class Leaf4(Branch): pass
|
||||
expected = [
|
||||
('Branch', 0, True),
|
||||
('Leaf1', 1, False),
|
||||
('Leaf2', 1, False),
|
||||
('Leaf3', 1, False),
|
||||
('Leaf4', 1, True),
|
||||
]
|
||||
result = list(tree(Branch))
|
||||
assert expected == result
|
||||
|
||||
|
||||
def test_3_levels_1_leaf():
|
||||
class X: pass
|
||||
class Y(X): pass
|
||||
class Z(Y): pass
|
||||
expected = [
|
||||
('X', 0, True),
|
||||
('Y', 1, True),
|
||||
('Z', 2, True),
|
||||
]
|
||||
result = list(tree(X))
|
||||
assert expected == result
|
||||
|
||||
|
||||
def test_4_levels_1_leaf():
|
||||
class Level0: pass
|
||||
class Level1(Level0): pass
|
||||
class Level2(Level1): pass
|
||||
class Level3(Level2): pass
|
||||
expected = [
|
||||
('Level0', 0, True),
|
||||
('Level1', 1, True),
|
||||
('Level2', 2, True),
|
||||
('Level3', 3, True),
|
||||
]
|
||||
|
||||
result = list(tree(Level0))
|
||||
assert expected == result
|
||||
|
||||
|
||||
def test_4_levels_3_leaves():
|
||||
class A: pass
|
||||
class B1(A): pass
|
||||
class C1(B1): pass
|
||||
class D1(C1): pass
|
||||
class B2(A): pass
|
||||
class D2(C1): pass
|
||||
class C2(B2): pass
|
||||
expected = [
|
||||
('A', 0, True),
|
||||
('B1', 1, False),
|
||||
('C1', 2, True),
|
||||
('D1', 3, False),
|
||||
('D2', 3, True),
|
||||
('B2', 1, True),
|
||||
('C2', 2, True),
|
||||
]
|
||||
|
||||
result = list(tree(A))
|
||||
assert expected == result
|
||||
|
||||
|
||||
def test_many_levels_1_leaf():
|
||||
class Root: pass
|
||||
level_count = 100
|
||||
expected = [('Root', 0, True)]
|
||||
parent = Root
|
||||
for level in range(1, level_count):
|
||||
name = f'Sub{level}'
|
||||
cls = type(name, (parent,), {})
|
||||
expected.append((name, level, True))
|
||||
parent = cls
|
||||
|
||||
result = list(tree(Root))
|
||||
assert len(result) == level_count
|
||||
assert result[0] == ('Root', 0, True)
|
||||
assert result[-1] == ('Sub99', 99, True)
|
||||
assert expected == result
|
||||
13
17-it-generator/tree/extra/tree.py
Normal file
13
17-it-generator/tree/extra/tree.py
Normal file
@@ -0,0 +1,13 @@
|
||||
def tree(cls, level=0, last_in_level=True):
|
||||
yield cls.__name__, level, last_in_level
|
||||
subclasses = cls.__subclasses__()
|
||||
if subclasses:
|
||||
last = subclasses[-1]
|
||||
for sub_cls in subclasses:
|
||||
yield from tree(sub_cls, level+1, sub_cls is last)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
for cls_name, level, _ in tree(BaseException):
|
||||
indent = ' ' * 4 * level
|
||||
print(f'{indent}{cls_name}')
|
||||
8
17-it-generator/tree/step0/test_tree.py
Normal file
8
17-it-generator/tree/step0/test_tree.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from tree import tree
|
||||
|
||||
|
||||
def test_1_level():
|
||||
class One: pass
|
||||
expected = ['One']
|
||||
result = list(tree(One))
|
||||
assert expected == result
|
||||
7
17-it-generator/tree/step0/tree.py
Normal file
7
17-it-generator/tree/step0/tree.py
Normal file
@@ -0,0 +1,7 @@
|
||||
def tree(cls):
|
||||
yield cls.__name__
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
for cls_name in tree(BaseException):
|
||||
print(cls_name)
|
||||
25
17-it-generator/tree/step1/test_tree.py
Normal file
25
17-it-generator/tree/step1/test_tree.py
Normal file
@@ -0,0 +1,25 @@
|
||||
from tree import tree
|
||||
|
||||
|
||||
def test_1_level():
|
||||
class One: pass
|
||||
expected = [('One', 0)]
|
||||
result = list(tree(One))
|
||||
assert expected == result
|
||||
|
||||
|
||||
def test_2_levels_4_leaves():
|
||||
class Branch: pass
|
||||
class Leaf1(Branch): pass
|
||||
class Leaf2(Branch): pass
|
||||
class Leaf3(Branch): pass
|
||||
class Leaf4(Branch): pass
|
||||
expected = [
|
||||
('Branch', 0),
|
||||
('Leaf1', 1),
|
||||
('Leaf2', 1),
|
||||
('Leaf3', 1),
|
||||
('Leaf4', 1),
|
||||
]
|
||||
result = list(tree(Branch))
|
||||
assert expected == result
|
||||
10
17-it-generator/tree/step1/tree.py
Normal file
10
17-it-generator/tree/step1/tree.py
Normal file
@@ -0,0 +1,10 @@
|
||||
def tree(cls):
|
||||
yield cls.__name__, 0 # <1>
|
||||
for sub_cls in cls.__subclasses__(): # <2>
|
||||
yield sub_cls.__name__, 1 # <3>
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
for cls_name, level in tree(BaseException):
|
||||
indent = ' ' * 4 * level # <4>
|
||||
print(f'{indent}{cls_name}')
|
||||
25
17-it-generator/tree/step2/test_tree.py
Normal file
25
17-it-generator/tree/step2/test_tree.py
Normal file
@@ -0,0 +1,25 @@
|
||||
from tree import tree
|
||||
|
||||
|
||||
def test_1_level():
|
||||
class One: pass
|
||||
expected = [('One', 0)]
|
||||
result = list(tree(One))
|
||||
assert expected == result
|
||||
|
||||
|
||||
def test_2_levels_4_leaves():
|
||||
class Branch: pass
|
||||
class Leaf1(Branch): pass
|
||||
class Leaf2(Branch): pass
|
||||
class Leaf3(Branch): pass
|
||||
class Leaf4(Branch): pass
|
||||
expected = [
|
||||
('Branch', 0),
|
||||
('Leaf1', 1),
|
||||
('Leaf2', 1),
|
||||
('Leaf3', 1),
|
||||
('Leaf4', 1),
|
||||
]
|
||||
result = list(tree(Branch))
|
||||
assert expected == result
|
||||
14
17-it-generator/tree/step2/tree.py
Normal file
14
17-it-generator/tree/step2/tree.py
Normal file
@@ -0,0 +1,14 @@
|
||||
def tree(cls):
|
||||
yield cls.__name__, 0
|
||||
yield from sub_tree(cls) # <1>
|
||||
|
||||
|
||||
def sub_tree(cls):
|
||||
for sub_cls in cls.__subclasses__():
|
||||
yield sub_cls.__name__, 1 # <2>
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
for cls_name, level in tree(BaseException):
|
||||
indent = ' ' * 4 * level
|
||||
print(f'{indent}{cls_name}')
|
||||
38
17-it-generator/tree/step3/test_tree.py
Normal file
38
17-it-generator/tree/step3/test_tree.py
Normal file
@@ -0,0 +1,38 @@
|
||||
from tree import tree
|
||||
|
||||
|
||||
def test_1_level():
|
||||
class One: pass
|
||||
expected = [('One', 0)]
|
||||
result = list(tree(One))
|
||||
assert expected == result
|
||||
|
||||
|
||||
def test_2_levels_4_leaves():
|
||||
class Branch: pass
|
||||
class Leaf1(Branch): pass
|
||||
class Leaf2(Branch): pass
|
||||
class Leaf3(Branch): pass
|
||||
class Leaf4(Branch): pass
|
||||
expected = [
|
||||
('Branch', 0),
|
||||
('Leaf1', 1),
|
||||
('Leaf2', 1),
|
||||
('Leaf3', 1),
|
||||
('Leaf4', 1),
|
||||
]
|
||||
result = list(tree(Branch))
|
||||
assert expected == result
|
||||
|
||||
|
||||
def test_3_levels_1_leaf():
|
||||
class X: pass
|
||||
class Y(X): pass
|
||||
class Z(Y): pass
|
||||
expected = [
|
||||
('X', 0),
|
||||
('Y', 1),
|
||||
('Z', 2),
|
||||
]
|
||||
result = list(tree(X))
|
||||
assert expected == result
|
||||
16
17-it-generator/tree/step3/tree.py
Normal file
16
17-it-generator/tree/step3/tree.py
Normal file
@@ -0,0 +1,16 @@
|
||||
def tree(cls):
|
||||
yield cls.__name__, 0
|
||||
yield from sub_tree(cls)
|
||||
|
||||
|
||||
def sub_tree(cls):
|
||||
for sub_cls in cls.__subclasses__():
|
||||
yield sub_cls.__name__, 1
|
||||
for sub_sub_cls in sub_cls.__subclasses__():
|
||||
yield sub_sub_cls.__name__, 2
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
for cls_name, level in tree(BaseException):
|
||||
indent = ' ' * 4 * level
|
||||
print(f'{indent}{cls_name}')
|
||||
76
17-it-generator/tree/step4/test_tree.py
Normal file
76
17-it-generator/tree/step4/test_tree.py
Normal file
@@ -0,0 +1,76 @@
|
||||
from tree import tree
|
||||
|
||||
|
||||
def test_1_level():
|
||||
class One: pass
|
||||
expected = [('One', 0)]
|
||||
result = list(tree(One))
|
||||
assert expected == result
|
||||
|
||||
|
||||
def test_2_levels_4_leaves():
|
||||
class Branch: pass
|
||||
class Leaf1(Branch): pass
|
||||
class Leaf2(Branch): pass
|
||||
class Leaf3(Branch): pass
|
||||
class Leaf4(Branch): pass
|
||||
expected = [
|
||||
('Branch', 0),
|
||||
('Leaf1', 1),
|
||||
('Leaf2', 1),
|
||||
('Leaf3', 1),
|
||||
('Leaf4', 1),
|
||||
]
|
||||
result = list(tree(Branch))
|
||||
assert expected == result
|
||||
|
||||
|
||||
def test_3_levels_1_leaf():
|
||||
class X: pass
|
||||
class Y(X): pass
|
||||
class Z(Y): pass
|
||||
expected = [
|
||||
('X', 0),
|
||||
('Y', 1),
|
||||
('Z', 2),
|
||||
]
|
||||
result = list(tree(X))
|
||||
assert expected == result
|
||||
|
||||
|
||||
def test_4_levels_1_leaf():
|
||||
class Level0: pass
|
||||
class Level1(Level0): pass
|
||||
class Level2(Level1): pass
|
||||
class Level3(Level2): pass
|
||||
expected = [
|
||||
('Level0', 0),
|
||||
('Level1', 1),
|
||||
('Level2', 2),
|
||||
('Level3', 3),
|
||||
]
|
||||
|
||||
result = list(tree(Level0))
|
||||
assert expected == result
|
||||
|
||||
|
||||
def test_4_levels_3_leaves():
|
||||
class A: pass
|
||||
class B1(A): pass
|
||||
class C1(B1): pass
|
||||
class D1(C1): pass
|
||||
class B2(A): pass
|
||||
class D2(C1): pass
|
||||
class C2(B2): pass
|
||||
expected = [
|
||||
('A', 0),
|
||||
('B1', 1),
|
||||
('C1', 2),
|
||||
('D1', 3),
|
||||
('D2', 3),
|
||||
('B2', 1),
|
||||
('C2', 2),
|
||||
]
|
||||
|
||||
result = list(tree(A))
|
||||
assert expected == result
|
||||
20
17-it-generator/tree/step4/tree.py
Normal file
20
17-it-generator/tree/step4/tree.py
Normal file
@@ -0,0 +1,20 @@
|
||||
def tree(cls):
|
||||
yield cls.__name__, 0
|
||||
yield from sub_tree(cls)
|
||||
|
||||
|
||||
# tag::SUB_TREE[]
|
||||
def sub_tree(cls):
|
||||
for sub_cls in cls.__subclasses__():
|
||||
yield sub_cls.__name__, 1
|
||||
for sub_sub_cls in sub_cls.__subclasses__():
|
||||
yield sub_sub_cls.__name__, 2
|
||||
for sub_sub_sub_cls in sub_sub_cls.__subclasses__():
|
||||
yield sub_sub_sub_cls.__name__, 3
|
||||
# end::SUB_TREE[]
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
for cls_name, level in tree(BaseException):
|
||||
indent = ' ' * 4 * level
|
||||
print(f'{indent}{cls_name}')
|
||||
94
17-it-generator/tree/step5/test_tree.py
Normal file
94
17-it-generator/tree/step5/test_tree.py
Normal file
@@ -0,0 +1,94 @@
|
||||
from tree import tree
|
||||
|
||||
|
||||
def test_1_level():
|
||||
class One: pass
|
||||
expected = [('One', 0)]
|
||||
result = list(tree(One))
|
||||
assert expected == result
|
||||
|
||||
|
||||
def test_2_levels_4_leaves():
|
||||
class Branch: pass
|
||||
class Leaf1(Branch): pass
|
||||
class Leaf2(Branch): pass
|
||||
class Leaf3(Branch): pass
|
||||
class Leaf4(Branch): pass
|
||||
expected = [
|
||||
('Branch', 0),
|
||||
('Leaf1', 1),
|
||||
('Leaf2', 1),
|
||||
('Leaf3', 1),
|
||||
('Leaf4', 1),
|
||||
]
|
||||
result = list(tree(Branch))
|
||||
assert expected == result
|
||||
|
||||
|
||||
def test_3_levels_1_leaf():
|
||||
class X: pass
|
||||
class Y(X): pass
|
||||
class Z(Y): pass
|
||||
expected = [
|
||||
('X', 0),
|
||||
('Y', 1),
|
||||
('Z', 2),
|
||||
]
|
||||
result = list(tree(X))
|
||||
assert expected == result
|
||||
|
||||
|
||||
def test_4_levels_1_leaf():
|
||||
class Level0: pass
|
||||
class Level1(Level0): pass
|
||||
class Level2(Level1): pass
|
||||
class Level3(Level2): pass
|
||||
expected = [
|
||||
('Level0', 0),
|
||||
('Level1', 1),
|
||||
('Level2', 2),
|
||||
('Level3', 3),
|
||||
]
|
||||
|
||||
result = list(tree(Level0))
|
||||
assert expected == result
|
||||
|
||||
|
||||
def test_4_levels_3_leaves():
|
||||
class A: pass
|
||||
class B1(A): pass
|
||||
class C1(B1): pass
|
||||
class D1(C1): pass
|
||||
class B2(A): pass
|
||||
class D2(C1): pass
|
||||
class C2(B2): pass
|
||||
expected = [
|
||||
('A', 0),
|
||||
('B1', 1),
|
||||
('C1', 2),
|
||||
('D1', 3),
|
||||
('D2', 3),
|
||||
('B2', 1),
|
||||
('C2', 2),
|
||||
]
|
||||
|
||||
result = list(tree(A))
|
||||
assert expected == result
|
||||
|
||||
|
||||
def test_many_levels_1_leaf():
|
||||
class Root: pass
|
||||
level_count = 100
|
||||
expected = [('Root', 0)]
|
||||
parent = Root
|
||||
for level in range(1, level_count):
|
||||
name = f'Sub{level}'
|
||||
cls = type(name, (parent,), {})
|
||||
expected.append((name, level))
|
||||
parent = cls
|
||||
|
||||
result = list(tree(Root))
|
||||
assert len(result) == level_count
|
||||
assert result[0] == ('Root', 0)
|
||||
assert result[-1] == ('Sub99', 99)
|
||||
assert expected == result
|
||||
15
17-it-generator/tree/step5/tree.py
Normal file
15
17-it-generator/tree/step5/tree.py
Normal file
@@ -0,0 +1,15 @@
|
||||
def tree(cls):
|
||||
yield cls.__name__, 0
|
||||
yield from sub_tree(cls, 1)
|
||||
|
||||
|
||||
def sub_tree(cls, level):
|
||||
for sub_cls in cls.__subclasses__():
|
||||
yield sub_cls.__name__, level
|
||||
yield from sub_tree(sub_cls, level+1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
for cls_name, level in tree(BaseException):
|
||||
indent = ' ' * 4 * level
|
||||
print(f'{indent}{cls_name}')
|
||||
94
17-it-generator/tree/step6/test_tree.py
Normal file
94
17-it-generator/tree/step6/test_tree.py
Normal file
@@ -0,0 +1,94 @@
|
||||
from tree import tree
|
||||
|
||||
|
||||
def test_1_level():
|
||||
class One: pass
|
||||
expected = [('One', 0)]
|
||||
result = list(tree(One))
|
||||
assert expected == result
|
||||
|
||||
|
||||
def test_2_levels_4_leaves():
|
||||
class Branch: pass
|
||||
class Leaf1(Branch): pass
|
||||
class Leaf2(Branch): pass
|
||||
class Leaf3(Branch): pass
|
||||
class Leaf4(Branch): pass
|
||||
expected = [
|
||||
('Branch', 0),
|
||||
('Leaf1', 1),
|
||||
('Leaf2', 1),
|
||||
('Leaf3', 1),
|
||||
('Leaf4', 1),
|
||||
]
|
||||
result = list(tree(Branch))
|
||||
assert expected == result
|
||||
|
||||
|
||||
def test_3_levels_1_leaf():
|
||||
class X: pass
|
||||
class Y(X): pass
|
||||
class Z(Y): pass
|
||||
expected = [
|
||||
('X', 0),
|
||||
('Y', 1),
|
||||
('Z', 2),
|
||||
]
|
||||
result = list(tree(X))
|
||||
assert expected == result
|
||||
|
||||
|
||||
def test_4_levels_1_leaf():
|
||||
class Level0: pass
|
||||
class Level1(Level0): pass
|
||||
class Level2(Level1): pass
|
||||
class Level3(Level2): pass
|
||||
expected = [
|
||||
('Level0', 0),
|
||||
('Level1', 1),
|
||||
('Level2', 2),
|
||||
('Level3', 3),
|
||||
]
|
||||
|
||||
result = list(tree(Level0))
|
||||
assert expected == result
|
||||
|
||||
|
||||
def test_4_levels_3_leaves():
|
||||
class A: pass
|
||||
class B1(A): pass
|
||||
class C1(B1): pass
|
||||
class D1(C1): pass
|
||||
class B2(A): pass
|
||||
class D2(C1): pass
|
||||
class C2(B2): pass
|
||||
expected = [
|
||||
('A', 0),
|
||||
('B1', 1),
|
||||
('C1', 2),
|
||||
('D1', 3),
|
||||
('D2', 3),
|
||||
('B2', 1),
|
||||
('C2', 2),
|
||||
]
|
||||
|
||||
result = list(tree(A))
|
||||
assert expected == result
|
||||
|
||||
|
||||
def test_many_levels_1_leaf():
|
||||
class Root: pass
|
||||
level_count = 100
|
||||
expected = [('Root', 0)]
|
||||
parent = Root
|
||||
for level in range(1, level_count):
|
||||
name = f'Sub{level}'
|
||||
cls = type(name, (parent,), {})
|
||||
expected.append((name, level))
|
||||
parent = cls
|
||||
|
||||
result = list(tree(Root))
|
||||
assert len(result) == level_count
|
||||
assert result[0] == ('Root', 0)
|
||||
assert result[-1] == ('Sub99', 99)
|
||||
assert expected == result
|
||||
10
17-it-generator/tree/step6/tree.py
Normal file
10
17-it-generator/tree/step6/tree.py
Normal file
@@ -0,0 +1,10 @@
|
||||
def tree(cls, level=0):
|
||||
yield cls.__name__, level
|
||||
for sub_cls in cls.__subclasses__():
|
||||
yield from tree(sub_cls, level+1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
for cls_name, level in tree(BaseException):
|
||||
indent = ' ' * 4 * level
|
||||
print(f'{indent}{cls_name}')
|
||||
Reference in New Issue
Block a user