Skip to content

Commit 9455682

Browse files
committed
Move from black/isort to ruff linting
1 parent fb84f4f commit 9455682

23 files changed

Lines changed: 464 additions & 390 deletions

File tree

.pre-commit-config.yaml

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
ci:
2+
autoupdate_commit_msg: "chore: update pre-commit hooks"
3+
14
repos:
25
- repo: https://github.com/pre-commit/pre-commit-hooks
3-
rev: v4.4.0
6+
rev: v6.0.0
47
hooks:
58
- id: trailing-whitespace
69
- id: end-of-file-fixer
@@ -9,14 +12,24 @@ repos:
912
- id: check-merge-conflict
1013
- id: debug-statements
1114

12-
- repo: https://github.com/psf/black
13-
rev: 23.3.0
15+
- repo: https://github.com/crate-ci/typos
16+
rev: v1
17+
hooks:
18+
- id: typos
19+
files: \.(py|md|rst|yaml|toml)
20+
exclude: pyproject.toml
21+
22+
- repo: https://github.com/astral-sh/ruff-pre-commit
23+
rev: v0.12.10
1424
hooks:
15-
- id: black
16-
language_version: python3
25+
# Run the linter.
26+
- id: ruff
27+
args: ["--fix"]
28+
# Run the formatter.
29+
- id: ruff-format
1730

18-
- repo: https://github.com/pycqa/isort
19-
rev: 5.12.0
31+
- repo: https://github.com/pre-commit/mirrors-prettier
32+
rev: "v4.0.0-alpha.8" # Use the sha or tag you want to point at
2033
hooks:
21-
- id: isort
22-
args: ["--profile", "black"]
34+
- id: prettier
35+
types_or: ["javascript", "css"]

codeclash/agents/__init__.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@
66
from codeclash.agents.utils import GameContext
77

88

9-
def get_agent(
10-
config: dict, game_context: GameContext, environment: DockerEnvironment
11-
) -> Player:
9+
def get_agent(config: dict, game_context: GameContext, environment: DockerEnvironment) -> Player:
1210
agents = {
1311
"dummy": Dummy,
1412
"mini": MiniSWEAgent,

codeclash/agents/abstract.py

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def __init__(
2424
self.config = config
2525
self.name = config["name"]
2626
self._player_unique_id = uuid.uuid4()
27-
"""Unique ID that doesn't clash even accross multiple games. Used for git tags."""
27+
"""Unique ID that doesn't clash even across multiple games. Used for git tags."""
2828
self.environment = environment
2929
self.game_context = game_context
3030
self.logger = get_logger(
@@ -51,9 +51,7 @@ def post_run_hook(self, *, round: int) -> None:
5151
"""Should be called after we called the run method."""
5252
self._commit()
5353
self._metadata["diff"][round] = self._get_round_diff(round)
54-
self._metadata["incremental_diff"][round] = self._get_round_diff(
55-
round, incremental=True
56-
)
54+
self._metadata["incremental_diff"][round] = self._get_round_diff(round, incremental=True)
5755

5856
@abstractmethod
5957
def run(self) -> None:
@@ -76,23 +74,15 @@ def push(self) -> None:
7674
"git push origin --tags",
7775
]:
7876
assert_zero_exit_code(self.environment.execute(cmd), logger=self.logger)
79-
self.logger.info(
80-
f"Pushed {self.name} commit history to remote repository (branch {self._branch_name})"
81-
)
77+
self.logger.info(f"Pushed {self.name} commit history to remote repository (branch {self._branch_name})")
8278

83-
def reset_and_apply_patch(
84-
self, patch: str, *, base_commit: str = "", filter_patch: bool = True
85-
) -> None:
86-
"""Clean all uncommited changes. If base_commit is provided, reset to that commit.
79+
def reset_and_apply_patch(self, patch: str, *, base_commit: str = "", filter_patch: bool = True) -> None:
80+
"""Clean all uncommitted changes. If base_commit is provided, reset to that commit.
8781
Then apply the patch to the codebase.
8882
"""
8983
# Need to clean before we copy over the patch (else it's gonna be removed by git clean)
9084
self.logger.debug(
91-
assert_zero_exit_code(
92-
self.environment.execute(
93-
f"git reset --hard {base_commit} && git clean -fd"
94-
)
95-
)
85+
assert_zero_exit_code(self.environment.execute(f"git reset --hard {base_commit} && git clean -fd"))
9686
)
9787

9888
patch = filter_git_diff(patch) if filter_patch else patch
@@ -112,19 +102,15 @@ def reset_and_apply_patch(
112102
commands = ["git status", "git apply tmp_patch.txt", "rm -f tmp_patch.txt"]
113103
for cmd in commands:
114104
self.logger.debug(f"Executing command: {cmd}")
115-
out = assert_zero_exit_code(
116-
self.environment.execute(cmd), logger=self.logger
117-
)
105+
out = assert_zero_exit_code(self.environment.execute(cmd), logger=self.logger)
118106
self.logger.debug(out)
119107

120108
# --- Helper methods ---
121109

122110
def _tag_round(self, round: int) -> None:
123111
"""Git tag the codebase at the given round."""
124112
assert_zero_exit_code(
125-
self.environment.execute(
126-
f"git tag -a {self._get_round_tag_name(round)} -m 'Round {round} Update'"
127-
),
113+
self.environment.execute(f"git tag -a {self._get_round_tag_name(round)} -m 'Round {round} Update'"),
128114
logger=self.logger,
129115
)
130116

@@ -161,9 +147,7 @@ def _get_round_diff(self, round: int, *, incremental: bool = False) -> str:
161147
previous_round_tag = self._get_round_tag_name(0)
162148
current_round_tag = self._get_round_tag_name(round)
163149
out = assert_zero_exit_code(
164-
self.environment.execute(
165-
f"git diff {previous_round_tag}..{current_round_tag}"
166-
),
150+
self.environment.execute(f"git diff {previous_round_tag}..{current_round_tag}"),
167151
logger=self.logger,
168152
)
169153
return out["output"]

codeclash/agents/minisweagent.py

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,7 @@ def add_message(self, role: str, content: str, **kwargs):
4747
super().add_message(role, content, **kwargs)
4848
self.logger.debug(f"[{role}] {content}", extra={"highlighter": None})
4949
if role == "assistant":
50-
self.logger.info(
51-
f"Step taken (step {self.model.n_calls}, cost {self.model.cost:.2f})"
52-
)
50+
self.logger.info(f"Step taken (step {self.model.n_calls}, cost {self.model.cost:.2f})")
5351

5452
def render_template(self, template: str, **kwargs) -> str:
5553
cs = (
@@ -69,9 +67,7 @@ def run(self) -> tuple[str, str]:
6967
class MiniSWEAgent(Player):
7068
"""Player with agentic code editing capabilities"""
7169

72-
def __init__(
73-
self, config: dict, environment: DockerEnvironment, game_context: GameContext
74-
):
70+
def __init__(self, config: dict, environment: DockerEnvironment, game_context: GameContext):
7571
super().__init__(config, environment=environment, game_context=game_context)
7672

7773
def run(self):
@@ -96,10 +92,7 @@ def run(self):
9692
result = exc_message
9793
print(exc_message)
9894
finally:
99-
traj_path = (
100-
self.game_context.log_local
101-
/ f"{self.name}_r{self.game_context.round}.traj.json"
102-
)
95+
traj_path = self.game_context.log_local / f"{self.name}_r{self.game_context.round}.traj.json"
10396
save_traj(
10497
self.agent, # type: ignore
10598
traj_path,

codeclash/agents/utils.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ def resolve_api_key(model: str) -> str:
1313
return os.getenv("ANTHROPIC_API_KEY")
1414
if "gpt" in model:
1515
return os.getenv("OPENAI_API_KEY")
16+
return ""
1617

1718

1819
@dataclass
@@ -38,10 +39,7 @@ class GameContext:
3839

3940
def _render_prompt_templates(self) -> dict:
4041
context = asdict(self)
41-
return {
42-
key: Template(template_str).render(**context)
43-
for key, template_str in self.prompts.items()
44-
}
42+
return {key: Template(template_str).render(**context) for key, template_str in self.prompts.items()}
4543

4644
def to_template_vars(self) -> dict[str, str]:
4745
"""Convert the GameContext to a dictionary for rendering prompts in the agent"""

codeclash/games/abstract.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@
1717
@dataclass
1818
class RoundStats:
1919
winner: str
20-
scores: dict[
21-
str, float
22-
] # Map of player to game metric (e.g. # of wins, assets accumulated)
20+
scores: dict[str, float] # Map of player to game metric (e.g. # of wins, assets accumulated)
2321
details: dict[str, Any] = None # Optional, for game-specific info
2422

2523
def __str__(self) -> str:
@@ -63,9 +61,7 @@ def __init__(self, config: dict, *, tournament_id: str, local_output_dir: Path):
6361
self.game_id: str = tournament_id
6462
self.log_env: Path = (DIR_WORK / DIR_LOGS / self.game_id).resolve()
6563
self.log_local: Path = local_output_dir
66-
self.logger = get_logger(
67-
self.name, log_path=self.log_local / "game.log", emoji="🏓"
68-
)
64+
self.logger = get_logger(self.name, log_path=self.log_local / "game.log", emoji="🏓")
6965
self.environment: DockerEnvironment = self.get_environment()
7066
"""The running docker environment for executing the game"""
7167
self._metadata: dict = {
@@ -106,9 +102,7 @@ def build_image(self):
106102
if result.returncode == 0:
107103
self.logger.info(f"✅ Built Docker image {self.image_name}")
108104
else:
109-
self.logger.error(
110-
f"❌ Failed to build Docker image: {result.stderr}\n{result.stdout}{result.stderr}"
111-
)
105+
self.logger.error(f"❌ Failed to build Docker image: {result.stderr}\n{result.stdout}{result.stderr}")
112106
raise RuntimeError(f"Failed to build Docker image: {result.stderr}")
113107

114108
def get_metadata(self) -> dict:

codeclash/games/battlecode/main.py

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@ class BattleCodeGame(CodeGame):
1212
name: str = "BattleCode"
1313

1414
def __init__(self, config, *, tournament_id: str, local_output_dir: Path):
15-
super().__init__(
16-
config, tournament_id=tournament_id, local_output_dir=local_output_dir
17-
)
15+
super().__init__(config, tournament_id=tournament_id, local_output_dir=local_output_dir)
1816
assert len(config["players"]) == 2, "BattleCode is a two-player game"
1917
self.run_cmd_round: str = "python run.py run"
2018
for arg, val in self.game_config.get("args", {}).items():
@@ -36,9 +34,7 @@ def get_stats(self, result_outputs: list[str], agents: list[Any]) -> RoundStats:
3634
winner_key = match.group(1)
3735
self.logger.debug(f"Winner key from match: {winner_key}")
3836
# Map A/B to actual agent names (much closer to original code)
39-
winner = {"A": agents[0].name, "B": agents[1].name}.get(
40-
winner_key, RESULT_TIE
41-
)
37+
winner = {"A": agents[0].name, "B": agents[1].name}.get(winner_key, RESULT_TIE)
4238
winners.append(winner)
4339
else:
4440
winners.append(RESULT_TIE)
@@ -49,14 +45,9 @@ def get_stats(self, result_outputs: list[str], agents: list[Any]) -> RoundStats:
4945

5046
def execute_round(self, agents: list[Any]) -> RoundData:
5147
for agent in agents:
52-
src, dest = f"/{agent.name}/src/mysubmission/", str(
53-
DIR_WORK / "src" / agent.name
54-
)
48+
src, dest = f"/{agent.name}/src/mysubmission/", str(DIR_WORK / "src" / agent.name)
5549
self.environment.execute(f"cp -r {src} {dest}")
56-
args = [
57-
f"--p{idx+1}-dir src --p{idx+1} {agent.name}"
58-
for idx, agent in enumerate(agents)
59-
]
50+
args = [f"--p{idx + 1}-dir src --p{idx + 1} {agent.name}" for idx, agent in enumerate(agents)]
6051
cmd = f"{self.run_cmd_round} {' '.join(args)}"
6152
self.logger.info(f"Running game: {cmd}")
6253
outputs = []

codeclash/games/battlesnake/main.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@ class BattleSnakeGame(CodeGame):
1414
name: str = "BattleSnake"
1515

1616
def __init__(self, config, *, tournament_id: str, local_output_dir: Path):
17-
super().__init__(
18-
config, tournament_id=tournament_id, local_output_dir=local_output_dir
19-
)
17+
super().__init__(config, tournament_id=tournament_id, local_output_dir=local_output_dir)
2018
self.run_cmd_round: str = "./battlesnake play"
2119
for arg, val in self.game_config.get("args", {}).items():
2220
if isinstance(val, bool):
@@ -29,9 +27,7 @@ def get_stats(self, result_outputs: list[str], agents: list[Player]) -> RoundSta
2927
winners = []
3028
for ro in result_outputs:
3129
lines = ro.strip().split("\n")
32-
last_line = (
33-
lines[-1] if lines else ""
34-
) # Get the last line which contains the game result
30+
last_line = lines[-1] if lines else "" # Get the last line which contains the game result
3531
winner = json.loads(last_line)["winnerName"]
3632
winners.append(winner)
3733

@@ -48,9 +44,7 @@ def execute_round(self, agents: list[Player]) -> RoundData:
4844
for idx, agent in enumerate(agents):
4945
port = 8001 + idx
5046
# Start server in background - just add & to run in background!
51-
self.environment.execute(
52-
f"PORT={port} python main.py &", cwd=f"/{agent.name}"
53-
)
47+
self.environment.execute(f"PORT={port} python main.py &", cwd=f"/{agent.name}")
5448
cmd.append(f"--url http://0.0.0.0:{port} -n {agent.name}")
5549

5650
time.sleep(3) # Give servers time to start

codeclash/games/corewar/main.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@ class CoreWarGame(CodeGame):
1010
name: str = "CoreWar"
1111

1212
def __init__(self, config, *, tournament_id: str, local_output_dir: Path):
13-
super().__init__(
14-
config, tournament_id=tournament_id, local_output_dir=local_output_dir
15-
)
13+
super().__init__(config, tournament_id=tournament_id, local_output_dir=local_output_dir)
1614
self.run_cmd_round: str = "./src/pmars"
1715
for arg, val in self.game_config.get("args", {}).items():
1816
if isinstance(val, bool):
@@ -50,9 +48,7 @@ def get_stats(self, result_outputs: list[str], agents: list[Player]) -> RoundSta
5048
)
5149
else:
5250
self.logger.debug("No scores found, returning unknown")
53-
return RoundStats(
54-
winner="unknown", scores={agent.name: 0 for agent in agents}
55-
)
51+
return RoundStats(winner="unknown", scores={agent.name: 0 for agent in agents})
5652

5753
def execute_round(self, agents: list[Player]) -> RoundData:
5854
args = [f"/{agent.name}/warriors/warrior.red" for agent in agents]

codeclash/games/robocode/main.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ class RoboCodeGame(CodeGame):
1111
name: str = "RoboCode"
1212

1313
def __init__(self, config, *, tournament_id: str, local_output_dir: Path):
14-
super().__init__(
15-
config, tournament_id=tournament_id, local_output_dir=local_output_dir
16-
)
14+
super().__init__(config, tournament_id=tournament_id, local_output_dir=local_output_dir)
1715
self.run_cmd_round: str = "./robocode.sh"
1816
for arg, val in self.game_config.get("args", {}).items():
1917
if isinstance(val, bool):
@@ -73,9 +71,7 @@ def get_stats(self, result_outputs: list[str], agents: list[Player]) -> RoundSta
7371
if int(match.group(1)) == 1:
7472
winner = player
7573

76-
return RoundStats(
77-
winner=winner, scores=scores, details={"stdout": "\n".join(lines)}
78-
)
74+
return RoundStats(winner=winner, scores=scores, details={"stdout": "\n".join(lines)})
7975

8076
def execute_round(self, agents: list[Player]) -> RoundData:
8177
for agent in agents:
@@ -96,9 +92,7 @@ def execute_round(self, agents: list[Player]) -> RoundData:
9692
{self._get_battle_config()}
9793
robocode.battle.selectedRobots={selected_robots}
9894
"""
99-
create_file_in_container(
100-
self.environment, content=battle_content, dest_path=f"battles/{battle_file}"
101-
)
95+
create_file_in_container(self.environment, content=battle_content, dest_path=f"battles/{battle_file}")
10296

10397
# Run battle with results output to file
10498
results_file = f"results_{int(time.time())}.txt"

0 commit comments

Comments
 (0)