perf(load): use libyaml CLoader when available

Base the TUM loaders (and the param-file load) on yaml.CLoader when
PyYAML is built with libyaml, falling back to the pure-Python Loader
otherwise. Same ParserError/ScannerError, same custom !include
constructors. YAML parse time ~8x lower; validation suite identical
(same verdicts, same 8 expected-fail tracebacks, post-exec SUCCESS).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-05-31 11:22:26 +02:00
parent 5086aa6c0e
commit 5adba7fcd5
3 changed files with 11 additions and 4 deletions

View File

@@ -6,10 +6,10 @@ from runtime.tum_except import ETUMFileError
from interpreter.utils.template import template_to_test from interpreter.utils.template import template_to_test
from copy import copy from copy import copy
from interpreter.utils.globdict import global_dict from interpreter.utils.globdict import global_dict
from interpreter.utils.yaml_load import yaml_load from interpreter.utils.yaml_load import yaml_load, YAML_BASE_LOADER
class TUMLoaderNoIncludes(yaml.Loader): class TUMLoaderNoIncludes(YAML_BASE_LOADER):
def __init__(self, stream): def __init__(self, stream):

View File

@@ -11,7 +11,7 @@ import api.testium as tm
import interpreter.utils.globdict as globdict import interpreter.utils.globdict as globdict
import interpreter.utils.settings as prefs import interpreter.utils.settings as prefs
from interpreter.utils.paths import testium_path from interpreter.utils.paths import testium_path
from interpreter.utils.yaml_load import yaml_load from interpreter.utils.yaml_load import yaml_load, YAML_BASE_LOADER
from interpreter.utils import clear_recursively from interpreter.utils import clear_recursively
from runtime.tum_except import ETUMSyntaxError from runtime.tum_except import ETUMSyntaxError
from interpreter.utils.params import expanse, eval_func_init from interpreter.utils.params import expanse, eval_func_init
@@ -89,7 +89,7 @@ def locate_report_file(rep_file):
def yamltodict(param_file, silent=True): def yamltodict(param_file, silent=True):
# load of the file # load of the file
with open(param_file, "r") as fd: with open(param_file, "r") as fd:
dp = yaml_load(fd, param_file, yaml.Loader) dp = yaml_load(fd, param_file, YAML_BASE_LOADER)
if dp is None: if dp is None:
tm.print_info(f"The YAML file '{param_file}' is empty.") tm.print_info(f"The YAML file '{param_file}' is empty.")

View File

@@ -1,3 +1,4 @@
import yaml
from yaml.parser import ParserError from yaml.parser import ParserError
from yaml import load, Loader from yaml import load, Loader
from yaml.scanner import ScannerError from yaml.scanner import ScannerError
@@ -5,6 +6,12 @@ from api.testium import print_debug
from runtime.tum_except import ETUMSyntaxError from runtime.tum_except import ETUMSyntaxError
import io import io
# Use the libyaml-backed loader (much faster parsing) when PyYAML was built
# with it, falling back to the pure-Python loader otherwise. The C loader
# raises the same ParserError/ScannerError and supports the same custom
# constructors (!include) and construct_* helpers the TUM loaders rely on.
YAML_BASE_LOADER = yaml.CLoader if getattr(yaml, "__with_libyaml__", False) else yaml.Loader
def print_yaml(file: io.TextIOWrapper, file_name): def print_yaml(file: io.TextIOWrapper, file_name):
""" Prints YAML file if debug mode is activated. """ Prints YAML file if debug mode is activated.