rattle-lint 1.0.1__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 (84) hide show
  1. rattle_lint-1.0.1/.editorconfig +10 -0
  2. rattle_lint-1.0.1/.gitignore +108 -0
  3. rattle_lint-1.0.1/.pre-commit-config.yaml +17 -0
  4. rattle_lint-1.0.1/.pre-commit-hooks.yaml +12 -0
  5. rattle_lint-1.0.1/.readthedocs.yml +13 -0
  6. rattle_lint-1.0.1/CONTRIBUTING.md +144 -0
  7. rattle_lint-1.0.1/Justfile +90 -0
  8. rattle_lint-1.0.1/LICENSE +76 -0
  9. rattle_lint-1.0.1/PKG-INFO +190 -0
  10. rattle_lint-1.0.1/README.md +68 -0
  11. rattle_lint-1.0.1/docs/_static/custom.css +23 -0
  12. rattle_lint-1.0.1/docs/_templates/badges.html +6 -0
  13. rattle_lint-1.0.1/docs/_templates/meta.html +5 -0
  14. rattle_lint-1.0.1/docs/api.md +67 -0
  15. rattle_lint-1.0.1/docs/conf.py +123 -0
  16. rattle_lint-1.0.1/docs/contributing.md +5 -0
  17. rattle_lint-1.0.1/docs/guide/builtins.md +1438 -0
  18. rattle_lint-1.0.1/docs/guide/commands.md +184 -0
  19. rattle_lint-1.0.1/docs/guide/configuration.md +329 -0
  20. rattle_lint-1.0.1/docs/guide/integrations.md +84 -0
  21. rattle_lint-1.0.1/docs/guide/quickstart.md +281 -0
  22. rattle_lint-1.0.1/docs/guide.md +15 -0
  23. rattle_lint-1.0.1/docs/index.md +28 -0
  24. rattle_lint-1.0.1/pyproject.toml +290 -0
  25. rattle_lint-1.0.1/scripts/check_copyright.py +45 -0
  26. rattle_lint-1.0.1/scripts/document_rules.py +152 -0
  27. rattle_lint-1.0.1/src/rattle/__init__.py +50 -0
  28. rattle_lint-1.0.1/src/rattle/__main__.py +9 -0
  29. rattle_lint-1.0.1/src/rattle/__version__.py +12 -0
  30. rattle_lint-1.0.1/src/rattle/api.py +421 -0
  31. rattle_lint-1.0.1/src/rattle/cli.py +395 -0
  32. rattle_lint-1.0.1/src/rattle/config.py +1244 -0
  33. rattle_lint-1.0.1/src/rattle/engine.py +150 -0
  34. rattle_lint-1.0.1/src/rattle/format.py +109 -0
  35. rattle_lint-1.0.1/src/rattle/ftypes.py +301 -0
  36. rattle_lint-1.0.1/src/rattle/local/__init__.py +6 -0
  37. rattle_lint-1.0.1/src/rattle/lsp.py +210 -0
  38. rattle_lint-1.0.1/src/rattle/output.py +203 -0
  39. rattle_lint-1.0.1/src/rattle/py.typed +0 -0
  40. rattle_lint-1.0.1/src/rattle/rule.py +409 -0
  41. rattle_lint-1.0.1/src/rattle/rules/__init__.py +9 -0
  42. rattle_lint-1.0.1/src/rattle/rules/avoid_or_in_except.py +103 -0
  43. rattle_lint-1.0.1/src/rattle/rules/chained_instance_check.py +172 -0
  44. rattle_lint-1.0.1/src/rattle/rules/cls_in_classmethod.py +281 -0
  45. rattle_lint-1.0.1/src/rattle/rules/compare_primitives_by_equal.py +96 -0
  46. rattle_lint-1.0.1/src/rattle/rules/compare_singleton_primitives_by_is.py +125 -0
  47. rattle_lint-1.0.1/src/rattle/rules/deprecated_abc_import.py +325 -0
  48. rattle_lint-1.0.1/src/rattle/rules/deprecated_unittest_asserts.py +96 -0
  49. rattle_lint-1.0.1/src/rattle/rules/extra/__init__.py +9 -0
  50. rattle_lint-1.0.1/src/rattle/rules/extra/explicit_frozen_dataclass.py +263 -0
  51. rattle_lint-1.0.1/src/rattle/rules/extra/use_lint_fixme_comment.py +62 -0
  52. rattle_lint-1.0.1/src/rattle/rules/no_assert_true_for_comparison.py +118 -0
  53. rattle_lint-1.0.1/src/rattle/rules/no_inherit_from_object.py +63 -0
  54. rattle_lint-1.0.1/src/rattle/rules/no_namedtuple.py +339 -0
  55. rattle_lint-1.0.1/src/rattle/rules/no_redundant_arguments_super.py +150 -0
  56. rattle_lint-1.0.1/src/rattle/rules/no_redundant_fstring.py +63 -0
  57. rattle_lint-1.0.1/src/rattle/rules/no_redundant_lambda.py +80 -0
  58. rattle_lint-1.0.1/src/rattle/rules/no_redundant_list_comprehension.py +60 -0
  59. rattle_lint-1.0.1/src/rattle/rules/no_static_if_condition.py +157 -0
  60. rattle_lint-1.0.1/src/rattle/rules/no_string_type_annotation.py +316 -0
  61. rattle_lint-1.0.1/src/rattle/rules/replace_union_with_optional.py +130 -0
  62. rattle_lint-1.0.1/src/rattle/rules/rewrite_to_comprehension.py +142 -0
  63. rattle_lint-1.0.1/src/rattle/rules/rewrite_to_literal.py +144 -0
  64. rattle_lint-1.0.1/src/rattle/rules/sorted_attributes_rule.py +120 -0
  65. rattle_lint-1.0.1/src/rattle/rules/use_assert_in.py +156 -0
  66. rattle_lint-1.0.1/src/rattle/rules/use_assert_is_not_none.py +156 -0
  67. rattle_lint-1.0.1/src/rattle/rules/use_async_sleep_in_async_def.py +145 -0
  68. rattle_lint-1.0.1/src/rattle/rules/use_fstring.py +235 -0
  69. rattle_lint-1.0.1/src/rattle/rules/use_types_from_typing.py +153 -0
  70. rattle_lint-1.0.1/src/rattle/rules/variadic_callable_syntax.py +126 -0
  71. rattle_lint-1.0.1/src/rattle/testing.py +229 -0
  72. rattle_lint-1.0.1/src/rattle/tests/__init__.py +27 -0
  73. rattle_lint-1.0.1/src/rattle/tests/__main__.py +12 -0
  74. rattle_lint-1.0.1/src/rattle/tests/cli.py +66 -0
  75. rattle_lint-1.0.1/src/rattle/tests/config.py +1269 -0
  76. rattle_lint-1.0.1/src/rattle/tests/engine.py +59 -0
  77. rattle_lint-1.0.1/src/rattle/tests/ftypes.py +175 -0
  78. rattle_lint-1.0.1/src/rattle/tests/rule.py +455 -0
  79. rattle_lint-1.0.1/src/rattle/tests/smoke.py +414 -0
  80. rattle_lint-1.0.1/src/rattle/tests/test_lsp.py +75 -0
  81. rattle_lint-1.0.1/src/rattle/tests/test_output.py +159 -0
  82. rattle_lint-1.0.1/src/rattle/tests/test_rules.py +22 -0
  83. rattle_lint-1.0.1/src/rattle/util.py +102 -0
  84. rattle_lint-1.0.1/uv.lock +1442 -0
@@ -0,0 +1,10 @@
1
+ root = true
2
+
3
+ [*.{py,pyi,toml,md}]
4
+ charset = utf-8
5
+ end_of_line = lf
6
+ indent_size = 4
7
+ indent_style = space
8
+ insert_final_newline = true
9
+ trim_trailing_whitespace = true
10
+ max_line_length = 88
@@ -0,0 +1,108 @@
1
+ html/
2
+
3
+ # Byte-compiled / optimized / DLL files
4
+ __pycache__/
5
+ *.py[cod]
6
+ *$py.class
7
+
8
+ # C extensions
9
+ *.so
10
+
11
+ # Distribution / packaging
12
+ .Python
13
+ build/
14
+ develop-eggs/
15
+ dist/
16
+ downloads/
17
+ eggs/
18
+ .eggs/
19
+ lib/
20
+ lib64/
21
+ parts/
22
+ sdist/
23
+ var/
24
+ 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
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ .hypothesis/
50
+ .pytest_cache/
51
+
52
+ # Translations
53
+ *.mo
54
+ *.pot
55
+
56
+ # Django stuff:
57
+ *.log
58
+ local_settings.py
59
+ db.sqlite3
60
+
61
+ # Flask stuff:
62
+ instance/
63
+ .webassets-cache
64
+
65
+ # Scrapy stuff:
66
+ .scrapy
67
+
68
+ # Sphinx documentation
69
+ docs/_build/
70
+
71
+ # PyBuilder
72
+ target/
73
+
74
+ # Jupyter Notebook
75
+ .ipynb_checkpoints
76
+
77
+ # pyenv
78
+ .python-version
79
+
80
+ # celery beat schedule file
81
+ celerybeat-schedule
82
+
83
+ # SageMath parsed files
84
+ *.sage.py
85
+
86
+ # Environments
87
+ .env
88
+ .venv
89
+ env/
90
+ venv/
91
+ ENV/
92
+ env.bak/
93
+ venv.bak/
94
+
95
+ # Spyder project settings
96
+ .spyderproject
97
+ .spyproject
98
+
99
+ # Rope project settings
100
+ .ropeproject
101
+
102
+ # mkdocs documentation
103
+ /site
104
+
105
+ .ruff_cache/
106
+
107
+ # Visual Studio Code
108
+ .vscode/
@@ -0,0 +1,17 @@
1
+ exclude: "^legacy/.*$"
2
+ repos:
3
+ - repo: https://github.com/pre-commit/pre-commit-hooks
4
+ rev: v5.0.0
5
+ hooks:
6
+ - id: trailing-whitespace
7
+ - id: end-of-file-fixer
8
+ - id: check-yaml
9
+ - id: check-toml
10
+ - id: check-added-large-files
11
+
12
+ - repo: https://github.com/astral-sh/ruff-pre-commit
13
+ rev: v0.15.8
14
+ hooks:
15
+ - id: ruff-check
16
+ args: [--fix, --exit-zero]
17
+ - id: ruff-format
@@ -0,0 +1,12 @@
1
+ - id: rattle-lint
2
+ name: Rattle - lint
3
+ description: This hook shows Rattle lints and suggested changes without applying autofixes.
4
+ entry: rattle lint --diff
5
+ language: python
6
+ types: [python]
7
+ - id: rattle-fix
8
+ name: Rattle - lint and apply autofixes
9
+ description: This hook shows Rattle lints and applies suggested changes.
10
+ entry: rattle fix --automatic
11
+ language: python
12
+ types: [python]
@@ -0,0 +1,13 @@
1
+ version: 2
2
+ sphinx:
3
+ configuration: docs/conf.py
4
+ build:
5
+ os: ubuntu-22.04
6
+ tools:
7
+ python: "3.10"
8
+ python:
9
+ install:
10
+ - method: pip
11
+ path: .
12
+ extra_requirements:
13
+ - docs
@@ -0,0 +1,144 @@
1
+ # Contributing to Rattle
2
+
3
+ ## Setup
4
+
5
+ Rattle requires Python 3.10 or newer. We recommend using [uv][] to install Python:
6
+
7
+ ```shell-session
8
+ $ uv python install 3.13
9
+
10
+ $ uv python pin 3.13
11
+ ```
12
+
13
+ You can then sync a local development environment with `just`:
14
+
15
+ ```shell-session
16
+ $ just sync
17
+ ```
18
+
19
+ This installs all project extras into `.venv` and sets up the local
20
+ `pre-commit` hooks. Once created, activate the environment:
21
+
22
+ ```shell-session
23
+ $ source .venv/bin/activate
24
+
25
+ (rattle) $
26
+ ```
27
+
28
+ ## Developing
29
+
30
+ Once activated, Rattle can be run locally:
31
+
32
+ ```shell-session
33
+ (rattle) $ rattle [args]
34
+ ```
35
+
36
+ To run the test suite, type checker, and linters:
37
+
38
+ ```shell-session
39
+ $ just test
40
+
41
+ $ just lint
42
+
43
+ $ just typecheck
44
+ ```
45
+
46
+ To format code, sort imports, and apply automatic lint fixes:
47
+
48
+ ```shell-session
49
+ $ just fix
50
+
51
+ $ just format
52
+ ```
53
+
54
+ Documentation is built using sphinx. You can generate and view the documentation
55
+ locally in your browser:
56
+
57
+ ```shell-session
58
+ $ just docs
59
+
60
+ $ open html/index.html
61
+ ```
62
+
63
+ To run the full test, lint, typecheck, spell-check, and header-check suite:
64
+
65
+ ```shell-session
66
+ $ just check
67
+ ```
68
+
69
+
70
+ ## Submitting PRs
71
+
72
+ Before submitting PRs, please address the following items:
73
+
74
+ - Add tests exercising any fixed bugs or new functionality
75
+ - Document any changes to configuration or behavior
76
+ - Apply formatting, regenerate documentation, and run the test suite (see above)
77
+ - Summarize the high level features or behavior changes in your commit message
78
+
79
+ For most developers, we recommend using the [github cli][gh] to submit pull
80
+ requests:
81
+
82
+ ```shell-session
83
+ $ gh pr create
84
+ ```
85
+
86
+ ## Code style
87
+
88
+ You can ensure your changes are well formatted, and imports are sorted:
89
+
90
+ ```shell-session
91
+ $ just format
92
+ ```
93
+
94
+ If you are using VS Code as your editor, enable Ruff for formatting and linting
95
+ to match the project workflow.
96
+
97
+
98
+ ## VS Code
99
+
100
+ Make sure you've created an environment for Rattle:
101
+
102
+ ```shell-session
103
+ $ just sync
104
+ ```
105
+
106
+ Now, the VS Code Python module should be able to find and offer the local
107
+ `.venv` path as an option for your active Python environment, and should then
108
+ be aware of what libraries are available, and enable "Go To Definition" for
109
+ those packages.
110
+
111
+
112
+ ## git-branchless
113
+
114
+ [git-branchless](https://github.com/arxanas/git-branchless) is a useful tool
115
+ for improving your local git CLI workflow, especially within a stack of commits.
116
+ It provides a "smartlog" command (`git sl`) to help visual the hierarchy of
117
+ commits and branches in your checkout, as well as `next`/`prev` commands to
118
+ make moving through your stacks even easier:
119
+
120
+ ```shell-session
121
+ amethyst@luxray ~/workspace/Rattle docs » git sl
122
+
123
+ ◇ a80603c 226d (0.x) Update 'master' (branch) references to 'main' (#220)
124
+
125
+ ◆ c3f8ff9 52d (main, ᐅ docs) Include scripts dir in linters
126
+
127
+ ◯ 33863f4 52d (local-rules) Simple example of local rule for copyright headers
128
+ ```
129
+
130
+ git-branchless is a Rust package, and can be installed with cargo:
131
+
132
+ ```shell-session
133
+ $ cargo install --locked git-branchless
134
+ ```
135
+
136
+ Once installed to your system, it must be enabled on each git repo that you
137
+ want to use it with, so that it can install hooks and new commands:
138
+
139
+ ```shell-session
140
+ $ git branchless init
141
+ ```
142
+
143
+ [gh]: https://cli.github.com/
144
+ [uv]: https://docs.astral.sh/uv/
@@ -0,0 +1,90 @@
1
+ @_:
2
+ just --list
3
+
4
+ _require-uv:
5
+ @uv --version > /dev/null || (echo "Please install uv: https://docs.astral.sh/uv/" && exit 1)
6
+
7
+ # install all project extras into the local environment
8
+ install: _require-uv
9
+ uv sync --inexact --all-extras
10
+
11
+ # install the dev and lsp extras used for local testing and CI
12
+ install-dev: _require-uv
13
+ uv sync --inexact --extra dev --extra lsp
14
+
15
+ # install only the docs extras used for documentation builds
16
+ install-docs: _require-uv
17
+ uv sync --inexact --extra docs
18
+
19
+ # create or refresh the local virtual environment
20
+ venv: install
21
+ @echo 'run `source .venv/bin/activate` to activate virtualenv'
22
+
23
+ # check code style and potential issues
24
+ lint: _require-uv
25
+ uv run --extra dev ruff check src/rattle scripts examples docs/conf.py
26
+ uv run --extra dev ruff format --check src/rattle scripts examples docs/conf.py
27
+ uv run --extra dev python -m rattle lint src/rattle
28
+
29
+ # format code
30
+ format: _require-uv
31
+ uv run --extra dev ruff format src/rattle scripts examples docs/conf.py
32
+
33
+ # fix automatically fixable linting issues
34
+ fix: _require-uv
35
+ uv run --extra dev ruff check --fix src/rattle scripts examples docs/conf.py
36
+
37
+ # run the pytest suite
38
+ test: _require-uv
39
+ uv run --extra dev --extra lsp pytest
40
+
41
+ # build the package
42
+ build: _require-uv
43
+ uv build
44
+
45
+ # setup or update local dev environment and install pre-commit hooks
46
+ sync: install
47
+ uv run --all-extras pre-commit install
48
+
49
+ # run tests with coverage and show a coverage report
50
+ coverage: _require-uv
51
+ uv run --extra dev --extra lsp coverage run -m pytest
52
+ uv run --extra dev coverage report
53
+
54
+ # build the docs and regenerate the builtins page
55
+ docs: _require-uv
56
+ uv run --extra docs python scripts/document_rules.py
57
+ uv run --extra docs sphinx-build -ab html docs html
58
+
59
+ # check source headers
60
+ headers: _require-uv
61
+ uv run --extra dev python scripts/check_copyright.py
62
+
63
+ # clean build artifacts and caches
64
+ clean:
65
+ rm -rf .venv .pytest_cache .ruff_cache build dist html htmlcov .coverage
66
+ find . -type d -name "__pycache__" -exec rm -r {} +
67
+
68
+ # static type check with pyright
69
+ typecheck: _require-uv
70
+ uv run --extra dev pyright
71
+
72
+ # check code for common misspellings
73
+ spell: _require-uv
74
+ uv run --extra dev codespell
75
+
76
+ # run all quality checks
77
+ check: lint coverage typecheck spell headers
78
+
79
+ # run the main local workflow
80
+ all: install test lint docs
81
+
82
+ # list available recipes
83
+ help:
84
+ just --list
85
+
86
+ alias fmt := format
87
+ alias cov := coverage
88
+ alias distclean := clean
89
+ alias html := docs
90
+ alias pyright := typecheck
@@ -0,0 +1,76 @@
1
+ MIT License
2
+
3
+ Copyright (c) Facebook, Inc. and its affiliates.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+ -------------------------------------------------------------------------------
24
+
25
+ PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
26
+
27
+ 1. This LICENSE AGREEMENT is between the Python Software Foundation
28
+ ("PSF"), and the Individual or Organization ("Licensee") accessing and
29
+ otherwise using this software ("Python") in source or binary form and
30
+ its associated documentation.
31
+
32
+ 2. Subject to the terms and conditions of this License Agreement, PSF hereby
33
+ grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
34
+ analyze, test, perform and/or display publicly, prepare derivative works,
35
+ distribute, and otherwise use Python alone or in any derivative version,
36
+ provided, however, that PSF's License Agreement and PSF's notice of copyright,
37
+ i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
38
+ 2011, 2012, 2013, 2014, 2015 Python Software Foundation; All Rights Reserved"
39
+ are retained in Python alone or in any derivative version prepared by Licensee.
40
+
41
+ 3. In the event Licensee prepares a derivative work that is based on
42
+ or incorporates Python or any part thereof, and wants to make
43
+ the derivative work available to others as provided herein, then
44
+ Licensee hereby agrees to include in any such work a brief summary of
45
+ the changes made to Python.
46
+
47
+ 4. PSF is making Python available to Licensee on an "AS IS"
48
+ basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
49
+ IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
50
+ DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
51
+ FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
52
+ INFRINGE ANY THIRD PARTY RIGHTS.
53
+
54
+ 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
55
+ FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
56
+ A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
57
+ OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
58
+
59
+ 6. This License Agreement will automatically terminate upon a material
60
+ breach of its terms and conditions.
61
+
62
+ 7. Nothing in this License Agreement shall be deemed to create any
63
+ relationship of agency, partnership, or joint venture between PSF and
64
+ Licensee. This License Agreement does not grant permission to use PSF
65
+ trademarks or trade name in a trademark sense to endorse or promote
66
+ products or services of Licensee, or any third party.
67
+
68
+ 8. By copying, installing or otherwise using Python, Licensee
69
+ agrees to be bound by the terms and conditions of this License
70
+ Agreement.
71
+
72
+ -------------------------------------------------------------------------------
73
+
74
+ APACHE LICENSE, VERSION 2.0
75
+
76
+ http://www.apache.org/licenses/LICENSE-2.0
@@ -0,0 +1,190 @@
1
+ Metadata-Version: 2.4
2
+ Name: rattle-lint
3
+ Version: 1.0.1
4
+ Summary: A lint framework that helps you write better Python code.
5
+ Project-URL: Home, https://github.com/zigai/rattle
6
+ Project-URL: Issues, https://github.com/zigai/rattle/issues
7
+ Author: zigai
8
+ License: MIT License
9
+
10
+ Copyright (c) Facebook, Inc. and its affiliates.
11
+
12
+ Permission is hereby granted, free of charge, to any person obtaining a copy
13
+ of this software and associated documentation files (the "Software"), to deal
14
+ in the Software without restriction, including without limitation the rights
15
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
+ copies of the Software, and to permit persons to whom the Software is
17
+ furnished to do so, subject to the following conditions:
18
+
19
+ The above copyright notice and this permission notice shall be included in all
20
+ copies or substantial portions of the Software.
21
+
22
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
+ SOFTWARE.
29
+
30
+ -------------------------------------------------------------------------------
31
+
32
+ PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
33
+
34
+ 1. This LICENSE AGREEMENT is between the Python Software Foundation
35
+ ("PSF"), and the Individual or Organization ("Licensee") accessing and
36
+ otherwise using this software ("Python") in source or binary form and
37
+ its associated documentation.
38
+
39
+ 2. Subject to the terms and conditions of this License Agreement, PSF hereby
40
+ grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
41
+ analyze, test, perform and/or display publicly, prepare derivative works,
42
+ distribute, and otherwise use Python alone or in any derivative version,
43
+ provided, however, that PSF's License Agreement and PSF's notice of copyright,
44
+ i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
45
+ 2011, 2012, 2013, 2014, 2015 Python Software Foundation; All Rights Reserved"
46
+ are retained in Python alone or in any derivative version prepared by Licensee.
47
+
48
+ 3. In the event Licensee prepares a derivative work that is based on
49
+ or incorporates Python or any part thereof, and wants to make
50
+ the derivative work available to others as provided herein, then
51
+ Licensee hereby agrees to include in any such work a brief summary of
52
+ the changes made to Python.
53
+
54
+ 4. PSF is making Python available to Licensee on an "AS IS"
55
+ basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
56
+ IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
57
+ DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
58
+ FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
59
+ INFRINGE ANY THIRD PARTY RIGHTS.
60
+
61
+ 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
62
+ FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
63
+ A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
64
+ OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
65
+
66
+ 6. This License Agreement will automatically terminate upon a material
67
+ breach of its terms and conditions.
68
+
69
+ 7. Nothing in this License Agreement shall be deemed to create any
70
+ relationship of agency, partnership, or joint venture between PSF and
71
+ Licensee. This License Agreement does not grant permission to use PSF
72
+ trademarks or trade name in a trademark sense to endorse or promote
73
+ products or services of Licensee, or any third party.
74
+
75
+ 8. By copying, installing or otherwise using Python, Licensee
76
+ agrees to be bound by the terms and conditions of this License
77
+ Agreement.
78
+
79
+ -------------------------------------------------------------------------------
80
+
81
+ APACHE LICENSE, VERSION 2.0
82
+
83
+ http://www.apache.org/licenses/LICENSE-2.0
84
+ License-File: LICENSE
85
+ Classifier: Development Status :: 3 - Alpha
86
+ Classifier: Intended Audience :: Developers
87
+ Classifier: License :: OSI Approved :: MIT License
88
+ Classifier: Operating System :: OS Independent
89
+ Classifier: Programming Language :: Python
90
+ Classifier: Programming Language :: Python :: 3 :: Only
91
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
92
+ Classifier: Topic :: Software Development :: Quality Assurance
93
+ Requires-Python: >=3.10
94
+ Requires-Dist: click<8.2,>=8.0
95
+ Requires-Dist: libcst>=0.3.18
96
+ Requires-Dist: moreorless>=0.4.0
97
+ Requires-Dist: packaging>=21
98
+ Requires-Dist: tomli>=2.0; python_version < '3.11'
99
+ Requires-Dist: trailrunner>=1.2
100
+ Provides-Extra: dev
101
+ Requires-Dist: attribution==1.8.0; extra == 'dev'
102
+ Requires-Dist: black==25.11.0; extra == 'dev'
103
+ Requires-Dist: build>1; extra == 'dev'
104
+ Requires-Dist: codespell; extra == 'dev'
105
+ Requires-Dist: coverage; extra == 'dev'
106
+ Requires-Dist: pre-commit; extra == 'dev'
107
+ Requires-Dist: pyright; extra == 'dev'
108
+ Requires-Dist: pytest; extra == 'dev'
109
+ Requires-Dist: ruff==0.15.8; extra == 'dev'
110
+ Requires-Dist: tomli; extra == 'dev'
111
+ Requires-Dist: ufmt==2.8.0; extra == 'dev'
112
+ Requires-Dist: usort==1.0.8.post1; extra == 'dev'
113
+ Provides-Extra: docs
114
+ Requires-Dist: jinja2==3.1.6; extra == 'docs'
115
+ Requires-Dist: myst-parser==4.0.1; extra == 'docs'
116
+ Requires-Dist: sphinx==8.0.2; extra == 'docs'
117
+ Provides-Extra: lsp
118
+ Requires-Dist: pygls[ws]~=2.0.0; extra == 'lsp'
119
+ Provides-Extra: pretty
120
+ Requires-Dist: rich>=12.6.0; extra == 'pretty'
121
+ Description-Content-Type: text/markdown
122
+
123
+ # Rattle
124
+
125
+ Rattle is a Python linting framework built on [LibCST](https://libcst.readthedocs.io) with support for autofixes, custom in-repo lint rules, and hierarchical configuration.
126
+
127
+ Rattle is a fork of [Fixit](https://github.com/Instagram/Fixit).
128
+
129
+ ## Features
130
+
131
+ - Built-in lint rules for common Python issues
132
+ - Autofix support when a rule can safely rewrite code
133
+ - Local custom rules that can live inside your repository
134
+ - Hierarchical `pyproject.toml` configuration
135
+ - Pre-commit integration for CI and local workflows
136
+ - LSP support
137
+
138
+ ## Install
139
+
140
+ Install the CLI from PyPI:
141
+
142
+ ```bash
143
+ pip install rattle-lint
144
+ ```
145
+
146
+ Install editor/LSP support too:
147
+
148
+ ```bash
149
+ pip install "rattle-lint[lsp]"
150
+ ```
151
+
152
+ ## Basic Usage
153
+
154
+
155
+ ```bash
156
+ rattle lint
157
+ ```
158
+
159
+ Apply available autofixes:
160
+
161
+ ```bash
162
+ rattle fix
163
+ ```
164
+
165
+ ## Example Configuration
166
+
167
+
168
+ ```toml
169
+ [tool.rattle]
170
+ root = true
171
+ python-version = "3.10"
172
+ output-format = "rattle"
173
+ disable = [
174
+ "NoStaticIfCondition",
175
+ "UseAssertIn",
176
+ ]
177
+ per-file-disable = {"tests/generated.py" = ["UseFstring"]}
178
+
179
+ [tool.rattle.options.UseFstring]
180
+ simple_expression_max_length = 40
181
+
182
+ [[tool.rattle.overrides]]
183
+ path = "tests"
184
+ enable = ["UseAssertIn"]
185
+ options = { UseFstring = { simple_expression_max_length = 60 } }
186
+ ```
187
+
188
+ ## License
189
+
190
+ MIT