33import os
44import time
55from contextlib import contextmanager
6- from typing import Any
6+ from pathlib import Path
7+ from typing import TYPE_CHECKING , Any
78
89import psutil
9- from loguru import _Logger as LoggerType
10+
11+ if TYPE_CHECKING :
12+ # Logger only available in type checking context.
13+ from loguru import Logger # type: ignore[attr-defined]
1014
1115
1216class MetricsProfiler :
@@ -30,7 +34,7 @@ def __init__(self, output_path: str):
3034 self .output_path = output_path
3135
3236 @contextmanager
33- def start_profiler (self , name : str , revision : str , logger : LoggerType ):
37+ def start_profiler (self , name : str , revision : str , logger : "Logger" ):
3438 """
3539 Starts a new profiling session for a given profile name.
3640 Returns a MetricsProfile instance that you can use to mark measurements.
@@ -55,14 +59,17 @@ class MetricsProfile:
5559 to a CSV file.
5660 """
5761
62+ if TYPE_CHECKING :
63+ logger : "Logger"
64+ measurements : list [dict [str , Any ]]
65+
5866 def __init__ (
59- self , name : str , revision : str , output_path : str | None , logger : LoggerType
67+ self , name : str , revision : str , output_path : str | None , logger : "Logger"
6068 ):
6169 self .name = name
6270 self .revision = revision
6371 self .output_path = output_path
6472 self .logger = logger
65- self .measurements = []
6673
6774 # Capture initial metrics.
6875 self .start_time = time .perf_counter ()
@@ -152,6 +159,8 @@ def _write_csv(self, measurement: dict[str, Any]):
152159 return
153160
154161 file_exists = os .path .isfile (self .output_path )
162+ if not file_exists :
163+ Path (self .output_path ).parent .mkdir (parents = True , exist_ok = True )
155164
156165 with open (self .output_path , mode = "a" , newline = "" ) as csv_file :
157166 writer = csv .DictWriter (csv_file , fieldnames = measurement .keys ())
0 commit comments