From f41ef1673e8a3448d211f58cdc22bcf8f80d6daa Mon Sep 17 00:00:00 2001 From: "M. Zain Sohail" Date: Mon, 30 Jan 2023 22:19:16 +0100 Subject: [PATCH 1/5] Add a decorator method to record function calls with parameters --- sed/core/processor.py | 3 +++ sed/core/workflow_recorder.py | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 sed/core/workflow_recorder.py diff --git a/sed/core/processor.py b/sed/core/processor.py index 448e7205..1b27446b 100644 --- a/sed/core/processor.py +++ b/sed/core/processor.py @@ -23,6 +23,7 @@ from sed.config.settings import parse_config from sed.core.dfops import apply_jitter from sed.core.metadata import MetaHandler +from sed.core.workflow_recorder import MethodCall, track_call from sed.diagnostics import grid_histogram from sed.loader.loader_interface import get_loader from sed.loader.mirrorutil import CopyTool @@ -59,6 +60,7 @@ def __init__( self._coordinates: Dict[Any, Any] = {} self.axis: Dict[Any, Any] = {} self._attributes = MetaHandler(meta=metadata) + self._call_tracker: List[MethodCall] = [] loader_name = self._config["core"]["loader"] self.loader = get_loader( @@ -207,6 +209,7 @@ def cpy(self, path: Union[str, List[str]]) -> Union[str, List[str]]: return path + @track_call def load( self, dataframe: Union[pd.DataFrame, ddf.DataFrame] = None, diff --git a/sed/core/workflow_recorder.py b/sed/core/workflow_recorder.py new file mode 100644 index 00000000..f62652df --- /dev/null +++ b/sed/core/workflow_recorder.py @@ -0,0 +1,20 @@ +"""Module contains a call tracker and a dataclass for saving the method calls.""" +from functools import wraps +from dataclasses import dataclass + +@dataclass +class MethodCall: + """A dataclass that records a method call with it's name, args and any additional kwargs.""" + name: str + args: list + kwargs: dict + +def track_call(func): + """A decorator that records each call to the decorated function.""" + @wraps(func) + def wrapper(self, *args, **kwargs): + self._call_tracker.append(MethodCall(func.__name__, args, kwargs)) + + return func(self, *args, **kwargs) + + return wrapper From 6b57ead93d4015ed0f1bc8a5e29afce101a0d92e Mon Sep 17 00:00:00 2001 From: rettigl Date: Wed, 1 Feb 2023 04:27:16 +0100 Subject: [PATCH 2/5] add class to call tracking --- sed/calibrator/delay.py | 12 ++++++ sed/calibrator/energy.py | 69 ++++++++++++++++++----------------- sed/calibrator/momentum.py | 24 ++++++++++++ sed/core/processor.py | 9 +++++ sed/core/workflow_recorder.py | 2 +- 5 files changed, 81 insertions(+), 35 deletions(-) diff --git a/sed/calibrator/delay.py b/sed/calibrator/delay.py index 0ba1aefd..ee7dd958 100644 --- a/sed/calibrator/delay.py +++ b/sed/calibrator/delay.py @@ -9,6 +9,7 @@ import numpy as np import pandas as pd +from sed.core.workflow_recorder import MethodCall, track_call class DelayCalibrator: """ @@ -18,6 +19,7 @@ class DelayCalibrator: def __init__( self, config: dict = None, + tracker: List[MethodCall] = None, ): """Initialization of the DelayCalibrator class passes the config dict.""" @@ -26,6 +28,11 @@ def __init__( self._config = config + if tracker is None: + tracker = [] + + self._call_tracker = tracker + self.adc_column = self._config.get("dataframe", {}).get( "adc_column", "ADC", @@ -35,6 +42,11 @@ def __init__( "delay", ) + @property + def call_tracker(self): + return self._call_tracker + + @track_call def append_delay_axis( self, df: Union[pd.DataFrame, dask.dataframe.DataFrame], diff --git a/sed/calibrator/energy.py b/sed/calibrator/energy.py index 7b3bbd62..25b1e2eb 100644 --- a/sed/calibrator/energy.py +++ b/sed/calibrator/energy.py @@ -40,6 +40,7 @@ from sed.binning import bin_dataframe from sed.loader.base.loader import BaseLoader +from sed.core.workflow_recorder import MethodCall, track_call class EnergyCalibrator: """ @@ -53,6 +54,7 @@ def __init__( traces: np.ndarray = None, tof: np.ndarray = None, config: dict = None, + tracker: List[MethodCall] = None, ): """The initialization of the EnergyCalibrator class, can happen by passing the following parameters: @@ -78,6 +80,11 @@ def __init__( self._config = config + if tracker is None: + tracker = [] + + self._call_tracker = tracker + self.featranges: List[Tuple] = [] # Value ranges for feature detection self.peaks: np.ndarray = np.asarray([]) self.calibration: Dict[Any, Any] = {} @@ -123,6 +130,10 @@ def __init__( }, ) + @property + def call_tracker(self): + return self._call_tracker + @property def ntraces(self) -> int: """The number of loaded/calculated traces.""" @@ -167,6 +178,7 @@ def load_data( else: self.traces = self.traces_normed = np.asarray([]) + @track_call def bin_data( self, data_files: List[str], @@ -241,6 +253,7 @@ def bin_data( self.tof = np.asarray(tof) self.biases = np.asarray(biases) + @track_call def normalize(self, smooth: bool = False, span: int = 7, order: int = 1): """Normalize the spectra along an axis. @@ -259,6 +272,7 @@ def normalize(self, smooth: bool = False, span: int = 7, order: int = 1): order=order, ) + @track_call def add_features( self, ranges: Union[List[Tuple], Tuple], @@ -316,6 +330,7 @@ def add_features( elif mode == "replace": self.featranges = newranges + @track_call def feature_extract( self, ranges: List[Tuple] = None, @@ -349,6 +364,7 @@ def feature_extract( pkwindow=peak_window, ) + @track_call def calibrate( self, ref_id: int = 0, @@ -609,6 +625,7 @@ def view( # pylint: disable=dangerous-default-value pbk.show(fig) + @track_call def append_energy_axis( self, df: Union[pd.DataFrame, dask.dataframe.DataFrame], @@ -885,14 +902,7 @@ def update(amplitude, x_center, y_center, **kwds): ) def apply_func(apply: bool): # pylint: disable=unused-argument - self.correction["amplitude"] = amplitude_slider.value - self.correction["center"] = ( - x_center_slider.value, - y_center_slider.value, - ) - self.correction["correction_type"] = correction_type - kwds["diameter"] = diameter_slider.value - self.correction["kwds"] = kwds + self.set_energy_correction(amplitude=amplitude_slider.value, center=(x_center_slider.value,y_center_slider.value), correction_type=correction_type, diameter=diameter_slider.value) amplitude_slider.close() x_center_slider.close() y_center_slider.close() @@ -920,14 +930,7 @@ def apply_func(apply: bool): # pylint: disable=unused-argument ) def apply_func(apply: bool): # pylint: disable=unused-argument - self.correction["amplitude"] = amplitude_slider.value - self.correction["center"] = ( - x_center_slider.value, - y_center_slider.value, - ) - self.correction["correction_type"] = correction_type - kwds["gamma"] = gamma_slider.value - self.correction["kwds"] = kwds + self.set_energy_correction(amplitude=amplitude_slider.value, center=(x_center_slider.value,y_center_slider.value), correction_type=correction_type, gamma=gamma_slider.value) amplitude_slider.close() x_center_slider.close() y_center_slider.close() @@ -955,14 +958,7 @@ def apply_func(apply: bool): # pylint: disable=unused-argument ) def apply_func(apply: bool): # pylint: disable=unused-argument - self.correction["amplitude"] = amplitude_slider.value - self.correction["center"] = ( - x_center_slider.value, - y_center_slider.value, - ) - self.correction["correction_type"] = correction_type - kwds["sigma"] = sigma_slider.value - self.correction["kwds"] = kwds + self.set_energy_correction(amplitude=amplitude_slider.value, center=(x_center_slider.value,y_center_slider.value), correction_type=correction_type, sigma=sigma_slider.value) amplitude_slider.close() x_center_slider.close() y_center_slider.close() @@ -1015,16 +1011,7 @@ def apply_func(apply: bool): # pylint: disable=unused-argument ) def apply_func(apply: bool): # pylint: disable=unused-argument - self.correction["amplitude"] = amplitude_slider.value - self.correction["center"] = ( - x_center_slider.value, - y_center_slider.value, - ) - self.correction["correction_type"] = correction_type - kwds["gamma"] = gamma_slider.value - kwds["amplitude2"] = amplitude2_slider.value - kwds["gamma2"] = gamma2_slider.value - self.correction["kwds"] = kwds + self.set_energy_correction(amplitude=amplitude_slider.value, center=(x_center_slider.value,y_center_slider.value), correction_type=correction_type, gamma=gamma_slider.value, amplitude2=amplitude2_slider.value, gamma2=gamma2_slider.value) amplitude_slider.close() x_center_slider.close() y_center_slider.close() @@ -1044,6 +1031,20 @@ def apply_func(apply: bool): # pylint: disable=unused-argument if apply: apply_func(True) + @track_call + def set_energy_correction( + self, + amplitude, + correction_type, + center, + **kwds, + ): + self.correction["amplitude"] = amplitude + self.correction["center"] = center + self.correction["correction_type"] = correction_type + self.correction["kwds"] = kwds + + @track_call def apply_energy_correction( self, df: Union[pd.DataFrame, dask.dataframe.DataFrame], diff --git a/sed/calibrator/momentum.py b/sed/calibrator/momentum.py index 888f9c7c..bee7c99b 100644 --- a/sed/calibrator/momentum.py +++ b/sed/calibrator/momentum.py @@ -30,6 +30,8 @@ from symmetrize import sym from symmetrize import tps +from sed.core.workflow_recorder import MethodCall, track_call + class MomentumCorrector: """ @@ -42,6 +44,7 @@ def __init__( bin_ranges: List[Tuple] = None, rotsym: int = 6, config: dict = None, + tracker: List[MethodCall] = None, ): """ Parameters: @@ -65,6 +68,11 @@ def __init__( self._config = config + if tracker is None: + tracker = [] + + self._call_tracker = tracker + self.detector_ranges = self._config.get("momentum", {}).get( "detector_ranges", [[0, 2048], [0, 2048]], @@ -93,6 +101,10 @@ def __init__( self.transformations: Dict[Any, Any] = {} self.calibration: Dict[Any, Any] = {} + @property + def call_tracker(self): + return self._call_tracker + @property def features(self) -> dict: """Dictionary of detected features for the symmetrization process. @@ -264,6 +276,7 @@ def apply_fun(apply: bool): # pylint: disable=unused-argument if apply: apply_fun(True) + @track_call def select_slice( self, selector: Union[slice, List[int], int], @@ -293,6 +306,7 @@ def select_slice( elif self.img_ndim == 2: raise ValueError("Input image dimension is already 2!") + @track_call def add_features( self, peaks: np.ndarray, @@ -355,6 +369,7 @@ def add_features( self.mcvdist = self.mdist self.mvvdist = self.mdist + @track_call def feature_extract( self, image: np.ndarray = None, @@ -424,6 +439,7 @@ def calc_symmetry_scores(self, symtype: str = "rotation") -> float: return csm + @track_call def spline_warp_estimate( self, image: np.ndarray = None, @@ -515,6 +531,7 @@ def spline_warp_estimate( return self.slice_corrected + @track_call def apply_correction( self, image: np.ndarray, @@ -591,6 +608,7 @@ def update_deformation(self, rdeform: np.ndarray, cdeform: np.ndarray): cval=np.nan, ) + @track_call def coordinate_transform( self, transform_type: str, @@ -741,6 +759,9 @@ def coordinate_transform( rdeform, cdeform, ) + else: + #remove tracked call to function if not keeping transformation + self.call_tracker.pop() return slice_transformed @@ -1068,6 +1089,7 @@ def view( # pylint: disable=dangerous-default-value pbk.show(fig) + @track_call def calibrate( self, point_a: Union[np.ndarray, List[int]], @@ -1174,6 +1196,7 @@ def calibrate( return self.calibration + @track_call def apply_distortion_correction( self, df: Union[pd.DataFrame, dask.dataframe.DataFrame], @@ -1233,6 +1256,7 @@ def apply_distortion_correction( ) return out_df + @track_call def append_k_axis( self, df: Union[pd.DataFrame, dask.dataframe.DataFrame], diff --git a/sed/core/processor.py b/sed/core/processor.py index 1b27446b..2db15e54 100644 --- a/sed/core/processor.py +++ b/sed/core/processor.py @@ -71,14 +71,17 @@ def __init__( self.ec = EnergyCalibrator( loader=self.loader, config=self._config, + tracker=self._call_tracker, ) self.mc = MomentumCorrector( config=self._config, + tracker=self._call_tracker, ) self.dc = DelayCalibrator( config=self._config, + tracker=self._call_tracker, ) self.use_copy_tool = self._config.get("core", {}).get( @@ -146,6 +149,10 @@ def config(self, config: Union[dict, str]): num_cores = N_CPU - 1 self._config["binning"]["num_cores"] = num_cores + @property + def call_tracker(self): + return self._call_tracker + @property def dimensions(self) -> list: """Getter attribute for the dimensions. @@ -788,6 +795,7 @@ def calibrate_delay_axis( print(self._dataframe.head(10)) + @track_call def add_jitter(self, cols: Sequence[str] = None) -> None: """Add jitter to the selected dataframe columns. @@ -868,6 +876,7 @@ def pre_binning( **kwds, ) + @track_call def compute( self, bins: Union[ diff --git a/sed/core/workflow_recorder.py b/sed/core/workflow_recorder.py index f62652df..c64ac838 100644 --- a/sed/core/workflow_recorder.py +++ b/sed/core/workflow_recorder.py @@ -13,7 +13,7 @@ def track_call(func): """A decorator that records each call to the decorated function.""" @wraps(func) def wrapper(self, *args, **kwargs): - self._call_tracker.append(MethodCall(func.__name__, args, kwargs)) + self.call_tracker.append(MethodCall(type(self).__name__ + "." + func.__name__, args, kwargs)) return func(self, *args, **kwargs) From 2c87a507d371f8e2a3f63448f31cef9393a31eec Mon Sep 17 00:00:00 2001 From: "M. Zain Sohail" Date: Wed, 1 Feb 2023 04:37:57 +0100 Subject: [PATCH 3/5] Keep state of all functions that hold this decorator --- sed/core/processor.py | 5 ++--- sed/core/workflow_recorder.py | 32 ++++++++++++++++++++++---------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/sed/core/processor.py b/sed/core/processor.py index 1b27446b..e788dd2d 100644 --- a/sed/core/processor.py +++ b/sed/core/processor.py @@ -23,7 +23,7 @@ from sed.config.settings import parse_config from sed.core.dfops import apply_jitter from sed.core.metadata import MetaHandler -from sed.core.workflow_recorder import MethodCall, track_call +from sed.core.workflow_recorder import CallTracker from sed.diagnostics import grid_histogram from sed.loader.loader_interface import get_loader from sed.loader.mirrorutil import CopyTool @@ -60,7 +60,6 @@ def __init__( self._coordinates: Dict[Any, Any] = {} self.axis: Dict[Any, Any] = {} self._attributes = MetaHandler(meta=metadata) - self._call_tracker: List[MethodCall] = [] loader_name = self._config["core"]["loader"] self.loader = get_loader( @@ -209,7 +208,7 @@ def cpy(self, path: Union[str, List[str]]) -> Union[str, List[str]]: return path - @track_call + @CallTracker def load( self, dataframe: Union[pd.DataFrame, ddf.DataFrame] = None, diff --git a/sed/core/workflow_recorder.py b/sed/core/workflow_recorder.py index f62652df..4cc0acd3 100644 --- a/sed/core/workflow_recorder.py +++ b/sed/core/workflow_recorder.py @@ -1,20 +1,32 @@ """Module contains a call tracker and a dataclass for saving the method calls.""" -from functools import wraps from dataclasses import dataclass +from functools import update_wrapper +from typing import List + @dataclass class MethodCall: - """A dataclass that records a method call with it's name, args and any additional kwargs.""" + """A dataclass that records a method call with it's name, + args and any additional kwargs.""" + name: str - args: list + args: tuple kwargs: dict -def track_call(func): - """A decorator that records each call to the decorated function.""" - @wraps(func) - def wrapper(self, *args, **kwargs): - self._call_tracker.append(MethodCall(func.__name__, args, kwargs)) - return func(self, *args, **kwargs) +class CallTracker: + """A decorator that records each call with its arguments to the + decorated function. The call_tracker is a class attribute and can + be accessed by the class name, and holds the list of all calls.""" + + call_tracker: List[MethodCall] = [] + + def __init__(self, func): + update_wrapper(self, func) + self.func = func - return wrapper + def __call__(self, *args, **kwargs): + self.__class__.call_tracker.append( + MethodCall(self.func.__name__, args, kwargs), + ) + return self.func(*args, **kwargs) From 914975a8c527da19a0eff2862212e1041184284d Mon Sep 17 00:00:00 2001 From: rettigl Date: Wed, 1 Feb 2023 04:47:51 +0100 Subject: [PATCH 4/5] linting --- sed/calibrator/delay.py | 11 ++++--- sed/calibrator/energy.py | 58 ++++++++++++++++++++++++++++------- sed/calibrator/momentum.py | 12 +++++--- sed/core/processor.py | 7 +++-- sed/core/workflow_recorder.py | 17 ++++++++-- 5 files changed, 80 insertions(+), 25 deletions(-) diff --git a/sed/calibrator/delay.py b/sed/calibrator/delay.py index ee7dd958..b8d0615b 100644 --- a/sed/calibrator/delay.py +++ b/sed/calibrator/delay.py @@ -9,7 +9,9 @@ import numpy as np import pandas as pd -from sed.core.workflow_recorder import MethodCall, track_call +from sed.core.workflow_recorder import MethodCall +from sed.core.workflow_recorder import track_call + class DelayCalibrator: """ @@ -23,14 +25,13 @@ def __init__( ): """Initialization of the DelayCalibrator class passes the config dict.""" + # pylint: disable=duplicate-code if config is None: config = {} - self._config = config if tracker is None: tracker = [] - self._call_tracker = tracker self.adc_column = self._config.get("dataframe", {}).get( @@ -43,7 +44,9 @@ def __init__( ) @property - def call_tracker(self): + def call_tracker(self) -> List[MethodCall]: + """List of tracked function calls.""" + return self._call_tracker @track_call diff --git a/sed/calibrator/energy.py b/sed/calibrator/energy.py index 25b1e2eb..aed2a377 100644 --- a/sed/calibrator/energy.py +++ b/sed/calibrator/energy.py @@ -38,9 +38,10 @@ from silx.io import dictdump from sed.binning import bin_dataframe +from sed.core.workflow_recorder import MethodCall +from sed.core.workflow_recorder import track_call from sed.loader.base.loader import BaseLoader -from sed.core.workflow_recorder import MethodCall, track_call class EnergyCalibrator: """ @@ -75,14 +76,13 @@ def __init__( if traces is not None and tof is not None and biases is not None: self.load_data(biases=biases, traces=traces, tof=tof) + # pylint: disable=duplicate-code if config is None: config = {} - self._config = config if tracker is None: tracker = [] - self._call_tracker = tracker self.featranges: List[Tuple] = [] # Value ranges for feature detection @@ -131,7 +131,9 @@ def __init__( ) @property - def call_tracker(self): + def call_tracker(self) -> List[MethodCall]: + """List of tracked function calls.""" + return self._call_tracker @property @@ -902,7 +904,12 @@ def update(amplitude, x_center, y_center, **kwds): ) def apply_func(apply: bool): # pylint: disable=unused-argument - self.set_energy_correction(amplitude=amplitude_slider.value, center=(x_center_slider.value,y_center_slider.value), correction_type=correction_type, diameter=diameter_slider.value) + self.set_energy_correction( + amplitude=amplitude_slider.value, + center=(x_center_slider.value, y_center_slider.value), + correction_type=correction_type, + diameter=diameter_slider.value, + ) amplitude_slider.close() x_center_slider.close() y_center_slider.close() @@ -930,7 +937,12 @@ def apply_func(apply: bool): # pylint: disable=unused-argument ) def apply_func(apply: bool): # pylint: disable=unused-argument - self.set_energy_correction(amplitude=amplitude_slider.value, center=(x_center_slider.value,y_center_slider.value), correction_type=correction_type, gamma=gamma_slider.value) + self.set_energy_correction( + amplitude=amplitude_slider.value, + center=(x_center_slider.value, y_center_slider.value), + correction_type=correction_type, + gamma=gamma_slider.value, + ) amplitude_slider.close() x_center_slider.close() y_center_slider.close() @@ -958,7 +970,12 @@ def apply_func(apply: bool): # pylint: disable=unused-argument ) def apply_func(apply: bool): # pylint: disable=unused-argument - self.set_energy_correction(amplitude=amplitude_slider.value, center=(x_center_slider.value,y_center_slider.value), correction_type=correction_type, sigma=sigma_slider.value) + self.set_energy_correction( + amplitude=amplitude_slider.value, + center=(x_center_slider.value, y_center_slider.value), + correction_type=correction_type, + sigma=sigma_slider.value, + ) amplitude_slider.close() x_center_slider.close() y_center_slider.close() @@ -1011,7 +1028,14 @@ def apply_func(apply: bool): # pylint: disable=unused-argument ) def apply_func(apply: bool): # pylint: disable=unused-argument - self.set_energy_correction(amplitude=amplitude_slider.value, center=(x_center_slider.value,y_center_slider.value), correction_type=correction_type, gamma=gamma_slider.value, amplitude2=amplitude2_slider.value, gamma2=gamma2_slider.value) + self.set_energy_correction( + amplitude=amplitude_slider.value, + center=(x_center_slider.value, y_center_slider.value), + correction_type=correction_type, + gamma=gamma_slider.value, + amplitude2=amplitude2_slider.value, + gamma2=gamma2_slider.value, + ) amplitude_slider.close() x_center_slider.close() y_center_slider.close() @@ -1034,11 +1058,23 @@ def apply_func(apply: bool): # pylint: disable=unused-argument @track_call def set_energy_correction( self, - amplitude, - correction_type, - center, + amplitude: float, + correction_type: str, + center: Tuple[float, float], **kwds, ): + """Set the supplied energy correction parameters in the class attribute + + Args: + amplitude (float): + Amplitude of the time-of-flight correction term + correction_type (str): + Type of correction to apply to the TOF axis. Defaults to config value. + center (Tuple(float, float)): + Center pixel (x, y) of the correction term. + **kwds: + Additional keyword arguments specific to the various correction_types + """ self.correction["amplitude"] = amplitude self.correction["center"] = center self.correction["correction_type"] = correction_type diff --git a/sed/calibrator/momentum.py b/sed/calibrator/momentum.py index bee7c99b..fb2358d1 100644 --- a/sed/calibrator/momentum.py +++ b/sed/calibrator/momentum.py @@ -30,7 +30,8 @@ from symmetrize import sym from symmetrize import tps -from sed.core.workflow_recorder import MethodCall, track_call +from sed.core.workflow_recorder import MethodCall +from sed.core.workflow_recorder import track_call class MomentumCorrector: @@ -63,14 +64,13 @@ def __init__( if data is not None: self.load_data(data=data, bin_ranges=bin_ranges, rotsym=rotsym) + # pylint: disable=duplicate-code if config is None: config = {} - self._config = config if tracker is None: tracker = [] - self._call_tracker = tracker self.detector_ranges = self._config.get("momentum", {}).get( @@ -102,7 +102,9 @@ def __init__( self.calibration: Dict[Any, Any] = {} @property - def call_tracker(self): + def call_tracker(self) -> List[MethodCall]: + """List of tracked function calls.""" + return self._call_tracker @property @@ -760,7 +762,7 @@ def coordinate_transform( cdeform, ) else: - #remove tracked call to function if not keeping transformation + # remove tracked call to function if not keeping transformation self.call_tracker.pop() return slice_transformed diff --git a/sed/core/processor.py b/sed/core/processor.py index 2db15e54..e13f148f 100644 --- a/sed/core/processor.py +++ b/sed/core/processor.py @@ -23,7 +23,8 @@ from sed.config.settings import parse_config from sed.core.dfops import apply_jitter from sed.core.metadata import MetaHandler -from sed.core.workflow_recorder import MethodCall, track_call +from sed.core.workflow_recorder import MethodCall +from sed.core.workflow_recorder import track_call from sed.diagnostics import grid_histogram from sed.loader.loader_interface import get_loader from sed.loader.mirrorutil import CopyTool @@ -150,7 +151,9 @@ def config(self, config: Union[dict, str]): self._config["binning"]["num_cores"] = num_cores @property - def call_tracker(self): + def call_tracker(self) -> List[MethodCall]: + """List of tracked function calls.""" + return self._call_tracker @property diff --git a/sed/core/workflow_recorder.py b/sed/core/workflow_recorder.py index c64ac838..739ce781 100644 --- a/sed/core/workflow_recorder.py +++ b/sed/core/workflow_recorder.py @@ -1,19 +1,30 @@ """Module contains a call tracker and a dataclass for saving the method calls.""" -from functools import wraps from dataclasses import dataclass +from functools import wraps + @dataclass class MethodCall: - """A dataclass that records a method call with it's name, args and any additional kwargs.""" + """A dataclass that records a method call with it's name, args and any + additional kwargs.""" + name: str args: list kwargs: dict + def track_call(func): """A decorator that records each call to the decorated function.""" + @wraps(func) def wrapper(self, *args, **kwargs): - self.call_tracker.append(MethodCall(type(self).__name__ + "." + func.__name__, args, kwargs)) + self.call_tracker.append( + MethodCall( + type(self).__name__ + "." + func.__name__, + args, + kwargs, + ), + ) return func(self, *args, **kwargs) From 356c02ed005b7d88500db0abe78669ecc5fe2d2a Mon Sep 17 00:00:00 2001 From: "M. Zain Sohail" Date: Thu, 2 Feb 2023 00:40:48 +0100 Subject: [PATCH 5/5] Fix behaviour fr not all arguments are passed --- sed/core/workflow_recorder.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sed/core/workflow_recorder.py b/sed/core/workflow_recorder.py index 4cc0acd3..c1637793 100644 --- a/sed/core/workflow_recorder.py +++ b/sed/core/workflow_recorder.py @@ -27,6 +27,6 @@ def __init__(self, func): def __call__(self, *args, **kwargs): self.__class__.call_tracker.append( - MethodCall(self.func.__name__, args, kwargs), + MethodCall(self.func.__qualname__, args, kwargs), ) - return self.func(*args, **kwargs) + return self.func(self, *args, **kwargs)