diff --git a/perun/cli_groups/__init__.py b/perun/cli_groups/__init__.py index b127cd76..828a2f35 100644 --- a/perun/cli_groups/__init__.py +++ b/perun/cli_groups/__init__.py @@ -1 +1,5 @@ """Collection of CLI groups that are not part of the standalone commands""" + +import lazy_loader as lazy + +__getattr__, __dir__, __all__ = lazy.attach_stub(__name__, __file__) diff --git a/perun/cli_groups/__init__.pyi b/perun/cli_groups/__init__.pyi new file mode 100644 index 00000000..0651caf0 --- /dev/null +++ b/perun/cli_groups/__init__.pyi @@ -0,0 +1,59 @@ +from . import check_cli as check_cli +from . import collect_cli as collect_cli +from . import config_cli as config_cli +from . import import_cli as import_cli +from . import run_cli as run_cli +from . import shared_options as shared_options +from . import showdiff_cli as showdiff_cli +from . import utils_cli as utils_cli + +from .check_cli import ( + check_group as check_group, + check_head as check_head, + check_all as check_all, + check_profiles as check_profiles, +) + +from .collect_cli import collect as collect + +from .config_cli import ( + config as config, + config_get as config_get, + config_set as config_set, + config_edit as config_edit, + config_reset as config_reset, +) + +from .import_cli import ( + import_group as import_group, + perf_group as perf_group, + from_binary as from_binary, + from_text as from_text, + from_stacks as from_stacks, + elk_group as elk_group, + from_json as from_json, +) + +from .run_cli import ( + run as run, + matrix as matrix, + job as job, +) + +from .shared_options import ( + flamegraph_cli_options as flamegraph_cli_options, + profile_postprocess_cli_options as profile_postprocess_cli_options, + profile_aggregation_cli_option as profile_aggregation_cli_options, +) + +from .showdiff_cli import ( + perun_profile_list_options as perun_profile_list_options, + common_html_options as common_html_options, + flamegraph_diff_cli_options as flamegraph_diff_cli_options, + showdiff_group as showdiff_group, + short_diff as short_diff, + flamegraph_diff as flamegraph_diff, + report_group as report_group, + report_native as report_native, + report_folded as report_folded, +) diff --git a/perun/cli_groups/import_cli.py b/perun/cli_groups/import_cli.py index c2d4c7f9..21c7f158 100755 --- a/perun/cli_groups/import_cli.py +++ b/perun/cli_groups/import_cli.py @@ -10,8 +10,7 @@ # Perun Imports from perun.logic import commands, config -from perun.profiles import native as profile -from perun.profiles.conversions import perf_native, elk_native +from perun.profiles import native as profile, conversions from perun.utils.common import cli_kit @@ -187,7 +186,7 @@ def from_binary(ctx: click.Context, import_entries: list[str], **kwargs: Any) -> that combines the --stats-headers option and profile entries. """ kwargs.update(ctx.obj) - perf_native.import_perf_from_record(import_entries, **kwargs) + conversions.perf_native.import_perf_from_record(import_entries, **kwargs) @perf_group.command("script") @@ -214,7 +213,7 @@ def from_text(ctx: click.Context, import_entries: list[str], **kwargs: Any) -> N that combines the --stats-headers option and profile entries. """ kwargs.update(ctx.obj) - perf_native.import_perf_from_script(import_entries, **kwargs) + conversions.perf_native.import_perf_from_script(import_entries, **kwargs) @perf_group.command("stack") @@ -242,7 +241,7 @@ def from_stacks(ctx: click.Context, import_entries: list[str], **kwargs: Any) -> that combines the --stats-headers option and profile entries. """ kwargs.update(ctx.obj) - perf_native.import_perf_from_stack(import_entries, **kwargs) + conversions.perf_native.import_perf_from_stack(import_entries, **kwargs) @import_group.group("elk") @@ -272,4 +271,4 @@ def from_json(ctx: click.Context, import_entries: list[str], **kwargs: Any) -> N Each import entry may specify a JSON path 'file_path.json'. """ kwargs.update(ctx.obj) - elk_native.import_elk_from_json(import_entries, **kwargs) + conversions.elk_native.import_elk_from_json(import_entries, **kwargs) diff --git a/perun/cli_groups/meson.build b/perun/cli_groups/meson.build index de396c8e..2590a7e2 100644 --- a/perun/cli_groups/meson.build +++ b/perun/cli_groups/meson.build @@ -2,6 +2,7 @@ perun_cli_groups_dir = perun_dir / 'cli_groups' perun_cli_groups_files = files( '__init__.py', + '__init__.pyi', 'check_cli.py', 'collect_cli.py', 'config_cli.py', diff --git a/perun/cli_groups/showdiff_cli.py b/perun/cli_groups/showdiff_cli.py index c771dcfe..14d52bc4 100644 --- a/perun/cli_groups/showdiff_cli.py +++ b/perun/cli_groups/showdiff_cli.py @@ -21,8 +21,8 @@ DEFAULT_TRACE_THRESHOLD, HeaderDisplayStyle, ) -from perun.view_diff import flamegraph, short -from perun.view_diff.report import native, folded +from perun import view_diff +from perun.view_diff import report if TYPE_CHECKING: from perun.profiles.native import Profile @@ -178,7 +178,7 @@ def short_diff(profile_list: tuple[Profile, Profile], *_: Any, **kwargs: Any) -> Supports only perun-native profiles. """ - short.compare_profiles(*profile_list, **kwargs) + view_diff.short.compare_profiles(*profile_list, **kwargs) @showdiff_group.command("flamegraph") @@ -221,7 +221,7 @@ def flamegraph_diff(profile_list: tuple[Profile, Profile], *_: Any, **kwargs: An Supports only perun-native profiles. """ - flamegraph.generate_flamegraph_difference(*profile_list, **kwargs) + view_diff.flamegraph.generate_flamegraph_difference(*profile_list, **kwargs) @showdiff_group.group("report") @@ -327,7 +327,7 @@ def report_native( perun showdiff report native -m HEAD~1 0@i 1@i """ kwargs.update(ctx.obj) - native.generate_report_from_native_profiles(*profile_list, **kwargs) + report.native.generate_report_from_native_profiles(*profile_list, **kwargs) @report_group.command("folded") @@ -507,4 +507,4 @@ def report_folded(ctx: click.Context, baseline: str, target: str, **kwargs: Any) """ kwargs.update(ctx.obj) - folded.generate_report_from_folded_profiles(baseline, target, **kwargs) + report.folded.generate_report_from_folded_profiles(baseline, target, **kwargs) diff --git a/perun/fuzz/__init__.pyi b/perun/fuzz/__init__.pyi index 1d99baf3..4f639b81 100644 --- a/perun/fuzz/__init__.pyi +++ b/perun/fuzz/__init__.pyi @@ -1 +1,7 @@ +from . import filesystem as filesystem +from . import filetype as filetype +from . import helpers as helpers +from . import interpret as interpret +from . import randomizer as randomizer + from .factory import run_fuzzing_for_command as run_fuzzing_for_command diff --git a/perun/profiles/conversions/__init__.pyi b/perun/profiles/conversions/__init__.pyi index b5a9ed45..22d17b98 100644 --- a/perun/profiles/conversions/__init__.pyi +++ b/perun/profiles/conversions/__init__.pyi @@ -1,3 +1,13 @@ +from . import ( + elk_native as elk_native, + folded_polars as folded_polars, + native_folded as native_folded, + native_pandas as native_pandas, + native_polars as native_polars, + perf_native as perf_native, + polars_folded as polars_folded, +) + from .elk_native import import_elk_from_json as import_elk_from_json from .folded_polars import ( diff --git a/perun/profiles/folded/__init__.pyi b/perun/profiles/folded/__init__.pyi index a49f6062..06e0d87f 100644 --- a/perun/profiles/folded/__init__.pyi +++ b/perun/profiles/folded/__init__.pyi @@ -1,3 +1,6 @@ +from . import parser as parser +from . import postprocess as postprocess + from .parser import ( parse_resources_from_stream as parse_resources_from_stream, parse_events_from_stream as parse_events_from_stream, diff --git a/perun/profiles/native/__init__.pyi b/perun/profiles/native/__init__.pyi index 2eedf077..406d56b4 100644 --- a/perun/profiles/native/__init__.pyi +++ b/perun/profiles/native/__init__.pyi @@ -1,3 +1,7 @@ +from . import factory as factory +from . import helpers as helpers +from . import query as query + from .factory import ( Profile as Profile, pass_profile as pass_profile, diff --git a/perun/profiles/polars/__init__.pyi b/perun/profiles/polars/__init__.pyi index ca7897d0..bd20779a 100644 --- a/perun/profiles/polars/__init__.pyi +++ b/perun/profiles/polars/__init__.pyi @@ -1,3 +1,7 @@ +from . import convert as convert +from . import parser as parser +from . import structs as structs + from .convert import ( create_polars_pair_profile as create_polars_pair_profile, merge_and_filter_polars_profiles as merge_and_filter_polars_profiles, diff --git a/perun/utils/log.py b/perun/utils/log.py index 1b4fe21c..5cb7b2c6 100644 --- a/perun/utils/log.py +++ b/perun/utils/log.py @@ -17,8 +17,6 @@ import traceback # Third-Party Imports -import numpy as np -import progressbar import termcolor # Perun Imports @@ -713,6 +711,8 @@ def aggregate_intervals( :return: list of the aggregated partial intervals to print """ # Fixme: This is baaaad. But the partial intervals are somewhat broken (sometimes list, sometimes narray) + import numpy as np + intervals = np.array(input_intervals) if isinstance(input_intervals, list) else input_intervals def get_indices_of_intervals() -> Iterable[tuple[int, int]]: @@ -867,6 +867,8 @@ def progress(collection: Iterable[T], description: str = "") -> Iterable[T]: :param collection: any iterable :param description: tag on the left side of the output of the bar """ + import progressbar + widgets: list[progressbar.widgets.WidgetBase | str] = [ (description + ": ") if description else "", progressbar.Percentage(), diff --git a/perun/view/flamegraph/__init__.pyi b/perun/view/flamegraph/__init__.pyi index 69c85664..92898206 100644 --- a/perun/view/flamegraph/__init__.pyi +++ b/perun/view/flamegraph/__init__.pyi @@ -1,3 +1,7 @@ +from . import core as core +from . import grid as grid +from . import run as run + from .core import ( generate_flamegraph as generate_flamegraph, generate_title as generate_title, diff --git a/perun/view/flamegraph/grid.py b/perun/view/flamegraph/grid.py index e51215cb..11b38bf9 100644 --- a/perun/view/flamegraph/grid.py +++ b/perun/view/flamegraph/grid.py @@ -25,6 +25,62 @@ from types import TracebackType +# SVG-escaping patterns. +# Function patterns. +_FUNC_PATTERN = re.compile( + r"(?\s*\n<") +_GET_ELEMENTS_PATTERN = re.compile(r'getElementsByTagName\("svg"\)\[0\]') +_SVG_TAG_PATTERN = re.compile(r'\s*\n<", r"><"), - ( - r"getElementsByTagName\(\"svg\"\)\[0\]", - f'getElementsByClassName("svg-content")[{tag_index}]', - ), - (r"document.", f"{tag}_svg."), - (f"{tag}_svg.createElementNS", "document.createElementNS"), - ( - f"({tag}_(svg|details|detailsName|detailsIncl|detailsExcl|matchedHoverCount|matchedHoverIncl|matchedHoverExcl|matchedSearchCount|matchedSearchIncl|matchedSearchExcl|nameTypeLabel|inclusiveLabel|exclusiveLabel|matchedHoverLabel|matchedSearchLabel|searchbtn|matchedtxt|matchedHoverTxt|ignorecaseBtn|unzoombtn)) = {tag}_svg.", - "\\1 = document.", - ), - # Huge thanks to following article: - # https://chartio.com/resources/tutorials/how-to-resize-an-svg-when-the-window-is-resized-in-d3-js/ - # Which helped to solve the issue with non-resizable flamegraphs - ( - ' str: + s = m.group(0) + if s[0] == '"': + return f'"{tag}_' + s[1:] + if s[0] == "#": + return f"#{tag}_" + s[1:] + return f"{tag}_" + s + + content = _LITERAL_PATTERN.sub(_literal_repl, content) + + content = re.sub(r"matched", f"{tag}_matched", content) + + content = _SVG_VAR_PATTERN.sub(rf"{tag}_svg\1", content) + content = _WS_PATTERN.sub("><", content) + content = _GET_ELEMENTS_PATTERN.sub( + f'getElementsByClassName("svg-content")[{tag_index}]', content + ) + + # Replace 'document.' references, then revert specific cases. + content = re.sub(r"document.", f"{tag}_svg.", content) + content = content.replace(f"{tag}_svg.createElementNS", "document.createElementNS") + content = re.sub( + f"({tag}_(svg|details|detailsName|detailsIncl|detailsExcl" + f"|matchedHoverCount|matchedHoverIncl|matchedHoverExcl" + f"|matchedSearchCount|matchedSearchIncl|matchedSearchExcl" + f"|nameTypeLabel|inclusiveLabel|exclusiveLabel" + f"|matchedHoverLabel|matchedSearchLabel" + f"|searchbtn|matchedtxt|matchedHoverTxt" + f"|ignorecaseBtn|unzoombtn)) = {tag}_svg.", + r"\1 = document.", + content, + ) + # Huge thanks to following article: + # https://chartio.com/resources/tutorials/how-to-resize-an-svg-when-the-window-is-resized-in-d3-js/ + # Which helped to solve the issue with non-resizable flamegraphs + content = _SVG_TAG_PATTERN.sub( + '