-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path11.py
More file actions
67 lines (49 loc) · 1.76 KB
/
Copy path11.py
File metadata and controls
67 lines (49 loc) · 1.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import functools
import logging
import os
import time
from typing import Callable, ParamSpec, Tuple, TypeVar
from pydantic import BaseModel
class TimingInfo(BaseModel):
cpu_time: float
wall_time: float
def _start_measurement() -> Tuple[float, float]:
return time.time(), os.times()[0] + os.times()[1]
def _end_measurement(
start_wall_time: float, start_cpu_time: float
) -> Tuple[float, float]:
end_wall_time = time.time()
end_cpu_time = os.times()[0] + os.times()[1]
return end_wall_time - start_wall_time, end_cpu_time - start_cpu_time
P = ParamSpec("P")
T = TypeVar("T")
logger = logging.getLogger(__name__)
def time_measured(func: Callable[P, T]) -> Callable[P, Tuple[TimingInfo, T]]:
"""
Decorator to measure the time taken by a function to execute.
"""
@functools.wraps(func)
def wrapper(*args: P.args, **kwargs: P.kwargs) -> Tuple[TimingInfo, T]:
start_wall_time, start_cpu_time = _start_measurement()
try:
result = func(*args, **kwargs)
finally:
wall_duration, cpu_duration = _end_measurement(
start_wall_time, start_cpu_time
)
timing_info = TimingInfo(cpu_time=cpu_duration, wall_time=wall_duration)
return timing_info, result
return wrapper
def error_logged(func: Callable[P, T]) -> Callable[P, T | None]:
"""
Decorator to suppress and log any exceptions raised by a function.
"""
@functools.wraps(func)
def wrapper(*args: P.args, **kwargs: P.kwargs) -> T | None:
try:
return func(*args, **kwargs)
except Exception as e:
logger.exception(
f"Error when calling function {func.__name__} with arguments {args} {kwargs}: {e}"
)
return wrapper