Skip to content

Commit 83d268a

Browse files
falloficarusspre-commit-ci[bot]quaquel
authored
Lint: Enable RUF012 and annotate mutable class attributes with ClassVar (mesa#3033)
* Enable RUF012 and fix mutable class attribute annotations - Enable RUF012 in ruff configuration. - Annotate mutable class attributes with ClassVar in core code and tests. - Affected files: mesa/agent.py, mesa/discrete_space/cell_agent.py, mesa/mesa_logging.py, pd_grid model, and visualization tests. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: Abhishek Shinde <[email protected]> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Jan Kwakkel <[email protected]>
1 parent 96a8f58 commit 83d268a

File tree

6 files changed

+23
-11
lines changed

6 files changed

+23
-11
lines changed

mesa/agent.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from random import Random
1919

2020
# mypy
21-
from typing import TYPE_CHECKING, Any, Literal, overload
21+
from typing import TYPE_CHECKING, Any, ClassVar, Literal, overload
2222

2323
import numpy as np
2424

@@ -45,7 +45,7 @@ class Agent:
4545
# this is a class level attribute
4646
# it is a dictionary, indexed by model instance
4747
# so, unique_id is unique relative to a model, and counting starts from 1
48-
_ids = defaultdict(functools.partial(itertools.count, 1))
48+
_ids: ClassVar[defaultdict] = defaultdict(functools.partial(itertools.count, 1))
4949

5050
def __init__(self, model: Model, *args, **kwargs) -> None:
5151
"""Create a new agent.

mesa/discrete_space/cell_agent.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
from __future__ import annotations
1515

16-
from typing import TYPE_CHECKING, Protocol
16+
from typing import TYPE_CHECKING, ClassVar, Protocol
1717

1818
from mesa.agent import Agent
1919

@@ -115,7 +115,7 @@ class Grid2DMovingAgent(CellAgent):
115115
"""Mixin for moving agents in 2D grids."""
116116

117117
# fmt: off
118-
DIRECTION_MAP = {
118+
DIRECTION_MAP: ClassVar[dict[str, tuple[int, int]]] = {
119119
"n": (-1, 0), "north": (-1, 0), "up": (-1, 0),
120120
"s": (1, 0), "south": (1, 0), "down": (1, 0),
121121
"e": (0, 1), "east": (0, 1), "right": (0, 1),

mesa/examples/advanced/pd_grid/model.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import typing
2+
13
import mesa
24
from mesa.discrete_space import OrthogonalMooreGrid
35
from mesa.examples.advanced.pd_grid.agents import PDAgent
@@ -6,12 +8,21 @@
68
class PdGrid(mesa.Model):
79
"""Model class for iterated, spatial prisoner's dilemma model."""
810

9-
activation_regimes = ["Sequential", "Random", "Simultaneous"]
11+
activation_regimes: typing.ClassVar[list[str]] = [
12+
"Sequential",
13+
"Random",
14+
"Simultaneous",
15+
]
1016

1117
# This dictionary holds the payoff for this agent,
1218
# keyed on: (my_move, other_move)
1319

14-
payoff = {("C", "C"): 1, ("C", "D"): 0, ("D", "C"): 1.6, ("D", "D"): 0}
20+
payoff: typing.ClassVar[dict[tuple[str, str], float]] = {
21+
("C", "C"): 1,
22+
("C", "D"): 0,
23+
("D", "C"): 1.6,
24+
("D", "D"): 0,
25+
}
1526

1627
def __init__(
1728
self, width=50, height=50, activation_order="Random", payoffs=None, seed=None

mesa/mesa_logging.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import logging
1010
from functools import wraps
1111
from logging import DEBUG, INFO
12+
from typing import ClassVar
1213

1314
__all__ = [
1415
"DEBUG",
@@ -75,7 +76,7 @@ class MESAColorFormatter(logging.Formatter):
7576
"[%(asctime)s] [%(name)s] [%(levelname)s] %(message)s [%(filename)s:%(lineno)d]"
7677
)
7778

78-
FORMATS = {
79+
FORMATS: ClassVar[dict[int, str]] = {
7980
logging.DEBUG: grey + format + reset,
8081
logging.INFO: green + format + reset,
8182
logging.WARNING: yellow + format + reset,

pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,6 @@ extend-ignore = [
163163
"B905", # `zip()` without an explicit `strict=` parameter
164164
"N802", # Function name should be lowercase
165165
"N999", # Invalid module name. We should revisit this in the future, TODO
166-
"RUF012", # Mutable class attributes should be annotated with `typing.ClassVar` TODO
167166
"S310", # Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
168167
"S603", # `subprocess` call: check for execution of untrusted input
169168
"ISC001", # ruff format asks to disable this feature

tests/visualization/test_backends.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import random
44
import types
5+
from typing import ClassVar
56
from unittest.mock import MagicMock
67

78
import numpy as np
@@ -49,7 +50,7 @@ class DummyAgent:
4950
cell = types.SimpleNamespace(coordinate=(0, 0))
5051

5152
class DummySpace:
52-
agents = [DummyAgent()]
53+
agents: ClassVar[list] = [DummyAgent()]
5354

5455
# Test with AgentPortrayalStyle
5556
def agent_portrayal_style(agent):
@@ -187,7 +188,7 @@ class DummyAgent:
187188
cell = types.SimpleNamespace(coordinate=(0, 0))
188189

189190
class DummySpace:
190-
agents = [DummyAgent()]
191+
agents: ClassVar[list] = [DummyAgent()]
191192

192193
# Test with AgentPortrayalStyle
193194
def agent_portrayal_style(agent):
@@ -225,7 +226,7 @@ class DummyAgent:
225226
cell = types.SimpleNamespace(coordinate=(0, 0))
226227

227228
class DummySpace:
228-
agents = [DummyAgent()]
229+
agents: ClassVar[list] = [DummyAgent()]
229230

230231
def agent_portrayal(agent):
231232
return AgentPortrayalStyle(

0 commit comments

Comments
 (0)