diff --git a/pype/modules/base.py b/pype/modules/base.py index 7f4ca70afd..b8c68586d7 100644 --- a/pype/modules/base.py +++ b/pype/modules/base.py @@ -499,6 +499,122 @@ class ModulesManager: output.extend(hook_paths) return output + def print_report(self): + """Print out report of time spent on modules initialization parts. + + Reporting is not automated must be implemented for each initialization + part separatelly. Reports must be stored to `_report` attribute. + Print is skipped if `_report` is empty. + + Attribute `_report` is dictionary where key is "label" describing + the processed part and value is dictionary where key is module's + class name and value is time delta of it's processing. + + It is good idea to add total time delta on processed part under key + which is defined in attribute `_report_total_key`. By default has value + `"Total"` but use the attribute please. + + ```javascript + { + "Initialization": { + "FtrackModule": 0.003, + ... + "Total": 1.003, + }, + ... + } + ``` + """ + if not self._report: + return + + available_col_names = set() + for module_names in self._report.values(): + available_col_names |= set(module_names.keys()) + + # Prepare ordered dictionary for columns + cols = collections.OrderedDict() + # Add module names to first columnt + cols["Module name"] = list(sorted( + module.__class__.__name__ + for module in self.modules + if module.__class__.__name__ in available_col_names + )) + # Add total key (as last module) + cols["Module name"].append(self._report_total_key) + + # Add columns from report + for label in self._report.keys(): + cols[label] = [] + + total_module_times = {} + for module_name in cols["Module name"]: + total_module_times[module_name] = 0 + + for label, reported in self._report.items(): + for module_name in cols["Module name"]: + col_time = reported.get(module_name) + if col_time is None: + cols[label].append("N/A") + continue + cols[label].append("{:.3f}".format(col_time)) + total_module_times[module_name] += col_time + + # Add to also total column that should sum the row + cols[self._report_total_key] = [] + for module_name in cols["Module name"]: + cols[self._report_total_key].append( + "{:.3f}".format(total_module_times[module_name]) + ) + + # Prepare column widths and total row count + # - column width is by + col_widths = {} + total_rows = None + for key, values in cols.items(): + if total_rows is None: + total_rows = 1 + len(values) + max_width = len(key) + for value in values: + value_length = len(value) + if value_length > max_width: + max_width = value_length + col_widths[key] = max_width + + rows = [] + for idx in range(total_rows): + rows.append([]) + + for key, values in cols.items(): + width = col_widths[key] + idx = 0 + rows[idx].append(key.ljust(width)) + for value in values: + idx += 1 + rows[idx].append(value.ljust(width)) + + filler_parts = [] + for width in col_widths.values(): + filler_parts.append(width * "-") + filler = "+".join(filler_parts) + + formatted_rows = [filler] + last_row_idx = len(rows) - 1 + for idx, row in enumerate(rows): + # Add filler before last row + if idx == last_row_idx: + formatted_rows.append(filler) + + formatted_rows.append("|".join(row)) + + # Add filler after first row + if idx == 0: + formatted_rows.append(filler) + + # Join rows with newline char and add new line at the end + output = "\n".join(formatted_rows) + "\n" + print(output) + class TrayModulesManager(ModulesManager): # Define order of modules in menu