From 23c88bd2e5f2eff4923920ef4281de4ba09df501 Mon Sep 17 00:00:00 2001 From: Aryaz Eghbali Date: Thu, 24 Aug 2023 15:03:59 +0200 Subject: [PATCH] Fixed problem with filters --- src/dynapyt/instrument/CodeInstrumenter.py | 13 ++------ src/dynapyt/runtime.py | 37 ++++++++++------------ src/dynapyt/utils/hooks.py | 7 ++-- src/dynapyt/utils/load_analysis.py | 24 ++++++++++++++ 4 files changed, 46 insertions(+), 35 deletions(-) create mode 100644 src/dynapyt/utils/load_analysis.py diff --git a/src/dynapyt/instrument/CodeInstrumenter.py b/src/dynapyt/instrument/CodeInstrumenter.py index 3ff1249..588e65c 100644 --- a/src/dynapyt/instrument/CodeInstrumenter.py +++ b/src/dynapyt/instrument/CodeInstrumenter.py @@ -218,7 +218,6 @@ def leave_Module(self, original_node: cst.Module, updated_node: cst.Module): ] ) dynapyt_imports = [cst.Newline(value="\n")] - dynapyt_imports.append(self.__create_import(["_catch_"])) import_names = list(self.to_import) for i in range(len(updated_node.body)): if m.matches(updated_node.body[i], m.SimpleStatementLine()) and ( @@ -1082,12 +1081,8 @@ def leave_FunctionDef( "function_enter" not in self.selected_hooks and "function_exit" not in self.selected_hooks ) or not ( - self.__selected_by_decorators( - "function_enter", function_metadata["name"] - ) - or self.__selected_by_decorators( - "function_exit", function_metadata["name"] - ) + self.__selected_by_decorators("function_enter", function_metadata["name"]) + or self.__selected_by_decorators("function_exit", function_metadata["name"]) ): return updated_node enter_name = cst.Attribute( @@ -1271,9 +1266,7 @@ def leave_Call(self, original_node: cst.Call, updated_node: cst.Call): m.matches(original_node.func, m.Name()) and ( not ( - self.__selected_by_decorators( - "pre_call", original_node.func - ) + self.__selected_by_decorators("pre_call", original_node.func) or self.__selected_by_decorators( "post_call", original_node.func ) diff --git a/src/dynapyt/runtime.py b/src/dynapyt/runtime.py index df0dea3..91d86a4 100644 --- a/src/dynapyt/runtime.py +++ b/src/dynapyt/runtime.py @@ -2,16 +2,16 @@ from pathlib import Path from sys import exc_info import sys -import os import atexit import signal import json import importlib from filelock import FileLock import libcst as cst -from dynapyt.utils.hooks import snake, get_name -from dynapyt.instrument.IIDs import IIDs -from dynapyt.instrument.filters import START, END, SEPERATOR +from .utils.hooks import snake, get_name +from .instrument.IIDs import IIDs +from .instrument.filters import START, END, SEPERATOR +from .utils.load_analysis import load_analyses analyses = None covered = None @@ -59,34 +59,29 @@ def set_analysis(new_analyses: List[Any]): signal.signal(signal.SIGINT, end_execution) signal.signal(signal.SIGTERM, end_execution) atexit.register(end_execution) - for ana in new_analyses: - if isinstance(ana, str): - conf = None - if ":" in ana: - ana, conf = ana.split(":") - module_parts = ana.split(".") - module = importlib.import_module(".".join(module_parts[:-1])) - class_ = getattr(module, module_parts[-1]) - if conf is not None: - analyses.append(class_(conf)) - else: - analyses.append(class_()) - else: - analyses.append(ana) + analyses = load_analyses(new_analyses) def filtered(func, f, args): docs = func.__doc__ if docs is None or START not in docs: return False + if len(args) >= 2: + sub_args = args[2:] + else: + return False while START in docs: start = docs.find(START) end = docs.find(END) fltr = docs[start + len(START) : end].strip() patterns = fltr.split(" -> ")[1].split(SEPERATOR) - if fltr.startswith("only ->") and f not in patterns: - return True - elif fltr.startswith("ignore ->") and f in patterns: + if fltr.startswith("only ->") and any( + [getattr(arg, "__name__", repr(arg)) in patterns for arg in sub_args] + ): + return False + elif fltr.startswith("ignore ->") and any( + [getattr(arg, "__name__", repr(arg)) in patterns for arg in sub_args] + ): return True docs = docs[end + len(END) :].lstrip() return False diff --git a/src/dynapyt/utils/hooks.py b/src/dynapyt/utils/hooks.py index 30fc2ce..3df5f04 100644 --- a/src/dynapyt/utils/hooks.py +++ b/src/dynapyt/utils/hooks.py @@ -11,6 +11,7 @@ import importlib from ..instrument.filters import START, END, SEPERATOR, get_details +from .load_analysis import load_analyses def snake(x): @@ -63,10 +64,8 @@ def get_used_leaves( def get_hooks_from_analysis(classes: List[str]) -> Dict[str, Dict[str, List[str]]]: try: methods = {} - for cls in classes: - module = importlib.import_module(".".join(cls.split(".")[:-1])) - class_ = getattr(module, cls.split(".")[-1]) - instance = class_() + analyses = load_analyses(classes) + for instance in analyses: methods.update( { func: get_details(getattr(instance, func)) diff --git a/src/dynapyt/utils/load_analysis.py b/src/dynapyt/utils/load_analysis.py new file mode 100644 index 0000000..d5ed555 --- /dev/null +++ b/src/dynapyt/utils/load_analysis.py @@ -0,0 +1,24 @@ +import importlib +from typing import List, Any +from ..analyses.BaseAnalysis import BaseAnalysis + + +def load_analyses(analyses: List[Any]) -> List[BaseAnalysis]: + res_analyses = [] + for ana in analyses: + if isinstance(ana, str): + conf = None + if ":" in ana: + ana, conf = ana.split(":") + module_parts = ana.split(".") + module = importlib.import_module(".".join(module_parts[:-1])) + class_ = getattr(module, module_parts[-1]) + if conf is not None: + res_analyses.append(class_(conf)) + else: + res_analyses.append(class_()) + elif isinstance(ana, BaseAnalysis): + res_analyses.append(ana) + else: + continue + return res_analyses