From e615bc23bbd6a42fbda5f53f8de12b8e9cfa6ba9 Mon Sep 17 00:00:00 2001 From: Imogen Date: Tue, 26 Dec 2023 19:59:28 +0100 Subject: [PATCH 1/4] fix minor typing issues --- algobattle/problem.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/algobattle/problem.py b/algobattle/problem.py index 65cabace..05236502 100644 --- a/algobattle/problem.py +++ b/algobattle/problem.py @@ -20,6 +20,7 @@ overload, cast, get_args, + runtime_checkable, ) from math import inf, isnan from annotated_types import GroupedMetadata @@ -132,6 +133,7 @@ def maximize(function: Callable[P, float]) -> Callable[P, float]: _S = TypeVar("_S", bound=Solution[Instance], contravariant=True) +@runtime_checkable class ScoreFunctionWithSol(Protocol, Generic[_I, _S]): """Type of `score` function passed to Problem if `with_solution` is set.""" @@ -150,6 +152,7 @@ def __call__(self, instance: _I, *, generator_solution: _S, solver_solution: _S) ... +@runtime_checkable class ScoreFunctionNoSol(Protocol, Generic[_I, _S]): """Type of `score` function passed to Problem if `with_solution` is not set.""" @@ -517,9 +520,9 @@ def __get_pydantic_core_schema__(cls, source: type[BaseModel], handler: GetCoreS if cls._validate_with_self(model_type): def validate_with_self(input: object, validate: ValidatorFunctionWrapHandler, info: ValidationInfo) -> Self: - self = validate(input) + self: Self = validate(input) if info.context is None or "self" not in info.context: - self = cls.model_validate(input, context=(info.context or {}) | {"self": self, model_type: self}) + self = cast(Self, cls.model_validate(input, context=(info.context or {}) | {"self": self, model_type: self})) return self schema = with_info_wrap_validator_function(validate_with_self, schema) From 86a9fd6935ff310bd6d8347b8c304de5bff0e117 Mon Sep 17 00:00:00 2001 From: Imogen Date: Tue, 26 Dec 2023 20:20:44 +0100 Subject: [PATCH 2/4] make exception thrown when docker not running an algobattle exception --- algobattle/program.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/algobattle/program.py b/algobattle/program.py index e836cee8..3ba32b80 100644 --- a/algobattle/program.py +++ b/algobattle/program.py @@ -55,7 +55,7 @@ def client() -> DockerClient: else: _client_var.ping() except (DockerException, APIError): - raise SystemExit("Could not connect to the docker daemon. Is docker running?") + raise DockerError("Could not connect to the docker daemon. Is docker running?") return _client_var From 5272516a854bf3eaa8668892ea8619eeb56a87f0 Mon Sep 17 00:00:00 2001 From: Imogen Date: Tue, 26 Dec 2023 20:50:41 +0100 Subject: [PATCH 3/4] dont catch DockerNotRunning in intermediate layers, on at the cli --- algobattle/cli.py | 7 +++++-- algobattle/program.py | 3 ++- algobattle/util.py | 4 ++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/algobattle/cli.py b/algobattle/cli.py index c97e1532..9535961c 100644 --- a/algobattle/cli.py +++ b/algobattle/cli.py @@ -52,7 +52,7 @@ from algobattle.match import AlgobattleConfig, EmptyUi, Match, MatchConfig, MatchupStr, Ui, ProjectConfig from algobattle.problem import Instance, Problem, Solution from algobattle.program import Generator, Matchup, Solver -from algobattle.util import BuildError, EncodableModel, ExceptionInfo, Role, RunningTimer, BaseModel, TempDir, timestamp +from algobattle.util import BuildError, DockerNotRunning, EncodableModel, ExceptionInfo, Role, RunningTimer, BaseModel, TempDir, timestamp from algobattle.templates import Language, PartialTemplateArgs, TemplateArgs, write_problem_template, write_templates @@ -170,11 +170,14 @@ def run_match( try: with CliUi() if ui else EmptyUi() as ui_obj: run_async_fn(result.run, config, ui_obj) + except DockerNotRunning: + console.print("[error]Could not connect to the Docker Daemon.[/] Is Docker running?") + save = False except KeyboardInterrupt: console.print("[error]Stopping match execution") finally: try: - if config.project.points > 0: + if config.project.points > 0 and result.active_teams: points = result.calculate_points(config.project.points) leaderboard = Table( Column("Team", justify="center"), diff --git a/algobattle/program.py b/algobattle/program.py index 3ba32b80..9788dae1 100644 --- a/algobattle/program.py +++ b/algobattle/program.py @@ -28,6 +28,7 @@ from algobattle.util import ( BuildError, DockerError, + DockerNotRunning, Encodable, EncodingError, ExceptionInfo, @@ -55,7 +56,7 @@ def client() -> DockerClient: else: _client_var.ping() except (DockerException, APIError): - raise DockerError("Could not connect to the docker daemon. Is docker running?") + raise DockerNotRunning return _client_var diff --git a/algobattle/util.py b/algobattle/util.py index f7691eaa..f093972d 100644 --- a/algobattle/util.py +++ b/algobattle/util.py @@ -182,6 +182,10 @@ class DockerError(AlgobattleBaseException): """Indicates that an issue with the docker daemon occured.""" +class DockerNotRunning(BaseException): + """Indicates that the Docker Daemon is not running.""" + + class ExceptionInfo(BaseModel): """Details about an exception that was raised.""" From 0dcf51b616a5862c4d7fecfca99685bc73455e87 Mon Sep 17 00:00:00 2001 From: Imogen Date: Tue, 26 Dec 2023 20:51:46 +0100 Subject: [PATCH 4/4] format --- algobattle/cli.py | 12 +++++++++++- algobattle/problem.py | 4 +++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/algobattle/cli.py b/algobattle/cli.py index 9535961c..da371128 100644 --- a/algobattle/cli.py +++ b/algobattle/cli.py @@ -52,7 +52,17 @@ from algobattle.match import AlgobattleConfig, EmptyUi, Match, MatchConfig, MatchupStr, Ui, ProjectConfig from algobattle.problem import Instance, Problem, Solution from algobattle.program import Generator, Matchup, Solver -from algobattle.util import BuildError, DockerNotRunning, EncodableModel, ExceptionInfo, Role, RunningTimer, BaseModel, TempDir, timestamp +from algobattle.util import ( + BuildError, + DockerNotRunning, + EncodableModel, + ExceptionInfo, + Role, + RunningTimer, + BaseModel, + TempDir, + timestamp, +) from algobattle.templates import Language, PartialTemplateArgs, TemplateArgs, write_problem_template, write_templates diff --git a/algobattle/problem.py b/algobattle/problem.py index 05236502..6d19f7a7 100644 --- a/algobattle/problem.py +++ b/algobattle/problem.py @@ -522,7 +522,9 @@ def __get_pydantic_core_schema__(cls, source: type[BaseModel], handler: GetCoreS def validate_with_self(input: object, validate: ValidatorFunctionWrapHandler, info: ValidationInfo) -> Self: self: Self = validate(input) if info.context is None or "self" not in info.context: - self = cast(Self, cls.model_validate(input, context=(info.context or {}) | {"self": self, model_type: self})) + self = cast( + Self, cls.model_validate(input, context=(info.context or {}) | {"self": self, model_type: self}) + ) return self schema = with_info_wrap_validator_function(validate_with_self, schema)