style: force parser.with be a BaseModel
All checks were successful
build / build (push) Successful in 2m37s
build / build (pull_request) Successful in 2m35s

This commit is contained in:
张泊明518370910136 2025-03-04 21:00:21 -05:00
parent 53819e63a2
commit 25da08ecfc
GPG Key ID: D47306D7062CDA9D
4 changed files with 52 additions and 43 deletions

View File

@ -1,6 +1,6 @@
from typing import Any, Dict, List, Optional, Union from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
from pydantic import BaseModel, Field from pydantic import BaseModel, ConfigDict, Field, field_validator
from joj3_config_generator.models.const import ( from joj3_config_generator.models.const import (
DEFAULT_CPU_LIMIT, DEFAULT_CPU_LIMIT,
@ -105,18 +105,34 @@ class OptionalCmd(BaseModel):
class ExecutorWith(BaseModel): class ExecutorWith(BaseModel):
default: Cmd default: Cmd = Cmd()
cases: List[OptionalCmd] cases: List[OptionalCmd] = []
class Executor(BaseModel): class Executor(BaseModel):
name: str name: str
with_: ExecutorWith = Field(..., serialization_alias="with") with_: ExecutorWith = Field(ExecutorWith(), serialization_alias="with")
class Parser(BaseModel): class Parser(BaseModel):
name: str name: str
with_: Dict[str, Any] = Field(..., serialization_alias="with") if TYPE_CHECKING:
class Empty(BaseModel):
pass
with_: BaseModel = Field(Empty(), serialization_alias="with")
else:
with_: Dict[str, Any] = Field({}, serialization_alias="with")
model_config = ConfigDict(validate_assignment=True)
@field_validator("with_", mode="before")
@classmethod
def validate_with(cls, v: Any) -> Dict[str, Any]:
if isinstance(v, BaseModel):
return v.model_dump(by_alias=True)
raise ValueError(f"Must be a BaseModel instance")
class StageDetail(BaseModel): class StageDetail(BaseModel):
@ -200,3 +216,11 @@ class DiffCasesConfig(BaseModel):
class DiffConfig(BaseModel): class DiffConfig(BaseModel):
name: str = "diff" name: str = "diff"
cases: List[DiffCasesConfig] = [] cases: List[DiffCasesConfig] = []
class MsgConfig(BaseModel):
msg: str = ""
class ScoreConfig(BaseModel):
score: int = 0

View File

@ -2,7 +2,7 @@ from datetime import datetime, timedelta
from pathlib import Path from pathlib import Path
from typing import Any, Dict, List, Type from typing import Any, Dict, List, Type
from pydantic import BaseModel, Field, field_validator, model_validator from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
from joj3_config_generator.models.common import Memory, Time from joj3_config_generator.models.common import Memory, Time
from joj3_config_generator.models.const import ( from joj3_config_generator.models.const import (
@ -63,6 +63,8 @@ class Limit(BaseModel):
stderr: int = DEFAULT_FILE_LIMIT stderr: int = DEFAULT_FILE_LIMIT
stdout: int = DEFAULT_FILE_LIMIT stdout: int = DEFAULT_FILE_LIMIT
model_config = ConfigDict(validate_assignment=True)
@field_validator("cpu", mode="before") @field_validator("cpu", mode="before")
@classmethod @classmethod
def ensure_time(cls, v: Any) -> Time: def ensure_time(cls, v: Any) -> Time:
@ -100,7 +102,7 @@ class Stage(BaseModel):
cases: Dict[str, "Stage"] = {} cases: Dict[str, "Stage"] = {}
diff: ParserDiff = ParserDiff() diff: ParserDiff = ParserDiff()
model_config = {"extra": "allow"} model_config = ConfigDict(extra="allow")
@model_validator(mode="before") @model_validator(mode="before")
@classmethod @classmethod

View File

@ -29,7 +29,7 @@ def get_teapot_stage(repo_conf: repo.Config) -> result.StageDetail:
cases=[], cases=[],
), ),
), ),
parsers=[result.Parser(name="log", with_={"msg": "joj3 summary"})], parsers=[result.Parser(name="log", with_=result.MsgConfig(msg="joj3 summary"))],
) )
return stage_conf return stage_conf
@ -87,8 +87,8 @@ def get_health_check_stage(repo_conf: repo.Config) -> result.StageDetail:
), ),
), ),
parsers=[ parsers=[
result.Parser(name="healthcheck", with_={"score": 1}), result.Parser(name="healthcheck", with_=result.ScoreConfig(score=1)),
result.Parser(name="debug", with_={"score": 0}), result.Parser(name="debug", with_=result.ScoreConfig(score=0)),
], ],
) )
return health_check_stage return health_check_stage

View File

@ -24,9 +24,7 @@ def get_conf_stage(
name="sandbox", name="sandbox",
with_=get_executor_with(task_stage, cached), with_=get_executor_with(task_stage, cached),
), ),
parsers=( parsers=([result.Parser(name=parser) for parser in task_stage.parsers]),
[result.Parser(name=parser, with_={}) for parser in task_stage.parsers]
),
) )
processed_dict = get_processed_dict(task_stage) processed_dict = get_processed_dict(task_stage)
for idx, parser in enumerate(task_stage.parsers): for idx, parser in enumerate(task_stage.parsers):
@ -108,11 +106,7 @@ def fix_keyword(
else: else:
continue continue
keyword_parser.with_.update( keyword_parser.with_ = result.KeywordMatchConfig(matches=keyword_weight)
result.KeywordMatchConfig(
matches=keyword_weight,
).model_dump(by_alias=True)
)
def fix_result_detail( def fix_result_detail(
@ -124,15 +118,13 @@ def fix_result_detail(
show_files.append("stdout") show_files.append("stdout")
if result_detail_parser_config.stderr: if result_detail_parser_config.stderr:
show_files.append("stderr") show_files.append("stderr")
result_detail_parser.with_.update( result_detail_parser.with_ = result.ResultDetailConfig(
result.ResultDetailConfig(
score=0, score=0,
comment="", comment="",
show_files=show_files, show_files=show_files,
show_exit_status=result_detail_parser_config.exitstatus, show_exit_status=result_detail_parser_config.exitstatus,
show_runtime=result_detail_parser_config.time, show_runtime=result_detail_parser_config.time,
show_memory=result_detail_parser_config.mem, show_memory=result_detail_parser_config.mem,
).model_dump(by_alias=True)
) )
@ -140,20 +132,15 @@ def fix_dummy(
dummy_parser_config: task.ParserDummy, dummy_parser: result.Parser dummy_parser_config: task.ParserDummy, dummy_parser: result.Parser
) -> None: ) -> None:
# we don't use dummy parser in real application # we don't use dummy parser in real application
dummy_parser.with_.update( dummy_parser.with_ = result.DummyConfig(
result.DummyConfig(
score=dummy_parser_config.score, score=dummy_parser_config.score,
comment=dummy_parser_config.comment, comment=dummy_parser_config.comment,
force_quit_on_not_accepted=dummy_parser_config.force_quit, force_quit_on_not_accepted=dummy_parser_config.force_quit,
).model_dump(by_alias=True)
) )
return
def fix_file(file_parser_config: task.ParserFile, file_parser: result.Parser) -> None: def fix_file(file_parser_config: task.ParserFile, file_parser: result.Parser) -> None:
file_parser.with_.update( file_parser.with_ = result.FileConfig(name=file_parser_config.name)
result.FileConfig(name=file_parser_config.name).model_dump(by_alias=True)
)
def fix_diff( def fix_diff(
@ -216,9 +203,5 @@ def fix_diff(
) )
) )
diff_parser_config.with_.update(
result.DiffConfig(name="diff", cases=parser_cases).model_dump(by_alias=True)
)
diff_executor.with_.cases = stage_cases diff_executor.with_.cases = stage_cases
diff_parser_config.with_ = result.DiffConfig(name="diff", cases=parser_cases)
return