diff --git a/scripts/code.py b/scripts/code.py index 09aa9116..b920137f 100755 --- a/scripts/code.py +++ b/scripts/code.py @@ -430,6 +430,7 @@ def table(Result, results, diff_results=None, *, header.append('d'+k) lines.append(header) + # entry helper def table_entry(name, r, diff_r=None): entry = [name] if diff_results is None: diff --git a/scripts/cov.py b/scripts/cov.py index 0b83842c..a8091fb9 100755 --- a/scripts/cov.py +++ b/scripts/cov.py @@ -418,6 +418,7 @@ def table(Result, results, diff_results=None, *, header.append('d'+k) lines.append(header) + # entry helper def table_entry(name, r, diff_r=None): entry = [name] if diff_results is None: diff --git a/scripts/data.py b/scripts/data.py index ccb1dfae..7f00ad9a 100755 --- a/scripts/data.py +++ b/scripts/data.py @@ -430,6 +430,7 @@ def table(Result, results, diff_results=None, *, header.append('d'+k) lines.append(header) + # entry helper def table_entry(name, r, diff_r=None): entry = [name] if diff_results is None: diff --git a/scripts/perf.py b/scripts/perf.py index 8086f1df..01c8590c 100755 --- a/scripts/perf.py +++ b/scripts/perf.py @@ -746,6 +746,7 @@ def table(Result, results, diff_results=None, *, header.append('d'+k) lines.append(header) + # entry helper def table_entry(name, r, diff_r=None): entry = [name] if diff_results is None: @@ -790,6 +791,110 @@ def table(Result, results, diff_results=None, *, getattr(diff_r, k, None))))) return entry + # recursive entry helpers + if hot: + def recurse(results_, depth_, seen=set(), + prefixes=('', '', '', '')): + # build the children table at each layer + results_ = fold(Result, results_, by=by) + table_ = { + ','.join(str(getattr(r, k) or '') for k in by): r + for r in results_} + names_ = list(table_.keys()) + if not names_: + return + + # find the "hottest" path at each step, we use + # the sort field if requested, but ignore reversedness + name = max(names_, + key=lambda n: tuple( + tuple( + # make sure to use the rebuilt table + (getattr(table_[n], k),) + if getattr(table_.get(n), k, None) is not None + else () + for k in ([k] if k else [ + k for k in Result._sort if k in fields]) + if k in fields) + for k, reverse in it.chain( + sort or [], + [(None, False)]))) + + r = table_[name] + is_last = not r.children + + line = table_entry(name, r) + line = [x if isinstance(x, tuple) else (x, []) for x in line] + # add prefixes + line[0] = (prefixes[0+is_last] + line[0][0], line[0][1]) + # add cycle detection + if name in seen: + line[-1] = (line[-1][0], line[-1][1] + ['cycle detected']) + lines.append(line) + + # found a cycle? + if name in seen: + return + + # recurse? + if depth_ > 1: + recurse( + r.children, + depth_-1, + seen | {name}, + prefixes) + + else: + def recurse(results_, depth_, seen=set(), + prefixes=('', '', '', '')): + # build the children table at each layer + results_ = fold(Result, results_, by=by) + table_ = { + ','.join(str(getattr(r, k) or '') for k in by): r + for r in results_} + names_ = list(table_.keys()) + + # sort the children layer + names_.sort() + if sort: + for k, reverse in reversed(sort): + names_.sort( + key=lambda n: tuple( + (getattr(table_[n], k),) + if getattr(table_.get(n), k, None) is not None + else () + for k in ([k] if k else [ + k for k in Result._sort if k in fields])), + reverse=reverse ^ (not k or k in Result._fields)) + + for i, name in enumerate(names_): + r = table_[name] + is_last = (i == len(names_)-1) + + line = table_entry(name, r) + line = [x if isinstance(x, tuple) else (x, []) for x in line] + # add prefixes + line[0] = (prefixes[0+is_last] + line[0][0], line[0][1]) + # add cycle detection + if name in seen: + line[-1] = (line[-1][0], line[-1][1] + ['cycle detected']) + lines.append(line) + + # found a cycle? + if name in seen: + continue + + # recurse? + if depth_ > 1: + recurse( + r.children, + depth_-1, + seen | {name}, + (prefixes[2+is_last] + "|-> ", + prefixes[2+is_last] + "'-> ", + prefixes[2+is_last] + "| ", + prefixes[2+is_last] + " ")) + # entries if not summary: for name in names: @@ -800,6 +905,17 @@ def table(Result, results, diff_results=None, *, diff_r = diff_table.get(name) lines.append(table_entry(name, r, diff_r)) + # recursive entries + if name in table and depth > 1: + recurse( + table[name].children, + depth-1, + {name}, + ("|-> ", + "'-> ", + "| ", + " ")) + # total r = next(iter(fold(Result, results, by=[])), None) if diff_results is None: @@ -822,186 +938,14 @@ def table(Result, results, diff_results=None, *, widths[i] = max(widths[i], ((len(x[0])+1+4-1)//4)*4-1) notes[i] = max(notes[i], 1+2*len(x[1])+sum(len(n) for n in x[1])) - if not summary: - # find the actual depth - depth_ = depth - if hot: - depth_ = 2 - elif m.isinf(depth_): - def rec_depth(results_, seen=set()): - # build the children table at each layer - results_ = fold(Result, results_, by=by) - table_ = { - ','.join(str(getattr(r, k) or '') for k in by): r - for r in results_} - names_ = list(table_.keys()) - - return max( - (rec_depth(table_[name].children, seen | {name}) - for name in names_ - if name not in seen), - default=-1) + 1 - - depth_ = max( - (rec_depth(table[name].children, {name}) - for name in names - if name in table), - default=-1) + 1 - - # adjust the name width based on the call depth - widths[0] += 4*max(depth_-1, 0) - - # print the tree recursively - print('%-*s %s' % ( - widths[0], lines[0][0][0], - ' '.join('%*s%-*s' % ( - widths[i], x[0], - notes[i], ' (%s)' % ', '.join(x[1]) if x[1] else '') - for i, x in enumerate(lines[0][1:], 1)))) - - if not summary: - if hot: - def recurse(results_, depth_, seen=set(), - prefixes=('', '', '', '')): - # build the children table at each layer - results_ = fold(Result, results_, by=by) - table_ = { - ','.join(str(getattr(r, k) or '') for k in by): r - for r in results_} - names_ = list(table_.keys()) - if not names_: - return - - # find the "hottest" path at each step, we use - # the sort field if requested, but ignore reversedness - name = max(names_, - key=lambda n: tuple( - tuple( - # make sure to use the rebuilt table - (getattr(table_[n], k),) - if getattr(table_.get(n), k, None) is not None - else () - for k in ([k] if k else [ - k for k in Result._sort if k in fields]) - if k in fields) - for k, reverse in it.chain( - sort or [], - [(None, False)]))) - - r = table_[name] - is_last = not r.children - - line = table_entry(name, r) - line = [x if isinstance(x, tuple) else (x, []) - for x in line] - print('%s%-*s %s' % ( - prefixes[0+is_last], - widths[0] - len(prefixes[0+is_last]), line[0][0], - ' '.join('%*s%-*s' % ( - widths[i], x[0], - notes[i], - ' (%s)' % ', '.join(it.chain( - x[1], ['cycle detected'])) - if i == len(widths)-1 and name in seen - else ' (%s)' % ', '.join(x[1]) if x[1] - else '') - for i, x in enumerate(line[1:], 1)))) - - # found a cycle? - if name in seen: - return - - # recurse? - if depth_ > 1: - recurse( - r.children, - depth_-1, - seen | {name}, - prefixes) - - else: - def recurse(results_, depth_, seen=set(), - prefixes=('', '', '', '')): - # build the children table at each layer - results_ = fold(Result, results_, by=by) - table_ = { - ','.join(str(getattr(r, k) or '') for k in by): r - for r in results_} - names_ = list(table_.keys()) - - # sort the children layer - names_.sort() - if sort: - for k, reverse in reversed(sort): - names_.sort( - key=lambda n: tuple( - (getattr(table_[n], k),) - if getattr(table_.get(n), k, None) is not None - else () - for k in ([k] if k else [ - k for k in Result._sort if k in fields])), - reverse=reverse ^ (not k or k in Result._fields)) - - for i, name in enumerate(names_): - r = table_[name] - is_last = (i == len(names_)-1) - - line = table_entry(name, r) - line = [x if isinstance(x, tuple) else (x, []) - for x in line] - print('%s%-*s %s' % ( - prefixes[0+is_last], - widths[0] - len(prefixes[0+is_last]), line[0][0], - ' '.join('%*s%-*s' % ( - widths[i], x[0], - notes[i], - ' (%s)' % ', '.join(it.chain( - x[1], ['cycle detected'])) - if i == len(widths)-1 and name in seen - else ' (%s)' % ', '.join(x[1]) if x[1] - else '') - for i, x in enumerate(line[1:], 1)))) - - # found a cycle? - if name in seen: - continue - - # recurse? - if depth_ > 1: - recurse( - r.children, - depth_-1, - seen | {name}, - (prefixes[2+is_last] + "|-> ", - prefixes[2+is_last] + "'-> ", - prefixes[2+is_last] + "| ", - prefixes[2+is_last] + " ")) - - # the top layer is a bit of a special case - for name, line in zip(names, lines[1:-1]): - print('%-*s %s' % ( - widths[0], line[0][0], - ' '.join('%*s%-*s' % ( - widths[i], x[0], - notes[i], ' (%s)' % ', '.join(x[1]) if x[1] else '') - for i, x in enumerate(line[1:], 1)))) - - if name in table and depth > 1: - recurse( - table[name].children, - depth-1, - {name}, - ("|-> ", - "'-> ", - "| ", - " ")) - - print('%-*s %s' % ( - widths[0], lines[-1][0][0], - ' '.join('%*s%-*s' % ( - widths[i], x[0], - notes[i], ' (%s)' % ', '.join(x[1]) if x[1] else '') - for i, x in enumerate(lines[-1][1:], 1)))) + # print our table + for line in lines: + print('%-*s %s' % ( + widths[0], line[0][0], + ' '.join('%*s%-*s' % ( + widths[i], x[0], + notes[i], ' (%s)' % ', '.join(x[1]) if x[1] else '') + for i, x in enumerate(line[1:], 1)))) def annotate(Result, results, *, diff --git a/scripts/perfbd.py b/scripts/perfbd.py index cfe2e8f1..1a2ba31d 100755 --- a/scripts/perfbd.py +++ b/scripts/perfbd.py @@ -710,6 +710,7 @@ def table(Result, results, diff_results=None, *, header.append('d'+k) lines.append(header) + # entry helper def table_entry(name, r, diff_r=None): entry = [name] if diff_results is None: @@ -754,6 +755,110 @@ def table(Result, results, diff_results=None, *, getattr(diff_r, k, None))))) return entry + # recursive entry helpers + if hot: + def recurse(results_, depth_, seen=set(), + prefixes=('', '', '', '')): + # build the children table at each layer + results_ = fold(Result, results_, by=by) + table_ = { + ','.join(str(getattr(r, k) or '') for k in by): r + for r in results_} + names_ = list(table_.keys()) + if not names_: + return + + # find the "hottest" path at each step, we use + # the sort field if requested, but ignore reversedness + name = max(names_, + key=lambda n: tuple( + tuple( + # make sure to use the rebuilt table + (getattr(table_[n], k),) + if getattr(table_.get(n), k, None) is not None + else () + for k in ([k] if k else [ + k for k in Result._sort if k in fields]) + if k in fields) + for k, reverse in it.chain( + sort or [], + [(None, False)]))) + + r = table_[name] + is_last = not r.children + + line = table_entry(name, r) + line = [x if isinstance(x, tuple) else (x, []) for x in line] + # add prefixes + line[0] = (prefixes[0+is_last] + line[0][0], line[0][1]) + # add cycle detection + if name in seen: + line[-1] = (line[-1][0], line[-1][1] + ['cycle detected']) + lines.append(line) + + # found a cycle? + if name in seen: + return + + # recurse? + if depth_ > 1: + recurse( + r.children, + depth_-1, + seen | {name}, + prefixes) + + else: + def recurse(results_, depth_, seen=set(), + prefixes=('', '', '', '')): + # build the children table at each layer + results_ = fold(Result, results_, by=by) + table_ = { + ','.join(str(getattr(r, k) or '') for k in by): r + for r in results_} + names_ = list(table_.keys()) + + # sort the children layer + names_.sort() + if sort: + for k, reverse in reversed(sort): + names_.sort( + key=lambda n: tuple( + (getattr(table_[n], k),) + if getattr(table_.get(n), k, None) is not None + else () + for k in ([k] if k else [ + k for k in Result._sort if k in fields])), + reverse=reverse ^ (not k or k in Result._fields)) + + for i, name in enumerate(names_): + r = table_[name] + is_last = (i == len(names_)-1) + + line = table_entry(name, r) + line = [x if isinstance(x, tuple) else (x, []) for x in line] + # add prefixes + line[0] = (prefixes[0+is_last] + line[0][0], line[0][1]) + # add cycle detection + if name in seen: + line[-1] = (line[-1][0], line[-1][1] + ['cycle detected']) + lines.append(line) + + # found a cycle? + if name in seen: + continue + + # recurse? + if depth_ > 1: + recurse( + r.children, + depth_-1, + seen | {name}, + (prefixes[2+is_last] + "|-> ", + prefixes[2+is_last] + "'-> ", + prefixes[2+is_last] + "| ", + prefixes[2+is_last] + " ")) + # entries if not summary: for name in names: @@ -764,6 +869,17 @@ def table(Result, results, diff_results=None, *, diff_r = diff_table.get(name) lines.append(table_entry(name, r, diff_r)) + # recursive entries + if name in table and depth > 1: + recurse( + table[name].children, + depth-1, + {name}, + ("|-> ", + "'-> ", + "| ", + " ")) + # total r = next(iter(fold(Result, results, by=[])), None) if diff_results is None: @@ -786,186 +902,14 @@ def table(Result, results, diff_results=None, *, widths[i] = max(widths[i], ((len(x[0])+1+4-1)//4)*4-1) notes[i] = max(notes[i], 1+2*len(x[1])+sum(len(n) for n in x[1])) - if not summary: - # find the actual depth - depth_ = depth - if hot: - depth_ = 2 - elif m.isinf(depth_): - def rec_depth(results_, seen=set()): - # build the children table at each layer - results_ = fold(Result, results_, by=by) - table_ = { - ','.join(str(getattr(r, k) or '') for k in by): r - for r in results_} - names_ = list(table_.keys()) - - return max( - (rec_depth(table_[name].children, seen | {name}) - for name in names_ - if name not in seen), - default=-1) + 1 - - depth_ = max( - (rec_depth(table[name].children, {name}) - for name in names - if name in table), - default=-1) + 1 - - # adjust the name width based on the call depth - widths[0] += 4*max(depth_-1, 0) - - # print the tree recursively - print('%-*s %s' % ( - widths[0], lines[0][0][0], - ' '.join('%*s%-*s' % ( - widths[i], x[0], - notes[i], ' (%s)' % ', '.join(x[1]) if x[1] else '') - for i, x in enumerate(lines[0][1:], 1)))) - - if not summary: - if hot: - def recurse(results_, depth_, seen=set(), - prefixes=('', '', '', '')): - # build the children table at each layer - results_ = fold(Result, results_, by=by) - table_ = { - ','.join(str(getattr(r, k) or '') for k in by): r - for r in results_} - names_ = list(table_.keys()) - if not names_: - return - - # find the "hottest" path at each step, we use - # the sort field if requested, but ignore reversedness - name = max(names_, - key=lambda n: tuple( - tuple( - # make sure to use the rebuilt table - (getattr(table_[n], k),) - if getattr(table_.get(n), k, None) is not None - else () - for k in ([k] if k else [ - k for k in Result._sort if k in fields]) - if k in fields) - for k, reverse in it.chain( - sort or [], - [(None, False)]))) - - r = table_[name] - is_last = not r.children - - line = table_entry(name, r) - line = [x if isinstance(x, tuple) else (x, []) - for x in line] - print('%s%-*s %s' % ( - prefixes[0+is_last], - widths[0] - len(prefixes[0+is_last]), line[0][0], - ' '.join('%*s%-*s' % ( - widths[i], x[0], - notes[i], - ' (%s)' % ', '.join(it.chain( - x[1], ['cycle detected'])) - if i == len(widths)-1 and name in seen - else ' (%s)' % ', '.join(x[1]) if x[1] - else '') - for i, x in enumerate(line[1:], 1)))) - - # found a cycle? - if name in seen: - return - - # recurse? - if depth_ > 1: - recurse( - r.children, - depth_-1, - seen | {name}, - prefixes) - - else: - def recurse(results_, depth_, seen=set(), - prefixes=('', '', '', '')): - # build the children table at each layer - results_ = fold(Result, results_, by=by) - table_ = { - ','.join(str(getattr(r, k) or '') for k in by): r - for r in results_} - names_ = list(table_.keys()) - - # sort the children layer - names_.sort() - if sort: - for k, reverse in reversed(sort): - names_.sort( - key=lambda n: tuple( - (getattr(table_[n], k),) - if getattr(table_.get(n), k, None) is not None - else () - for k in ([k] if k else [ - k for k in Result._sort if k in fields])), - reverse=reverse ^ (not k or k in Result._fields)) - - for i, name in enumerate(names_): - r = table_[name] - is_last = (i == len(names_)-1) - - line = table_entry(name, r) - line = [x if isinstance(x, tuple) else (x, []) - for x in line] - print('%s%-*s %s' % ( - prefixes[0+is_last], - widths[0] - len(prefixes[0+is_last]), line[0][0], - ' '.join('%*s%-*s' % ( - widths[i], x[0], - notes[i], - ' (%s)' % ', '.join(it.chain( - x[1], ['cycle detected'])) - if i == len(widths)-1 and name in seen - else ' (%s)' % ', '.join(x[1]) if x[1] - else '') - for i, x in enumerate(line[1:], 1)))) - - # found a cycle? - if name in seen: - continue - - # recurse? - if depth_ > 1: - recurse( - r.children, - depth_-1, - seen | {name}, - (prefixes[2+is_last] + "|-> ", - prefixes[2+is_last] + "'-> ", - prefixes[2+is_last] + "| ", - prefixes[2+is_last] + " ")) - - # the top layer is a bit of a special case - for name, line in zip(names, lines[1:-1]): - print('%-*s %s' % ( - widths[0], line[0][0], - ' '.join('%*s%-*s' % ( - widths[i], x[0], - notes[i], ' (%s)' % ', '.join(x[1]) if x[1] else '') - for i, x in enumerate(line[1:], 1)))) - - if name in table and depth > 1: - recurse( - table[name].children, - depth-1, - {name}, - ("|-> ", - "'-> ", - "| ", - " ")) - - print('%-*s %s' % ( - widths[0], lines[-1][0][0], - ' '.join('%*s%-*s' % ( - widths[i], x[0], - notes[i], ' (%s)' % ', '.join(x[1]) if x[1] else '') - for i, x in enumerate(lines[-1][1:], 1)))) + # print our table + for line in lines: + print('%-*s %s' % ( + widths[0], line[0][0], + ' '.join('%*s%-*s' % ( + widths[i], x[0], + notes[i], ' (%s)' % ', '.join(x[1]) if x[1] else '') + for i, x in enumerate(line[1:], 1)))) def annotate(Result, results, *, diff --git a/scripts/stack.py b/scripts/stack.py index 6390721b..9501ebdf 100755 --- a/scripts/stack.py +++ b/scripts/stack.py @@ -395,6 +395,7 @@ def table(Result, results, diff_results=None, *, header.append('d'+k) lines.append(header) + # entry helper def table_entry(name, r, diff_r=None): entry = [name] if diff_results is None: @@ -439,6 +440,110 @@ def table(Result, results, diff_results=None, *, getattr(diff_r, k, None))))) return entry + # recursive entry helpers + if hot: + def recurse(results_, depth_, seen=set(), + prefixes=('', '', '', '')): + # build the children table at each layer + results_ = fold(Result, results_, by=by) + table_ = { + ','.join(str(getattr(r, k) or '') for k in by): r + for r in results_} + names_ = list(table_.keys()) + if not names_: + return + + # find the "hottest" path at each step, we use + # the sort field if requested, but ignore reversedness + name = max(names_, + key=lambda n: tuple( + tuple( + # make sure to use the rebuilt table + (getattr(table_[n], k),) + if getattr(table_.get(n), k, None) is not None + else () + for k in ([k] if k else [ + k for k in Result._sort if k in fields]) + if k in fields) + for k, reverse in it.chain( + sort or [], + [(None, False)]))) + + r = table_[name] + is_last = not r.children + + line = table_entry(name, r) + line = [x if isinstance(x, tuple) else (x, []) for x in line] + # add prefixes + line[0] = (prefixes[0+is_last] + line[0][0], line[0][1]) + # add cycle detection + if name in seen: + line[-1] = (line[-1][0], line[-1][1] + ['cycle detected']) + lines.append(line) + + # found a cycle? + if name in seen: + return + + # recurse? + if depth_ > 1: + recurse( + r.children, + depth_-1, + seen | {name}, + prefixes) + + else: + def recurse(results_, depth_, seen=set(), + prefixes=('', '', '', '')): + # build the children table at each layer + results_ = fold(Result, results_, by=by) + table_ = { + ','.join(str(getattr(r, k) or '') for k in by): r + for r in results_} + names_ = list(table_.keys()) + + # sort the children layer + names_.sort() + if sort: + for k, reverse in reversed(sort): + names_.sort( + key=lambda n: tuple( + (getattr(table_[n], k),) + if getattr(table_.get(n), k, None) is not None + else () + for k in ([k] if k else [ + k for k in Result._sort if k in fields])), + reverse=reverse ^ (not k or k in Result._fields)) + + for i, name in enumerate(names_): + r = table_[name] + is_last = (i == len(names_)-1) + + line = table_entry(name, r) + line = [x if isinstance(x, tuple) else (x, []) for x in line] + # add prefixes + line[0] = (prefixes[0+is_last] + line[0][0], line[0][1]) + # add cycle detection + if name in seen: + line[-1] = (line[-1][0], line[-1][1] + ['cycle detected']) + lines.append(line) + + # found a cycle? + if name in seen: + continue + + # recurse? + if depth_ > 1: + recurse( + r.children, + depth_-1, + seen | {name}, + (prefixes[2+is_last] + "|-> ", + prefixes[2+is_last] + "'-> ", + prefixes[2+is_last] + "| ", + prefixes[2+is_last] + " ")) + # entries if not summary: for name in names: @@ -449,6 +554,17 @@ def table(Result, results, diff_results=None, *, diff_r = diff_table.get(name) lines.append(table_entry(name, r, diff_r)) + # recursive entries + if name in table and depth > 1: + recurse( + table[name].children, + depth-1, + {name}, + ("|-> ", + "'-> ", + "| ", + " ")) + # total r = next(iter(fold(Result, results, by=[])), None) if diff_results is None: @@ -471,186 +587,14 @@ def table(Result, results, diff_results=None, *, widths[i] = max(widths[i], ((len(x[0])+1+4-1)//4)*4-1) notes[i] = max(notes[i], 1+2*len(x[1])+sum(len(n) for n in x[1])) - if not summary: - # find the actual depth - depth_ = depth - if hot: - depth_ = 2 - elif m.isinf(depth_): - def rec_depth(results_, seen=set()): - # build the children table at each layer - results_ = fold(Result, results_, by=by) - table_ = { - ','.join(str(getattr(r, k) or '') for k in by): r - for r in results_} - names_ = list(table_.keys()) - - return max( - (rec_depth(table_[name].children, seen | {name}) - for name in names_ - if name not in seen), - default=-1) + 1 - - depth_ = max( - (rec_depth(table[name].children, {name}) - for name in names - if name in table), - default=-1) + 1 - - # adjust the name width based on the call depth - widths[0] += 4*max(depth_-1, 0) - - # print the tree recursively - print('%-*s %s' % ( - widths[0], lines[0][0][0], - ' '.join('%*s%-*s' % ( - widths[i], x[0], - notes[i], ' (%s)' % ', '.join(x[1]) if x[1] else '') - for i, x in enumerate(lines[0][1:], 1)))) - - if not summary: - if hot: - def recurse(results_, depth_, seen=set(), - prefixes=('', '', '', '')): - # build the children table at each layer - results_ = fold(Result, results_, by=by) - table_ = { - ','.join(str(getattr(r, k) or '') for k in by): r - for r in results_} - names_ = list(table_.keys()) - if not names_: - return - - # find the "hottest" path at each step, we use - # the sort field if requested, but ignore reversedness - name = max(names_, - key=lambda n: tuple( - tuple( - # make sure to use the rebuilt table - (getattr(table_[n], k),) - if getattr(table_.get(n), k, None) is not None - else () - for k in ([k] if k else [ - k for k in Result._sort if k in fields]) - if k in fields) - for k, reverse in it.chain( - sort or [], - [(None, False)]))) - - r = table_[name] - is_last = not r.children - - line = table_entry(name, r) - line = [x if isinstance(x, tuple) else (x, []) - for x in line] - print('%s%-*s %s' % ( - prefixes[0+is_last], - widths[0] - len(prefixes[0+is_last]), line[0][0], - ' '.join('%*s%-*s' % ( - widths[i], x[0], - notes[i], - ' (%s)' % ', '.join(it.chain( - x[1], ['cycle detected'])) - if i == len(widths)-1 and name in seen - else ' (%s)' % ', '.join(x[1]) if x[1] - else '') - for i, x in enumerate(line[1:], 1)))) - - # found a cycle? - if name in seen: - return - - # recurse? - if depth_ > 1: - recurse( - r.children, - depth_-1, - seen | {name}, - prefixes) - - else: - def recurse(results_, depth_, seen=set(), - prefixes=('', '', '', '')): - # build the children table at each layer - results_ = fold(Result, results_, by=by) - table_ = { - ','.join(str(getattr(r, k) or '') for k in by): r - for r in results_} - names_ = list(table_.keys()) - - # sort the children layer - names_.sort() - if sort: - for k, reverse in reversed(sort): - names_.sort( - key=lambda n: tuple( - (getattr(table_[n], k),) - if getattr(table_.get(n), k, None) is not None - else () - for k in ([k] if k else [ - k for k in Result._sort if k in fields])), - reverse=reverse ^ (not k or k in Result._fields)) - - for i, name in enumerate(names_): - r = table_[name] - is_last = (i == len(names_)-1) - - line = table_entry(name, r) - line = [x if isinstance(x, tuple) else (x, []) - for x in line] - print('%s%-*s %s' % ( - prefixes[0+is_last], - widths[0] - len(prefixes[0+is_last]), line[0][0], - ' '.join('%*s%-*s' % ( - widths[i], x[0], - notes[i], - ' (%s)' % ', '.join(it.chain( - x[1], ['cycle detected'])) - if i == len(widths)-1 and name in seen - else ' (%s)' % ', '.join(x[1]) if x[1] - else '') - for i, x in enumerate(line[1:], 1)))) - - # found a cycle? - if name in seen: - continue - - # recurse? - if depth_ > 1: - recurse( - r.children, - depth_-1, - seen | {name}, - (prefixes[2+is_last] + "|-> ", - prefixes[2+is_last] + "'-> ", - prefixes[2+is_last] + "| ", - prefixes[2+is_last] + " ")) - - # the top layer is a bit of a special case - for name, line in zip(names, lines[1:-1]): - print('%-*s %s' % ( - widths[0], line[0][0], - ' '.join('%*s%-*s' % ( - widths[i], x[0], - notes[i], ' (%s)' % ', '.join(x[1]) if x[1] else '') - for i, x in enumerate(line[1:], 1)))) - - if name in table and depth > 1: - recurse( - table[name].children, - depth-1, - {name}, - ("|-> ", - "'-> ", - "| ", - " ")) - - print('%-*s %s' % ( - widths[0], lines[-1][0][0], - ' '.join('%*s%-*s' % ( - widths[i], x[0], - notes[i], ' (%s)' % ', '.join(x[1]) if x[1] else '') - for i, x in enumerate(lines[-1][1:], 1)))) + # print our table + for line in lines: + print('%-*s %s' % ( + widths[0], line[0][0], + ' '.join('%*s%-*s' % ( + widths[i], x[0], + notes[i], ' (%s)' % ', '.join(x[1]) if x[1] else '') + for i, x in enumerate(line[1:], 1)))) def main(ci_paths, diff --git a/scripts/structs.py b/scripts/structs.py index eec1f49f..3d2a9e7f 100755 --- a/scripts/structs.py +++ b/scripts/structs.py @@ -379,6 +379,7 @@ def table(Result, results, diff_results=None, *, header.append('d'+k) lines.append(header) + # entry helper def table_entry(name, r, diff_r=None): entry = [name] if diff_results is None: diff --git a/scripts/summary.py b/scripts/summary.py index 4e70fe36..fd48f7eb 100755 --- a/scripts/summary.py +++ b/scripts/summary.py @@ -510,6 +510,7 @@ def table(Result, results, diff_results=None, *, header.append('d'+k) lines.append(header) + # entry helper def table_entry(name, r, diff_r=None): entry = [name] if diff_results is None: