diff --git a/src/sio3pack/files/local_file.py b/src/sio3pack/files/local_file.py index f17115b..b80ac81 100644 --- a/src/sio3pack/files/local_file.py +++ b/src/sio3pack/files/local_file.py @@ -41,6 +41,9 @@ def __init__(self, path: str, exists=True): super().__init__(path) self.filename = os.path.basename(path) + def __repr__(self): + return f"" + def read(self) -> str: with open(self.path, "r") as f: return f.read() diff --git a/src/sio3pack/packages/package/model.py b/src/sio3pack/packages/package/model.py index 9a841c4..3e49b3a 100644 --- a/src/sio3pack/packages/package/model.py +++ b/src/sio3pack/packages/package/model.py @@ -164,6 +164,9 @@ def __getattr__(self, name: str) -> Any: except AttributeError: raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{name}'") + def reload_config(self): + pass + @wrap_exceptions def get_title(self, lang: str | None = None) -> str: raise NotImplementedError("This method should be implemented in subclasses.") @@ -171,6 +174,10 @@ def get_title(self, lang: str | None = None) -> str: @wrap_exceptions def get_statement(self, lang: str | None = None) -> File | None: raise NotImplementedError("This method should be implemented in subclasses.") + pass + + def reload_tests(self): + pass @wrap_exceptions def get_test(self, test_id: str) -> Test: diff --git a/src/sio3pack/packages/sinolpack/model.py b/src/sio3pack/packages/sinolpack/model.py index 7b31948..f486329 100644 --- a/src/sio3pack/packages/sinolpack/model.py +++ b/src/sio3pack/packages/sinolpack/model.py @@ -113,7 +113,6 @@ def _from_file(self, file: LocalFile, configuration: SIO3PackConfig = None): archive.extract(to_path=self.tmpdir.name) self.rootdir = os.path.join(self.tmpdir.name, self.short_name) else: - # FIXME: Won't work in sinol-make. self.short_name = os.path.basename(os.path.abspath(file.path)) self.rootdir = os.path.abspath(file.path) @@ -164,7 +163,7 @@ def get_prog_dir(self) -> str: """ return os.path.join(self.rootdir, "prog") - def get_in_prog_dir(self, filename: str) -> File: + def get_in_prog_dir(self, filename: str) -> LocalFile: """ Returns the path to the input file in the program directory. """ @@ -193,9 +192,16 @@ def _process_config_yml(self): try: config = self.get_in_root("config.yml") self.config = yaml.safe_load(config.read()) + self.short_name = self.config.get("sinol_task_id", self.short_name) except FileNotFoundError: self.config = {} + def reload_config(self): + """ + Process the config.yml file again in case it was modified. + """ + self._process_config_yml() + def _detect_full_name(self): """ Sets the problem's full name from the ``config.yml`` (key ``title``) @@ -300,6 +306,12 @@ def special_file_types(self) -> list[str]: """ return ["ingen", "inwer", "soc", "chk"] + def _get_all_files_from_list(self, filenames: list[str]) -> list[LocalFile]: + files = [] + for filename in filenames: + files.append(self.get_in_prog_dir(filename)) + return files + def _process_prog_files(self): """ Process all files in the problem's program directory that are used. @@ -313,13 +325,17 @@ def _process_prog_files(self): self.model_solutions = self.sort_model_solutions(self._get_model_solutions()) self.additional_files = [] - for file in self.config.get("extra_compilation_files", []) + self.config.get("extra_execution_files", []): + extra_files = [] + extra_files.extend(self.config.get("extra_compilation_files", [])) + for lang_extra_files in self.config.get("extra_execution_files", {}).values(): + extra_files.extend(lang_extra_files) + for file in extra_files: try: lf = LocalFile(os.path.join(self.get_prog_dir(), file)) self.additional_files.append(lf) except FileNotFoundError: pass - extensions = self.get_submittable_extensions() + extensions = self.get_submittable_extensions() + ["sh"] self.special_files: dict[str, File | None] = {} for file in self.special_file_types(): try: @@ -478,6 +494,12 @@ def _process_existing_tests(self): out_file = None self.tests.append(Test(test_name, test_id, in_file, out_file, group)) + def reload_tests(self): + """ + Updates `self.tests` variable with existing tests. + """ + self._process_existing_tests() + def get_input_tests(self) -> list[Test]: """ Returns the list of tests with input files. @@ -493,11 +515,11 @@ def get_test(self, test_id: str) -> Test: return test raise ValueError(f"Test with ID {test_id} not found.") - def get_tests_with_inputs(self) -> list[Test]: + def get_tests_with_inputs(self, tests: list[Test] = None) -> list[Test]: """ Returns the list of input tests. """ - return [test for test in self.tests if test.in_file is not None] + return [test for test in tests or self.tests if test.in_file is not None] def get_corresponding_out_filename(self, in_test: str) -> str: """ @@ -617,8 +639,8 @@ def get(conf) -> int: if f"{type}_limits" in conf: if test.test_id in conf[f"{type}_limits"]: return conf[f"{type}_limits"][test.test_id] - if test.group in conf[f"{type}_limits"]: - return conf[f"{type}_limits"][test.group] + if int(test.group) in conf[f"{type}_limits"]: + return conf[f"{type}_limits"][int(test.group)] if f"{type}_limit" in conf: return conf[f"{type}_limit"] return None diff --git a/src/sio3pack/test/test.py b/src/sio3pack/test/test.py index e6e3c64..2d5a555 100644 --- a/src/sio3pack/test/test.py +++ b/src/sio3pack/test/test.py @@ -18,3 +18,6 @@ def __init__(self, test_name: str, test_id: str, in_file: File, out_file: File, self.in_file = in_file self.out_file = out_file self.group = group + + def __repr__(self): + return f"" diff --git a/src/sio3pack/workflow/workflow.py b/src/sio3pack/workflow/workflow.py index ac3a249..84d9d09 100644 --- a/src/sio3pack/workflow/workflow.py +++ b/src/sio3pack/workflow/workflow.py @@ -1,3 +1,4 @@ +from sio3pack.files.file import File from sio3pack.workflow.object import Object, ObjectList, ObjectsManager from sio3pack.workflow.tasks import ExecutionTask, ScriptTask, Task @@ -160,7 +161,7 @@ def add_task(self, task: Task): """ self.tasks.append(task) - def get_prog_files(self) -> list[str]: + def get_prog_files(self) -> list[File]: """ Get all program files in the workflow. diff --git a/src/sio3pack/workflow/workflow_manager.py b/src/sio3pack/workflow/workflow_manager.py index 71c60e8..62dc875 100644 --- a/src/sio3pack/workflow/workflow_manager.py +++ b/src/sio3pack/workflow/workflow_manager.py @@ -87,7 +87,7 @@ def get_default(self, name: str) -> Workflow: return self._get_compile_python_workflow() return None - def get_prog_files(self) -> list[str]: + def get_prog_files(self) -> list[File]: """ Get all program files used in all graphs. """ diff --git a/tests/packages/sinolpack/test_utils.py b/tests/packages/sinolpack/test_utils.py index 4366d50..a6c91e5 100644 --- a/tests/packages/sinolpack/test_utils.py +++ b/tests/packages/sinolpack/test_utils.py @@ -62,11 +62,11 @@ def test_get_limits(get_package): "time_limit": 1000, "memory_limit": 1024, "time_limits": { - "1": 2000, + 1: 2000, "1a": 3000, }, "memory_limits": { - "1": 2048, + 1: 2048, "1a": 3072, }, "override_limits": { @@ -74,11 +74,11 @@ def test_get_limits(get_package): "time_limit": 5000, "memory_limit": 4096, "time_limits": { - "2": 6000, + 2: 6000, "2a": 7000, }, "memory_limits": { - "2": 4096, + 2: 4096, "2a": 5120, }, } diff --git a/tests/packages/sinolpack/test_workflows.py b/tests/packages/sinolpack/test_workflows.py index dc81bc6..956d775 100644 --- a/tests/packages/sinolpack/test_workflows.py +++ b/tests/packages/sinolpack/test_workflows.py @@ -306,7 +306,7 @@ def test_extra_files(get_package): workflow = workflows[0] print(workflow.external_objects) - assert len(workflow.external_objects) == 5 + assert len(workflow.external_objects) == 4 extlib_h = None extlib_py = None for obj in workflow.external_objects: @@ -315,7 +315,7 @@ def test_extra_files(get_package): elif obj.handle.endswith("extlib.py"): extlib_py = obj assert extlib_h is not None, "Should have extlib.h as external object" - assert extlib_py is not None, "Should have extlib.py as external object" + assert extlib_py is None, "Should not have extlib.py as external object" for task in workflow.tasks: if isinstance(task, ExecutionTask): @@ -333,14 +333,11 @@ def test_extra_files(get_package): proc = task.processes[0] assert "extlib.h" in proc.arguments, "Should have extlib.h in arguments" elif task.name.startswith("Run solution for test"): - assert task.filesystem_manager.len() == 2 - ext_fs = task.filesystem_manager.get_by_id(1) - assert isinstance(ext_fs, ObjectFilesystem), "Should have object filesystem with external file" - assert ext_fs.object.handle == extlib_py.handle, "Should have extlib.py as external file" + assert task.filesystem_manager.len() == 1 assert task.mountnamespace_manager.len() == 1, "Should have one mount namespace" assert ( - len(task.mountnamespace_manager.get_by_id(0).mountpoints) == 2 + len(task.mountnamespace_manager.get_by_id(0).mountpoints) == 1 ), "Should have two mount points" # Check that python compilation doesnt have extlib.h in compilation args. diff --git a/tests/test_packages/extra_files/config.yml b/tests/test_packages/extra_files/config.yml index 305355f..91c7f21 100644 --- a/tests/test_packages/extra_files/config.yml +++ b/tests/test_packages/extra_files/config.yml @@ -3,5 +3,7 @@ extra_compilation_files: ['extlib.h'] extra_compilation_args: cpp: - 'extlib.h' -extra_execution_files: ['extlib.py'] +extra_execution_files: + py: + - 'extlib.py' extra_files: ['dir/some_file.txt']