dev #10

Merged
李衍志523370910113 merged 238 commits from dev into master 2025-03-05 16:20:39 +08:00
16 changed files with 81 additions and 70 deletions
Showing only changes of commit 82fa325cf6 - Show all commits

View File

@ -1,4 +1,6 @@
import os
from datetime import datetime
from pathlib import Path
from typing import List
from joj3_config_generator.models import joj1, repo, result, task
@ -29,6 +31,11 @@ def convert(repo_conf: repo.Config, task_conf: task.Config) -> result.Config:
if task_conf.release.end_time
else -1
jon-lee marked this conversation as resolved Outdated

Make this Path.home() default to /home/tt. For now, create a const for this dir.

Make this `Path.home()` default to `/home/tt`. For now, create a const for this dir.

fixed

fixed
),
effective_unix_timestamp=(
int(task_conf.release.begin_time.timestamp())
if task_conf.release.begin_time
else -1
jon-lee marked this conversation as resolved Outdated

where is it used?

where is it used?

this should be storing all the files that are about to be copy in or out

this should be storing all the files that are about to be copy in or out

It is as the input and output for the following functions about parsers

It is as the input and output for the following functions about parsers

so this feature is not implemented?

so this feature is not implemented?
    if not repo_conf.force_skip_health_check_on_test or not current_test:
        result_conf.stage.stages.append(get_health_check_config(repo_conf))
    cached: List[str] = []
    # Convert each stage in the task configuration
    for task_stage in task_conf.stages:
        executor_with_config, cached = get_executor_with_config(task_stage, cached)
        conf_stage = get_conf_stage(task_stage, executor_with_config)
        conf_stage = fix_result_detail(task_stage, conf_stage)
        conf_stage = fix_dummy(task_stage, conf_stage)
        conf_stage = fix_keyword(task_stage, conf_stage)
        conf_stage = fix_file(task_stage, conf_stage)
        conf_stage = fix_diff(task_stage, conf_stage, task_conf)
        result_conf.stage.stages.append(conf_stage)

it is

    for task_stage in task_conf.stages:
        executor_with_config, cached = get_executor_with_config(task_stage, cached)

this is a loop, so this cached will be updated in every round of stage

```python if not repo_conf.force_skip_health_check_on_test or not current_test: result_conf.stage.stages.append(get_health_check_config(repo_conf)) cached: List[str] = [] # Convert each stage in the task configuration for task_stage in task_conf.stages: executor_with_config, cached = get_executor_with_config(task_stage, cached) conf_stage = get_conf_stage(task_stage, executor_with_config) conf_stage = fix_result_detail(task_stage, conf_stage) conf_stage = fix_dummy(task_stage, conf_stage) conf_stage = fix_keyword(task_stage, conf_stage) conf_stage = fix_file(task_stage, conf_stage) conf_stage = fix_diff(task_stage, conf_stage, task_conf) result_conf.stage.stages.append(conf_stage) ``` it is ```python for task_stage in task_conf.stages: executor_with_config, cached = get_executor_with_config(task_stage, cached) ``` this is a loop, so this `cached` will be updated in every round of stage

The return value is unnecessary.

The return value is unnecessary.

I have a lazing coding style here, everything has get imported would get exported, so should maintain this until the end of the loop. Everything is exported in previous stage would be imported in the next stage.

I have a lazing coding style here, everything has get imported would get exported, so should maintain this until the end of the loop. Everything is exported in previous stage would be imported in the next stage.
  1. The return value is unnecessary
  2. It should be a set
1. The return value is unnecessary 2. It should be a `set`

try it yourself

try it yourself

I see why

I see why

resolved.

resolved.
),
actor_csv_path="/home/tt/.config/joj/students.csv", # students.csv position
max_total_score=repo_conf.max_total_score,
stage=result.Stage(
@ -62,9 +69,11 @@ def convert(repo_conf: repo.Config, task_conf: task.Config) -> result.Config:
def convert_joj1(joj1_conf: joj1.Config) -> task.Config:
stages = [get_joj1_run_stage(joj1_conf)]
return task.Config(
root=Path(""),
path=Path(""),
task=task.Task(
name=(""),
),
release=task.Release(end_time=None, begin_time=None),
release=task.Release(end_time=datetime.now(), begin_time=datetime.now()),
stages=stages,
)

View File

@ -1,6 +1,6 @@
from datetime import datetime
jon-lee marked this conversation as resolved Outdated

every field in this file should not be optional. we give an default value here if any field does not exist

every field in this file should not be optional. we give an default value here if any field does not exist

and use underscore naming in this file

and use underscore naming in this file

every field in this file should not be optional. we give an default value here if any field does not exist

fixed

> every field in this file should not be optional. we give an default value here if any field does not exist fixed

and use underscore naming in this file

fixed.

> and use underscore naming in this file fixed.
from pathlib import Path
from typing import Any, Dict, List, Optional, Type
from typing import Any, Dict, List, Type
from pydantic import BaseModel, Field, field_validator, model_validator
@ -13,48 +13,48 @@ from joj3_config_generator.models.const import (
class ParserResultDetail(BaseModel):
time: Optional[bool] = True # Display run time
mem: Optional[bool] = True # Display memory usage
stdout: Optional[bool] = False # Display stdout messages
stderr: Optional[bool] = False # Display stderr messages
exitstatus: Optional[bool] = False
time: bool = True # Display run time
mem: bool = True # Display memory usage
stdout: bool = False # Display stdout messages
stderr: bool = False # Display stderr messages
exitstatus: bool = False
class ParserFile(BaseModel):
name: Optional[str] = None
name: str = ""
class ParserLog(BaseModel):
fileName: Optional[str] = None
msg: Optional[str] = None
level: Optional[str] = None
file_name: str = Field("", alias="fileName")
msg: str = ""
level: str = ""
class ParserDummy(BaseModel):
comment: Optional[str] = ""
score: Optional[int] = 0
forcequit: Optional[bool] = False
comment: str = ""
score: int = 0
forcequit: bool = False
class ParserKeyword(BaseModel):
keyword: Optional[List[str]] = []
weight: Optional[List[int]] = []
keyword: List[str] = []
weight: List[int] = []
class Outputs(BaseModel):
score: Optional[int] = 0
ignorespaces: Optional[bool] = True
hide: Optional[bool] = False
forcequit: Optional[bool] = False
score: int = 0
ignorespaces: bool = True
hide: bool = False
forcequit: bool = False
class ParserDiff(BaseModel):
output: Optional[Outputs] = Outputs()
output: Outputs = Outputs()
class Files(BaseModel):
import_: Optional[List[str]] = Field([], alias="import")
export: Optional[List[str]] = []
import_: List[str] = Field([], alias="import")
export: List[str] = []
class Limit(BaseModel):
@ -75,30 +75,30 @@ class Limit(BaseModel):
class Stage(BaseModel):
name: Optional[str] = None # Stage name
env: Optional[List[str]] = None
command: Optional[str] = None # Command to run
files: Optional[Files] = None
in_: Optional[str] = Field(None, alias="in")
out_: Optional[str] = Field(None, alias="out")
score: Optional[int] = 0
parsers: Optional[List[str]] = [] # list of parsers
name: str = "" # Stage name
env: List[str] = []
command: str = "" # Command to run
files: Files = Files()
in_: str = Field("", alias="in")
out_: str = Field("", alias="out")
score: int = 0
parsers: List[str] = [] # list of parsers
jon-lee marked this conversation as resolved Outdated

deprecated

deprecated

@bomingzh any suggestions on the structure?

@bomingzh any suggestions on the structure?
PydanticDeprecatedSince20: Support for class-based `config` is deprecated, use ConfigDict instead. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.9/migration/
``` PydanticDeprecatedSince20: Support for class-based `config` is deprecated, use ConfigDict instead. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.9/migration/ ```

fixed with model_config

fixed with `model_config`

str here need to be a StrEnum now.

str here need to be a `StrEnum` now.

But I guess we don't know the set of case in advance, making it dynamic StrEnum is meaningless

But I guess we don't know the set of case in advance, making it dynamic `StrEnum` is meaningless

line changed, the comment is for parsers

line changed, the comment is for `parsers`
limit: Limit = Limit()
dummy: Optional[ParserDummy] = ParserDummy()
result_status: Optional[ParserDummy] = Field(ParserDummy(), alias="result-status")
keyword: Optional[ParserKeyword] = ParserKeyword()
clangtidy: Optional[ParserKeyword] = ParserKeyword()
cppcheck: Optional[ParserKeyword] = ParserKeyword()
cpplint: Optional[ParserKeyword] = ParserKeyword()
result_detail: Optional[ParserResultDetail] = Field(
dummy: ParserDummy = ParserDummy()
jon-lee marked this conversation as resolved Outdated

this should be the StrEnum

this should be the `StrEnum`

It is supported now.

It is supported now.
result_status: ParserDummy = Field(ParserDummy(), alias="result-status")
keyword: ParserKeyword = ParserKeyword()
clangtidy: ParserKeyword = ParserKeyword()
cppcheck: ParserKeyword = ParserKeyword()
cpplint: ParserKeyword = ParserKeyword()
result_detail: ParserResultDetail = Field(
ParserResultDetail(), alias="result-detail"
)
file: Optional[ParserFile] = ParserFile()
skip: Optional[List[str]] = []
file: ParserFile = ParserFile()
skip: List[str] = []
# cases related
cases: Optional[Dict[str, "Stage"]] = None
diff: Optional[ParserDiff] = ParserDiff()
cases: Dict[str, "Stage"] = {}
jon-lee marked this conversation as resolved Outdated

begin_time and end_time to make them match

`begin_time` and `end_time` to make them match

resolved

resolved
diff: ParserDiff = ParserDiff()
model_config = {"extra": "allow"}
@ -113,20 +113,18 @@ class Stage(BaseModel):
class Release(BaseModel):
end_time: Optional[datetime] = None # RFC 3339 formatted date-time with offset
begin_time: Optional[datetime] = None
end_time: datetime = datetime.now() # RFC 3339 formatted date-time with offset
begin_time: datetime = datetime.now() # RFC 3339 formatted date-time with offset
class Task(BaseModel):
type_: Optional[str] = Field(
"", serialization_alias="type", validation_alias="type"
)
type_: str = Field("", serialization_alias="type", validation_alias="type")
name: str
class Config(BaseModel):
root: Optional[Path] = None
path: Optional[Path] = None
root: Path = Path(".")
path: Path = Path("task.toml")
task: Task # Task name (e.g., hw3 ex5)
release: Release # Release configuration
stages: List[Stage] # list of stage configurations

View File

@ -9,7 +9,7 @@ def get_joj1_run_stage(joj1_config: joj1.Config) -> task.Stage:
cases_conf.append(
task.Stage(
score=case.score,
command=case.execute_args if case.execute_args else None,
command=case.execute_args if case.execute_args else "",
limit=task.Limit(
cpu=Time(case.time) if case.time else DEFAULT_CPU_LIMIT,
mem=(Memory(case.memory) if case.memory else DEFAULT_MEMORY_LIMIT),

View File

@ -207,8 +207,8 @@ def fix_diff(
clock_limit = 2 * case_stage.limit.cpu
memory_limit = case_stage.limit.mem
command = case_stage.command if case_stage.command is not None else None
stdin = case_stage.in_ if case_stage.in_ is not None else f"{case}.in"
stdout = case_stage.out_ if case_stage.out_ is not None else f"{case}.out"
stdin = case_stage.in_ if case_stage.in_ != "" else f"{case}.in"
stdout = case_stage.out_ if case_stage.out_ != "" else f"{case}.out"
jon-lee marked this conversation as resolved Outdated

Create models for these dicts, then update them with the dict from model_dump

Create models for these dicts, then update them with the dict from `model_dump`

@bomingzh I don't think we can change it. This is to make proper alias so that we can get the content of result-status.

@bomingzh I don't think we can change it. This is to make proper alias so that we can get the content of `result-status`.
class DummyConfig(BaseModel):
    score: int
    comment: str

Then dummy_parser_.with_.update(dummy_config(...).model_dump()).

``` class DummyConfig(BaseModel): score: int comment: str ``` Then `dummy_parser_.with_.update(dummy_config(...).model_dump())`.

fixed

fixed
stage_cases.append(
result.OptionalCmd(

View File

@ -1,8 +1,8 @@
{
"name": "hw7 ex2",
"logPath": "/home/tt/.cache/joj3/homework/h7/e2.log",
"expireUnixTimestamp": -1,
"effectiveUnixTimestamp": -1,
"expireUnixTimestamp": 1735574399,
"effectiveUnixTimestamp": 1735487999,
"actorCsvPath": "/home/tt/.config/joj/students.csv",
"maxTotalScore": 100,
"stage": {
@ -660,6 +660,7 @@
},
"cases": [
{
"args": [],
"stdin": {
"src": "/home/tt/.config/joj/homework/h7/e2/case0.in"
},
@ -669,6 +670,7 @@
"procLimit": 50
},
{
"args": [],
"stdin": {
"src": "/home/tt/.config/joj/homework/h7/e2/case1.in"
},

View File

@ -2,7 +2,7 @@
task.name = "hw7 ex2" # task name
task.type = "homework/h7/e2" # remove this task type later
release.deadline = 2024-12-30 23:59:59+08:00
release.end_time = 2024-12-30 23:59:59+08:00
release.begin_time = 2024-12-29 23:59:59+08:00
[[stages]]

View File

@ -1,8 +1,8 @@
{
"name": "hw7 ex2",
"logPath": "/home/tt/.cache/joj3/homework/h7/e2.log",
"expireUnixTimestamp": -1,
"effectiveUnixTimestamp": -1,
"expireUnixTimestamp": 1735574399,
"effectiveUnixTimestamp": 1735487999,
"actorCsvPath": "/home/tt/.config/joj/students.csv",
"maxTotalScore": 100,
"stage": {

View File

@ -2,7 +2,7 @@
task.name = "hw7 ex2" # task name
task.type = "homework/h7/e2" # remove this task type later
release.deadline = 2024-12-30 23:59:59+08:00
release.end_time = 2024-12-30 23:59:59+08:00
release.begin_time = 2024-12-29 23:59:59+08:00
[[stages]]

View File

@ -1,8 +1,8 @@
{
"name": "hw7 ex2",
"logPath": "/home/tt/.cache/joj3/homework/h7/e2.log",
"expireUnixTimestamp": -1,
"effectiveUnixTimestamp": -1,
"expireUnixTimestamp": 1735574399,
"effectiveUnixTimestamp": 1735487999,
"actorCsvPath": "/home/tt/.config/joj/students.csv",
"maxTotalScore": 100,
"stage": {

View File

@ -2,7 +2,7 @@
task.name = "hw7 ex2" # task name
task.type = "homework/h7/e2" # remove this task type later
release.deadline = 2024-12-30 23:59:59+08:00
release.end_time = 2024-12-30 23:59:59+08:00
release.begin_time = 2024-12-29 23:59:59+08:00
[[stages]]

View File

@ -1,8 +1,8 @@
{
"name": "hw7 ex2",
"logPath": "/home/tt/.cache/joj3/homework/h7/e2.log",
"expireUnixTimestamp": -1,
"effectiveUnixTimestamp": -1,
"expireUnixTimestamp": 1735574399,
"effectiveUnixTimestamp": 1735487999,
"actorCsvPath": "/home/tt/.config/joj/students.csv",
"maxTotalScore": 100,
"stage": {

View File

@ -2,7 +2,7 @@
task.name = "hw7 ex2" # task name
task.type = "homework/h7/e2" # remove this task type later
release.deadline = 2024-12-30 23:59:59+08:00
release.end_time = 2024-12-30 23:59:59+08:00
release.begin_time = 2024-12-29 23:59:59+08:00
[[stages]]

View File

@ -1,8 +1,8 @@
{
"name": "hw7 ex2",
"logPath": "/home/tt/.cache/joj3/homework/h7/e2.log",
"expireUnixTimestamp": -1,
"effectiveUnixTimestamp": -1,
"expireUnixTimestamp": 1735574399,
"effectiveUnixTimestamp": 1735487999,
"actorCsvPath": "/home/tt/.config/joj/students.csv",
"maxTotalScore": 100,
"stage": {
@ -63,6 +63,7 @@
},
"cases": [
{
"args": [],
"stdin": {
"src": "/home/tt/.config/joj/homework/h7/e2/case0.in"
},
@ -72,6 +73,7 @@
"procLimit": 50
},
{
"args": [],
"stdin": {
"src": "/home/tt/.config/joj/homework/h7/e2/case1.in"
},

View File

@ -2,7 +2,7 @@
task.name = "hw7 ex2" # task name
task.type = "homework/h7/e2" # remove this task type later
release.deadline = 2024-12-30 23:59:59+08:00
release.end_time = 2024-12-30 23:59:59+08:00
release.begin_time = 2024-12-29 23:59:59+08:00
[[stages]]

View File

@ -1,8 +1,8 @@
{
"name": "hw7 ex2",
"logPath": "/home/tt/.cache/joj3/homework/h7/e2.log",
"expireUnixTimestamp": -1,
"effectiveUnixTimestamp": -1,
"expireUnixTimestamp": 1735574399,
"effectiveUnixTimestamp": 1735487999,
"actorCsvPath": "/home/tt/.config/joj/students.csv",
"maxTotalScore": 100,
"stage": {

View File

@ -2,7 +2,7 @@
task.name = "hw7 ex2" # task name
task.type = "homework/h7/e2" # remove this task type later
release.deadline = 2024-12-30 23:59:59+08:00
release.end_time = 2024-12-30 23:59:59+08:00
release.begin_time = 2024-12-29 23:59:59+08:00
[[stages]]