python-linters 0.1.4__tar.gz → 0.1.6__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.
Files changed (23) hide show
  1. python_linters-0.1.6/.gitignore +161 -0
  2. python_linters-0.1.4/README.md → python_linters-0.1.6/PKG-INFO +52 -57
  3. python_linters-0.1.4/PKG-INFO → python_linters-0.1.6/README.md +38 -82
  4. python_linters-0.1.6/pyproject.toml +40 -0
  5. {python_linters-0.1.4 → python_linters-0.1.6}/python_linters/add_noqa.py +8 -6
  6. {python_linters-0.1.4 → python_linters-0.1.6}/python_linters/config_files.py +0 -2
  7. {python_linters-0.1.4 → python_linters-0.1.6}/python_linters/extending_ruff_toml.py +3 -3
  8. python_linters-0.1.6/python_linters/fix_code.py +25 -0
  9. {python_linters-0.1.4 → python_linters-0.1.6}/python_linters/getting_to_be_linted_folders.py +2 -11
  10. {python_linters-0.1.4 → python_linters-0.1.6}/python_linters/pyrightconfig.json +5 -1
  11. {python_linters-0.1.4 → python_linters-0.1.6}/python_linters/ruff.toml +6 -6
  12. {python_linters-0.1.4 → python_linters-0.1.6}/python_linters/ruff_rule_categories.py +4 -2
  13. python_linters-0.1.6/python_linters/ruff_rules.txt +1182 -0
  14. python_linters-0.1.6/python_linters/run_linters.py +49 -0
  15. python_linters-0.1.6/python_linters/utils.py +72 -0
  16. python_linters-0.1.4/pyproject.toml +0 -34
  17. python_linters-0.1.4/python_linters/.flake8 +0 -32
  18. python_linters-0.1.4/python_linters/fix_code.py +0 -29
  19. python_linters-0.1.4/python_linters/ruff_rules.txt +0 -956
  20. python_linters-0.1.4/python_linters/run_linters.py +0 -42
  21. {python_linters-0.1.4 → python_linters-0.1.6}/LICENSE +0 -0
  22. {python_linters-0.1.4 → python_linters-0.1.6}/python_linters/__init__.py +0 -0
  23. {python_linters-0.1.4 → python_linters-0.1.6}/python_linters/parse_rules.py +0 -0
@@ -0,0 +1,161 @@
1
+ _version.py
2
+ # Byte-compiled / optimized / DLL files
3
+ __pycache__/
4
+ *.py[cod]
5
+ *$py.class
6
+
7
+ # C extensions
8
+ *.so
9
+
10
+ # Distribution / packaging
11
+ .Python
12
+ build/
13
+ develop-eggs/
14
+ dist/
15
+ downloads/
16
+ eggs/
17
+ .eggs/
18
+ lib/
19
+ lib64/
20
+ parts/
21
+ sdist/
22
+ var/
23
+ wheels/
24
+ share/python-wheels/
25
+ *.egg-info/
26
+ .installed.cfg
27
+ *.egg
28
+ MANIFEST
29
+
30
+ # PyInstaller
31
+ # Usually these files are written by a python script from a template
32
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
33
+ *.manifest
34
+ *.spec
35
+
36
+ # Installer logs
37
+ pip-log.txt
38
+ pip-delete-this-directory.txt
39
+
40
+ # Unit test / coverage reports
41
+ htmlcov/
42
+ .tox/
43
+ .nox/
44
+ .coverage
45
+ .coverage.*
46
+ .cache
47
+ nosetests.xml
48
+ coverage.xml
49
+ *.cover
50
+ *.py,cover
51
+ .hypothesis/
52
+ .pytest_cache/
53
+ cover/
54
+
55
+ # Translations
56
+ *.mo
57
+ *.pot
58
+
59
+ # Django stuff:
60
+ *.log
61
+ local_settings.py
62
+ db.sqlite3
63
+ db.sqlite3-journal
64
+
65
+ # Flask stuff:
66
+ instance/
67
+ .webassets-cache
68
+
69
+ # Scrapy stuff:
70
+ .scrapy
71
+
72
+ # Sphinx documentation
73
+ docs/_build/
74
+
75
+ # PyBuilder
76
+ .pybuilder/
77
+ target/
78
+
79
+ # Jupyter Notebook
80
+ .ipynb_checkpoints
81
+
82
+ # IPython
83
+ profile_default/
84
+ ipython_config.py
85
+
86
+ # pyenv
87
+ # For a library or package, you might want to ignore these files since the code is
88
+ # intended to run in multiple environments; otherwise, check them in:
89
+ # .python-version
90
+
91
+ # pipenv
92
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
93
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
94
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
95
+ # install all needed dependencies.
96
+ #Pipfile.lock
97
+
98
+ # poetry
99
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
100
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
101
+ # commonly ignored for libraries.
102
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
103
+ #poetry.lock
104
+
105
+ # pdm
106
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
107
+ #pdm.lock
108
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
109
+ # in version control.
110
+ # https://pdm.fming.dev/#use-with-ide
111
+ .pdm.toml
112
+
113
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
114
+ __pypackages__/
115
+
116
+ # Celery stuff
117
+ celerybeat-schedule
118
+ celerybeat.pid
119
+
120
+ # SageMath parsed files
121
+ *.sage.py
122
+
123
+ # Environments
124
+ .env
125
+ .venv
126
+ env/
127
+ venv/
128
+ ENV/
129
+ env.bak/
130
+ venv.bak/
131
+
132
+ # Spyder project settings
133
+ .spyderproject
134
+ .spyproject
135
+
136
+ # Rope project settings
137
+ .ropeproject
138
+
139
+ # mkdocs documentation
140
+ /site
141
+
142
+ # mypy
143
+ .mypy_cache/
144
+ .dmypy.json
145
+ dmypy.json
146
+
147
+ # Pyre type checker
148
+ .pyre/
149
+
150
+ # pytype static type analyzer
151
+ .pytype/
152
+
153
+ # Cython debug symbols
154
+ cython_debug/
155
+
156
+ # PyCharm
157
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
158
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
159
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
160
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
161
+ .idea/
@@ -1,12 +1,44 @@
1
+ Metadata-Version: 2.4
2
+ Name: python-linters
3
+ Version: 0.1.6
4
+ Summary: bundling config files for linters like ruff and pyright
5
+ Project-URL: repository, https://github.com/dertilo/python-linters
6
+ Author-email: Tilo Himmelsbach <dertilo@gmail.com>
7
+ License: MIT
8
+ License-File: LICENSE
9
+ Requires-Python: <4.0,>=3.10
10
+ Requires-Dist: basedpyright<2.0.0,>=1.12.5
11
+ Requires-Dist: json-with-comments<2.0.0,>=1.2.9
12
+ Requires-Dist: ruff>=0.0.291
13
+ Requires-Dist: toml<1.0.0,>=0.10.2
14
+ Description-Content-Type: text/markdown
15
+
1
16
  ![pypi](https://github.com/dertilo/python-linters/actions/workflows/release.yml/badge.svg)
2
17
  [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
3
18
  [![bear-ified](https://raw.githubusercontent.com/beartype/beartype-assets/main/badge/bear-ified.svg)](https://beartype.readthedocs.io)
4
19
  # python-linters
5
- - bundles flake8, ruff and basedpyright into a single poetry-script
6
- - project independent linter configuration (via `ruff.toml`,`.flake8`) -> one config to rule them all
20
+ - bundles ruff and ~~flake8~~ basedpyright into a single ~~poetry~~uv-script
21
+ - even though I liked some flake8-rules (especially from [wemake-python-styleguide](https://wemake-python-styleguide.readthedocs.io/en/latest/)) dropped it in favor of ruff for being too slow
22
+ - project independent linter configuration (via `ruff.toml`,~~`.flake8`~~`pyrightconfig.json`) -> one config to rule them all
23
+ - well one can still override the default config via `ruff_extensions.toml` and `pyrightconfig.json`
7
24
  ### use-cases:
8
- 1. interactively learning python code quality standards via ruff+flake8, see [local development workflow](#2-local-development-workflow-before-pushing-to-ci-pipeline)
25
+ 1. interactively learning python code quality standards via ruff+pyright, see [local development workflow](#2-local-development-workflow-before-pushing-to-ci-pipeline)
9
26
  2. enforcing minimal quality-standards via a "lint-stage" in a ci-pipeline, see [setup for ci-pipeline](#3-setup-for-ci-pipeline)
27
+ ## 0. motivation:
28
+ ### Python is a Bicycle!
29
+ - initial idea of python: `Bridge the gap between the shell and C.`[see](https://www.artima.com/articles/pythons-design-goals)
30
+ ![img.png](images/python_is_a_bicycle.png)
31
+ ### run-time "safety"
32
+ - type and data validation at runtime
33
+ - pytests run your code -> runtime
34
+ ![img.png](images/runtime_safety.png)
35
+ ### lint-time "safety"
36
+ - linting and static type checking
37
+ ![img.png](images/lint_time_safety.png)
38
+ - flake8 already fell down!
39
+ ### more "safety" via shorter feed-back loops
40
+ ![img_3.png](images/feedback_loops.png)
41
+
10
42
 
11
43
  ## 1. install (via poetry)
12
44
  1. in `pyproject.toml` add to dependencies
@@ -38,13 +70,12 @@ python-linters = { version = "<some-version-here>" }
38
70
  ],
39
71
  ```
40
72
  ### three scripts/commands that you can run locally
41
- 1. `poetry run fixcode` to let black+isort+ruff "auto-fix" your code -> always have a `clean` git-repo before doing this (no uncommitted changes)
73
+ 1. `uv run fixcode` to let black+isort+ruff "auto-fix" your code -> always have a `clean` git-repo before doing this (no uncommitted changes)
42
74
  - [example output](#fixcode-example)
43
- 1. `poetry run pythonlinter` -> to lint your code
75
+ 1. `uv run pythonlinter` -> to lint your code
44
76
  - [example black is not happy](#pythonlinter-black-is-not-happy) -> if you ran `fixcode` black is guaranteed to be happy!
45
77
  - [example ruff is not happy](#pythonlinter-ruff-is-not-happy)
46
- - [example flake8 is not happy](#pythonlinter-flake8-is-not-happy)
47
- 1. `poetry run addnoqa` to let ruff insert rules-violation-comments to your code
78
+ 1. `uv run addnoqa` to let ruff insert rules-violation-comments to your code
48
79
  - [example](#addnoqa-example)
49
80
  ```mermaid
50
81
  flowchart TD
@@ -54,22 +85,22 @@ classDef style2 fill:#ffffba
54
85
  classDef style3 fill:#baffc9
55
86
  classDef style4 fill:#bae1ff
56
87
  op1["start: have a 'clean' repo"]:::style4 --> op2
57
- op2[\"poetry run fixcode\n refactor & git commit"/]:::style1 --> cond9{{"poetry run pythonlinter"}}:::style0
88
+ op2[\"uv run fixcode\n refactor & git commit"/]:::style1 --> cond9{{"uv run pythonlinter"}}:::style0
58
89
  cond9 --> | complains | cond47{{"ruff"}}:::style0
59
- cond47 --> | complains | op51[\"poetry run addnoqa"/]:::style1
90
+ cond47 --> | complains | op51[\"uv run addnoqa"/]:::style1
60
91
  op51 --> sub53[\"refactor your code \nOR\n keep/add noqa-comment"/]:::style1
61
92
  sub53 --> op2
62
- cond47 --> | is happy | cond58{{"flake8"}}:::style0
93
+ cond47 --> | is happy | cond58{{"pyright"}}:::style0
63
94
  cond58 --> | complains | sub53
64
95
  cond58 --> | is happy | sub66["git commit"]
65
96
  sub66 --> sub80
66
97
  cond9 --> | is happy | sub80["git push"]:::style3
67
98
  ```
68
- - write-operations (changing your code): `poetry run fixcode`, `poerty run addnoqa`, `refactor your code`
69
- - read-only-operations: `poetry run pythonlinter`,`git commit`, `git push`
99
+ - write-operations (changing your code): `uv run fixcode`, `poerty run addnoqa`, `refactor your code`
100
+ - read-only-operations: `uv run pythonlinter`,`git commit`, `git push`
70
101
 
71
102
  ## 3. setup for ci-pipeline
72
- * if you specified the packages in the `pyproject.toml` and you run just run `poetry run pythonlinter` without any arguments than the `pyproject.toml` is getting parsed and specified packages are getting linted
103
+ * if you specified the packages in the `pyproject.toml` and you run just run `uv run pythonlinter` without any arguments than the `pyproject.toml` is getting parsed and specified packages are getting linted
73
104
  ```yaml
74
105
  stages:
75
106
  - lint # lint-stage!
@@ -97,7 +128,7 @@ linting:
97
128
  ### fixcode example
98
129
  ```commandline
99
130
  cd <somehwere>/whisper-streaming
100
- poetry run fixcode
131
+ uv run fixcode
101
132
  Fixing <somehwere>/whisper-streaming/whisper_streaming/post_asr_preparations.py
102
133
  whisper_streaming/faster_whisper_inference/faster_whisper_inferencer.py:231:30: ARG005 Unused lambda argument: `x`
103
134
  whisper_streaming/faster_whisper_inference/faster_whisper_inferencer.py:234:5: RET503 Missing explicit `return` at the end of function able to return non-`None` value
@@ -113,27 +144,14 @@ All done! ✨ 🍰 ✨
113
144
  folders_to_be_linted=['whisper_streaming', 'tests']
114
145
  ```
115
146
 
116
- ### pythonlinter black is not happy
117
- ```commandline
118
- poetry run pythonlinter
119
- linter-order: black->ruff->flake8
120
- folders_tobelinted=['whisper_streaming', 'tests']
121
- running black
122
- would reformat <somehwere>/whisper-streaming/whisper_streaming/post_asr_preparations.py
123
- would reformat <somehwere>/whisper-streaming/whisper_streaming/faster_whisper_inference/faster_whisper_inferencer.py
124
-
125
- Oh no! 💥 💔 💥
126
- 2 files would be reformatted, 20 files would be left unchanged.
127
- python_linters.run_linters.LinterException: 💩 black is not happy! 💩
128
- ```
129
147
  ### pythonlinter ruff is not happy
130
148
  - complains about
131
149
  - an unused argument
132
150
  - a missing return statement
133
151
  - missing type annotations
134
152
  ```commandline
135
- poetry run pythonlinter
136
- linter-order: black->ruff->flake8
153
+ uv run pythonlinter
154
+ linter-order: black->ruff->pyright
137
155
 
138
156
  ...
139
157
 
@@ -146,31 +164,10 @@ Found 4 errors.
146
164
  No fixes available (2 hidden fixes can be enabled with the `--unsafe-fixes` option).
147
165
  python_linters.run_linters.LinterException: 💩 ruff is not happy! 💩
148
166
  ```
149
- ### pythonlinter flake8 is not happy
150
- - complains about too many methods in a class and wrong position of a function in a module
151
- ```commandline
152
- poetry run pythonlinter
153
- linter-order: black->ruff->flake8
154
- folders_tobelinted=['whisper_streaming', 'tests']
155
- running black
156
- All done! ✨ 🍰 ✨
157
- 22 files would be left unchanged.
158
-
159
- passed black linter! ✨ 🍰 ✨
160
-
161
- running ruff
162
-
163
- passed ruff linter! ✨ 🍰 ✨
164
-
165
- running flake8
166
- whisper_streaming/faster_whisper_inference/faster_whisper_inferencer.py:111:1: WPS214 Found too many methods: 10 > 9
167
- tests/conftest.py:35:8: NEW100 newspaper style: function is_in_docker_container defined in line 16 should be moved down
168
- python_linters.run_linters.LinterException: 💩 flake8 is not happy! 💩
169
- ```
170
167
  ### addnoqa example
171
168
  - only shows how many noqas it added (`3`) and how many files it left unchanged (`22`)
172
169
  ```commandline
173
- poetry run addnoqa
170
+ uv run addnoqa
174
171
  Added 3 noqa directives.
175
172
  All done! ✨ 🍰 ✨
176
173
  22 files would be left unchanged.
@@ -179,11 +176,9 @@ addnoqa iteration: 0
179
176
  ```
180
177
  - it adds noqas like this one:
181
178
  ```python
182
- def foobar(x):
179
+ def foobar(x): # noqa: ANN001, ANN202
183
180
  return "whatever"
184
181
 
185
- from faster_whisper.transcribe import Segment as FasterWhisperSegment # noqa: E402
186
-
187
182
  ```
188
183
  # IDE integration
189
184
  ## manual vscode integration
@@ -197,17 +192,17 @@ from faster_whisper.transcribe import Segment as FasterWhisperSegment # noqa: E
197
192
  {
198
193
  "label": "fixcode",
199
194
  "type": "shell",
200
- "command": "cd $(cd ${fileDirname} && git rev-parse --show-toplevel) && poetry run fixcode"
195
+ "command": "cd $(cd ${fileDirname} && git rev-parse --show-toplevel) && uv run fixcode"
201
196
  },
202
197
  {
203
198
  "label": "addnoqa",
204
199
  "type": "shell",
205
- "command": "cd $(cd ${fileDirname} && git rev-parse --show-toplevel) && poetry run addnoqa"
200
+ "command": "cd $(cd ${fileDirname} && git rev-parse --show-toplevel) && uv run addnoqa"
206
201
  },
207
202
  {
208
203
  "label": "pythonlinter",
209
204
  "type": "shell",
210
- "command": "cd $(cd ${fileDirname} && git rev-parse --show-toplevel) && poetry run pythonlinter"
205
+ "command": "cd $(cd ${fileDirname} && git rev-parse --show-toplevel) && uv run pythonlinter"
211
206
  }
212
207
  ]
213
208
  }
@@ -1,36 +1,29 @@
1
- Metadata-Version: 2.1
2
- Name: python-linters
3
- Version: 0.1.4
4
- Summary: bundling config files for linters like ruff and flake8
5
- Home-page: https://github.com/dertilo/python-linters
6
- License: MIT
7
- Author: Tilo Himmelsbach
8
- Author-email: dertilo@gmail.com
9
- Requires-Python: >=3.10,<4.0
10
- Classifier: License :: OSI Approved :: MIT License
11
- Classifier: Programming Language :: Python :: 3
12
- Classifier: Programming Language :: Python :: 3.10
13
- Classifier: Programming Language :: Python :: 3.11
14
- Classifier: Programming Language :: Python :: 3.12
15
- Requires-Dist: basedpyright (>=1.12.5,<2.0.0)
16
- Requires-Dist: black (>=23.9.1,<24.0.0)
17
- Requires-Dist: flake8 (>=6.1.0,<7.0.0)
18
- Requires-Dist: flake8-newspaper-style (>=0.4.3,<0.5.0)
19
- Requires-Dist: ruff (>=0.0.291)
20
- Requires-Dist: toml (>=0.10.2,<0.11.0)
21
- Requires-Dist: wemake-python-styleguide (>=0.18.0,<0.19.0)
22
- Project-URL: Repository, https://github.com/dertilo/python-linters
23
- Description-Content-Type: text/markdown
24
-
25
1
  ![pypi](https://github.com/dertilo/python-linters/actions/workflows/release.yml/badge.svg)
26
2
  [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
27
3
  [![bear-ified](https://raw.githubusercontent.com/beartype/beartype-assets/main/badge/bear-ified.svg)](https://beartype.readthedocs.io)
28
4
  # python-linters
29
- - bundles flake8, ruff and basedpyright into a single poetry-script
30
- - project independent linter configuration (via `ruff.toml`,`.flake8`) -> one config to rule them all
5
+ - bundles ruff and ~~flake8~~ basedpyright into a single ~~poetry~~uv-script
6
+ - even though I liked some flake8-rules (especially from [wemake-python-styleguide](https://wemake-python-styleguide.readthedocs.io/en/latest/)) dropped it in favor of ruff for being too slow
7
+ - project independent linter configuration (via `ruff.toml`,~~`.flake8`~~`pyrightconfig.json`) -> one config to rule them all
8
+ - well one can still override the default config via `ruff_extensions.toml` and `pyrightconfig.json`
31
9
  ### use-cases:
32
- 1. interactively learning python code quality standards via ruff+flake8, see [local development workflow](#2-local-development-workflow-before-pushing-to-ci-pipeline)
10
+ 1. interactively learning python code quality standards via ruff+pyright, see [local development workflow](#2-local-development-workflow-before-pushing-to-ci-pipeline)
33
11
  2. enforcing minimal quality-standards via a "lint-stage" in a ci-pipeline, see [setup for ci-pipeline](#3-setup-for-ci-pipeline)
12
+ ## 0. motivation:
13
+ ### Python is a Bicycle!
14
+ - initial idea of python: `Bridge the gap between the shell and C.`[see](https://www.artima.com/articles/pythons-design-goals)
15
+ ![img.png](images/python_is_a_bicycle.png)
16
+ ### run-time "safety"
17
+ - type and data validation at runtime
18
+ - pytests run your code -> runtime
19
+ ![img.png](images/runtime_safety.png)
20
+ ### lint-time "safety"
21
+ - linting and static type checking
22
+ ![img.png](images/lint_time_safety.png)
23
+ - flake8 already fell down!
24
+ ### more "safety" via shorter feed-back loops
25
+ ![img_3.png](images/feedback_loops.png)
26
+
34
27
 
35
28
  ## 1. install (via poetry)
36
29
  1. in `pyproject.toml` add to dependencies
@@ -62,13 +55,12 @@ python-linters = { version = "<some-version-here>" }
62
55
  ],
63
56
  ```
64
57
  ### three scripts/commands that you can run locally
65
- 1. `poetry run fixcode` to let black+isort+ruff "auto-fix" your code -> always have a `clean` git-repo before doing this (no uncommitted changes)
58
+ 1. `uv run fixcode` to let black+isort+ruff "auto-fix" your code -> always have a `clean` git-repo before doing this (no uncommitted changes)
66
59
  - [example output](#fixcode-example)
67
- 1. `poetry run pythonlinter` -> to lint your code
60
+ 1. `uv run pythonlinter` -> to lint your code
68
61
  - [example black is not happy](#pythonlinter-black-is-not-happy) -> if you ran `fixcode` black is guaranteed to be happy!
69
62
  - [example ruff is not happy](#pythonlinter-ruff-is-not-happy)
70
- - [example flake8 is not happy](#pythonlinter-flake8-is-not-happy)
71
- 1. `poetry run addnoqa` to let ruff insert rules-violation-comments to your code
63
+ 1. `uv run addnoqa` to let ruff insert rules-violation-comments to your code
72
64
  - [example](#addnoqa-example)
73
65
  ```mermaid
74
66
  flowchart TD
@@ -78,22 +70,22 @@ classDef style2 fill:#ffffba
78
70
  classDef style3 fill:#baffc9
79
71
  classDef style4 fill:#bae1ff
80
72
  op1["start: have a 'clean' repo"]:::style4 --> op2
81
- op2[\"poetry run fixcode\n refactor & git commit"/]:::style1 --> cond9{{"poetry run pythonlinter"}}:::style0
73
+ op2[\"uv run fixcode\n refactor & git commit"/]:::style1 --> cond9{{"uv run pythonlinter"}}:::style0
82
74
  cond9 --> | complains | cond47{{"ruff"}}:::style0
83
- cond47 --> | complains | op51[\"poetry run addnoqa"/]:::style1
75
+ cond47 --> | complains | op51[\"uv run addnoqa"/]:::style1
84
76
  op51 --> sub53[\"refactor your code \nOR\n keep/add noqa-comment"/]:::style1
85
77
  sub53 --> op2
86
- cond47 --> | is happy | cond58{{"flake8"}}:::style0
78
+ cond47 --> | is happy | cond58{{"pyright"}}:::style0
87
79
  cond58 --> | complains | sub53
88
80
  cond58 --> | is happy | sub66["git commit"]
89
81
  sub66 --> sub80
90
82
  cond9 --> | is happy | sub80["git push"]:::style3
91
83
  ```
92
- - write-operations (changing your code): `poetry run fixcode`, `poerty run addnoqa`, `refactor your code`
93
- - read-only-operations: `poetry run pythonlinter`,`git commit`, `git push`
84
+ - write-operations (changing your code): `uv run fixcode`, `poerty run addnoqa`, `refactor your code`
85
+ - read-only-operations: `uv run pythonlinter`,`git commit`, `git push`
94
86
 
95
87
  ## 3. setup for ci-pipeline
96
- * if you specified the packages in the `pyproject.toml` and you run just run `poetry run pythonlinter` without any arguments than the `pyproject.toml` is getting parsed and specified packages are getting linted
88
+ * if you specified the packages in the `pyproject.toml` and you run just run `uv run pythonlinter` without any arguments than the `pyproject.toml` is getting parsed and specified packages are getting linted
97
89
  ```yaml
98
90
  stages:
99
91
  - lint # lint-stage!
@@ -121,7 +113,7 @@ linting:
121
113
  ### fixcode example
122
114
  ```commandline
123
115
  cd <somehwere>/whisper-streaming
124
- poetry run fixcode
116
+ uv run fixcode
125
117
  Fixing <somehwere>/whisper-streaming/whisper_streaming/post_asr_preparations.py
126
118
  whisper_streaming/faster_whisper_inference/faster_whisper_inferencer.py:231:30: ARG005 Unused lambda argument: `x`
127
119
  whisper_streaming/faster_whisper_inference/faster_whisper_inferencer.py:234:5: RET503 Missing explicit `return` at the end of function able to return non-`None` value
@@ -137,27 +129,14 @@ All done! ✨ 🍰 ✨
137
129
  folders_to_be_linted=['whisper_streaming', 'tests']
138
130
  ```
139
131
 
140
- ### pythonlinter black is not happy
141
- ```commandline
142
- poetry run pythonlinter
143
- linter-order: black->ruff->flake8
144
- folders_tobelinted=['whisper_streaming', 'tests']
145
- running black
146
- would reformat <somehwere>/whisper-streaming/whisper_streaming/post_asr_preparations.py
147
- would reformat <somehwere>/whisper-streaming/whisper_streaming/faster_whisper_inference/faster_whisper_inferencer.py
148
-
149
- Oh no! 💥 💔 💥
150
- 2 files would be reformatted, 20 files would be left unchanged.
151
- python_linters.run_linters.LinterException: 💩 black is not happy! 💩
152
- ```
153
132
  ### pythonlinter ruff is not happy
154
133
  - complains about
155
134
  - an unused argument
156
135
  - a missing return statement
157
136
  - missing type annotations
158
137
  ```commandline
159
- poetry run pythonlinter
160
- linter-order: black->ruff->flake8
138
+ uv run pythonlinter
139
+ linter-order: black->ruff->pyright
161
140
 
162
141
  ...
163
142
 
@@ -170,31 +149,10 @@ Found 4 errors.
170
149
  No fixes available (2 hidden fixes can be enabled with the `--unsafe-fixes` option).
171
150
  python_linters.run_linters.LinterException: 💩 ruff is not happy! 💩
172
151
  ```
173
- ### pythonlinter flake8 is not happy
174
- - complains about too many methods in a class and wrong position of a function in a module
175
- ```commandline
176
- poetry run pythonlinter
177
- linter-order: black->ruff->flake8
178
- folders_tobelinted=['whisper_streaming', 'tests']
179
- running black
180
- All done! ✨ 🍰 ✨
181
- 22 files would be left unchanged.
182
-
183
- passed black linter! ✨ 🍰 ✨
184
-
185
- running ruff
186
-
187
- passed ruff linter! ✨ 🍰 ✨
188
-
189
- running flake8
190
- whisper_streaming/faster_whisper_inference/faster_whisper_inferencer.py:111:1: WPS214 Found too many methods: 10 > 9
191
- tests/conftest.py:35:8: NEW100 newspaper style: function is_in_docker_container defined in line 16 should be moved down
192
- python_linters.run_linters.LinterException: 💩 flake8 is not happy! 💩
193
- ```
194
152
  ### addnoqa example
195
153
  - only shows how many noqas it added (`3`) and how many files it left unchanged (`22`)
196
154
  ```commandline
197
- poetry run addnoqa
155
+ uv run addnoqa
198
156
  Added 3 noqa directives.
199
157
  All done! ✨ 🍰 ✨
200
158
  22 files would be left unchanged.
@@ -203,11 +161,9 @@ addnoqa iteration: 0
203
161
  ```
204
162
  - it adds noqas like this one:
205
163
  ```python
206
- def foobar(x):
164
+ def foobar(x): # noqa: ANN001, ANN202
207
165
  return "whatever"
208
166
 
209
- from faster_whisper.transcribe import Segment as FasterWhisperSegment # noqa: E402
210
-
211
167
  ```
212
168
  # IDE integration
213
169
  ## manual vscode integration
@@ -221,17 +177,17 @@ from faster_whisper.transcribe import Segment as FasterWhisperSegment # noqa: E
221
177
  {
222
178
  "label": "fixcode",
223
179
  "type": "shell",
224
- "command": "cd $(cd ${fileDirname} && git rev-parse --show-toplevel) && poetry run fixcode"
180
+ "command": "cd $(cd ${fileDirname} && git rev-parse --show-toplevel) && uv run fixcode"
225
181
  },
226
182
  {
227
183
  "label": "addnoqa",
228
184
  "type": "shell",
229
- "command": "cd $(cd ${fileDirname} && git rev-parse --show-toplevel) && poetry run addnoqa"
185
+ "command": "cd $(cd ${fileDirname} && git rev-parse --show-toplevel) && uv run addnoqa"
230
186
  },
231
187
  {
232
188
  "label": "pythonlinter",
233
189
  "type": "shell",
234
- "command": "cd $(cd ${fileDirname} && git rev-parse --show-toplevel) && poetry run pythonlinter"
190
+ "command": "cd $(cd ${fileDirname} && git rev-parse --show-toplevel) && uv run pythonlinter"
235
191
  }
236
192
  ]
237
193
  }
@@ -240,4 +196,4 @@ from faster_whisper.transcribe import Segment as FasterWhisperSegment # noqa: E
240
196
  ![pycharm_settings.png](pycharm_settings.png)
241
197
  ## alternatives
242
198
  - https://github.com/astral-sh/ruff-vscode
243
- - https://plugins.jetbrains.com/plugin/20574-ruff
199
+ - https://plugins.jetbrains.com/plugin/20574-ruff
@@ -0,0 +1,40 @@
1
+ [project]
2
+ name = "python-linters"
3
+ description = "bundling config files for linters like ruff and pyright"
4
+ authors = [ { name = "Tilo Himmelsbach", email = "dertilo@gmail.com" } ]
5
+ readme = "README.md"
6
+ license = {text = "MIT"}
7
+ requires-python = "<4.0,>=3.10"
8
+ dependencies = [
9
+ "toml<1.0.0,>=0.10.2",
10
+ "ruff>=0.0.291",
11
+ "basedpyright<2.0.0,>=1.12.5",
12
+ "json-with-comments<2.0.0,>=1.2.9",
13
+ ]
14
+ dynamic = [
15
+ "version"
16
+ ]
17
+
18
+ [project.urls]
19
+ repository = "https://github.com/dertilo/python-linters"
20
+
21
+ [project.scripts]
22
+ pythonlinter = "python_linters.run_linters:main"
23
+ fixcode = "python_linters.fix_code:main"
24
+ addnoqa = "python_linters.add_noqa:main"
25
+
26
+ [build-system]
27
+ requires = ["hatchling", "hatch-vcs"]
28
+ build-backend = "hatchling.build"
29
+
30
+ [tool.hatch.version]
31
+ source = "vcs"
32
+
33
+ [tool.hatch.build.hooks.vcs]
34
+ version-file = "_version.py"
35
+
36
+ [tool.hatch.build.targets.sdist]
37
+ packages = ["python_linters"] # packages option is semantically equivalent to only-include
38
+
39
+ [tool.hatch.build.targets.wheel]
40
+ packages = ["python_linters"]
@@ -2,28 +2,30 @@ import os
2
2
 
3
3
  from python_linters.extending_ruff_toml import create_extended_ruff_toml
4
4
  from python_linters.getting_to_be_linted_folders import get_folders_to_be_linted
5
- from python_linters.run_linters import run_cmd
5
+ from python_linters.utils import run_cmd, get_pyproject_dir
6
6
 
7
7
 
8
8
  def main() -> None:
9
9
  """
10
10
  expects to run from $ContentRoot$
11
11
  """
12
- folders_tobelinted = get_folders_to_be_linted("pyproject.toml")
12
+ dirr = get_pyproject_dir()
13
+ folders_tobelinted = get_folders_to_be_linted(f"{dirr}/pyproject.toml")
14
+
13
15
  BIG_NUMBER = 9
14
16
  for k in range(
15
17
  BIG_NUMBER,
16
18
  ): # theoretically could be necessary to run this loop as long as code changes!
17
19
  print(f"addnoqa iteration: {k}")
18
20
  run_cmd(
19
- f"ruff check {' '.join(folders_tobelinted)} --config={create_extended_ruff_toml()} --add-noqa",
21
+ f"cd {dirr} && ruff check {' '.join(folders_tobelinted)} --config={create_extended_ruff_toml(str(dirr))} --add-noqa",
20
22
  )
21
23
  try:
22
- run_cmd(f"ruff format --check {' '.join(folders_tobelinted)}")
24
+ run_cmd(f"cd {dirr} && ruff format --check {' '.join(folders_tobelinted)}")
23
25
  break
24
26
  except Exception:
25
- run_cmd(f"ruff format {' '.join(folders_tobelinted)}")
26
- run_cmd(f"fixcode {os.getcwd()}")
27
+ run_cmd(f"cd {dirr} && ruff format {' '.join(folders_tobelinted)}")
28
+ run_cmd(f"fixcode {dirr}")
27
29
 
28
30
 
29
31
  if __name__ == "__main__":
@@ -2,10 +2,8 @@ import pathlib
2
2
 
3
3
  package_dir = str(pathlib.Path(__file__).parent.resolve())
4
4
 
5
- FLAKE8_CONFIG_FILE = f"{package_dir}/.flake8"
6
5
  RUFF_CONFIG_FILE = f"{package_dir}/ruff.toml"
7
6
  PYRIGHT_CONFIG_FILE = f"{package_dir}/pyrightconfig.json"
8
7
 
9
- assert pathlib.Path(FLAKE8_CONFIG_FILE).is_file()
10
8
  assert pathlib.Path(RUFF_CONFIG_FILE).is_file()
11
9
  assert pathlib.Path(PYRIGHT_CONFIG_FILE).is_file()
@@ -4,12 +4,12 @@ from pathlib import Path
4
4
  from python_linters.config_files import RUFF_CONFIG_FILE
5
5
 
6
6
 
7
- def create_extended_ruff_toml() -> str:
8
- ruff_extension_file = Path("ruff_extension.toml")
7
+ def create_extended_ruff_toml(package_root:str) -> str:
8
+ ruff_extension_file = Path(f"{package_root}/ruff_extension.toml")
9
9
 
10
10
  if ruff_extension_file.is_file():
11
11
  fingerprint = f"{ruff_extension_file.stat().st_size}-{ruff_extension_file.stat().st_mtime}"
12
- extended_ruff_toml_file = f"extended_ruff-{fingerprint}.toml"
12
+ extended_ruff_toml_file = f"{package_root}/extended_ruff-{fingerprint}.toml"
13
13
  if not Path(extended_ruff_toml_file).is_file():
14
14
  print(f"extending {RUFF_CONFIG_FILE} with {ruff_extension_file=}")
15
15
  with Path(extended_ruff_toml_file).open("w", encoding="locale") as f: