Skip to content

Commit ef1f392

Browse files
committed
move ruff and ty configurations to their own files
1 parent 3ef2a09 commit ef1f392

14 files changed

Lines changed: 167 additions & 172 deletions

File tree

app/datastore/database.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def get_engine(
4242
return ENGINE
4343

4444

45-
async def get_db_session() -> AsyncGenerator[AsyncSession, None]:
45+
async def get_db_session() -> AsyncGenerator[AsyncSession]:
4646
"""Start a SessionLocal transaction and yield it."""
4747
engine = get_engine()
4848
async_session = async_sessionmaker(engine, expire_on_commit=False)

app/datastore/db_models.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ class BlogPost(Base):
114114
id: Mapped[IntPK]
115115
title: Mapped[StrIndexedUnique]
116116
slug: Mapped[StrIndexedUnique]
117-
old_slugs: Mapped[list["OldBlogPostSlug"]] = relationship(back_populates="blog_post")
118-
tags: Mapped[list["BlogPostTag"]] = relationship(
117+
old_slugs: Mapped[list[OldBlogPostSlug]] = relationship(back_populates="blog_post")
118+
tags: Mapped[list[BlogPostTag]] = relationship(
119119
secondary="blog_tags_associations",
120120
back_populates="blog_posts",
121121
order_by="asc(BlogPostTag.tag)",
@@ -131,20 +131,20 @@ class BlogPost(Base):
131131
html_content: Mapped[str]
132132
html_toc: Mapped[str]
133133

134-
media: Mapped[list["BlogPostMedia"]] = relationship(
134+
media: Mapped[list[BlogPostMedia]] = relationship(
135135
back_populates="blog_post",
136136
order_by="asc(BlogPostMedia.position), asc(BlogPostMedia.created_timestamp)",
137137
)
138138
created_timestamp: Mapped[DateTimeIndexed]
139139
updated_timestamp: Mapped[DateTimeIndexed]
140140
likes: Mapped[IntIndexed]
141141
views: Mapped[IntIndexed]
142-
comments: Mapped[list["BlogPostComment"]] = relationship(
142+
comments: Mapped[list[BlogPostComment]] = relationship(
143143
back_populates="blog_post", order_by="asc(BlogPostComment.created_timestamp)"
144144
)
145145
series_id: Mapped[BPSeriesFK | None]
146146
series_position: Mapped[IntNullable]
147-
series: Mapped["BlogPostSeries"] = relationship(back_populates="posts")
147+
series: Mapped[BlogPostSeries] = relationship(back_populates="posts")
148148

149149
ts_vector: Mapped[TSVector] = mapped_column(
150150
TSVector(),
@@ -160,7 +160,7 @@ class OldBlogPostSlug(Base):
160160

161161
slug: Mapped[StrPK]
162162
blog_post_id: Mapped[BlogPostFK]
163-
blog_post: Mapped["BlogPost"] = relationship(back_populates="old_slugs")
163+
blog_post: Mapped[BlogPost] = relationship(back_populates="old_slugs")
164164

165165

166166
class BlogPostTag(Base):
@@ -169,7 +169,7 @@ class BlogPostTag(Base):
169169
__tablename__ = "blog_post_tags"
170170

171171
tag: Mapped[StrPK]
172-
blog_posts: Mapped[list["BlogPost"]] = relationship(
172+
blog_posts: Mapped[list[BlogPost]] = relationship(
173173
secondary="blog_tags_associations", back_populates="tags"
174174
)
175175

@@ -191,7 +191,7 @@ class BlogPostMedia(Base):
191191

192192
id: Mapped[IntPK]
193193
blog_post_id: Mapped[BlogPostFK | None]
194-
blog_post: Mapped["BlogPost"] = relationship(back_populates="media")
194+
blog_post: Mapped[BlogPost] = relationship(back_populates="media")
195195
name: Mapped[str]
196196
locations: Mapped[str]
197197
media_type: Mapped[str]
@@ -210,12 +210,12 @@ class BlogPostComment(Base):
210210

211211
id: Mapped[IntPK]
212212
blog_post_id: Mapped[BlogPostFK | None]
213-
blog_post: Mapped["BlogPost"] = relationship(back_populates="comments")
213+
blog_post: Mapped[BlogPost] = relationship(back_populates="comments")
214214
name: Mapped[StrNullable] # Name of the commenter
215215
email: Mapped[StrNullable] # Email of the commenter
216216
guest_id: Mapped[StrNullable] # Guest ID of the commenter
217217
user_id: Mapped[UsersFk | None]
218-
user: Mapped["User"] = relationship()
218+
user: Mapped[User] = relationship()
219219
md_content: Mapped[str]
220220
html_content: Mapped[str]
221221
created_timestamp: Mapped[DateTimeIndexed]
@@ -262,4 +262,4 @@ class PasswordResetToken(Base):
262262
encrypted_query: Mapped[StrIndexedUnique]
263263
created_timestamp: Mapped[DateTimeIndexed]
264264
expires_timestamp: Mapped[DateTimeIndexed]
265-
user: Mapped["User"] = relationship()
265+
user: Mapped[User] = relationship()

app/permissions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def requires_permission(permission: Action) -> Callable:
4747

4848
def decorator(func: Callable) -> Callable:
4949
@wraps(func)
50-
async def wrapper(*args: Any, current_user: "AuthUserMixin", **kwargs: Any) -> Any:
50+
async def wrapper(*args: Any, current_user: AuthUserMixin, **kwargs: Any) -> Any:
5151
if not current_user.has_permission(permission):
5252
raise errors.UserPermissionsError
5353
return await func(*args, current_user=current_user, **kwargs)

app/web/html/templates/shared/base.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{% set libraries_static_version = 'e454b3c1' %}
22
{% set custom_static_version = '56505df6' %}
3-
{% set tailwind_static_version = '254b2dde' %}
3+
{% set tailwind_static_version = '12fb53c3' %}
44
<!doctype html>
55
<html
66
lang="en"

app/web/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ async def api_home(request: Request) -> RedirectResponse:
5656

5757

5858
@asynccontextmanager
59-
async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]: # noqa: ARG001 (unused-argument)
59+
async def lifespan(app: FastAPI) -> AsyncGenerator[None]: # noqa: ARG001 (unused-argument)
6060
"""Code to run before taking any requests and just before shutdown."""
6161
engine = get_engine()
6262
try:

pyproject.toml

Lines changed: 0 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -189,144 +189,3 @@ exclude_lines = [
189189
]
190190
include = ["app/*", "scripts/*", "tests/*"]
191191
skip_covered = true # Don't show fully covered files in the report
192-
193-
194-
# ----------------------- Ty: type checker ---------------------------------
195-
# Reference: https://docs.astral.sh/ty/reference/configuration/
196-
[tool.ty.environment]
197-
python = "./venv"
198-
python-version = "3.14"
199-
200-
201-
# Rules references: https://docs.astral.sh/ty/reference/rules/
202-
# Most rules have a default value already ("error", "warn", "ignore")
203-
# This overwrites some of those rules
204-
[tool.ty.rules]
205-
invalid-ignore-comment = "error"
206-
possibly-unbound-attribute = "error"
207-
possibly-unbound-import = "error"
208-
redundant-cast = "error"
209-
undefined-reveal = "error"
210-
unknown-rule = "error"
211-
unresolved-global = "error"
212-
unsupported-base = "error"
213-
division-by-zero = "error"
214-
possibly-unresolved-reference = "error"
215-
unused-ignore-comment = "error"
216-
217-
218-
# ------------------------ Ruff: linter + formatter-------------------------
219-
# Reference: https://docs.astral.sh/ruff/configuration/
220-
[tool.ruff]
221-
line-length = 100
222-
target-version = "py314"
223-
224-
225-
[tool.ruff.format]
226-
docstring-code-format = true
227-
docstring-code-line-length = "dynamic"
228-
229-
230-
[tool.ruff.lint]
231-
# Rules to run
232-
# Reference: https://docs.astral.sh/ruff/rules/
233-
select = [
234-
"A", # flake8-builtins
235-
"ANN", # flake8-annotations
236-
"ASYNC", # flake8-async
237-
"ARG", # flake8-unused-arguments
238-
"B", # flake8-bugbear
239-
"BLE", # flake8-blind-except
240-
"C4", # flake8-comprehensions
241-
"C90", # mccabe (complexity)
242-
"COM", # flake8-commas
243-
"D", # pydocstyle
244-
"DTZ", # flake8-datetimez
245-
"E", # pycodestyle errors
246-
"EM", # flake8-errmsg
247-
"ERA", # eradicate
248-
"EXE", # flake8-executable
249-
"F", # pyflakes
250-
"FBT", # flake8-boolean-trap
251-
"FLY", # flynt
252-
# "FURB", # Refurb (In preview)
253-
"G", # flake8-logging-format
254-
"I", # isort
255-
"ICN", # flake8-import-conventions
256-
"INP", # flake8-no-pep420
257-
"ISC", # flake8-implicit-str-concat
258-
# "LOG", # flake8-logging (In preview)
259-
"N", # pep8-naming
260-
"NPY", # NumPy-specific rules
261-
"PERF", # Perflint
262-
"PD", # pandas-vet
263-
"PGH", # pygrep-hooks
264-
"PIE", # flake8-pie
265-
"PL", # pylint
266-
"PLC", # pylint-convention
267-
"PLE", # pylint-error
268-
"PLR", # pylint-refactor
269-
"PLW", # pylint-warning
270-
"PT", # flake8-pytest-style
271-
"PTH", # flake8-use-pathlib
272-
"Q", # flake8-quotes
273-
"RET", # flake8-return
274-
"RSE", # flake8-raise
275-
"RUF", # ruff-specific rules
276-
"S", # flake8-bandit
277-
"SIM", # flake8-simplify
278-
"SLF", # flake8-self
279-
"T10", # flake8-debugger
280-
"T20", # flake8-print
281-
"TID", # flake8-tidy-imports
282-
"TRY", # tryceratops
283-
"UP", # pyupgrade
284-
"W", # pycodestyle warnings
285-
"YTT", # flake8-2020
286-
]
287-
# Roles to ignore
288-
ignore = [
289-
"A003", # builtin-attribute-shadowing. Shadowing `id` in a model for instance.
290-
"ANN401", # No dynamically typed expressions (like "Any")
291-
"COM812", # Missing trailing comma (can cause ruff formatter conflicts)
292-
"D105", # Missing docstring in magic method
293-
"D107", # Missing docstring in __init__
294-
"D203", # 1 blank line required before class docstring (conflicts with D211 - No blank lines allowed before class docstring)
295-
"D213", # Multi-line docstring summary should start at the second line (conflicts with D212 - Multi-line docstring summary should start at the first line)
296-
"ISC001", # Implicit string concatenation found (can cause ruff formatter conflicts)
297-
]
298-
# Don't automatically fix these errors, but still report them
299-
unfixable = [
300-
"ERA001", # eradicate commented out code
301-
"T20", # flake8-print
302-
"RUF100", # unused-noqa
303-
]
304-
305-
306-
[tool.ruff.lint.per-file-ignores]
307-
"**/__init__.py" = ["D104"] # Missing docstring in public package
308-
"scripts/*" = [
309-
"FBT003", # boolean-positional-value-in-call (needed for typer default arg)
310-
"S101", # use of assert
311-
"S311", # random-not-for-cryptography
312-
"T201", # 'print' found
313-
]
314-
"scripts/alembic.py" = ["S603"] # subprocess-without-shell-equals-true
315-
"migrations/versions/*" = ["D103"] # Missing docstring in public function
316-
"tests/*" = [
317-
"ANN002", # Missing type annotation for *args
318-
"ANN003", # Missing type annotation for **kwargs
319-
"ANN201", # Missing return type annotation for function
320-
"E501", # line-too-long
321-
"PLR2004", # Magic value comparison
322-
"S101", # assert-used
323-
"S105", # Passwords should not be hard-coded
324-
]
325-
326-
327-
[tool.ruff.lint.mccabe]
328-
max-complexity = 8
329-
330-
331-
[tool.ruff.lint.isort]
332-
known-first-party = ["app", "tests", "scripts"]

ruff.toml

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# ruff.toml: Ruff linter + formatter configuration
2+
# Reference: https://docs.astral.sh/ruff/configuration/
3+
line-length = 100
4+
target-version = "py314"
5+
6+
7+
[format]
8+
docstring-code-format = true
9+
docstring-code-line-length = "dynamic"
10+
11+
12+
[lint]
13+
# Rules to run
14+
# Reference: https://docs.astral.sh/ruff/rules/
15+
select = [
16+
"A", # flake8-builtins
17+
"ANN", # flake8-annotations
18+
"ASYNC", # flake8-async
19+
"ARG", # flake8-unused-arguments
20+
"B", # flake8-bugbear
21+
"BLE", # flake8-blind-except
22+
"C4", # flake8-comprehensions
23+
"C90", # mccabe (complexity)
24+
"COM", # flake8-commas
25+
"D", # pydocstyle
26+
"DTZ", # flake8-datetimez
27+
"E", # pycodestyle errors
28+
"EM", # flake8-errmsg
29+
"ERA", # eradicate
30+
"EXE", # flake8-executable
31+
"F", # pyflakes
32+
"FBT", # flake8-boolean-trap
33+
"FLY", # flynt
34+
# "FURB", # Refurb (In preview)
35+
"G", # flake8-logging-format
36+
"I", # isort
37+
"ICN", # flake8-import-conventions
38+
"INP", # flake8-no-pep420
39+
"ISC", # flake8-implicit-str-concat
40+
# "LOG", # flake8-logging (In preview)
41+
"N", # pep8-naming
42+
"NPY", # NumPy-specific rules
43+
"PERF", # Perflint
44+
"PD", # pandas-vet
45+
"PGH", # pygrep-hooks
46+
"PIE", # flake8-pie
47+
"PL", # pylint
48+
"PLC", # pylint-convention
49+
"PLE", # pylint-error
50+
"PLR", # pylint-refactor
51+
"PLW", # pylint-warning
52+
"PT", # flake8-pytest-style
53+
"PTH", # flake8-use-pathlib
54+
"Q", # flake8-quotes
55+
"RET", # flake8-return
56+
"RSE", # flake8-raise
57+
"RUF", # ruff-specific rules
58+
"S", # flake8-bandit
59+
"SIM", # flake8-simplify
60+
"SLF", # flake8-self
61+
"T10", # flake8-debugger
62+
"T20", # flake8-print
63+
"TID", # flake8-tidy-imports
64+
"TRY", # tryceratops
65+
"UP", # pyupgrade
66+
"W", # pycodestyle warnings
67+
"YTT", # flake8-2020
68+
]
69+
# Rules to ignore
70+
ignore = [
71+
"A003", # builtin-attribute-shadowing. Shadowing `id` in a model for instance.
72+
"ANN401", # No dynamically typed expressions (like "Any")
73+
"COM812", # Missing trailing comma (can cause ruff formatter conflicts)
74+
"D105", # Missing docstring in magic method
75+
"D107", # Missing docstring in __init__
76+
"D203", # 1 blank line required before class docstring (conflicts with D211 - No blank lines allowed before class docstring)
77+
"D213", # Multi-line docstring summary should start at the second line (conflicts with D212 - Multi-line docstring summary should start at the first line)
78+
"ISC001", # Implicit string concatenation found (can cause ruff formatter conflicts)
79+
]
80+
# Don't automatically fix these errors, but still report them
81+
unfixable = [
82+
"ERA001", # eradicate commented out code
83+
"T20", # flake8-print
84+
"RUF100", # unused-noqa
85+
]
86+
87+
88+
[lint.per-file-ignores]
89+
"**/__init__.py" = ["D104"] # Missing docstring in public package
90+
"scripts/*" = [
91+
"FBT003", # boolean-positional-value-in-call (needed for typer default arg)
92+
"S101", # use of assert
93+
"S311", # random-not-for-cryptography
94+
"T201", # 'print' found
95+
]
96+
"scripts/alembic.py" = ["S603"] # subprocess-without-shell-equals-true
97+
"migrations/versions/*" = ["D103"] # Missing docstring in public function
98+
"tests/*" = [
99+
"ANN002", # Missing type annotation for *args
100+
"ANN003", # Missing type annotation for **kwargs
101+
"ANN201", # Missing return type annotation for function
102+
"E501", # line-too-long
103+
"PLR2004", # Magic value comparison
104+
"S101", # assert-used
105+
"S105", # Passwords should not be hard-coded
106+
]
107+
108+
109+
[lint.mccabe]
110+
max-complexity = 8
111+
112+
113+
[lint.isort]
114+
known-first-party = ["app", "tests", "scripts"]

tests/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class TestCase(BaseModel, arbitrary_types_allowed=True):
2323

2424
@staticmethod
2525
def parametrize(
26-
test_cases: Sequence["TestCase"], *, arg_name: str = "test_case"
26+
test_cases: Sequence[TestCase], *, arg_name: str = "test_case"
2727
) -> pytest.MarkDecorator:
2828
"""Parametrize the test cases."""
2929
return pytest.mark.parametrize(

0 commit comments

Comments
 (0)