@@ -82,7 +82,7 @@ def is_available(self) -> bool:
8282
8383class PythonRuntime (Runtime ):
8484 def __init__ (self , python_path : Path | None = None ):
85- self ._python_path = python_path
85+ self ._exe = str ( python_path ) if python_path else sys . executable
8686
8787 @property
8888 def name (self ) -> str :
@@ -93,14 +93,16 @@ def extensions(self) -> tuple[str, ...]:
9393 return (".py" ,)
9494
9595 def build_command (self , path : Path ) -> list [str ]:
96- exe = str (self ._python_path ) if self ._python_path else sys .executable
97- return [exe , str (path )]
96+ return [self ._exe , str (path )]
9897
9998 def is_available (self ) -> bool :
10099 return True
101100
102101
103102class NodeRuntime (Runtime ):
103+ def __init__ (self ) -> None :
104+ self ._exe = shutil .which ("node" )
105+
104106 @property
105107 def name (self ) -> str :
106108 return "Node.js"
@@ -110,10 +112,12 @@ def extensions(self) -> tuple[str, ...]:
110112 return (".js" , ".ts" )
111113
112114 def build_command (self , path : Path ) -> list [str ]:
113- node = shutil .which ("node" )
114- if not node :
115+ if not self ._exe :
115116 raise RuntimeError ("Node.js not found on PATH (required for .js/.ts evaluators)" )
116- return [node , str (path )]
117+ return [self ._exe , str (path )]
118+
119+ def is_available (self ) -> bool :
120+ return self ._exe is not None
117121
118122
119123_RUNTIMES : list [Runtime ] = [
@@ -229,18 +233,16 @@ async def run(self, eval_input: EvalInput, metric_name: str) -> EvalResult:
229233# ---------------------------------------------------------------------------
230234
231235_EXECUTOR_FACTORIES : dict [str , Callable [..., EvaluatorBackend ]] = {
232- "local" : lambda path , timeout , runtime = None : SubprocessBackend (path , timeout , runtime ),
236+ "local" : lambda path , timeout : SubprocessBackend (path , timeout ),
233237}
234238
235239
236- def create_executor (
237- executor_name : str , path : Path , timeout : int = 30 , runtime : Runtime | None = None
238- ) -> EvaluatorBackend :
240+ def create_executor (executor_name : str , path : Path , timeout : int = 30 ) -> EvaluatorBackend :
239241 """Construct an EvaluatorBackend by executor name (e.g. 'local', 'docker')."""
240242 factory = _EXECUTOR_FACTORIES .get (executor_name )
241243 if factory is None :
242244 raise ValueError (f"Unknown executor '{ executor_name } '. Available: { sorted (_EXECUTOR_FACTORIES .keys ())} " )
243- return factory (path , timeout , runtime )
245+ return factory (path , timeout )
244246
245247
246248def register_executor (name : str , factory : Callable [..., EvaluatorBackend ]) -> None :
@@ -449,7 +451,10 @@ async def evaluate_custom_evaluator(
449451 if venv_python :
450452 runtime = PythonRuntime (python_path = venv_python )
451453
452- backend = create_executor (evaluator_def .executor , evaluator_path , evaluator_def .timeout , runtime = runtime )
454+ if runtime is not None :
455+ backend = SubprocessBackend (evaluator_path , evaluator_def .timeout , runtime = runtime )
456+ else :
457+ backend = create_executor (evaluator_def .executor , evaluator_path , evaluator_def .timeout )
453458 else :
454459 raise ValueError (f"Unsupported custom evaluator type: { type (evaluator_def ).__name__ } " )
455460
0 commit comments