@@ -336,23 +336,23 @@ def delete_empty_dirs(path: Path) -> None:
336336 # Provide more context in the error message
337337 raise OSError (f"Failed to remove empty directory { path } : { e } " ) from e
338338
339-
339+ # only run this parser once per unique input string
340+ # chache the results for efficiency.
340341@lru_cache (maxsize = None )
341342def parse_slurm_signal_settings (signal_settings : Optional [str ]) -> dict [str , str ]:
342343 """
343- Parse rule-specific SLURM signal settings (format: rule[:SCOPE] :SIGNAL@TIME).
344+ Parse rule-specific SLURM signal settings (format: rule:SIGNAL@TIME).
344345
345346 - rule: rule name or 'all' for all rules
346- - SCOPE: B (batch script, default) or R (reservation)
347347 - SIGNAL: signal name (SIGTERM, SIGUSR1) or number (15, 10)
348348 - TIME: seconds before wall time (must be >= 1)
349349
350350 Examples:
351- - rule1:SIGTERM@30 → batch script, SIGTERM at 30 secs
352- - rule2:R: SIGUSR1@60 → reservation, SIGUSR1 at 60 secs
351+ - rule1:SIGTERM@30 → SIGTERM at 30 secs
352+ - rule2:SIGUSR1@60 → SIGUSR1 at 60 secs
353353 - all:15@45 → all rules, signal 15 at 45 secs
354354
355- Returns dict mapping rule names to SLURM signal specs: [B:|R:]<sig_num >@<time>
355+ Returns dict mapping rule names to SLURM signal specs: <signal >@<time>
356356 """
357357 if not signal_settings :
358358 return {}
@@ -392,25 +392,25 @@ def parse_slurm_signal_settings(signal_settings: Optional[str]) -> dict[str, str
392392 "SIGSYS" : 31 ,
393393 }
394394
395- # Pattern: rule[:SCOPE]: SIGNAL@TIME where SCOPE is optional (B|R)
395+ # Pattern: rule: SIGNAL@TIME
396396 pattern = re .compile (
397- r"^(?P<rule>\w+)(?::(?P<scope>[BR]))? :(?P<signal>\w+)@(?P<seconds>\d+)$"
397+ r"^(?P<rule>\w+):(?P<signal>\w+)@(?P<seconds>\d+)$"
398398 )
399399
400400 for raw_entry in signal_settings .split ("," ):
401401 entry = raw_entry .strip ()
402402 if not entry :
403403 raise WorkflowError (
404404 "Invalid signal specification: empty entry found. "
405- "Expected 'rule[:SCOPE] :SIGNAL@TIME' (e.g., 'rule1:SIGTERM@30')."
405+ "Expected 'rule:SIGNAL@TIME' (e.g., 'rule1:SIGTERM@30')."
406406 )
407407
408408 match = pattern .fullmatch (entry )
409409 if match is None :
410410 raise WorkflowError (
411411 f"Invalid signal specification '{ entry } '. "
412- "Expected 'rule[:SCOPE] :SIGNAL@TIME' (e.g., 'rule1:SIGTERM@30', "
413- "'rule2:R: 15@60', 'all:SIGUSR1@45')."
412+ "Expected 'rule:SIGNAL@TIME' (e.g., 'rule1:SIGTERM@30', "
413+ "'rule2:15@60', 'all:SIGUSR1@45')."
414414 )
415415
416416 rule_name = match .group ("rule" )
@@ -420,7 +420,7 @@ def parse_slurm_signal_settings(signal_settings: Optional[str]) -> dict[str, str
420420 )
421421
422422 signal_str = match .group ("signal" )
423- # Convert signal name to number if needed
423+ # Validate signal name or number.
424424 if signal_str .isdigit ():
425425 signal_num = int (signal_str )
426426 if signal_num < 1 or signal_num > 31 :
@@ -439,8 +439,7 @@ def parse_slurm_signal_settings(signal_settings: Optional[str]) -> dict[str, str
439439 if seconds < 1 :
440440 raise WorkflowError ("Signal lead time must be at least 1 second." )
441441
442- scope = match .group ("scope" ) or "B" # Default to batch script
443- parsed_settings [rule_name ] = f"{ scope } :{ signal_num } @{ seconds } "
442+ parsed_settings [rule_name ] = f"{ signal_str } @{ seconds } "
444443
445444 return parsed_settings
446445
@@ -451,14 +450,15 @@ def get_slurm_signal_arg(signal_settings: Optional[str], rule_name: str) -> str:
451450 Checks for rule-specific signal first, then falls back to 'all' if set.
452451 """
453452 # we need to check the signal settings, first.
454- signal_settings_pattern = (
455- r"^\s*(\w+)(?::[BR])?:\w+@\d+\s*" r"(,\s*\w+(?::[BR])?:\w+@\d+\s*)*$"
456- )
453+ if not signal_settings :
454+ return ""
455+
456+ signal_settings_pattern = r"^\s*\w+:\w+@\d+\s*(,\s*\w+:\w+@\d+\s*)*$"
457457 if not re .match (signal_settings_pattern , signal_settings ):
458458 raise WorkflowError (
459459 f"Invalid signal specification: '{ signal_settings } '. "
460- "Expected format: 'rule[:SCOPE] :SIGNAL@TIME' "
461- "(e.g., 'rule1:SIGTERM@30', 'rule2:R: 15@60', "
460+ "Expected format: 'rule:SIGNAL@TIME' "
461+ "(e.g., 'rule1:SIGTERM@30', 'rule2:15@60', "
462462 "'all:SIGUSR1@45')."
463463 )
464464
0 commit comments