-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpyproject.toml
More file actions
259 lines (185 loc) · 9.49 KB
/
Copy pathpyproject.toml
File metadata and controls
259 lines (185 loc) · 9.49 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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
[project]
name = "posit-vip"
version = "2026.10.0"
description = "Verified Installation of Posit - An extensible test suite for validating Posit Team deployments"
readme = "README.md"
license = { file = "LICENSE" }
authors = [
{ name = "Elliot Murphy", email = "elliot.murphy@posit.co" },
{ name = "Ian Flores Siaca", email = "iflores.siaca@posit.co" },
]
requires-python = ">=3.10"
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: System Administrators",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
]
dependencies = [
"filelock>=3.12,<5",
"httpx>=0.27,<1",
"playwright==1.63.0", # exact-pinned: shapes vip run output; see docs/development.md
"pyotp~=2.9",
"pytest==9.1.1", # exact-pinned; at/above CVE-2025-71176 floor (9.0.3)
"pytest-bdd==8.1.0", # exact-pinned
"pytest-order==1.5.0", # exact-pinned
"pytest-playwright==0.9.0", # exact-pinned
"pytest-xdist==3.8.0", # exact-pinned
"tomli>=2.0,<3;python_version<'3.11'",
"requests>=2.33.0,<3", # transitive via pytest-playwright; capped to track updates
"pygments>=2.20.0,<3", # CVE-2026-4539 fix
"pip>=26.1.2,<27", # CVE-2026-3219, PYSEC-2026-196 fix; transitive via pip-api
"mako>=1.3.12,<2", # CVE-2026-44307 fix; transitive via pytest-bdd
"idna>=3.15,<4", # CVE-2026-45409 fix; transitive via httpx/requests/anyio
"anyio>=4.14.2,<5", # CVE-2026-63374, CVE-2026-64847 fix; transitive via httpx
# Report rendering (`vip report` shells out to quarto, which starts a
# Jupyter kernel to execute report/*.qmd). Folded into base deps (was the
# [report] extra) so a bare `uv tool install posit-vip` can render without
# a second `--force ...[report]` install. See issue #554. Only the kernel
# itself is needed here -- Quarto does its own HTML conversion, so the
# heavier `jupyter`/`jupyterlab` metapackages (notebook, nbconvert,
# jupyter-console, ...) were pure bloat and have been dropped.
"pyyaml>=6.0,<7", # imported directly by Quarto's own kernel-launch script
"jupyter-client>=8.0,<9", # imported directly by Quarto's own kernel-launch script
"ipykernel<8",
"nbformat>=5.7,<6",
"nbclient>=0.8,<1",
"tornado>=6.5.7,<7", # CVE-2026-31958, GHSA-pw6j-qg29-8w7f fix; transitive via ipykernel
]
[project.optional-dependencies]
# Back-compat alias: the report/jupyter stack moved into [project.dependencies]
# (issue #554) so a bare install renders. `posit-vip[report]` still resolves --
# it now just pulls the base deps, which already include everything it named.
report = []
load = [
"locust>=2.20,<3",
"click>=8.3.3,<9", # PYSEC-2026-2132 fix; transitive via flask/locust
"msgpack>=1.2.1,<2", # GHSA-6v7p-g79w-8964 fix; transitive via locust
"python-engineio>=4.13.2,<5", # CVE-2026-48802, CVE-2026-48809 fix; transitive via locust
"python-socketio>=5.16.2,<6", # CVE-2026-48804 fix; transitive via locust
]
dev = [
"ruff==0.16.9",
"mypy>=1.10",
"pytest-cov>=6.0",
"pip-audit>=2.7",
"msgpack>=1.2.1", # GHSA-6v7p-g79w-8964 fix; transitive via pip-audit (cachecontrol)
]
[project.urls]
Homepage = "https://posit-dev.github.io/vip/"
Repository = "https://github.com/posit-dev/vip"
Documentation = "https://posit-dev.github.io/vip/getting-started/"
Changelog = "https://github.com/posit-dev/vip/blob/main/CHANGELOG.md"
[project.scripts]
vip = "vip.cli:main"
[project.entry-points.pytest11]
vip = "vip.plugin"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.uv]
# Pin the uv version used in this repo so `uv.lock` is reproducible across
# machines. Older uv (< 0.11) strips the `upload-time` wheel annotations and
# uses an older lockfile revision, which churns ~2000 lines on any relock. The
# floor rejects those versions for every uv command; `just relock` pins an exact
# version on top of it. See docs/development.md ("The lockfile").
required-version = ">=0.11"
# urllib3 is transitive. Floor it at the first release that fixes
# CVE-2026-97687/97688/97689 so a relock cannot resolve back to a vulnerable 2.7.x.
constraint-dependencies = ["urllib3>=2.8.0"]
[tool.hatch.build.targets.wheel]
packages = ["src/vip", "src/vip_tests"]
[tool.hatch.build.targets.wheel.force-include]
"examples/cross_product_validation" = "vip/_scaffold/cross_product_validation"
"examples/custom_tests" = "vip/_scaffold/custom_tests"
# AGENTS.md source shared by every scaffold template; copied into the output
# dir by run_scaffold() after copytree(). Keep this path in sync with
# _resolve_scaffold_source("_shared") in src/vip/cli/scaffold.py.
"examples/_shared" = "vip/_scaffold/_shared"
# Quarto report templates so `vip report` works when installed as a wheel,
# not only from a source checkout. Copied into the working ./report dir by
# run_report(). Keep this list in sync with cli._REPORT_TEMPLATE_FILES.
"report/index.qmd" = "vip/_report/index.qmd"
"report/details.qmd" = "vip/_report/details.qmd"
"report/vip-report.qmd" = "vip/_report/vip-report.qmd"
# The PDF's vendored faces (Source Sans 3 / Source Code Pro, both OFL — the
# licenses ride along in the same directory). Vendored so the Typst render is
# identical on a laptop, in CI, and on an air-gapped host.
"report/fonts/SourceSans3-Regular.otf" = "vip/_report/fonts/SourceSans3-Regular.otf"
"report/fonts/SourceSans3-It.otf" = "vip/_report/fonts/SourceSans3-It.otf"
"report/fonts/SourceSans3-Semibold.otf" = "vip/_report/fonts/SourceSans3-Semibold.otf"
"report/fonts/SourceSans3-Bold.otf" = "vip/_report/fonts/SourceSans3-Bold.otf"
"report/fonts/SourceCodePro-Regular.otf" = "vip/_report/fonts/SourceCodePro-Regular.otf"
"report/fonts/LICENSE-SourceSans3.md" = "vip/_report/fonts/LICENSE-SourceSans3.md"
"report/fonts/LICENSE-SourceCodePro.md" = "vip/_report/fonts/LICENSE-SourceCodePro.md"
"report/_quarto.yml" = "vip/_report/_quarto.yml"
"report/styles.css" = "vip/_report/styles.css"
[tool.pytest.ini_options]
testpaths = ["src/vip_tests"]
addopts = "-n auto --dist loadgroup"
# Warning filters live in src/vip/plugin/configure.py::pytest_configure so they apply
# anywhere vip is installed, not just runs from this repo.
markers = [
"connect: tests for Posit Connect",
"workbench: tests for Posit Workbench",
"package_manager: tests for Posit Package Manager",
"prerequisites: prerequisite checks that run first",
"cross_product: tests that span multiple products",
"performance: performance validation tests (opt-in; excluded by default)",
"security: security validation tests",
"config_hygiene: checks of VIP's own configuration (opt-in; excluded by default)",
"slow: detailed/long-running checks; excluded by --basic",
"min_version(product, version): only run when product meets minimum version",
"if_applicable: test is skipped when the feature is not configured",
"api_auth: test requires only an API key, not browser credentials",
"rstudio: Workbench RStudio IDE scenario",
"vscode: Workbench VS Code IDE scenario",
"jupyter: Workbench JupyterLab IDE scenario",
"positron: Workbench Positron IDE scenario",
]
[tool.mypy]
python_version = "3.10"
warn_unused_configs = true
ignore_missing_imports = true
check_untyped_defs = true
no_implicit_optional = true
warn_unused_ignores = true
explicit_package_bases = true
namespace_packages = true
mypy_path = "src"
# vip_tests/selftests widen mypy's scope but never opted into wave 1's
# check_untyped_defs; scoping it off keeps the widening cheap (real bugs
# only) instead of surfacing untyped test-double/fixture noise. (Wave 1's
# other new flag, no_implicit_optional, is left enabled here -- it matches
# zero sites today, so scoping it off would carve out a blind spot for no
# present benefit.)
[[tool.mypy.overrides]]
module = ["vip_tests.*", "selftests.*"]
check_untyped_defs = false
# The load-test engine is the one place VIP builds and executes dynamic,
# heavily-generic locust/gevent plumbing; strict flags scoped here catch what
# --strict finds cheaply, without taking on --strict's cost across all of src/vip.
[[tool.mypy.overrides]]
module = ["vip.load_engine", "vip.load_users"]
disallow_untyped_defs = true
disallow_any_generics = true
warn_return_any = true
[tool.ruff]
line-length = 100
src = ["src", "selftests", "examples"]
[tool.ruff.lint]
select = ["ARG001", "ARG002", "ARG005", "B", "BLE", "C4", "D101", "D102", "D103", "D202", "D209", "D210", "D403", "D413", "E", "F", "I", "ISC", "N", "PERF", "PGH", "PIE", "PLC0207", "PLC0415", "PLR0124", "PLR0402", "PLR1711", "PLR5501", "PLW0108", "PLW1510", "PT", "PTH", "RET", "RUF001", "RUF002", "RUF003", "RUF012", "RUF023", "RUF043", "RUF059", "RUF100", "S101", "SIM", "TID", "UP"]
# PERF203: per-item try/except in cleanup and probe loops is deliberate (the loop must continue past a failing item), and the per-iteration cost it flags is gone on Python 3.11+.
ignore = [
"PERF203",
# SIM105: converting try/except Exception: pass to contextlib.suppress(Exception) would erase the noqa: BLE001 markers wave 2 narrows; re-enable after wave 2.
"SIM105",
]
[tool.ruff.lint.per-file-ignores]
"selftests/**" = ["ARG001", "ARG002", "ARG005", "D101", "D102", "D103", "PLC0415", "S101"]
"src/vip_tests/**" = ["ARG001", "ARG002", "ARG005", "D101", "D102", "D103", "PLC0415", "S101"]
"examples/**" = ["ARG001", "ARG002", "ARG005", "D101", "D102", "D103", "S101"]
"docker/**" = ["ARG001", "ARG002", "ARG005", "S101"]