Skip to content

Commit 49b925e

Browse files
authored
Merge pull request #50 from ProtixIT/ruff-formatting
Format code and imports using Ruff
2 parents ad9a57e + 2e8ad81 commit 49b925e

5 files changed

Lines changed: 28 additions & 41 deletions

File tree

.pre-commit-config.yaml

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,10 @@ repos:
44
hooks:
55
- id: end-of-file-fixer
66
- id: trailing-whitespace
7-
- repo: https://github.com/psf/black
8-
rev: 22.12.0
9-
hooks:
10-
- id: black
11-
- repo: https://github.com/pycqa/isort
12-
rev: 5.12.0
13-
hooks:
14-
- id: isort
157
- repo: https://github.com/astral-sh/ruff-pre-commit
16-
rev: v0.0.274
8+
rev: v0.14.6
179
hooks:
18-
- id: ruff
10+
- id: ruff-check
11+
- id: ruff-check
12+
args: [--select, I, --fix]
13+
- id: ruff-format

pyproject.toml

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,24 +26,17 @@ pre-commit = "^4.5.0"
2626
mypy = "^1.5"
2727
pytest = "^7.2.0"
2828
pytest-cov = "^4.0.0"
29-
ruff = "0.0.274"
29+
ruff = "0.14.6"
3030

3131
[tool.poetry.group.coverage.dependencies]
3232
coverage = {version = "^7.0.0", extras = ["toml"]}
3333

34-
[tool.black]
35-
line-length = 120
36-
target-version = ["py310"]
37-
38-
[tool.isort]
39-
profile = "black"
40-
multi_line_output = 3
41-
line_length = 120
42-
4334
[tool.ruff]
4435
line-length = 120
4536
target-version = "py310"
4637
src = ["src"]
38+
39+
[tool.ruff.lint]
4740
select = [
4841
"F", "E", "W", "I", "N", "UP", "ANN0", "ANN2", "FBT", "B", "A", "C4", "FA",
4942
"ISC", "ICN", "G", "INP", "PIE", "T20", "PT", "Q", "RSE", "RET", "SIM",
@@ -57,6 +50,9 @@ ignore = [
5750
"TRY301", # alternatives might be worse
5851
]
5952

53+
[tool.ruff.lint.isort]
54+
split-on-trailing-comma = false
55+
6056
[tool.mypy]
6157
disallow_incomplete_defs = true
6258
disallow_untyped_defs = true

src/dataclass_binder/_impl.py

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ def _get_fields(cls: type) -> Iterator[tuple[Field, type]]:
187187
continue
188188
if isinstance(annotation, str):
189189
try:
190-
annotation = eval(annotation, cls_globals, cls_locals) # noqa: PGH001
190+
annotation = eval(annotation, cls_globals, cls_locals)
191191
except NameError as ex:
192192
raise TypeError(f"Failed to parse annotation of field '{cls.__name__}.{name}': {ex}") from None
193193
yield field, annotation
@@ -211,7 +211,6 @@ def _check_field(field: Field, field_type: type, context: str) -> None:
211211

212212
@dataclass(slots=True)
213213
class _ClassInfo(Generic[T]):
214-
215214
_cache: ClassVar[MutableMapping[type[Any], _ClassInfo[Any]]] = WeakKeyDictionary()
216215

217216
dataclass: type[T]
@@ -260,7 +259,8 @@ class Binder(Generic[T]):
260259
Binds TOML data to a specific dataclass.
261260
"""
262261

263-
__slots__ = ("_dataclass", "_instance", "_class_info")
262+
__slots__ = "_class_info", "_dataclass", "_instance"
263+
264264
_dataclass: type[T]
265265
_instance: T | None
266266
_class_info: _ClassInfo[T]
@@ -270,12 +270,10 @@ def __class_getitem__(cls: type[Binder[T]], dataclass: type[T]) -> Binder[T]:
270270
return cls(dataclass)
271271

272272
@overload
273-
def __init__(self, class_or_instance: type[T]) -> None:
274-
...
273+
def __init__(self, class_or_instance: type[T]) -> None: ...
275274

276275
@overload
277-
def __init__(self, class_or_instance: T) -> None:
278-
...
276+
def __init__(self, class_or_instance: T) -> None: ...
279277

280278
def __init__(self, class_or_instance: type[T] | T) -> None:
281279
if isinstance(class_or_instance, type):
@@ -323,7 +321,7 @@ def _bind_to_single_type(self, value: object, field_type: type, context: str) ->
323321
elif issubclass(origin, Mapping):
324322
if not isinstance(value, dict):
325323
raise TypeError(f"Value for '{context}' has type '{type(value).__name__}', expected table")
326-
key_type, elem_type = get_args(field_type)
324+
_key_type, elem_type = get_args(field_type)
327325
mapping = {
328326
key: self._bind_to_field(elem, elem_type, None, f'{context}["{key}"]') for key, elem in value.items()
329327
}
@@ -506,7 +504,7 @@ def _format_toml_table(
506504
origin = get_origin(field_type)
507505
if origin is not None:
508506
if issubclass(origin, Mapping):
509-
key_type, value_type = get_args(field_type)
507+
_key_type, value_type = get_args(field_type)
510508
if isinstance(value_type, Binder):
511509
if value is None:
512510
nested_map = {f"{key_fmt}.<name>": None}
@@ -568,12 +566,10 @@ def _format_toml_table(
568566
# These definitions exist to support the deprecated `Binder[DC]` syntax in mypy.
569567

570568
@classmethod
571-
def bind(cls, data: Mapping[str, Any]) -> T:
572-
...
569+
def bind(cls, data: Mapping[str, Any]) -> T: ...
573570

574571
@classmethod
575-
def parse_toml(cls, file: BinaryIO | str | Path) -> T:
576-
...
572+
def parse_toml(cls, file: BinaryIO | str | Path) -> T: ...
577573

578574
else:
579575

tests/test_formatting.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,9 @@ def round_trip_value(value: T, dc: type[Any]) -> T:
100100
"\"both\" 'quotes'",
101101
"embedded\nnewline",
102102
r"back\slash",
103-
'I\'m a string. "You can quote me". Name\tJos\u00E9\nLocation\tSF.',
104-
"complex string with back\\slash, \"both\" 'quotes' and \u0000control\u007Fchars\u0007",
105-
"\U0001F44D",
103+
'I\'m a string. "You can quote me". Name\tJos\u00e9\nLocation\tSF.',
104+
"complex string with back\\slash, \"both\" 'quotes' and \u0000control\u007fchars\u0007",
105+
"\U0001f44d",
106106
date(2022, 10, 5),
107107
datetime(2022, 10, 5, 19, 16, 29),
108108
time(19, 16, 29),
@@ -240,9 +240,9 @@ def test_format_value_nested_dataclass(*, optional: bool, string: bool) -> None:
240240

241241

242242
def test_format_value_unsupported_type() -> None:
243-
with pytest.raises(TypeError, match="^NoneType$"):
243+
with pytest.raises(TypeError, match=r"^NoneType$"):
244244
format_toml_pair("unsupported", None)
245-
with pytest.raises(TypeError, match="^NoneType$"):
245+
with pytest.raises(TypeError, match=r"^NoneType$"):
246246
list(_iter_format_value(None))
247247

248248

@@ -821,7 +821,7 @@ def test_format_template_depth_first() -> None:
821821
)
822822

823823

824-
@pytest.fixture()
824+
@pytest.fixture
825825
def sourceless_class() -> type[Any]:
826826
"""A class for which no source code is available."""
827827

tests/test_parsing.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,7 @@ def test_bind_timedelta_direct() -> None:
659659
duration = false
660660
"""
661661
) as stream,
662-
pytest.raises(TypeError, match="^Value for 'TimeDeltaConfig.duration' has type 'bool', expected time$"),
662+
pytest.raises(TypeError, match=r"^Value for 'TimeDeltaConfig.duration' has type 'bool', expected time$"),
663663
):
664664
Binder(TimeDeltaConfig).parse_toml(stream)
665665

@@ -693,7 +693,7 @@ def test_bind_timedelta_suffix() -> None:
693693
) as stream,
694694
pytest.raises(
695695
TypeError,
696-
match="^Value for 'TimeDeltaConfig.duration' with suffix 'weeks' has type 'bool', expected number$",
696+
match=r"^Value for 'TimeDeltaConfig.duration' with suffix 'weeks' has type 'bool', expected number$",
697697
),
698698
):
699699
Binder(TimeDeltaConfig).parse_toml(stream)

0 commit comments

Comments
 (0)