-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpyproject.toml
More file actions
102 lines (93 loc) · 4.75 KB
/
Copy pathpyproject.toml
File metadata and controls
102 lines (93 loc) · 4.75 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
# Root manifest for the uv workspace. This is NOT a deployable Python project
# (`tool.uv.package = false` keeps uv from building it). It exists to:
#
# 1. Declare the uv workspace (`[tool.uv.workspace]`) so all Python projects in
# the repo resolve against a single shared lock graph.
# 2. Hold repo-wide tool config (ruff, ty) — one canonical home, mirrored by
# per-project overrides only when needed.
# 3. Carry deps used by repo-level scripts (currently `packaging`, consumed by
# meta/scripts/ratify_renovate_proposals.py) and the temporary smoke target.
#
# `members = []` is intentional. The existing `tools/` subdirs are Go modules,
# so a `tools/*` glob would error at lock time; members are added explicitly as
# real Python projects land.
[project]
name = "unnatural-designs-workspace"
version = "0.0.0"
description = "Workspace root for the unnatural_designs monorepo. Not a published package."
requires-python = ">=3.14"
dependencies = [
# pep440 version comparison for meta/scripts/ratify_renovate_proposals.py.
# The script ratifies Renovate's Python dep-bump proposals via uv; comparing
# resolved vs. proposed versions reliably needs proper pep440 semantics rather
# than lexical string compare.
"packaging>=24.0",
# TODO: delete this dep along with the meta/scripts/smoke_py smoke target once the
# pip.parse chain has been verified end-to-end.
"requests>=2.32",
]
[tool.uv]
package = false
required-version = ">=0.9"
# TEND(project-expand): every new Python project lands as an entry (or matching glob)
# here so uv pulls it into the workspace resolution. check_modules.py's
# check_python_workspace_members catches a forgotten one at CI time; this tag is the
# forward pointer at the site that needs updating.
[tool.uv.workspace]
members = []
# ruff: format + lint. Single repo-wide config. Per-project pyproject.toml
# files inherit unless they redeclare `[tool.ruff]`. CI runs `ruff format
# --check .` and `ruff check .`; pre-commit runs the fixing variants.
[tool.ruff]
line-length = 100
target-version = "py314"
# Where first-party code lives. Load-bearing: ruff's `I` (isort) rules classify
# top-level dirs listed here as first-party and group their imports separately
# from third-party. A missed entry surfaces as `I001` ("imports out of order")
# in a *different* file than this one — the symptom decoupled from the cause.
# TEND(project-expand): every new top-level Python root (apps/, services/,
# libs/, infra/, etc.) is added here so ruff classifies its imports correctly.
src = ["meta", "tools"]
extend-exclude = [
"bazel-*",
".venv",
"venv",
]
[tool.ruff.lint]
# Strict-but-reasonable. E/F = pycodestyle + pyflakes baseline; I = import sort;
# B = bugbear (real bugs, not style); UP = pyupgrade (modern syntax); SIM =
# code-simplification; RUF = ruff's own catches; S = bandit security rules.
select = ["E", "F", "I", "B", "UP", "SIM", "RUF", "S"]
[tool.ruff.lint.per-file-ignores]
# meta/scripts shell out to first-party tools (`git`, `go`) by name. S607
# (partial executable path) and S603 (untrusted subprocess input) flag those
# calls, but the executables come from a controlled devcontainer/CI PATH and
# the arguments are not externally controlled — false positives in this
# context.
"meta/scripts/**" = ["S603", "S607"]
# Same false positives, same reason: the devcontainer plumbing tests shell out to `bash`
# by name to source the scripts under test.
".devcontainer/**" = ["S603", "S607"]
"meta/devcontainer-base/**" = ["S603", "S607"]
# Test conveniences that aren't actual problems in test code:
# S101 = `assert` (the whole point of a test); S105/S106/S311 = throwaway
# "secrets" and non-crypto randomness in fixtures; S108 = stable fake paths
# like "/tmp/repo" used as mock arguments (no actual temp file is created).
"**/test_*.py" = ["S101", "S105", "S106", "S108", "S311"]
"**/*_test.py" = ["S101", "S105", "S106", "S108", "S311"]
# ty: static type checker. Single repo-wide config. CI runs `uvx ty@<pin> check`;
# the editor extension (`astral-sh.ty` in devcontainer.json) reads the same
# section. Rule severities are left at ty's defaults (see comment below).
[tool.ty]
[tool.ty.environment]
python-version = "3.14"
[tool.ty.src]
# Mirror ruff's `src` so ty scans the same first-party trees. Excludes cover
# Bazel's symlink farm, virtualenvs, and the host-state directory populated by
# .devcontainer/initialize.sh (none of which are first-party source).
include = ["meta", "tools"]
exclude = ["bazel-*", ".venv", "venv", ".git-plumbing"]
# Rule severities are left at ty's defaults for now. ty ships with a
# strict-leaning default profile and refining the rule map preemptively (before
# real Python code lands) would be speculative; tighten as needed when real
# code surfaces a category of finding we want to escalate.