typecheck-runner 0.2.0__tar.gz → 0.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: typecheck-runner
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Summary: Unified api to multiple typecheckers
5
5
  Keywords: typecheck-runner
6
6
  Author: William P. Krekelberg
@@ -16,6 +16,7 @@ Classifier: Programming Language :: Python :: 3.11
16
16
  Classifier: Programming Language :: Python :: 3.12
17
17
  Classifier: Programming Language :: Python :: 3.13
18
18
  Classifier: Programming Language :: Python :: 3.14
19
+ Classifier: Programming Language :: Python :: 3.15
19
20
  Classifier: Programming Language :: Python :: Implementation :: CPython
20
21
  Classifier: Programming Language :: Python :: Implementation :: PyPy
21
22
  Classifier: Topic :: Utilities
@@ -0,0 +1,466 @@
1
+ [build-system]
2
+ build-backend = "uv_build"
3
+ requires = ["uv-build>=0.12.24,<0.13.0"]
4
+
5
+ [project]
6
+ name = "typecheck-runner"
7
+ version = "0.2.2"
8
+ description = "Unified api to multiple typecheckers"
9
+ readme = "README.md"
10
+ keywords = ["typecheck-runner"]
11
+ license = "NIST-PD"
12
+ license-files = ["LICENSE"]
13
+ requires-python = ">=3.10"
14
+ classifiers = [
15
+ "Development Status :: 2 - Pre-Alpha",
16
+ "Operating System :: OS Independent",
17
+ "Programming Language :: Python",
18
+ "Programming Language :: Python :: 3 :: Only",
19
+ "Programming Language :: Python :: 3.10",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Programming Language :: Python :: 3.13",
23
+ "Programming Language :: Python :: 3.14",
24
+ "Programming Language :: Python :: 3.15",
25
+ "Programming Language :: Python :: Implementation :: CPython",
26
+ "Programming Language :: Python :: Implementation :: PyPy",
27
+ "Topic :: Utilities",
28
+ "Typing :: Typed",
29
+ ]
30
+ dependencies = ["packaging>=25.0"]
31
+
32
+ [[project.authors]]
33
+ name = "William P. Krekelberg"
34
+ email = "wpk@nist.gov"
35
+
36
+ [project.urls]
37
+ Homepage = "https://github.com/wpk-nist-gov/typecheck-runner"
38
+
39
+ [project.scripts]
40
+ typecheck-runner = "typecheck_runner.typecheck_runner:main"
41
+
42
+ [dependency-groups]
43
+ test = [
44
+ "pytest-cov",
45
+ "pytest-sugar",
46
+ "tomli; python_version<'3.11'",
47
+ { include-group = "pytest" },
48
+ ]
49
+ basedpyright = ["basedpyright>=1.40.2"]
50
+ ipython = ["ipython"]
51
+ mypy = ["mypy[faster-cache]>=2.4.0"]
52
+ nox = ["nox>=2026.8.17"]
53
+ pylint = ["pylint"]
54
+ pytest = ["pytest"]
55
+
56
+ [[dependency-groups.dev]]
57
+ include-group = "mypy"
58
+
59
+ [[dependency-groups.dev]]
60
+ include-group = "nox"
61
+
62
+ [[dependency-groups.dev]]
63
+ include-group = "test"
64
+
65
+ [[dependency-groups.dev]]
66
+ include-group = "type"
67
+
68
+ [[dependency-groups.type]]
69
+ include-group = "nox"
70
+
71
+ [[dependency-groups.type]]
72
+ include-group = "pylint"
73
+
74
+ [[dependency-groups.type]]
75
+ include-group = "pytest"
76
+
77
+ [[dependency-groups.test-extras]]
78
+ include-group = "test"
79
+
80
+ [tool.uv]
81
+ required-version = ">=0.11.8"
82
+ default-groups = ["dev"]
83
+ fork-strategy = "requires-python"
84
+ exclude-newer = "7 days"
85
+ managed = true
86
+
87
+ [tool.uv.exclude-newer-package]
88
+ prek = "0 days"
89
+
90
+ [tool.uv.build-backend]
91
+ source-exclude = [".*cache"]
92
+ source-include = ["tests/**"]
93
+
94
+ [tool.uv.pip]
95
+ annotation-style = "line"
96
+ generate-hashes = true
97
+
98
+ [tool.uv.dependency-groups.dev]
99
+ requires-python = ">=3.14"
100
+
101
+ [tool.uv.dependency-groups.ipython]
102
+ requires-python = ">=3.14"
103
+
104
+ [tool.uv.dependency-groups.mypy]
105
+ requires-python = ">=3.14"
106
+
107
+ [tool.uv.dependency-groups.nox]
108
+ requires-python = ">=3.14"
109
+
110
+ [tool.ruff]
111
+ extend-include = ["*.ipynb"]
112
+ extend-exclude = [
113
+ ".numba_cache",
114
+ ".venv",
115
+ "dist-conda",
116
+ ]
117
+ fix = true
118
+
119
+ [tool.ruff.format]
120
+ preview = true
121
+ docstring-code-format = true
122
+
123
+ [tool.ruff.lint]
124
+ select = ["ALL"]
125
+ ignore = [
126
+ "any-type",
127
+ "COM",
128
+ "CPY",
129
+ "docstring-missing-exception",
130
+ "docstring-missing-returns",
131
+ "FBT",
132
+ "import-outside-top-level",
133
+ "incorrect-blank-line-before-class",
134
+ "lambda-assignment",
135
+ "line-too-long",
136
+ "missing-blank-line-after-summary",
137
+ "missing-trailing-period",
138
+ "multi-line-summary-first-line",
139
+ "non-imperative-mood",
140
+ "relative-imports",
141
+ "start-process-with-partial-path",
142
+ "subprocess-without-shell-equals-true",
143
+ "suspicious-subprocess-import",
144
+ "undocumented-magic-method",
145
+ "undocumented-public-init",
146
+ ]
147
+ unfixable = [
148
+ "ERA",
149
+ "non-augmented-assignment",
150
+ "T",
151
+ ]
152
+ preview = true
153
+
154
+ [tool.ruff.lint.per-file-ignores]
155
+ "src/**" = [
156
+ "NPY",
157
+ "PD",
158
+ ]
159
+ "tests/**" = [
160
+ "assert",
161
+ "D",
162
+ ]
163
+
164
+ [tool.ruff.lint.isort]
165
+ known-first-party = ["typecheck_runner"]
166
+
167
+ [tool.ruff.lint.pydocstyle]
168
+ convention = "numpy"
169
+
170
+ [tool.ruff.lint.pylint]
171
+ max-args = 15
172
+ max-positional-args = 15
173
+ max-public-methods = 30
174
+
175
+ [tool.ruff.lint.ruff]
176
+ strictly-empty-init-modules = false
177
+
178
+ [tool.repo-review]
179
+ ignore = [
180
+ "NOX103",
181
+ "PC111",
182
+ "PC140",
183
+ "PC160",
184
+ "PC170",
185
+ "PY004",
186
+ ]
187
+
188
+ [tool.deptry]
189
+ known_first_party = ["typecheck_runner"]
190
+
191
+ [tool.deptry.per_rule_ignores]
192
+ DEP001 = ["pkginfo"]
193
+ DEP004 = [
194
+ "nox",
195
+ "pytest",
196
+ ]
197
+
198
+ [tool.pyproject-fmt]
199
+ indent = 4
200
+ keep_full_version = true
201
+ expand_tables = [
202
+ "project.entry-points",
203
+ "project.optional-dependencies",
204
+ "project.scripts",
205
+ "project.urls",
206
+ "tool.mypy.overrides",
207
+ "tool.pyproject2conda",
208
+ "tool.pyrefly",
209
+ "tool.pyright.executionEnvironments",
210
+ "tool.pytest",
211
+ "tool.ruff.format",
212
+ "tool.ruff.lint",
213
+ "tool.ruff.lint.per-file-ignores",
214
+ "tool.ty.overrides",
215
+ "tool.ty.rules",
216
+ "tool.typos",
217
+ "tool.uv.dependency-groups",
218
+ "tool.uv.exclude-newer-package",
219
+ ]
220
+
221
+ [tool.typos.default.extend-identifiers]
222
+ CPY = "CPY"
223
+
224
+ [tool.mypy]
225
+ files = [
226
+ "noxfile.py",
227
+ "src",
228
+ "tests",
229
+ "tools",
230
+ ]
231
+ check_untyped_defs = true
232
+ warn_unused_ignores = true
233
+ warn_return_any = true
234
+ warn_unreachable = true
235
+ enable_error_code = [
236
+ "ignore-without-code",
237
+ "redundant-expr",
238
+ "truthy-bool",
239
+ ]
240
+ strict = true
241
+ warn_unused_configs = true
242
+
243
+ [tool.pyrefly]
244
+ project-includes = [
245
+ "noxfile.py",
246
+ "src",
247
+ "tests",
248
+ "tools",
249
+ ]
250
+ search-path = ["."]
251
+ enabled-ignores = ["pyrefly"]
252
+ min-severity = "warn"
253
+ preset = "strict"
254
+
255
+ [tool.pyrefly.errors]
256
+ implicit-abstract-class = "error"
257
+ implicit-any = "error"
258
+ implicitly-defined-attribute = "error"
259
+ missing-override-decorator = "error"
260
+ missing-source = "ignore"
261
+ not-required-key-access = "error"
262
+ open-unpacking = "error"
263
+ unannotated-attribute = "error"
264
+ unannotated-parameter = "error"
265
+ unannotated-return = "error"
266
+ untyped-import = "error"
267
+ unused-ignore = "error"
268
+ variance-mismatch = "error"
269
+
270
+ [[tool.pyrefly.sub-config]]
271
+ matches = "noxfile.py"
272
+
273
+ [tool.pyrefly.sub-config.errors]
274
+ open-unpacking = "ignore"
275
+
276
+ [tool.pyright]
277
+ typeCheckingMode = "strict"
278
+ include = [
279
+ "noxfile.py",
280
+ "src",
281
+ "tests",
282
+ "tools",
283
+ ]
284
+ exclude = [
285
+ "**/.mypy_cache",
286
+ "**/.numba_cache",
287
+ "**/__pycache__",
288
+ ".nox/**",
289
+ ".tox/**",
290
+ ".venv/**",
291
+ ]
292
+ enableTypeIgnoreComments = false
293
+ deprecateTypingAliases = true
294
+ reportCallInDefaultInitializer = true
295
+ reportImplicitOverride = true
296
+ reportImplicitStringConcatenation = false
297
+ reportImportCycles = true
298
+ reportOverlappingOverload = true
299
+ reportPrivateImportUsage = false
300
+ reportPrivateUsage = false
301
+ reportPropertyTypeMismatch = true
302
+ reportUninitializedInstanceVariable = true
303
+ reportUnnecessaryTypeIgnoreComment = true
304
+ reportUnreachable = "warning"
305
+ reportUntypedClassDecorator = true
306
+ reportUntypedFunctionDecorator = true
307
+ reportUnusedCallResult = true
308
+ reportUnusedImport = false
309
+ reportUnusedVariable = false
310
+ enableReachabilityAnalysis = false
311
+
312
+ [[tool.pyright.executionEnvironments]]
313
+ reportUnusedCallResult = false
314
+ root = "tests"
315
+
316
+ [tool.ty.src]
317
+ include = [
318
+ "noxfile.py",
319
+ "src",
320
+ "tests",
321
+ "tools",
322
+ ]
323
+
324
+ [tool.ty.analysis]
325
+ respect-type-ignore-comments = false
326
+
327
+ [tool.ty.rules]
328
+ division-by-zero = "error"
329
+ possibly-missing-import = "error"
330
+ possibly-unresolved-reference = "error"
331
+ unsupported-dynamic-base = "error"
332
+ unused-ignore-comment = "error"
333
+
334
+ [tool.pytest.ini_options]
335
+ minversion = "8"
336
+ testpaths = [
337
+ "README.md",
338
+ "tests",
339
+ "typecheck_runner",
340
+ ]
341
+ addopts = [
342
+ "--cov-config=pyproject.toml",
343
+ "--doctest-glob=*.md",
344
+ "--doctest-modules",
345
+ "--pyargs",
346
+ "--strict-config",
347
+ "--strict-markers",
348
+ "-ra",
349
+ ]
350
+ filterwarnings = ["error"]
351
+ log_level = "INFO"
352
+ log_cli_level = "INFO"
353
+ strict_xfail = "true"
354
+
355
+ [tool.coverage.run]
356
+ source = ["typecheck_runner"]
357
+ branch = true
358
+
359
+ [tool.coverage.paths]
360
+ source = [
361
+ "src/",
362
+ ".nox/**/site-packages/",
363
+ "*/.nox/**/site-packages",
364
+ "*/src",
365
+ ]
366
+
367
+ [tool.coverage.report]
368
+ include = ["src/*"]
369
+ omit = [
370
+ "*/_typing.py",
371
+ "*/vendored/*",
372
+ ]
373
+ exclude_also = [
374
+ "@overload",
375
+ "if __name__",
376
+ "if TYPE_CHECKING:",
377
+ ]
378
+ show_missing = true
379
+
380
+ [tool.commitizen]
381
+ use_shortcuts = true
382
+
383
+ [tool.pyproject2conda]
384
+ template-python = "requirements/py{py}-{env}"
385
+ template = "requirements/{env}"
386
+ name = "py{py}-{env}"
387
+ python = "default"
388
+ channels = "conda-forge"
389
+ style = "yaml"
390
+ conda-deps = "pip"
391
+
392
+ [tool.pyproject2conda.envs.dev]
393
+ groups = "dev"
394
+
395
+ [tool.pyproject2conda.envs.test]
396
+ groups = "test"
397
+ python = "all"
398
+
399
+ [tool.pyproject2conda.envs.test-extras]
400
+ groups = "test-extras"
401
+ python = "all"
402
+ skip-package = true
403
+
404
+ [tool.pyproject2conda.envs.uvx-tools]
405
+ pip-deps = [
406
+ "conda-lock>=4.0.2",
407
+ "copier-template-extensions>=0.3.3",
408
+ "copier>=9.18.2",
409
+ "grayskull>=3.2.0",
410
+ "prek>=0.5.5",
411
+ "pyrefly>=1.3.2",
412
+ "pyright>=1.1.414",
413
+ "rooster>=0.1.1",
414
+ "rust-just>=1.58.0",
415
+ "twine>=7.0.0",
416
+ "ty>=0.0.85",
417
+ ]
418
+ groups = [
419
+ "basedpyright",
420
+ "mypy",
421
+ "nox",
422
+ ]
423
+ skip-package = true
424
+ style = "requirements"
425
+
426
+ [tool.uv-locker]
427
+ scripts = [
428
+ "noxfile.py",
429
+ "tools/check_dist_version.py",
430
+ "tools/cog_runner.py",
431
+ ]
432
+
433
+ [[tool.uv-locker.requirements]]
434
+ path = "requirements/uvx-tools.txt"
435
+ output-file = "requirements/lock/uvx-tools.txt"
436
+ python = "min"
437
+ options = [
438
+ "--no-deps",
439
+ "--no-strip-extras",
440
+ "--universal",
441
+ ]
442
+
443
+ [tool.rooster]
444
+ changelog_contributors = true
445
+ major-labels = ["breaking"]
446
+ minor_labels = ["enhancement"]
447
+ patch-labels = [
448
+ "bug",
449
+ "documentation",
450
+ ]
451
+ ignore-labels = ["internal"]
452
+ require-labels = [
453
+ "breaking",
454
+ "bug",
455
+ "documentation",
456
+ "enhancement",
457
+ ]
458
+ version_files = ["pyproject.toml"]
459
+
460
+ [tool.rooster.section-labels]
461
+ "Breaking changes" = ["breaking"]
462
+ "Bug fixes" = ["bug"]
463
+ Documentation = ["documentation"]
464
+ Enhancements = ["enhancement"]
465
+ Internal = ["internal"]
466
+ "Other changes" = ["__unknown__"]
@@ -1,12 +1,12 @@
1
1
  [build-system]
2
2
  build-backend = "uv_build"
3
3
  requires = [
4
- "uv-build>=0.11.0,<0.12.0",
4
+ "uv-build>=0.12.24,<0.13.0",
5
5
  ]
6
6
 
7
7
  [project]
8
8
  name = "typecheck-runner"
9
- version = "0.2.0"
9
+ version = "0.2.2"
10
10
  description = "Unified api to multiple typecheckers"
11
11
  readme = "README.md"
12
12
  keywords = [
@@ -28,6 +28,7 @@ classifiers = [
28
28
  "Programming Language :: Python :: 3.12",
29
29
  "Programming Language :: Python :: 3.13",
30
30
  "Programming Language :: Python :: 3.14",
31
+ "Programming Language :: Python :: 3.15",
31
32
  "Programming Language :: Python :: Implementation :: CPython",
32
33
  "Programming Language :: Python :: Implementation :: PyPy",
33
34
  "Topic :: Utilities",
@@ -37,12 +38,12 @@ dependencies = [
37
38
  "packaging>=25.0",
38
39
  ]
39
40
 
40
- [project.scripts]
41
- typecheck-runner = "typecheck_runner.typecheck_runner:main"
42
-
43
41
  [project.urls]
44
42
  Homepage = "https://github.com/wpk-nist-gov/typecheck-runner"
45
43
 
44
+ [project.scripts]
45
+ typecheck-runner = "typecheck_runner.typecheck_runner:main"
46
+
46
47
  [dependency-groups]
47
48
  dev = [
48
49
  { include-group = "mypy" },
@@ -62,24 +63,26 @@ type = [
62
63
  { include-group = "pytest" },
63
64
  ]
64
65
  # other groups
65
- basedpyright = [ "basedpyright>=1.31.3" ]
66
- cog = [ "cogapp" ]
66
+ basedpyright = [ "basedpyright>=1.40.2" ]
67
67
  ipython = [ "ipython" ]
68
- mypy = [ "mypy[faster-cache]>=1.15.0" ]
69
- nox = [ "nox>=2025.5.1" ]
68
+ mypy = [ "mypy[faster-cache]>=2.4.0" ]
69
+ nox = [ "nox>=2026.8.17" ]
70
70
  pylint = [ "pylint" ]
71
71
  pytest = [ "pytest" ]
72
72
  test-extras = [
73
73
  { include-group = "test" },
74
74
  ]
75
75
 
76
- # * uv -------------------------------------------------------------------------
76
+ # * uv ---------------------------------------------------------------------------------------------
77
77
  [tool.uv]
78
- required-version = ">=0.7.15"
78
+ required-version = ">=0.11.8"
79
79
  default-groups = [ "dev" ]
80
80
  fork-strategy = "requires-python"
81
81
  exclude-newer = "7 days"
82
+ # Needed until prek>=0.5.0 is 7 days old
83
+ exclude-newer-package = { prek = "0 days" }
82
84
  managed = true
85
+ build-backend.source-exclude = [ ".*cache" ]
83
86
  build-backend.source-include = [ "tests/**" ]
84
87
  pip.annotation-style = "line"
85
88
  pip.generate-hashes = true
@@ -87,12 +90,80 @@ pip.generate-hashes = true
87
90
  [tool.uv.dependency-groups]
88
91
  dev.requires-python = ">=3.14"
89
92
  # other tools
90
- cog.requires-python = ">=3.14"
91
93
  ipython.requires-python = ">=3.14"
92
94
  mypy.requires-python = ">=3.14"
93
95
  nox.requires-python = ">=3.14"
94
96
 
95
- # * Checks ---------------------------------------------------------------------
97
+ # * ruff -------------------------------------------------------------------------------------------
98
+ [tool.ruff]
99
+ extend-include = [
100
+ "*.ipynb",
101
+ ]
102
+ extend-exclude = [
103
+ ".numba_cache",
104
+ ".venv",
105
+ "dist-conda",
106
+ ]
107
+ fix = true
108
+ # unsafe-fixes = true
109
+
110
+ [tool.ruff.format]
111
+ preview = true # needed for markdown support
112
+ docstring-code-format = true
113
+
114
+ [tool.ruff.lint.per-file-ignores]
115
+ "src/**" = [
116
+ "NPY", # - not using numpy?
117
+ "PD", # - not using pandas?
118
+ ]
119
+ "tests/**" = [
120
+ "assert", # - Assert is fine with tests
121
+ "D", # - Don't need to document tests
122
+ ]
123
+
124
+ [tool.ruff.lint]
125
+ select = [
126
+ "ALL",
127
+ ]
128
+ ignore = [
129
+ "any-type", # - Any ok sometimes
130
+ "COM", # - flake8-commas, formatter should take care of this?
131
+ "CPY", # - Don't require copyright
132
+ "docstring-missing-exception", # - Missing raises from documentation
133
+ "docstring-missing-returns", # - Missing return from documentation
134
+ "FBT", # - bools are ok
135
+ "import-outside-top-level", # - import should be at top level (leads to issues with imports in func?)
136
+ "incorrect-blank-line-before-class", # - 1 blank line required before class docstring
137
+ "lambda-assignment", # - do not assign a lambda expression, use a def
138
+ "line-too-long", # - line too long - let formatter fix this
139
+ "missing-blank-line-after-summary", # - blank line after summary
140
+ "missing-trailing-period", # - First line should end with a period
141
+ "multi-line-summary-first-line", # - Multi-line docstring summary should start at the first line
142
+ "non-imperative-mood", # - First line of docstring should be in imperative mood: "{first_line}"
143
+ "relative-imports", # - Allow relative imports
144
+ "start-process-with-partial-path", # - start-process-with-partial-path
145
+ "subprocess-without-shell-equals-true", # - subprocess-without-shell-equals-true
146
+ "suspicious-subprocess-import", # - Want to use subprocess sometimes
147
+ "undocumented-magic-method", # - Missing magic method docstring
148
+ "undocumented-public-init", # - Missing docstring in __init__
149
+ ]
150
+ # fixable = [ "ALL" ]
151
+ unfixable = [
152
+ "ERA",
153
+ "non-augmented-assignment",
154
+ "T",
155
+ ]
156
+ isort.known-first-party = [
157
+ "typecheck_runner",
158
+ ]
159
+ pydocstyle.convention = "numpy"
160
+ pylint.max-args = 15
161
+ pylint.max-positional-args = 15
162
+ pylint.max-public-methods = 30
163
+ preview = true
164
+ ruff.strictly-empty-init-modules = false
165
+
166
+ # * Checks -----------------------------------------------------------------------------------------
96
167
  [tool.repo-review]
97
168
  ignore = [
98
169
  "NOX103", # I prefer using "nox.options.sessions"
@@ -103,8 +174,16 @@ ignore = [
103
174
  "PY004", # no docs for simple tool
104
175
  ]
105
176
 
177
+ [tool.deptry]
178
+ known_first_party = [ "typecheck_runner" ]
179
+ # Group: ignores
180
+ per_rule_ignores.DEP001 = [ "pkginfo" ]
181
+ per_rule_ignores.DEP004 = [ "nox", "pytest" ]
182
+
106
183
  [tool.pyproject-fmt]
107
- # max_supported_python = "3.13"
184
+ indent = 4
185
+ keep_full_version = true
186
+ # max_supported_python = "3.14"
108
187
  expand_tables = [
109
188
  "project.entry-points",
110
189
  "project.optional-dependencies",
@@ -112,51 +191,89 @@ expand_tables = [
112
191
  "project.urls",
113
192
  "tool.mypy.overrides",
114
193
  "tool.pyproject2conda",
194
+ "tool.pyrefly",
115
195
  "tool.pyright.executionEnvironments",
116
196
  "tool.pytest",
197
+ "tool.ruff.format",
198
+ "tool.ruff.lint",
199
+ "tool.ruff.lint.per-file-ignores",
200
+ "tool.ty.overrides",
201
+ "tool.ty.rules",
117
202
  "tool.typos",
118
203
  "tool.uv.dependency-groups",
204
+ "tool.uv.exclude-newer-package",
119
205
  ]
120
- indent = 4
121
- keep_full_version = true
122
206
 
123
207
  [tool.typos.default.extend-identifiers]
124
208
  CPY = "CPY"
125
209
 
126
- # * typecheck ---------------------------------------------------------------------
210
+ # * typecheck --------------------------------------------------------------------------------------
127
211
  [tool.mypy]
128
212
  files = [
213
+ "noxfile.py",
129
214
  "src",
130
215
  "tests",
131
- # tools
132
- "noxfile.py",
133
216
  "tools",
134
217
  ]
135
- strict = true
136
218
  # options
137
219
  check_untyped_defs = true
220
+ warn_unused_ignores = true
221
+ warn_return_any = true
222
+ warn_unreachable = true
138
223
  enable_error_code = [
139
224
  "ignore-without-code",
140
225
  "redundant-expr",
141
226
  "truthy-bool",
142
227
  ]
143
- warn_return_any = true
144
- warn_unreachable = true
228
+ strict = true
145
229
  warn_unused_configs = true
146
- warn_unused_ignores = true
147
230
 
148
231
  [tool.pyrefly]
149
- enabled-ignores = [ "pyrefly" ]
150
232
  project-includes = [
233
+ "noxfile.py",
151
234
  "src",
152
235
  "tests",
153
- # tools
154
- "noxfile.py",
155
236
  "tools",
156
237
  ]
157
238
  search-path = [ "." ]
239
+ enabled-ignores = [ "pyrefly" ]
240
+ min-severity = "warn"
241
+ preset = "strict"
242
+
243
+ [tool.pyrefly.errors]
244
+ # NOTE: overlap between below and strict mode
245
+ implicit-abstract-class = "error"
246
+ implicit-any = "error"
247
+ implicitly-defined-attribute = "error"
248
+ missing-override-decorator = "error"
249
+ missing-source = "ignore"
250
+ not-required-key-access = "error"
251
+ open-unpacking = "error"
252
+ unannotated-attribute = "error"
253
+ unannotated-parameter = "error"
254
+ unannotated-return = "error"
255
+ untyped-import = "error"
256
+ unused-ignore = "error"
257
+ variance-mismatch = "error"
258
+
259
+ [[tool.pyrefly.sub-config]]
260
+ matches = "noxfile.py"
261
+ errors.open-unpacking = "ignore"
158
262
 
159
263
  [tool.pyright]
264
+ typeCheckingMode = "strict"
265
+ # strict = [
266
+ # "noxfile.py",
267
+ # "src",
268
+ # "tests",
269
+ # "tools/*.py",
270
+ # ]
271
+ include = [
272
+ "noxfile.py",
273
+ "src",
274
+ "tests",
275
+ "tools",
276
+ ]
160
277
  exclude = [
161
278
  "**/.mypy_cache",
162
279
  "**/.numba_cache",
@@ -165,30 +282,17 @@ exclude = [
165
282
  ".tox/**",
166
283
  ".venv/**",
167
284
  ]
168
- include = [
169
- "src",
170
- "tests",
171
- # tools
172
- "noxfile.py",
173
- "tools",
174
- ]
175
- typeCheckingMode = "strict"
176
- # typeCheckingMode = "standard"
177
- # strict = [
178
- # "src",
179
- # "tests",
180
- # "noxfile.py",
181
- # "tools/*.py",
182
- # ]
183
- # options
184
- # reportMissingSuperCall = true
185
- deprecateTypingAliases = true
186
- enableReachabilityAnalysis = false
187
285
  enableTypeIgnoreComments = false
286
+ deprecateTypingAliases = true
188
287
  reportCallInDefaultInitializer = true
189
288
  reportImplicitOverride = true
289
+ reportImplicitStringConcatenation = false
190
290
  reportImportCycles = true
291
+ # options
292
+ # reportMissingSuperCall = true
191
293
  reportOverlappingOverload = true
294
+ reportPrivateImportUsage = false
295
+ reportPrivateUsage = false
192
296
  reportPropertyTypeMismatch = true
193
297
  reportUninitializedInstanceVariable = true
194
298
  reportUnnecessaryTypeIgnoreComment = true
@@ -196,30 +300,38 @@ reportUnreachable = "warning"
196
300
  reportUntypedClassDecorator = true
197
301
  reportUntypedFunctionDecorator = true
198
302
  reportUnusedCallResult = true
199
- # type-checkers should type-check; linters should lint
200
- reportImplicitStringConcatenation = false
201
- reportPrivateImportUsage = false
202
- reportPrivateUsage = false
203
303
  reportUnusedImport = false
204
304
  reportUnusedVariable = false
305
+ enableReachabilityAnalysis = false
205
306
 
206
307
  [[tool.pyright.executionEnvironments]]
207
308
  reportUnusedCallResult = false
208
309
  root = "tests"
209
310
 
210
311
  [tool.ty]
211
- # Disable support for `type: ignore` comments
212
- analysis.respect-type-ignore-comments = false
213
312
  src.include = [
313
+ "noxfile.py",
214
314
  "src",
215
315
  "tests",
216
- # tools
217
- "noxfile.py",
218
316
  "tools",
219
317
  ]
318
+ analysis.respect-type-ignore-comments = false
319
+
320
+ [tool.ty.rules]
321
+ division-by-zero = "error"
322
+ possibly-missing-import = "error"
323
+ possibly-unresolved-reference = "error"
324
+ unsupported-dynamic-base = "error"
325
+ unused-ignore-comment = "error"
220
326
 
221
- # * Testing --------------------------------------------------------------------
327
+ # * Testing ----------------------------------------------------------------------------------------
222
328
  [tool.pytest.ini_options]
329
+ minversion = "8"
330
+ testpaths = [
331
+ "README.md",
332
+ "tests",
333
+ "typecheck_runner",
334
+ ]
223
335
  addopts = [
224
336
  "--cov-config=pyproject.toml",
225
337
  "--doctest-glob=*.md",
@@ -229,23 +341,17 @@ addopts = [
229
341
  "--strict-markers",
230
342
  "-ra",
231
343
  ]
232
- testpaths = [
233
- "README.md",
234
- "tests",
235
- "typecheck_runner",
236
- ]
237
344
  # options
238
345
  filterwarnings = [ "error" ]
239
- log_cli_level = "INFO"
240
346
  log_level = "INFO"
241
- minversion = "8"
347
+ log_cli_level = "INFO"
242
348
  strict_xfail = "true"
243
349
 
244
350
  [tool.coverage]
245
- run.branch = true
246
351
  run.source = [
247
352
  "typecheck_runner",
248
353
  ]
354
+ run.branch = true
249
355
  paths.source = [
250
356
  "src/",
251
357
  # required for installed package doctests
@@ -253,11 +359,6 @@ paths.source = [
253
359
  "*/.nox/**/site-packages",
254
360
  "*/src",
255
361
  ]
256
- report.exclude_also = [
257
- "@overload",
258
- "if __name__",
259
- "if TYPE_CHECKING:",
260
- ]
261
362
  report.include = [
262
363
  "src/*",
263
364
  ]
@@ -265,18 +366,25 @@ report.omit = [
265
366
  "*/_typing.py",
266
367
  "*/vendored/*",
267
368
  ]
369
+ report.exclude_also = [
370
+ "@overload",
371
+ "if __name__",
372
+ "if TYPE_CHECKING:",
373
+ ]
268
374
  report.show_missing = true
269
375
 
270
- # * Dependency creation --------------------------------------------------------
376
+ [tool.commitizen]
377
+ use_shortcuts = true
378
+
379
+ # * Dependency creation ----------------------------------------------------------------------------
271
380
  [tool.pyproject2conda]
272
- user-config = "config/userconfig.toml"
273
381
  template-python = "requirements/py{py}-{env}"
274
382
  template = "requirements/{env}"
275
383
  name = "py{py}-{env}"
276
384
  python = "default"
277
385
  channels = "conda-forge"
278
386
  style = "yaml"
279
- deps = "pip"
387
+ conda-deps = "pip"
280
388
 
281
389
  [tool.pyproject2conda.envs.dev]
282
390
  groups = "dev"
@@ -291,18 +399,19 @@ python = "all"
291
399
  skip-package = true
292
400
 
293
401
  [tool.pyproject2conda.envs.uvx-tools]
294
- reqs = [
402
+ pip-deps = [
295
403
  # these used solely for specking tools to be run via uvx ...
296
- "conda-lock>=2.5.5",
297
- "copier",
298
- "copier-template-extensions>=0.3.1",
299
- "grayskull>=2.5.3",
300
- "prek",
301
- "pyrefly>=0.37.0",
302
- "pyright>=1.1.396",
404
+ "conda-lock>=4.0.2",
405
+ "copier-template-extensions>=0.3.3", # sync-pyproject-min-versions: ignore
406
+ "copier>=9.18.2",
407
+ "grayskull>=3.2.0",
408
+ "prek>=0.5.5",
409
+ "pyrefly>=1.3.2",
410
+ "pyright>=1.1.414",
303
411
  "rooster>=0.1.1",
304
- "twine>=5.0.0",
305
- "ty>=0.0.14",
412
+ "rust-just>=1.58.0",
413
+ "twine>=7.0.0",
414
+ "ty>=0.0.85",
306
415
  ]
307
416
  groups = [
308
417
  "basedpyright",
@@ -312,10 +421,24 @@ groups = [
312
421
  skip-package = true
313
422
  style = "requirements"
314
423
 
315
- # * Other tools ----------------------------------------------------------------
316
- [tool.commitizen]
317
- use_shortcuts = true
424
+ [tool.uv-locker]
425
+ scripts = [
426
+ "noxfile.py",
427
+ "tools/check_dist_version.py",
428
+ "tools/cog_runner.py",
429
+ ]
430
+
431
+ [[tool.uv-locker.requirements]]
432
+ path = "requirements/uvx-tools.txt"
433
+ output-file = "requirements/lock/uvx-tools.txt"
434
+ python = "min"
435
+ options = [
436
+ "--no-deps",
437
+ "--no-strip-extras",
438
+ "--universal",
439
+ ]
318
440
 
441
+ # * Other tools ------------------------------------------------------------------------------------
319
442
  [tool.rooster]
320
443
  changelog_contributors = true
321
444
  major-labels = [ "breaking" ]
@@ -6,7 +6,7 @@ Top level API (:mod:`typecheck_runner`)
6
6
  from importlib.metadata import PackageNotFoundError
7
7
  from importlib.metadata import version as _version
8
8
 
9
- try: # noqa: RUF067
9
+ try: # ruff:ignore[non-empty-init-module]
10
10
  __version__ = _version("typecheck-runner")
11
11
  except PackageNotFoundError: # pragma: no cover
12
12
  __version__ = "999"
@@ -31,7 +31,7 @@ FORMAT = "[typecheck-runner %(levelname)s] %(message)s"
31
31
  logger: Logger = logging.getLogger(__name__)
32
32
 
33
33
 
34
- # * Utilities -----------------------------------------------------------------
34
+ # * Utilities --------------------------------------------------------------------------
35
35
  def _setup_logging(
36
36
  verbosity: int = 0,
37
37
  stdout: bool = False,
@@ -50,7 +50,7 @@ def _setup_logging(
50
50
  logging.basicConfig(level=logging.WARNING, format=FORMAT)
51
51
 
52
52
 
53
- # * Runner --------------------------------------------------------------------
53
+ # * Runner -----------------------------------------------------------------------------
54
54
 
55
55
 
56
56
  def _infer_venv_location() -> Path:
@@ -202,25 +202,26 @@ def _get_python_flags(
202
202
 
203
203
  def _run_checker(
204
204
  *args: str,
205
+ checker: str,
205
206
  dry_run: bool = False,
206
207
  ) -> int:
207
208
  cleaned_args = [os.fsdecode(arg) for arg in args]
208
209
  full_cmd = shlex.join(cleaned_args)
209
- logger.info("Command: %s", full_cmd)
210
+ logger.info("%s command: %s", checker, full_cmd)
210
211
 
211
212
  if dry_run:
212
213
  return 0
213
214
 
214
215
  start_time = perf_counter()
215
216
  returncode = subprocess.call(cleaned_args)
216
- logger.info("Execution time: %s", perf_counter() - start_time)
217
+ logger.info("%s execution time: %s", checker, perf_counter() - start_time)
217
218
  if returncode:
218
- logger.error("Failed with exit code: %s", returncode)
219
+ logger.error("%s exit code: %s", checker, returncode)
219
220
 
220
221
  return returncode
221
222
 
222
223
 
223
- # * Application ---------------------------------------------------------------
224
+ # * Application ------------------------------------------------------------------------
224
225
  def get_parser() -> ArgumentParser:
225
226
  """Get argparser."""
226
227
  parser = ArgumentParser(description="Run executable using uvx.")
@@ -381,7 +382,7 @@ def main(args: Sequence[str] | None = None) -> int:
381
382
  if options.version:
382
383
  from typecheck_runner import __version__
383
384
 
384
- print("typecheck-runner", __version__) # noqa: T201
385
+ print("typecheck-runner", __version__) # ruff:ignore[print]
385
386
  return 0
386
387
 
387
388
  if not options.checkers:
@@ -418,11 +419,13 @@ def main(args: Sequence[str] | None = None) -> int:
418
419
  uvx_delimiter=options.uvx_delimiter,
419
420
  uvx_options=uvx_options,
420
421
  )
421
- logger.info("Checker: %s", checker)
422
+ _ = sys.stderr.write(f"\n> {checker}\n")
423
+ logger.info("%s checker", checker)
422
424
  checker_code = _run_checker(
423
425
  *args,
424
426
  *_get_python_flags(checker, python_version, python_executable),
425
427
  *options.args,
428
+ checker=checker,
426
429
  dry_run=options.dry_run,
427
430
  )
428
431
  if options.fail_fast and checker_code:
@@ -1,4 +1,4 @@
1
- # ruff: noqa: SLF001
1
+ # ruff:file-ignore[private-member-access]
2
2
  # pylint: disable=protected-access,use-implicit-booleaness-not-comparison-to-zero
3
3
  from __future__ import annotations
4
4
 
@@ -412,7 +412,7 @@ def test__parser_command_uvx(
412
412
  )
413
413
  @patch("typecheck_runner.typecheck_runner.shutil.which", side_effect=_dummy_which)
414
414
  def test__parse_command_no_uvx(
415
- mock_which: Any, # noqa: ARG001
415
+ mock_which: Any, # ruff:ignore[unused-function-argument]
416
416
  command: str,
417
417
  expected_command: str,
418
418
  expected_args: list[str],
@@ -427,7 +427,7 @@ def test__parse_command_no_uvx(
427
427
  def test__parse_command_no_uvx_no_which() -> None:
428
428
  with patch(
429
429
  "typecheck_runner.typecheck_runner.shutil.which",
430
- side_effect=lambda x: None, # pyright: ignore[reportUnknownLambdaType] # noqa: ARG005
430
+ side_effect=lambda x: None, # pyright: ignore[reportUnknownLambdaType] # ruff:ignore[unused-lambda-argument] # pyrefly: ignore [implicit-any-lambda]
431
431
  ):
432
432
  assert typecheck_runner._parse_command("hello -b --c", True, "", []) == (
433
433
  "hello",
@@ -500,7 +500,10 @@ def test__run_checker(
500
500
  autospec=True,
501
501
  return_value=return_value,
502
502
  ) as mocked_call:
503
- assert typecheck_runner._run_checker(*args, dry_run=dry_run) == expected
503
+ assert (
504
+ typecheck_runner._run_checker(*args, checker="dummy", dry_run=dry_run)
505
+ == expected
506
+ )
504
507
  assert (
505
508
  mocked_logger.error.call_count == 0 if (dry_run or not return_value) else 1
506
509
  )
@@ -575,7 +578,7 @@ def test__run_checker(
575
578
  @patch("typecheck_runner.typecheck_runner._run_checker", autospec=True, return_value=0)
576
579
  @patch("typecheck_runner.typecheck_runner.shutil.which", side_effect=_dummy_which)
577
580
  def test_main(
578
- mocked_which: Any, # noqa: ARG001
581
+ mocked_which: Any, # ruff:ignore[unused-function-argument]
579
582
  mocked_run_checker: Any,
580
583
  checkers: list[str],
581
584
  args: Sequence[str],
@@ -583,7 +586,7 @@ def test_main(
583
586
  ) -> None:
584
587
  assert not typecheck_runner.main(args)
585
588
  assert mocked_run_checker.call_args_list == [
586
- call(*[str(Path(e[0])), *e[1:]], dry_run=False)
589
+ call(*[str(Path(e[0])), *e[1:]], checker=checker, dry_run=False)
587
590
  for checker, e in zip(checkers, expecteds, strict=True)
588
591
  ]
589
592
 
@@ -621,7 +624,7 @@ def test_main(
621
624
  @patch("typecheck_runner.typecheck_runner._run_checker", autospec=True, return_value=1)
622
625
  @patch("typecheck_runner.typecheck_runner.shutil.which", side_effect=_identity)
623
626
  def test_main_fail_fast(
624
- mocked_which: Any, # noqa: ARG001
627
+ mocked_which: Any, # ruff:ignore[unused-function-argument]
625
628
  mocked_run_checker: Any,
626
629
  checkers: list[str],
627
630
  args: Sequence[str],
@@ -638,7 +641,8 @@ def test_main_fail_fast(
638
641
 
639
642
  assert out == len(expects)
640
643
  assert mocked_run_checker.call_args_list == [
641
- call(*e, dry_run=False) for checker, e in zip(checkers, expecteds, strict=True)
644
+ call(*e, checker=checker, dry_run=False)
645
+ for checker, e in zip(checkers, expecteds, strict=True)
642
646
  ]
643
647
 
644
648
 
@@ -646,7 +650,7 @@ def test_main_fail_fast(
646
650
  def test_main_help(
647
651
  mocked_run_checker: Any,
648
652
  ) -> None:
649
- assert typecheck_runner.main([]) == 2 # noqa: PLR2004
653
+ assert typecheck_runner.main([]) == 2 # ruff:ignore[magic-value-comparison]
650
654
  assert mocked_run_checker.call_args_list == []
651
655
 
652
656
 
@@ -661,6 +665,6 @@ def test_main_version(mocked_print: Any) -> None:
661
665
  @patch("typecheck_runner.typecheck_runner.main", return_value=0)
662
666
  def test__main__(mocked_main: Any) -> None:
663
667
  with contextlib.suppress(SystemExit):
664
- import typecheck_runner.__main__ # noqa: F401
668
+ import typecheck_runner.__main__ # ruff:ignore[unused-import]
665
669
 
666
670
  mocked_main.assert_called_once_with()