python-constricter 0.3.2__tar.gz → 0.3.5__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.
- {python_constricter-0.3.2 → python_constricter-0.3.5}/.gitignore +1 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/PKG-INFO +42 -38
- {python_constricter-0.3.2 → python_constricter-0.3.5}/README.md +41 -37
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/__init__.py +1 -1
- python_constricter-0.3.5/constricter/__main__.py +26 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/cli/command.py +111 -56
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/cli/config.py +30 -2
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/cli/hints.py +18 -12
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/cli/options.py +57 -3
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/cli/protocol.py +25 -5
- python_constricter-0.3.5/constricter/cli/remembered.py +52 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/cli/report.py +7 -5
- python_constricter-0.3.5/constricter/cli/runs.py +90 -0
- python_constricter-0.3.5/constricter/cli/schedule.py +415 -0
- python_constricter-0.3.5/constricter/cli/traced.py +401 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/cli/workers.py +85 -23
- python_constricter-0.3.5/constricter/fix/core/asked.py +56 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/core/fixes.py +63 -9
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/core/imports.py +196 -10
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/core/inherited.py +128 -15
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/core/known.py +271 -55
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/core/signatures.py +29 -6
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/index/atoms.py +22 -4
- python_constricter-0.3.5/constricter/fix/index/awaits.py +90 -0
- python_constricter-0.3.5/constricter/fix/index/beyond.py +148 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/index/callers.py +3 -2
- python_constricter-0.3.5/constricter/fix/index/chained.py +69 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/index/classnames.py +17 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/index/declared.py +83 -3
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/index/decorated.py +4 -2
- python_constricter-0.3.5/constricter/fix/index/fixtures.py +176 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/index/installed.py +68 -15
- python_constricter-0.3.5/constricter/fix/index/linked.py +142 -0
- python_constricter-0.3.5/constricter/fix/index/loose.py +98 -0
- python_constricter-0.3.5/constricter/fix/index/managed.py +63 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/index/modules.py +368 -46
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/index/offers.py +4 -1
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/index/order.py +13 -3
- python_constricter-0.3.5/constricter/fix/index/own_methods.py +67 -0
- python_constricter-0.3.5/constricter/fix/index/own_overloads.py +70 -0
- python_constricter-0.3.5/constricter/fix/index/own_types.py +161 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/index/plain.py +13 -8
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/index/project.py +222 -180
- python_constricter-0.3.5/constricter/fix/index/read.py +70 -0
- python_constricter-0.3.5/constricter/fix/index/sides.py +160 -0
- python_constricter-0.3.5/constricter/fix/index/strings.py +46 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/index/stubbed.py +86 -80
- python_constricter-0.3.5/constricter/fix/index/taken.py +45 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/index/tuples.py +54 -28
- python_constricter-0.3.5/constricter/fix/libraries/library.py +374 -0
- python_constricter-0.3.5/constricter/fix/libraries/opened.py +147 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/libraries/overloads.py +155 -14
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/libraries/stdlib.py +278 -24
- python_constricter-0.3.5/constricter/fix/libraries/walks.py +49 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/tables/attributes.json +25 -0
- python_constricter-0.3.5/constricter/fix/tables/awaited.json +69 -0
- python_constricter-0.3.5/constricter/fix/tables/awaited_overloads.json +14 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/tables/classes.json +3 -1
- python_constricter-0.3.5/constricter/fix/tables/elements.json +156 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/tables/functions.json +0 -1
- python_constricter-0.3.5/constricter/fix/tables/generic_attributes.json +254 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/tables/method_overloads.json +146 -99
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/tables/method_signatures.json +229 -40
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/tables/methods.json +35 -10
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/tables/overloads.json +88 -63
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/tables/scalars.json +5 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/tables/source.json +4 -1
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/tables/subscriptable.json +1 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/tables/type_parameters.json +3 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/tables/variables.json +21 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/values/aliased.py +9 -1
- python_constricter-0.3.5/constricter/fix/values/bodies.py +76 -0
- python_constricter-0.3.5/constricter/fix/values/callables.py +321 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/values/called.py +10 -12
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/values/classvars.py +216 -40
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/values/decided.py +74 -11
- python_constricter-0.3.5/constricter/fix/values/displays.py +87 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/values/doubts.py +152 -28
- python_constricter-0.3.5/constricter/fix/values/entered.py +331 -0
- python_constricter-0.3.5/constricter/fix/values/fills.py +434 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/values/guesses.py +80 -21
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/values/hinted.py +94 -7
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/values/inference.py +145 -146
- python_constricter-0.3.5/constricter/fix/values/members.py +564 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/values/narrowed.py +60 -4
- python_constricter-0.3.5/constricter/fix/values/operated.py +200 -0
- python_constricter-0.3.5/constricter/fix/values/ordered.py +74 -0
- python_constricter-0.3.5/constricter/fix/values/returned.py +967 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/values/returns.py +45 -1
- python_constricter-0.3.5/constricter/fix/values/shapes.py +494 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/values/targets.py +51 -18
- python_constricter-0.3.5/constricter/fix/values/unchecked.py +162 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/offences.py +48 -6
- python_constricter-0.3.5/constricter/recording.py +571 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/rules/annotations.py +52 -13
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/rules/binding.py +237 -48
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/rules/calls.py +222 -26
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/rules/checker.py +301 -77
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/rules/decorators.py +12 -0
- python_constricter-0.3.5/constricter/rules/keys.py +79 -0
- python_constricter-0.3.5/constricter/rules/late.py +663 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/rules/parsed.py +42 -3
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/rules/quoted.py +32 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/rules/rebinding.py +38 -11
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/rules/recorded.py +53 -10
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/rules/scope.py +291 -88
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/rules/syntax.py +20 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/rules/tables.py +79 -9
- python_constricter-0.3.5/constricter/rules/widened.py +322 -0
- python_constricter-0.3.5/constricter/trace.py +378 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/pyproject.toml +56 -8
- python_constricter-0.3.5/stdlib_tables/elements.py +101 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/stdlib_tables/generate.py +176 -16
- {python_constricter-0.3.2 → python_constricter-0.3.5}/stdlib_tables/overloads.py +123 -34
- {python_constricter-0.3.2 → python_constricter-0.3.5}/stdlib_tables/reading.py +57 -11
- {python_constricter-0.3.2 → python_constricter-0.3.5}/stdlib_tables/templates.py +6 -1
- python_constricter-0.3.2/constricter/__main__.py +0 -9
- python_constricter-0.3.2/constricter/cli/runs.py +0 -43
- python_constricter-0.3.2/constricter/cli/schedule.py +0 -242
- python_constricter-0.3.2/constricter/fix/index/sides.py +0 -65
- python_constricter-0.3.2/constricter/fix/libraries/library.py +0 -172
- python_constricter-0.3.2/constricter/fix/libraries/opened.py +0 -74
- python_constricter-0.3.2/constricter/fix/tables/generic_attributes.json +0 -55
- python_constricter-0.3.2/constricter/fix/values/entered.py +0 -152
- python_constricter-0.3.2/constricter/fix/values/fills.py +0 -256
- python_constricter-0.3.2/constricter/fix/values/members.py +0 -277
- python_constricter-0.3.2/constricter/fix/values/returned.py +0 -706
- python_constricter-0.3.2/constricter/fix/values/shapes.py +0 -279
- python_constricter-0.3.2/constricter/rules/late.py +0 -324
- {python_constricter-0.3.2 → python_constricter-0.3.5}/LICENSE.md +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/cli/__init__.py +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/cli/baseline.py +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/cli/collecting.py +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/cli/edits.py +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/cli/explain.py +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/cli/guard.py +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/cli/paths.py +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/__init__.py +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/core/__init__.py +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/index/__init__.py +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/libraries/__init__.py +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/tables/aliases.json +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/tables/bases.json +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/tables/returns.json +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/tables/scalar_members.json +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/fix/values/__init__.py +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/jsonc.py +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/noqa.py +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/notebook.py +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/plugins/__init__.py +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/plugins/flake8.py +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/plugins/pylint.py +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/py.typed +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/rules/__init__.py +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/rules/flow.py +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/rules/narrowing.py +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/rules/redundant.py +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/constricter/rules/walked.py +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/hatch_build.py +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/stdlib_tables/__init__.py +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/stdlib_tables/__main__.py +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/stdlib_tables/partial.json +0 -0
- {python_constricter-0.3.2 → python_constricter-0.3.5}/stdlib_tables/stubs.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: python-constricter
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.5
|
|
4
4
|
Import-Name: constricter
|
|
5
5
|
Summary: Lint rules: every local variable is typed where it's first bound. A flake8 plugin, a pylint plugin and a standalone CLI.
|
|
6
6
|
Author: Ivy Duggan
|
|
@@ -173,37 +173,39 @@ enabled).
|
|
|
173
173
|
|
|
174
174
|
Options:
|
|
175
175
|
|
|
176
|
-
| Option | CLI
|
|
177
|
-
| ---------------- |
|
|
178
|
-
| level | `--level`
|
|
179
|
-
| strictest | `--max`: `--level=suffocate` for every path, `--all-scopes`, and the opt-in `LVA012`
|
|
180
|
-
| every fix | `--max-fix`: `--max`, `--fix --unsafe-fixes`, and `--infer-with` each of basedpyright, ty and pyrefly that's installed and runs
|
|
181
|
-
| type comments | `--type-comments`
|
|
182
|
-
| all scopes | `--all-scopes`
|
|
183
|
-
| nesting | `--nesting N`
|
|
184
|
-
| max length | `--max-length N` (LVA011)
|
|
185
|
-
| vague | `--vague LEVEL` (LVA005, and the fixes offered): -1 none (the default), 0 one `Any` inside a type that says the rest (`tuple[str, Any]`), N from 1 N + 1, or one alone
|
|
186
|
-
| min python | `--min-python VERSION` (the oldest Python the code runs on, whose syntax `--fix` writes; default: `requires-python`'s)
|
|
187
|
-
| type hierarchy | -
|
|
188
|
-
| fix | `--fix` (`--unsafe-fixes` for guesses), `--diff` to preview
|
|
189
|
-
| infer with | `--infer-with CHECKERS` (`basedpyright`, `ty`, `pyrefly`, several: inferred types, as guesses)
|
|
190
|
-
|
|
|
191
|
-
|
|
|
192
|
-
| fix
|
|
193
|
-
|
|
|
194
|
-
|
|
|
195
|
-
|
|
|
196
|
-
|
|
|
197
|
-
|
|
|
198
|
-
|
|
|
199
|
-
|
|
|
200
|
-
|
|
|
201
|
-
|
|
|
202
|
-
|
|
|
203
|
-
|
|
|
204
|
-
|
|
|
205
|
-
|
|
|
206
|
-
|
|
|
176
|
+
| Option | CLI | `[tool.constricter]` | flake8 (CLI or config) | pylint |
|
|
177
|
+
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | ------------------------------- | --------------------------------- |
|
|
178
|
+
| level | `--level` | `level` | `--constricter-level` | `constricter-level` |
|
|
179
|
+
| strictest | `--max`: `--level=suffocate` for every path, `--all-scopes`, and the opt-in `LVA012` | — | — | — |
|
|
180
|
+
| every fix | `--max-fix`: `--max`, `--fix --unsafe-fixes`, and `--infer-with` each of basedpyright, ty and pyrefly that's installed and runs | — | — | — |
|
|
181
|
+
| type comments | `--type-comments` | `type-comments` | `--constricter-type-comments` | `constricter-type-comments = yes` |
|
|
182
|
+
| all scopes | `--all-scopes` | `all-scopes` | `--constricter-all-scopes` | `constricter-all-scopes = yes` |
|
|
183
|
+
| nesting | `--nesting N` | `nesting` | `--constricter-nesting` | `constricter-nesting` |
|
|
184
|
+
| max length | `--max-length N` (LVA011) | `max-length` | `--constricter-max-length` | `constricter-max-length` |
|
|
185
|
+
| vague | `--vague LEVEL` (LVA005, and the fixes offered): -1 none (the default), 0 one `Any` inside a type that says the rest (`tuple[str, Any]`), N from 1 N + 1, or one alone | `vague` | `--constricter-vague` | `constricter-vague` |
|
|
186
|
+
| min python | `--min-python VERSION` (the oldest Python the code runs on, whose syntax `--fix` writes; default: `requires-python`'s) | `min-python` | - | - |
|
|
187
|
+
| type hierarchy | - | `narrower` (a table) | `--constricter-narrower` | `constricter-narrower` |
|
|
188
|
+
| fix | `--fix` (`--unsafe-fixes` for guesses), `--diff` to preview | - | - | - |
|
|
189
|
+
| infer with | `--infer-with CHECKERS` (`basedpyright`, `ty`, `pyrefly`, several: inferred types, as guesses) | `infer-with` | - | - |
|
|
190
|
+
| infer from | `--infer-from FILE` (the types `python -m constricter.trace -m pytest` recorded from a run, as guesses) | `infer-from` | - | - |
|
|
191
|
+
| show fixes | `--show-fixes` (each fix and how it was decided; with `--fix`, those made too) | - | - | - |
|
|
192
|
+
| fix levels | `--fix-select`, `--fix-ignore`, `--unsafe-fix-select` (mechanisms: [docs/FIXES.md](https://github.com/ivylikethevine/python-constricter/blob/main/docs/FIXES.md#fix-levels)) | `fix-select`, `fix-ignore`, `unsafe-fix-select` | - | - |
|
|
193
|
+
| fix plain bases | `--fix-plain-bases BASES` (frameworks' classes whose subclasses' bodies `--fix` annotates; django's are built in) | `fix-plain-bases` | - | - |
|
|
194
|
+
| fix widen | `--fix-widen KINDS` (wider types `--fix` may write, each marked: `untyped-parameters`, `empty-containers`, `mixed-containers`, `unions`, `vague`, `untyped-calls`, `unknown-calls`; `all`: every one; [docs/FIXES.md](https://github.com/ivylikethevine/python-constricter/blob/main/docs/FIXES.md#wider-types-fix-widen)) | `fix-widen` | - | - |
|
|
195
|
+
| select | `--select CODES` (codes or prefixes) | `select` | flake8's own `select` | pylint's own `enable` |
|
|
196
|
+
| extend select | `--extend-select CODES` (also report these; an opt-in code by its full code) | `extend-select` | flake8's own `extend-select` | pylint's own `enable` |
|
|
197
|
+
| ignore | `--ignore CODES` | `ignore` | flake8's own `extend-ignore` | pylint's own `disable` |
|
|
198
|
+
| exclude | `--exclude GLOB` (repeatable) | `exclude` | flake8's own `exclude` | pylint's own `ignore-paths` |
|
|
199
|
+
| format | `--format`: `text`, `full` (with source), `json`, `github`, `sarif`, `gitlab`, `junit`, `rdjson` | - | - | - |
|
|
200
|
+
| statistics | `--statistics` (counts per code, text format) | - | - | - |
|
|
201
|
+
| jobs | `--jobs N` (`-j`; 0: one per CPU) | `jobs` | flake8's own `--jobs` | pylint's own `--jobs` |
|
|
202
|
+
| baseline | `--baseline FILE`; `--write-baseline` records it | `baseline` | - | - |
|
|
203
|
+
| coverage | `--coverage`, `--fail-under PCT` | - | - | - |
|
|
204
|
+
| per-path levels | - | `per-path-levels` | - | - |
|
|
205
|
+
| per-file ignores | - | `per-file-ignores` | flake8's own `per-file-ignores` | - |
|
|
206
|
+
| stdin | `-` as the path, `--stdin-filename PATH` | - | flake8's own `-` | - |
|
|
207
|
+
| exit status | `--exit-zero` | - | flake8's own `--exit-zero` | pylint's own `--exit-zero` |
|
|
208
|
+
| output file | `--output-file FILE` | - | flake8's own `--output-file` | pylint's own `--output` |
|
|
207
209
|
|
|
208
210
|
`constricter --explain LVA002` prints a code's rationale, its fix, and the levels that report it.
|
|
209
211
|
|
|
@@ -244,9 +246,11 @@ ignore = ["LVA003"]
|
|
|
244
246
|
return type or whose `return`s agree (in another checked file too), a copy, subscript, attribute or
|
|
245
247
|
method call of a local whose type is known, and values computed from those; a loop's target or an
|
|
246
248
|
unpacking's names get a declaration on the line before. `--unsafe-fixes` adds guesses, and
|
|
247
|
-
`--show-fixes` lists each fix and how its value decided it
|
|
248
|
-
`pyrefly`, or several: `basedpyright,ty`; each installed
|
|
249
|
-
what `--fix` can't type itself, as guesses
|
|
249
|
+
`--show-fixes` lists each fix and how its value decided it, and after `--fix` each one made.
|
|
250
|
+
`--infer-with basedpyright` (or `ty`, or `pyrefly`, or several: `basedpyright,ty`; each installed
|
|
251
|
+
alongside) asks those type checkers for what `--fix` can't type itself, as guesses;
|
|
252
|
+
`--infer-from FILE` takes the types a run bound each name to, recorded by
|
|
253
|
+
`python -m constricter.trace -m pytest`, the same way. The full list is in
|
|
250
254
|
[docs/FIXES.md](https://github.com/ivylikethevine/python-constricter/blob/main/docs/FIXES.md).
|
|
251
255
|
|
|
252
256
|
### Installing and running
|
|
@@ -272,7 +276,7 @@ pre-commit, after ruff's hooks (or `constricter-fix`, which runs `--fix` first):
|
|
|
272
276
|
|
|
273
277
|
```yaml
|
|
274
278
|
- repo: https://github.com/ivylikethevine/python-constricter
|
|
275
|
-
rev: v0.3.
|
|
279
|
+
rev: v0.3.5
|
|
276
280
|
hooks:
|
|
277
281
|
- id: constricter
|
|
278
282
|
```
|
|
@@ -305,8 +309,8 @@ default one is used only if it exists.
|
|
|
305
309
|
total; the bindings are the ones the rules cover (with `--all-scopes`, module and class bodies too),
|
|
306
310
|
and `# noqa` doesn't make one typed. `--fail-under PCT` (which implies `--coverage`) exits 1 below
|
|
307
311
|
PCT, so CI can hold a codebase to a share. With `--format=json` it prints
|
|
308
|
-
`{"typed", "total", "percent", "files"}`, which a badge can read: publish that JSON
|
|
309
|
-
gist, a release asset) and point
|
|
312
|
+
`{"typed", "total", "widened", "percent", "files"}`, which a badge can read: publish that JSON
|
|
313
|
+
somewhere (a gist, a release asset) and point
|
|
310
314
|
[shields.io's dynamic JSON badge](https://shields.io/badges/dynamic-json-badge) at it with the query
|
|
311
315
|
`$.percent`. This project keeps its own share at 100% in CI, so its badge is static.
|
|
312
316
|
|
|
@@ -146,37 +146,39 @@ enabled).
|
|
|
146
146
|
|
|
147
147
|
Options:
|
|
148
148
|
|
|
149
|
-
| Option | CLI
|
|
150
|
-
| ---------------- |
|
|
151
|
-
| level | `--level`
|
|
152
|
-
| strictest | `--max`: `--level=suffocate` for every path, `--all-scopes`, and the opt-in `LVA012`
|
|
153
|
-
| every fix | `--max-fix`: `--max`, `--fix --unsafe-fixes`, and `--infer-with` each of basedpyright, ty and pyrefly that's installed and runs
|
|
154
|
-
| type comments | `--type-comments`
|
|
155
|
-
| all scopes | `--all-scopes`
|
|
156
|
-
| nesting | `--nesting N`
|
|
157
|
-
| max length | `--max-length N` (LVA011)
|
|
158
|
-
| vague | `--vague LEVEL` (LVA005, and the fixes offered): -1 none (the default), 0 one `Any` inside a type that says the rest (`tuple[str, Any]`), N from 1 N + 1, or one alone
|
|
159
|
-
| min python | `--min-python VERSION` (the oldest Python the code runs on, whose syntax `--fix` writes; default: `requires-python`'s)
|
|
160
|
-
| type hierarchy | -
|
|
161
|
-
| fix | `--fix` (`--unsafe-fixes` for guesses), `--diff` to preview
|
|
162
|
-
| infer with | `--infer-with CHECKERS` (`basedpyright`, `ty`, `pyrefly`, several: inferred types, as guesses)
|
|
163
|
-
|
|
|
164
|
-
|
|
|
165
|
-
| fix
|
|
166
|
-
|
|
|
167
|
-
|
|
|
168
|
-
|
|
|
169
|
-
|
|
|
170
|
-
|
|
|
171
|
-
|
|
|
172
|
-
|
|
|
173
|
-
|
|
|
174
|
-
|
|
|
175
|
-
|
|
|
176
|
-
|
|
|
177
|
-
|
|
|
178
|
-
|
|
|
179
|
-
|
|
|
149
|
+
| Option | CLI | `[tool.constricter]` | flake8 (CLI or config) | pylint |
|
|
150
|
+
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | ------------------------------- | --------------------------------- |
|
|
151
|
+
| level | `--level` | `level` | `--constricter-level` | `constricter-level` |
|
|
152
|
+
| strictest | `--max`: `--level=suffocate` for every path, `--all-scopes`, and the opt-in `LVA012` | — | — | — |
|
|
153
|
+
| every fix | `--max-fix`: `--max`, `--fix --unsafe-fixes`, and `--infer-with` each of basedpyright, ty and pyrefly that's installed and runs | — | — | — |
|
|
154
|
+
| type comments | `--type-comments` | `type-comments` | `--constricter-type-comments` | `constricter-type-comments = yes` |
|
|
155
|
+
| all scopes | `--all-scopes` | `all-scopes` | `--constricter-all-scopes` | `constricter-all-scopes = yes` |
|
|
156
|
+
| nesting | `--nesting N` | `nesting` | `--constricter-nesting` | `constricter-nesting` |
|
|
157
|
+
| max length | `--max-length N` (LVA011) | `max-length` | `--constricter-max-length` | `constricter-max-length` |
|
|
158
|
+
| vague | `--vague LEVEL` (LVA005, and the fixes offered): -1 none (the default), 0 one `Any` inside a type that says the rest (`tuple[str, Any]`), N from 1 N + 1, or one alone | `vague` | `--constricter-vague` | `constricter-vague` |
|
|
159
|
+
| min python | `--min-python VERSION` (the oldest Python the code runs on, whose syntax `--fix` writes; default: `requires-python`'s) | `min-python` | - | - |
|
|
160
|
+
| type hierarchy | - | `narrower` (a table) | `--constricter-narrower` | `constricter-narrower` |
|
|
161
|
+
| fix | `--fix` (`--unsafe-fixes` for guesses), `--diff` to preview | - | - | - |
|
|
162
|
+
| infer with | `--infer-with CHECKERS` (`basedpyright`, `ty`, `pyrefly`, several: inferred types, as guesses) | `infer-with` | - | - |
|
|
163
|
+
| infer from | `--infer-from FILE` (the types `python -m constricter.trace -m pytest` recorded from a run, as guesses) | `infer-from` | - | - |
|
|
164
|
+
| show fixes | `--show-fixes` (each fix and how it was decided; with `--fix`, those made too) | - | - | - |
|
|
165
|
+
| fix levels | `--fix-select`, `--fix-ignore`, `--unsafe-fix-select` (mechanisms: [docs/FIXES.md](https://github.com/ivylikethevine/python-constricter/blob/main/docs/FIXES.md#fix-levels)) | `fix-select`, `fix-ignore`, `unsafe-fix-select` | - | - |
|
|
166
|
+
| fix plain bases | `--fix-plain-bases BASES` (frameworks' classes whose subclasses' bodies `--fix` annotates; django's are built in) | `fix-plain-bases` | - | - |
|
|
167
|
+
| fix widen | `--fix-widen KINDS` (wider types `--fix` may write, each marked: `untyped-parameters`, `empty-containers`, `mixed-containers`, `unions`, `vague`, `untyped-calls`, `unknown-calls`; `all`: every one; [docs/FIXES.md](https://github.com/ivylikethevine/python-constricter/blob/main/docs/FIXES.md#wider-types-fix-widen)) | `fix-widen` | - | - |
|
|
168
|
+
| select | `--select CODES` (codes or prefixes) | `select` | flake8's own `select` | pylint's own `enable` |
|
|
169
|
+
| extend select | `--extend-select CODES` (also report these; an opt-in code by its full code) | `extend-select` | flake8's own `extend-select` | pylint's own `enable` |
|
|
170
|
+
| ignore | `--ignore CODES` | `ignore` | flake8's own `extend-ignore` | pylint's own `disable` |
|
|
171
|
+
| exclude | `--exclude GLOB` (repeatable) | `exclude` | flake8's own `exclude` | pylint's own `ignore-paths` |
|
|
172
|
+
| format | `--format`: `text`, `full` (with source), `json`, `github`, `sarif`, `gitlab`, `junit`, `rdjson` | - | - | - |
|
|
173
|
+
| statistics | `--statistics` (counts per code, text format) | - | - | - |
|
|
174
|
+
| jobs | `--jobs N` (`-j`; 0: one per CPU) | `jobs` | flake8's own `--jobs` | pylint's own `--jobs` |
|
|
175
|
+
| baseline | `--baseline FILE`; `--write-baseline` records it | `baseline` | - | - |
|
|
176
|
+
| coverage | `--coverage`, `--fail-under PCT` | - | - | - |
|
|
177
|
+
| per-path levels | - | `per-path-levels` | - | - |
|
|
178
|
+
| per-file ignores | - | `per-file-ignores` | flake8's own `per-file-ignores` | - |
|
|
179
|
+
| stdin | `-` as the path, `--stdin-filename PATH` | - | flake8's own `-` | - |
|
|
180
|
+
| exit status | `--exit-zero` | - | flake8's own `--exit-zero` | pylint's own `--exit-zero` |
|
|
181
|
+
| output file | `--output-file FILE` | - | flake8's own `--output-file` | pylint's own `--output` |
|
|
180
182
|
|
|
181
183
|
`constricter --explain LVA002` prints a code's rationale, its fix, and the levels that report it.
|
|
182
184
|
|
|
@@ -217,9 +219,11 @@ ignore = ["LVA003"]
|
|
|
217
219
|
return type or whose `return`s agree (in another checked file too), a copy, subscript, attribute or
|
|
218
220
|
method call of a local whose type is known, and values computed from those; a loop's target or an
|
|
219
221
|
unpacking's names get a declaration on the line before. `--unsafe-fixes` adds guesses, and
|
|
220
|
-
`--show-fixes` lists each fix and how its value decided it
|
|
221
|
-
`pyrefly`, or several: `basedpyright,ty`; each installed
|
|
222
|
-
what `--fix` can't type itself, as guesses
|
|
222
|
+
`--show-fixes` lists each fix and how its value decided it, and after `--fix` each one made.
|
|
223
|
+
`--infer-with basedpyright` (or `ty`, or `pyrefly`, or several: `basedpyright,ty`; each installed
|
|
224
|
+
alongside) asks those type checkers for what `--fix` can't type itself, as guesses;
|
|
225
|
+
`--infer-from FILE` takes the types a run bound each name to, recorded by
|
|
226
|
+
`python -m constricter.trace -m pytest`, the same way. The full list is in
|
|
223
227
|
[docs/FIXES.md](https://github.com/ivylikethevine/python-constricter/blob/main/docs/FIXES.md).
|
|
224
228
|
|
|
225
229
|
### Installing and running
|
|
@@ -245,7 +249,7 @@ pre-commit, after ruff's hooks (or `constricter-fix`, which runs `--fix` first):
|
|
|
245
249
|
|
|
246
250
|
```yaml
|
|
247
251
|
- repo: https://github.com/ivylikethevine/python-constricter
|
|
248
|
-
rev: v0.3.
|
|
252
|
+
rev: v0.3.5
|
|
249
253
|
hooks:
|
|
250
254
|
- id: constricter
|
|
251
255
|
```
|
|
@@ -278,8 +282,8 @@ default one is used only if it exists.
|
|
|
278
282
|
total; the bindings are the ones the rules cover (with `--all-scopes`, module and class bodies too),
|
|
279
283
|
and `# noqa` doesn't make one typed. `--fail-under PCT` (which implies `--coverage`) exits 1 below
|
|
280
284
|
PCT, so CI can hold a codebase to a share. With `--format=json` it prints
|
|
281
|
-
`{"typed", "total", "percent", "files"}`, which a badge can read: publish that JSON
|
|
282
|
-
gist, a release asset) and point
|
|
285
|
+
`{"typed", "total", "widened", "percent", "files"}`, which a badge can read: publish that JSON
|
|
286
|
+
somewhere (a gist, a release asset) and point
|
|
283
287
|
[shields.io's dynamic JSON badge](https://shields.io/badges/dynamic-json-badge) at it with the query
|
|
284
288
|
`$.percent`. This project keeps its own share at 100% in CI, so its badge is static.
|
|
285
289
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
"""`python -m constricter`, and the `constricter` script."""
|
|
3
|
+
|
|
4
|
+
import contextlib
|
|
5
|
+
import os
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
from constricter.cli.command import main
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def run() -> None:
|
|
12
|
+
"""Run the command, and leave with its status at once.
|
|
13
|
+
|
|
14
|
+
Not by the interpreter's own exit, which frees every parsed file and the index an object at a
|
|
15
|
+
time: a fifth of a check of a thousand files. What the command wrote is flushed first; nothing
|
|
16
|
+
else waits on the exit (its workers have ended, its output file is closed).
|
|
17
|
+
"""
|
|
18
|
+
status: int = main()
|
|
19
|
+
with contextlib.suppress(OSError, ValueError): # a reader that left, a stream closed already
|
|
20
|
+
_ = sys.stdout.flush()
|
|
21
|
+
_ = sys.stderr.flush()
|
|
22
|
+
os._exit(status)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
if __name__ == "__main__": # not when `--jobs` workers import it
|
|
26
|
+
run()
|