Repository navigation
Expand file tree
/
Copy pathpyproject.toml
More file actions
148 lines (137 loc) · 5.65 KB
/
Copy pathpyproject.toml
File metadata and controls
148 lines (137 loc) · 5.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
[project]
name = "simple-module-python"
version = "0.1.0"
description = "A modular monolith framework for Python using FastAPI, Inertia.js, and React"
requires-python = ">=3.12"
dependencies = []
[tool.uv.workspace]
members = [
"framework/*",
"modules/*",
"host",
]
[dependency-groups]
dev = [
"pytest>=8.0",
"pytest-asyncio>=0.24",
"pytest-benchmark>=4.0",
"pytest-xdist>=3.6",
"httpx>=0.27",
"ruff>=0.8",
"playwright>=1.58.0",
"pytest-playwright>=0.7.2",
"ty>=0.0.29",
"memray>=1.14; sys_platform != 'win32'",
"locust>=2.31",
"faker>=30",
"aioboto3>=13",
"moto[s3]>=5",
"tomlkit>=0.13",
"pyyaml>=6.0",
"pytest-httpx>=0.36.2",
# Test-only: builds real brotli payloads for the pre-compressed static-file
# tests. The build itself compresses with Node's zlib, so nothing at runtime
# needs this. Declared explicitly because it was otherwise only present as a
# transitive dep of locust's geventhttpclient.
"brotli>=1.1",
# Test-only: the optional ``simple_module_hosting[sentry]`` extra, exercised with a fake transport.
"sentry-sdk[fastapi,celery]>=2.20,<3",
]
[tool.ruff]
line-length = 100
target-version = "py312"
# Scaffold templates are copied verbatim (and some live under __PACKAGE__/
# placeholder dirs that aren't valid Python packages until substituted).
extend-exclude = ["framework/cli/simple_module_cli/templates"]
[tool.ruff.lint]
select = [
"E", # pycodestyle errors (PEP 8)
"W", # pycodestyle warnings (PEP 8)
"F", # pyflakes
"I", # isort
"N", # PEP 8 naming
"UP", # pyupgrade
"B", # flake8-bugbear
"SIM", # flake8-simplify
"C4", # flake8-comprehensions
"RET", # flake8-return
"PTH", # flake8-use-pathlib
"PIE", # flake8-pie
"RUF", # ruff-specific rules
]
ignore = [
"B008", # Depends() in default args is idiomatic FastAPI
"B027", # Empty methods in ABC without @abstractmethod — used for optional hooks
]
[tool.ty.environment]
extra-paths = [
"framework/cli",
# The page-perf skill's audit script: its modules import each other flat.
"skills/simple-module-page-perf/scripts/page_audit",
"framework/core",
"framework/db",
"framework/hosting",
"framework/inertia",
"framework/testing",
"modules/auth",
"modules/dashboard",
"modules/users",
"modules/permissions",
"modules/background_tasks",
"modules/file_storage",
"modules/settings",
"modules/feature_flags",
"modules/keycloak",
"modules/oidc",
"modules/audit_log",
"modules/site_lock",
"modules/branding",
"modules/tenants",
"modules/api_tokens",
"modules/mail",
"modules/sharing",
"host",
"scripts",
]
[tool.ty.src]
# Host scaffold templates are copied verbatim; they aren't imported, so
# type-checking them against this repo's alembic version is misleading.
exclude = ["framework/hosting/simple_module_hosting/templates/**"]
[tool.ty.rules]
# SQLModel declares fields with plain Python types (``str``, ``int``, ``bool``)
# even though at runtime they become SQLAlchemy ``InstrumentedAttribute``s
# that support ``.is_()``, ``.in_()``, ``.ilike()``, ``==``, etc. ty can't see
# through this, so query-construction expressions like
# ``select(Product).where(Product.id == x)`` and ``Role.name.in_(names)``
# trigger false positives in every service / endpoint / test that uses the ORM.
# Downgrading these rules trades a known SQLModel typing limitation for a
# clean lint baseline. Real bugs caught by these rules surface in tests.
unresolved-attribute = "ignore"
unsupported-operator = "ignore"
unknown-argument = "ignore"
no-matching-overload = "ignore"
# ``invalid-argument-type`` and ``invalid-assignment`` are on for shipped code
# (GH #507): they catch real bugs such as an unvalidated ``object`` flowing
# into a ``str`` parameter. Tests are exempt below because they pass fakes
# (``SimpleNamespace`` requests, stub apps, echo translators) on purpose.
# A remaining false positive in shipped code gets a line-level
# ``# ty: ignore[<rule>]`` with the reason, which ty reports once unused.
# Never write ``# type: ignore[<mypy-code>]``: ty matches the bracket against
# its own rule names, so a mypy code suppresses nothing.
[[tool.ty.overrides]]
include = ["**/tests/**", "**/conftest.py", "tests/**", "scripts/bench_*.py"]
[tool.ty.overrides.rules]
invalid-argument-type = "ignore"
invalid-assignment = "ignore"
[tool.pytest.ini_options]
asyncio_mode = "auto"
testpaths = ["framework/cli/tests", "framework/core/tests", "framework/db/tests", "framework/hosting/tests", "framework/inertia/tests", "framework/testing/tests", "host/tests", "modules/auth/tests", "modules/dashboard/tests", "modules/users/tests", "modules/permissions/tests", "modules/background_tasks/tests", "modules/file_storage/tests", "modules/settings/tests", "modules/feature_flags/tests", "modules/keycloak/tests", "modules/oidc/tests", "modules/audit_log/tests", "modules/branding/tests", "modules/site_lock/tests", "modules/tenants/tests", "modules/api_tokens/tests", "modules/mail/tests", "modules/sharing/tests", "scripts/tests", "tests"]
markers = [
"e2e: end-to-end tests requiring a live browser",
"perf: performance benchmarks (opt-in; run via `make bench`)",
"postgres: needs a PostgreSQL test database (skipped unless SM_TEST_DATABASE_URL is Postgres)",
]
# --durations=20 prints the 20 slowest tests after every run so slow fixtures
# (e.g. function-scoped ``app`` rebuilds) surface without needing an opt-in flag.
# Benchmarks are opt-in — they run under `make bench`, not the default suite.
addopts = "-m 'not e2e and not perf' --durations=20 --benchmark-disable"