Skip to content

Commit db2edac

Browse files
committed
Enable more ruff rulesets.
1 parent 3f2edbf commit db2edac

File tree

6 files changed

+82
-66
lines changed

6 files changed

+82
-66
lines changed

noxfile.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def tests(session):
4141

4242
if session.posargs and session.posargs[0] == "coverage":
4343
if len(session.posargs) > 1 and session.posargs[1] == "github":
44-
github = os.environ["GITHUB_STEP_SUMMARY"]
44+
github = Path(os.environ["GITHUB_STEP_SUMMARY"])
4545
else:
4646
github = None
4747

@@ -50,7 +50,7 @@ def tests(session):
5050
if github is None:
5151
session.run("coverage", "report")
5252
else:
53-
with open(github, "a") as summary:
53+
with github.open("a") as summary:
5454
summary.write("### Coverage\n\n")
5555
summary.flush() # without a flush, output seems out of order.
5656
session.run(

pyproject.toml

Lines changed: 55 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ source = "vcs"
88
[project]
99
name = "referencing"
1010
description = "JSON Referencing + Python"
11+
requires-python = ">=3.8"
1112
readme = "README.rst"
1213
license = {text = "MIT"}
13-
requires-python = ">=3.8"
1414
keywords = ["json", "referencing", "jsonschema", "openapi", "asyncapi"]
1515
authors = [
1616
{email = "[email protected]"},
@@ -66,6 +66,7 @@ skip_covered = true
6666

6767
[tool.doc8]
6868
ignore = [
69+
"D000", # see PyCQA/doc8#125
6970
"D001", # one sentence per line, so max length doesn't make sense
7071
]
7172

@@ -87,52 +88,64 @@ exclude = [
8788

8889
[tool.ruff]
8990
line-length = 79
90-
select = [
91-
"ANN", "B", "D", "D204", "E", "F", "Q", "RUF", "SIM", "TCH", "UP", "W",
92-
]
91+
select = ["ALL"]
9392
ignore = [
94-
# Wat, type annotations for self and cls, why is this a thing?
95-
"ANN101",
96-
"ANN102",
97-
# Private annotations are fine to leave out.
98-
"ANN202",
99-
# I don't know how to more properly annotate "pass along all arguments".
100-
"ANN401",
101-
# It's totally OK to call functions for default arguments.
102-
"B008",
103-
# raise SomeException(...) is fine.
104-
"B904",
105-
# There's no need for explicit strict, this is simply zip's default behavior.
106-
"B905",
107-
# It's fine to not have docstrings for magic methods.
108-
"D105",
109-
# __init__ especially doesn't need a docstring
110-
"D107",
111-
# This rule makes diffs uglier when expanding docstrings (and it's uglier)
112-
"D200",
113-
# No blank lines before docstrings.
114-
"D203",
115-
# Start docstrings on the second line.
116-
"D212",
117-
# This rule misses sassy docstrings ending with ! or ?.
118-
"D400",
119-
# Section headers should end with a colon not a newline
120-
"D406",
121-
# Underlines aren't needed
122-
"D407",
123-
# Plz spaces after section headers
124-
"D412",
125-
# Not sure what heuristic this uses, but it seems easy for it to be wrong.
126-
"SIM300",
127-
# We support 3.8 + 3.9
128-
"UP007",
93+
"A001", # It's fine to shadow builtins
94+
"A002",
95+
"A003",
96+
"ARG", # This is all wrong whenever an interface is involved
97+
"ANN", # Just let the type checker do this
98+
"B008", # It's totally OK to call functions for default arguments.
99+
"B904", # raise SomeException(...) is fine.
100+
"B905", # No need for explicit strict, this is simply zip's default behavior
101+
"C408", # Calling dict is fine when it saves quoting the keys
102+
"C901", # Not really something to focus on
103+
"D105", # It's fine to not have docstrings for magic methods.
104+
"D107", # __init__ especially doesn't need a docstring
105+
"D200", # This rule makes diffs uglier when expanding docstrings
106+
"D203", # No blank lines before docstrings.
107+
"D212", # Start docstrings on the second line.
108+
"D400", # This rule misses sassy docstrings ending with ! or ?
109+
"D401", # This rule is too flaky.
110+
"D406", # Section headers should end with a colon not a newline
111+
"D407", # Underlines aren't needed
112+
"D412", # Plz spaces after section headers
113+
"EM101", # These don't bother me, it's fine there's some duplication.
114+
"EM102",
115+
"FBT", # It's worth avoiding boolean args but I don't care to enforce it
116+
"FIX", # Yes thanks, if I could it wouldn't be there
117+
"I001", # We can't yet use ruff's isort
118+
"N", # These naming rules are silly
119+
"PLR0912", # These metrics are fine to be aware of but not to enforce
120+
"PLR0913",
121+
"PLR0915",
122+
"PLW2901", # Shadowing for loop variables is occasionally fine.
123+
"PT006", # pytest parametrize takes strings as well
124+
"PYI025", # wat, I'm not confused, thanks.
125+
"RET502", # Returning None implicitly is fine
126+
"RET503",
127+
"RET505", # These push you to use `if` instead of `elif`, but for no reason
128+
"RET506",
129+
"RSE102", # Ha, what, who even knew you could leave the parens off. But no.
130+
"SIM300", # Not sure what heuristic this uses, but it's easily incorrect
131+
"SLF001", # Private usage within this package itself is fine
132+
"TD", # These TODO style rules are also silly
133+
"UP007", # We support 3.8 + 3.9
129134
]
130135
extend-exclude = ["suite"]
131136

137+
[tool.ruff.lint.flake8-pytest-style]
138+
mark-parentheses = false
139+
132140
[tool.ruff.flake8-quotes]
133141
docstring-quotes = "double"
134142

143+
[tool.ruff.lint.isort]
144+
combine-as-imports = true
145+
from-first = true
146+
135147
[tool.ruff.per-file-ignores]
136-
"noxfile.py" = ["ANN", "D100"]
137-
"docs/*" = ["ANN", "D"]
138-
"referencing/tests/*" = ["ANN", "D", "RUF012"]
148+
"noxfile.py" = ["ANN", "D100", "S101", "T201"]
149+
"docs/*" = ["ANN", "D", "INP001"]
150+
"referencing/tests/*" = ["ANN", "D", "RUF012", "S", "PLR", "TRY"]
151+
"referencing/typing.py" = ["PLC0414"]

referencing/_attrs.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,14 @@ def frozen(cls: type[_T]) -> type[_T]:
1818

1919

2020
class UnsupportedSubclassing(Exception):
21-
pass
21+
def __str__(self):
22+
return (
23+
"Subclassing is not part of referencing's public API. "
24+
"If no other suitable API exists for what you're trying to do, "
25+
"feel free to file an issue asking for one."
26+
)
2227

2328

2429
@staticmethod
2530
def _do_not_subclass() -> NoReturn: # pragma: no cover
26-
raise UnsupportedSubclassing(
27-
"Subclassing is not part of referencing's public API. "
28-
"If no other suitable API exists for what you're trying to do, "
29-
"feel free to file an issue asking for one.",
30-
)
31+
raise UnsupportedSubclassing()

referencing/_core.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -266,8 +266,9 @@ def pointer(self, pointer: str, resolver: Resolver[D]) -> Resolved[D]:
266266
segment = segment.replace("~1", "/").replace("~0", "~")
267267
try:
268268
contents = contents[segment] # type: ignore[reportUnknownArgumentType]
269-
except LookupError:
270-
raise exceptions.PointerToNowhere(ref=pointer, resource=self)
269+
except LookupError as lookup_error:
270+
error = exceptions.PointerToNowhere(ref=pointer, resource=self)
271+
raise error from lookup_error
271272

272273
segments.append(segment)
273274
last = resolver
@@ -326,7 +327,7 @@ def __getitem__(self, uri: URI) -> Resource[D]:
326327
try:
327328
return self._resources[uri.rstrip("#")]
328329
except KeyError:
329-
raise exceptions.NoSuchResource(ref=uri)
330+
raise exceptions.NoSuchResource(ref=uri) from None
330331

331332
def __iter__(self) -> Iterator[URI]:
332333
"""
@@ -421,8 +422,8 @@ def get_or_retrieve(self, uri: URI) -> Retrieved[D, Resource[D]]:
421422
exceptions.NoSuchResource,
422423
):
423424
raise
424-
except Exception:
425-
raise exceptions.Unretrievable(ref=uri)
425+
except Exception as error: # noqa: BLE001
426+
raise exceptions.Unretrievable(ref=uri) from error
426427
else:
427428
registry = registry.with_resource(uri, resource)
428429
return Retrieved(registry=registry, value=resource)
@@ -556,7 +557,7 @@ def combine(self, *registries: Registry[D]) -> Registry[D]:
556557

557558
if registry._retrieve is not _fail_to_retrieve:
558559
if registry._retrieve is not retrieve is not _fail_to_retrieve:
559-
raise ValueError(
560+
raise ValueError( # noqa: TRY003
560561
"Cannot combine registries with conflicting retrieval "
561562
"functions.",
562563
)
@@ -668,8 +669,8 @@ def lookup(self, ref: URI) -> Resolved[D]:
668669
retrieved = self._registry.get_or_retrieve(uri)
669670
except exceptions.NoSuchResource:
670671
raise exceptions.Unresolvable(ref=ref) from None
671-
except exceptions.Unretrievable:
672-
raise exceptions.Unresolvable(ref=ref)
672+
except exceptions.Unretrievable as error:
673+
raise exceptions.Unresolvable(ref=ref) from error
673674

674675
if fragment.startswith("/"):
675676
resolver = self._evolve(registry=retrieved.registry, base_uri=uri)

referencing/exceptions.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class NoSuchResource(KeyError):
2525

2626
ref: URI
2727

28-
def __eq__(self, other: Any) -> bool:
28+
def __eq__(self, other: object) -> bool:
2929
if self.__class__ is not other.__class__:
3030
return NotImplemented
3131
return attrs.astuple(self) == attrs.astuple(other)
@@ -47,7 +47,7 @@ class NoInternalID(Exception):
4747

4848
resource: Resource[Any]
4949

50-
def __eq__(self, other: Any) -> bool:
50+
def __eq__(self, other: object) -> bool:
5151
if self.__class__ is not other.__class__:
5252
return NotImplemented
5353
return attrs.astuple(self) == attrs.astuple(other)
@@ -64,7 +64,7 @@ class Unretrievable(KeyError):
6464

6565
ref: URI
6666

67-
def __eq__(self, other: Any) -> bool:
67+
def __eq__(self, other: object) -> bool:
6868
if self.__class__ is not other.__class__:
6969
return NotImplemented
7070
return attrs.astuple(self) == attrs.astuple(other)
@@ -84,7 +84,7 @@ class CannotDetermineSpecification(Exception):
8484

8585
contents: Any
8686

87-
def __eq__(self, other: Any) -> bool:
87+
def __eq__(self, other: object) -> bool:
8888
if self.__class__ is not other.__class__:
8989
return NotImplemented
9090
return attrs.astuple(self) == attrs.astuple(other)
@@ -101,7 +101,7 @@ class Unresolvable(Exception):
101101

102102
ref: URI
103103

104-
def __eq__(self, other: Any) -> bool:
104+
def __eq__(self, other: object) -> bool:
105105
if self.__class__ is not other.__class__:
106106
return NotImplemented
107107
return attrs.astuple(self) == attrs.astuple(other)

referencing/jsonschema.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -336,9 +336,10 @@ def maybe_in_subresource(
336336
) -> _Resolver[Any]:
337337
_segments = iter(segments)
338338
for segment in _segments:
339-
if (
340-
segment == "items" or segment == "dependencies"
341-
) and isinstance(subresource.contents, Mapping):
339+
if segment in {"items", "dependencies"} and isinstance(
340+
subresource.contents,
341+
Mapping,
342+
):
342343
return resolver.in_subresource(subresource)
343344
if segment not in in_value and (
344345
segment not in in_child or next(_segments, None) is None

0 commit comments

Comments
 (0)