import functools import logging import threading import time import warnings def log_decorator(func): def wrapper(*args, **kwargs): logging.info(f'Entering {func.__name__}') result = func(*args, **kwargs) logging.info(f'Exiting {func.__name__}') return result return wrapper def error_decorator(func): def wrapper(*args, **kwargs): try: return func(*args, **kwargs) except Exception as e: logging.error(f'Error in {func.__name__}: {str(e)}') raise return wrapper def timing_decorator(func): def wrapper(*args, **kwargs): start_time = time.time() result = func(*args, **kwargs) end_time = time.time() logging.info(f'{func.__name__} executed in {end_time - start_time} seconds') return result return wrapper def retry_decorator(max_retries=5): def decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): for _ in range(max_retries): try: return func(*args, **kwargs) except Exception as error: logging.error(f" Error in {func.__name__}: {str(error)} Retrying ....") return func(*args, **kwargs) return wrapper return decorator def singleton_decorator(cls): instances = {} def wrapper(*args, **kwargs): if cls not in instances: instances[cls] = cls(*args, **kwargs) return instances[cls] return wrapper def synchronized_decorator(func): func.__lock__ = threading.Lock() def wrapper(*args, **kwargs): with func.__lock__: return func(*args, **kwargs) return wrapper def deprecated_decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): warnings.warn(f"{func.__name__} is deprecated", category=DeprecationWarning) return func(*args, **kwargs) return wrapper def validate_inputs_decorator(validator): def decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): if not validator(*args, **kwargs): raise ValueError("Invalid Inputs") return func(*args, **kwargs) return wrapper return decorator