From 4f5ce464e01a61efc597e82dfc5d898b7f78c454 Mon Sep 17 00:00:00 2001 From: prandla Date: Thu, 24 Sep 2026 14:10:29 +0300 Subject: [PATCH 1/3] italy_yaml: fix loading of OutputOnly tasks the part that set OutputOnly was overwritten by the later if statement. i also added a check to make sure only one of the non-Batch types is specified. --- cmscontrib/loaders/italy_yaml.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/cmscontrib/loaders/italy_yaml.py b/cmscontrib/loaders/italy_yaml.py index 088e8d86f1..e52a4ecaa6 100644 --- a/cmscontrib/loaders/italy_yaml.py +++ b/cmscontrib/loaders/italy_yaml.py @@ -766,13 +766,7 @@ def get_task(self, get_statement=True) -> Task | None: args["score_type_parameters"] = input_value # If output_only is set, then the task type is OutputOnly - if conf.get('output_only', False): - args["task_type"] = "OutputOnly" - args["time_limit"] = None - args["memory_limit"] = None - args["task_type_parameters"] = [evaluation_param] - task.submission_format = \ - ["output_%03d.txt" % i for i in range(n_input)] + output_only = bool(conf.get('output_only', False)) # If there is check/controller (or equivalent), then the task # type is Interactive @@ -792,8 +786,9 @@ def get_task(self, get_statement=True) -> Task | None: manager_path = path break - if controller_path is not None and manager_path is not None: - logger.fatal("Cannot have both a manager and a controller") + if sum((controller_path is not None, manager_path is not None, output_only)) > 1: + logger.critical("Can have at most one of manager, controller, and output_only") + sys.exit(1) if controller_path is not None: args["task_type"] = "Interactive" @@ -812,6 +807,7 @@ def get_task(self, get_statement=True) -> Task | None: controller_path, "Controller for task %s" % task.name) args["managers"] += [Manager("controller", digest)] + elif manager_path is not None: num_processes = load(conf, None, "num_processes") if num_processes is None: @@ -832,6 +828,14 @@ def get_task(self, get_statement=True) -> Task | None: manager_path, "Manager for task %s" % task.name) args["managers"] += [Manager("manager", digest)] + + elif output_only: + args["task_type"] = "OutputOnly" + args["time_limit"] = None + args["memory_limit"] = None + args["task_type_parameters"] = [evaluation_param] + task.submission_format = ["output_%03d.txt" % i for i in range(n_input)] + else: # Otherwise, the task type is Batch or BatchAndOutput args["task_type"] = "Batch" From a4d62c565dad37b33c145b1d211deb3d7f71f0d9 Mon Sep 17 00:00:00 2001 From: prandla Date: Thu, 24 Sep 2026 19:26:23 +0300 Subject: [PATCH 2/3] italy_yaml: replace logging.fatal with logging.critical logging.fatal's docstring says "Don't use this function, use critical() instead." --- cmscontrib/loaders/italy_yaml.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmscontrib/loaders/italy_yaml.py b/cmscontrib/loaders/italy_yaml.py index e52a4ecaa6..3e49049946 100644 --- a/cmscontrib/loaders/italy_yaml.py +++ b/cmscontrib/loaders/italy_yaml.py @@ -605,7 +605,7 @@ def get_task(self, get_statement=True) -> Task | None: stubs = True if graders and stubs: - logger.fatal("Task contains both sol/grader and sol/stub") + logger.critical("Task contains both sol/grader and sol/stub") return None elif graders: # Read grader for each language From 9907de1480cde7db32f2aa0a8034536e1118dba4 Mon Sep 17 00:00:00 2001 From: prandla Date: Thu, 24 Sep 2026 19:39:27 +0300 Subject: [PATCH 3/3] italy_yaml: remove a python 2 compat hack --- cmscontrib/loaders/italy_yaml.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/cmscontrib/loaders/italy_yaml.py b/cmscontrib/loaders/italy_yaml.py index 3e49049946..08f04ef25b 100644 --- a/cmscontrib/loaders/italy_yaml.py +++ b/cmscontrib/loaders/italy_yaml.py @@ -49,16 +49,6 @@ logger = logging.getLogger(__name__) -# Patch PyYAML to make it load all strings as unicode instead of str -# (see http://stackoverflow.com/questions/2890146). -def construct_yaml_str(self, node): - return self.construct_scalar(node) - - -yaml.Loader.add_constructor("tag:yaml.org,2002:str", construct_yaml_str) -yaml.SafeLoader.add_constructor("tag:yaml.org,2002:str", construct_yaml_str) - - def getmtime(fname): return os.stat(fname).st_mtime