codesorter 0.2.4__tar.gz → 0.2.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.
- {codesorter-0.2.4 → codesorter-0.2.6}/CHANGES.rst +29 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/PKG-INFO +33 -15
- {codesorter-0.2.4 → codesorter-0.2.6}/README.rst +31 -14
- {codesorter-0.2.4 → codesorter-0.2.6}/codesorter/const.py +1 -1
- codesorter-0.2.6/docs/_static/custom.css +26 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/docs/code_overview/sort_code.rst +4 -3
- {codesorter-0.2.4 → codesorter-0.2.6}/docs/conf.py +2 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/docs/contributing/pre_commit.rst +3 -3
- {codesorter-0.2.4 → codesorter-0.2.6}/docs/index.rst +6 -0
- codesorter-0.2.6/docs/usage/barriers.rst +87 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/pyproject.toml +3 -3
- {codesorter-0.2.4 → codesorter-0.2.6}/uv.lock +3 -7
- codesorter-0.2.4/.libcst.codemod.yaml +0 -36
- {codesorter-0.2.4 → codesorter-0.2.6}/.github/dependabot.yml +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/.github/workflows/ci.yml +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/.github/workflows/pre-commit_autoupdate.yml +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/.github/workflows/prepare_release.yml +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/.github/workflows/pypi.yml +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/.github/workflows/scorecard.yml +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/.github/workflows/stale_action.yml +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/.github/workflows/tag_release.yml +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/.gitignore +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/.pre-commit-config.yaml +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/.pre-commit-hooks.yaml +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/.python-version +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/.readthedocs.yaml +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/LICENSE.txt +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/codesorter/__init__.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/codesorter/cli.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/codesorter/py.typed +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/codesorter/sort_code.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/docs/Makefile +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/docs/docutils.conf +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/docs/genindex.rst +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/docs/make.bat +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/docs/package_info/change_log.rst +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/examples/after_example.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/examples/before_example.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/__init__.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/conftest.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/alias_function_input.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/alias_function_output.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/augmented_assignment_input.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/augmented_assignment_output.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/barrier_input.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/barrier_output.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/basic_function_input.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/basic_function_output.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/class_global_dependency_input.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/class_global_dependency_output.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/class_inheritance_input.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/class_inheritance_output.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/class_method_input.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/class_method_output.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/classmethod_input.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/classmethod_output.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/comprehension_dependency_input.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/comprehension_dependency_output.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/comprehensive_input.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/comprehensive_output.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/constant_ordering_input.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/constant_ordering_output.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/custom_decorators_input.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/custom_decorators_output.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/keyword_arguments_input.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/keyword_arguments_output.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/lazy_annotation_cycle_input.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/lazy_annotation_cycle_output.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/mixed_decorators_input.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/mixed_decorators_output.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/name_rebinding_input.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/name_rebinding_output.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/order_sensitive_input.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/order_sensitive_output.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/property_input.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/property_output.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/pytest_fixtures_input.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/pytest_fixtures_output.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/staticmethod_input.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/staticmethod_output.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/underscore_ordering_input.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_files/underscore_ordering_output.py +0 -0
- {codesorter-0.2.4 → codesorter-0.2.6}/tests/test_sort_code.py +0 -0
|
@@ -4,6 +4,35 @@
|
|
|
4
4
|
|
|
5
5
|
codesorter follows `semantic versioning <https://semver.org/>`_.
|
|
6
6
|
|
|
7
|
+
********************
|
|
8
|
+
0.2.6 (2026/06/14)
|
|
9
|
+
********************
|
|
10
|
+
|
|
11
|
+
**Added**
|
|
12
|
+
|
|
13
|
+
- Documentation page describing how barriers limit sorting to segments between
|
|
14
|
+
side-effecting statements, and how to relocate a statement that should not be a
|
|
15
|
+
barrier.
|
|
16
|
+
|
|
17
|
+
**Changed**
|
|
18
|
+
|
|
19
|
+
- Refresh the documentation: the installation instructions use uv-native commands, the
|
|
20
|
+
class-method ordering reference and example now match the implementation, and the
|
|
21
|
+
barrier relocation example is split into separate, color-tinted before and after
|
|
22
|
+
blocks.
|
|
23
|
+
|
|
24
|
+
********************
|
|
25
|
+
0.2.5 (2026/06/14)
|
|
26
|
+
********************
|
|
27
|
+
|
|
28
|
+
**Changed**
|
|
29
|
+
|
|
30
|
+
- Depend on ``ruff`` directly so the formatter is always installed alongside
|
|
31
|
+
``codesorter``. The CLI shells out to ``ruff format``, which previously only worked
|
|
32
|
+
when ``ruff`` happened to be on ``PATH`` from another source; it is now a runtime
|
|
33
|
+
dependency, so ``codesorter`` is self-contained in a clean environment and in the
|
|
34
|
+
isolated pre-commit hook.
|
|
35
|
+
|
|
7
36
|
********************
|
|
8
37
|
0.2.4 (2026/06/14)
|
|
9
38
|
********************
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codesorter
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.6
|
|
4
4
|
Summary: A Python codemod that sorts and organizes code in your files.
|
|
5
5
|
Project-URL: Change Log, https://codesorter.readthedocs.io/en/latest/package_info/change_log.html
|
|
6
6
|
Project-URL: Documentation, https://codesorter.readthedocs.io/
|
|
@@ -51,6 +51,7 @@ Classifier: Typing :: Typed
|
|
|
51
51
|
Requires-Python: >=3.10
|
|
52
52
|
Requires-Dist: libcst<2.0.0,>=1.8.6
|
|
53
53
|
Requires-Dist: pathspec>=1.1.1
|
|
54
|
+
Requires-Dist: ruff>=0.1.2
|
|
54
55
|
Description-Content-Type: text/x-rst
|
|
55
56
|
|
|
56
57
|
############
|
|
@@ -59,6 +60,15 @@ Description-Content-Type: text/x-rst
|
|
|
59
60
|
|
|
60
61
|
CodeSorter is a LibCST codemod that automatically sorts and organizes Python code.
|
|
61
62
|
|
|
63
|
+
.. warning::
|
|
64
|
+
|
|
65
|
+
Only apply CodeSorter to a code base you own or maintain. Reordering an entire file
|
|
66
|
+
is a sweeping, opinionated change that conflicts with in-flight work and erases the
|
|
67
|
+
history of carefully chosen ordering. Opening a pull request that runs CodeSorter
|
|
68
|
+
across **someone else's** project is strongly discouraged — it is noisy,
|
|
69
|
+
unsolicited, and burdensome to review. Adopt it as a pre-commit hook in your own
|
|
70
|
+
repositories instead, where every contributor benefits from the consistent ordering.
|
|
71
|
+
|
|
62
72
|
**********
|
|
63
73
|
Features
|
|
64
74
|
**********
|
|
@@ -84,10 +94,10 @@ From PyPI:
|
|
|
84
94
|
|
|
85
95
|
.. code-block:: bash
|
|
86
96
|
|
|
87
|
-
#
|
|
97
|
+
# install the codesorter CLI as a standalone tool
|
|
98
|
+
uv tool install codesorter
|
|
99
|
+
# or add it to a project's lint dependency group
|
|
88
100
|
uv add --group lint codesorter
|
|
89
|
-
# or using pip
|
|
90
|
-
pip install codesorter
|
|
91
101
|
|
|
92
102
|
From Source:
|
|
93
103
|
|
|
@@ -95,7 +105,7 @@ From Source:
|
|
|
95
105
|
|
|
96
106
|
git clone https://github.com/praw-dev/CodeSorter.git
|
|
97
107
|
cd CodeSorter
|
|
98
|
-
uv
|
|
108
|
+
uv tool install .
|
|
99
109
|
|
|
100
110
|
Development Installation:
|
|
101
111
|
|
|
@@ -136,7 +146,7 @@ commit:
|
|
|
136
146
|
# .pre-commit-config.yaml
|
|
137
147
|
repos:
|
|
138
148
|
- repo: https://github.com/praw-dev/CodeSorter
|
|
139
|
-
rev: v0.
|
|
149
|
+
rev: v0.2.5
|
|
140
150
|
hooks:
|
|
141
151
|
- id: codesorter
|
|
142
152
|
|
|
@@ -146,7 +156,7 @@ Or use the check-only variant, which fails the hook without modifying files:
|
|
|
146
156
|
|
|
147
157
|
repos:
|
|
148
158
|
- repo: https://github.com/praw-dev/CodeSorter
|
|
149
|
-
rev: v0.
|
|
159
|
+
rev: v0.2.5
|
|
150
160
|
hooks:
|
|
151
161
|
- id: codesorter-check
|
|
152
162
|
|
|
@@ -194,10 +204,18 @@ Function Sorting
|
|
|
194
204
|
Class Method Sorting
|
|
195
205
|
====================
|
|
196
206
|
|
|
197
|
-
- Methods are
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
-
|
|
207
|
+
- Methods are grouped by kind, in this order:
|
|
208
|
+
|
|
209
|
+
- ``@abstractmethod`` methods
|
|
210
|
+
- pytest fixtures (``autouse`` fixtures first)
|
|
211
|
+
- ``@staticmethod`` methods
|
|
212
|
+
- ``@classmethod`` methods
|
|
213
|
+
- cached properties and ``@property`` methods (getter, then setter, then deleter)
|
|
214
|
+
- ``@contextmanager`` methods
|
|
215
|
+
- regular instance methods
|
|
216
|
+
|
|
217
|
+
- Within each group, methods are sorted alphabetically, with leading-underscore
|
|
218
|
+
(``_private`` and ``__dunder__``) names ahead of public ones
|
|
201
219
|
|
|
202
220
|
Pytest Fixture Sorting
|
|
203
221
|
======================
|
|
@@ -230,14 +248,14 @@ Example Transformation
|
|
|
230
248
|
.. code-block:: python
|
|
231
249
|
|
|
232
250
|
class MyClass:
|
|
233
|
-
@property
|
|
234
|
-
def a_property(self):
|
|
235
|
-
pass
|
|
236
|
-
|
|
237
251
|
@staticmethod
|
|
238
252
|
def b_static():
|
|
239
253
|
pass
|
|
240
254
|
|
|
255
|
+
@property
|
|
256
|
+
def a_property(self):
|
|
257
|
+
pass
|
|
258
|
+
|
|
241
259
|
def z_method(self):
|
|
242
260
|
pass
|
|
243
261
|
|
|
@@ -4,6 +4,15 @@
|
|
|
4
4
|
|
|
5
5
|
CodeSorter is a LibCST codemod that automatically sorts and organizes Python code.
|
|
6
6
|
|
|
7
|
+
.. warning::
|
|
8
|
+
|
|
9
|
+
Only apply CodeSorter to a code base you own or maintain. Reordering an entire file
|
|
10
|
+
is a sweeping, opinionated change that conflicts with in-flight work and erases the
|
|
11
|
+
history of carefully chosen ordering. Opening a pull request that runs CodeSorter
|
|
12
|
+
across **someone else's** project is strongly discouraged — it is noisy,
|
|
13
|
+
unsolicited, and burdensome to review. Adopt it as a pre-commit hook in your own
|
|
14
|
+
repositories instead, where every contributor benefits from the consistent ordering.
|
|
15
|
+
|
|
7
16
|
**********
|
|
8
17
|
Features
|
|
9
18
|
**********
|
|
@@ -29,10 +38,10 @@ From PyPI:
|
|
|
29
38
|
|
|
30
39
|
.. code-block:: bash
|
|
31
40
|
|
|
32
|
-
#
|
|
41
|
+
# install the codesorter CLI as a standalone tool
|
|
42
|
+
uv tool install codesorter
|
|
43
|
+
# or add it to a project's lint dependency group
|
|
33
44
|
uv add --group lint codesorter
|
|
34
|
-
# or using pip
|
|
35
|
-
pip install codesorter
|
|
36
45
|
|
|
37
46
|
From Source:
|
|
38
47
|
|
|
@@ -40,7 +49,7 @@ From Source:
|
|
|
40
49
|
|
|
41
50
|
git clone https://github.com/praw-dev/CodeSorter.git
|
|
42
51
|
cd CodeSorter
|
|
43
|
-
uv
|
|
52
|
+
uv tool install .
|
|
44
53
|
|
|
45
54
|
Development Installation:
|
|
46
55
|
|
|
@@ -81,7 +90,7 @@ commit:
|
|
|
81
90
|
# .pre-commit-config.yaml
|
|
82
91
|
repos:
|
|
83
92
|
- repo: https://github.com/praw-dev/CodeSorter
|
|
84
|
-
rev: v0.
|
|
93
|
+
rev: v0.2.5
|
|
85
94
|
hooks:
|
|
86
95
|
- id: codesorter
|
|
87
96
|
|
|
@@ -91,7 +100,7 @@ Or use the check-only variant, which fails the hook without modifying files:
|
|
|
91
100
|
|
|
92
101
|
repos:
|
|
93
102
|
- repo: https://github.com/praw-dev/CodeSorter
|
|
94
|
-
rev: v0.
|
|
103
|
+
rev: v0.2.5
|
|
95
104
|
hooks:
|
|
96
105
|
- id: codesorter-check
|
|
97
106
|
|
|
@@ -139,10 +148,18 @@ Function Sorting
|
|
|
139
148
|
Class Method Sorting
|
|
140
149
|
====================
|
|
141
150
|
|
|
142
|
-
- Methods are
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
-
|
|
151
|
+
- Methods are grouped by kind, in this order:
|
|
152
|
+
|
|
153
|
+
- ``@abstractmethod`` methods
|
|
154
|
+
- pytest fixtures (``autouse`` fixtures first)
|
|
155
|
+
- ``@staticmethod`` methods
|
|
156
|
+
- ``@classmethod`` methods
|
|
157
|
+
- cached properties and ``@property`` methods (getter, then setter, then deleter)
|
|
158
|
+
- ``@contextmanager`` methods
|
|
159
|
+
- regular instance methods
|
|
160
|
+
|
|
161
|
+
- Within each group, methods are sorted alphabetically, with leading-underscore
|
|
162
|
+
(``_private`` and ``__dunder__``) names ahead of public ones
|
|
146
163
|
|
|
147
164
|
Pytest Fixture Sorting
|
|
148
165
|
======================
|
|
@@ -175,14 +192,14 @@ Example Transformation
|
|
|
175
192
|
.. code-block:: python
|
|
176
193
|
|
|
177
194
|
class MyClass:
|
|
178
|
-
@property
|
|
179
|
-
def a_property(self):
|
|
180
|
-
pass
|
|
181
|
-
|
|
182
195
|
@staticmethod
|
|
183
196
|
def b_static():
|
|
184
197
|
pass
|
|
185
198
|
|
|
199
|
+
@property
|
|
200
|
+
def a_property(self):
|
|
201
|
+
pass
|
|
202
|
+
|
|
186
203
|
def z_method(self):
|
|
187
204
|
pass
|
|
188
205
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/* Tint the before/after code blocks on the barriers page.
|
|
2
|
+
Translucent fills layer over the page background, so they read correctly in
|
|
3
|
+
both the light and dark Furo themes. */
|
|
4
|
+
.codesorter-before,
|
|
5
|
+
.codesorter-after {
|
|
6
|
+
border-left: 4px solid;
|
|
7
|
+
border-radius: 0.2rem;
|
|
8
|
+
margin-bottom: 1rem;
|
|
9
|
+
padding-left: 0.4rem;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.codesorter-before {
|
|
13
|
+
background-color: rgba(229, 83, 75, 0.08);
|
|
14
|
+
border-left-color: #e5534b;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.codesorter-after {
|
|
18
|
+
background-color: rgba(63, 185, 80, 0.08);
|
|
19
|
+
border-left-color: #3fb950;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/* Let the container tint show through instead of Furo's code background. */
|
|
23
|
+
.codesorter-before div.highlight,
|
|
24
|
+
.codesorter-after div.highlight {
|
|
25
|
+
background: transparent;
|
|
26
|
+
}
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
Sort Code
|
|
3
3
|
###########
|
|
4
4
|
|
|
5
|
-
The :class:`.SortCodeCommand` is the libcst codemod that performs the reordering.
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
The :class:`.SortCodeCommand` is the libcst codemod that performs the reordering. The
|
|
6
|
+
``codesorter`` CLI applies it to the files you pass it; you can also use it directly as
|
|
7
|
+
a libcst codemod in your own tooling by constructing it with a ``CodemodContext`` and
|
|
8
|
+
calling ``transform_module`` (see the programmatic example in the README).
|
|
8
9
|
|
|
9
10
|
.. autoclass:: codesorter.sort_code.SortCodeCommand
|
|
10
11
|
|
|
@@ -21,9 +21,9 @@ hook so the repository is always sorted by the code on the current branch:
|
|
|
21
21
|
***************************
|
|
22
22
|
|
|
23
23
|
Because the hook uses ``language: system``, it runs the ``codesorter`` executable from
|
|
24
|
-
your environment instead of an isolated one pre-commit manages. CodeSorter
|
|
25
|
-
``ruff format`` as its formatter
|
|
26
|
-
``
|
|
24
|
+
your environment instead of an isolated one pre-commit manages. CodeSorter always
|
|
25
|
+
invokes ``ruff format`` as its formatter, so both ``codesorter`` and ``ruff`` must be on
|
|
26
|
+
``PATH`` when the hook runs.
|
|
27
27
|
|
|
28
28
|
Install the development environment and the git hook:
|
|
29
29
|
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
######################
|
|
2
|
+
Sorting and Barriers
|
|
3
|
+
######################
|
|
4
|
+
|
|
5
|
+
CodeSorter reorders the classes, functions, and assignments within a module or class
|
|
6
|
+
body, but only within a *segment* of consecutive definitions. Any statement that is not
|
|
7
|
+
a sortable definition acts as a **barrier**, and no definition is ever moved across one.
|
|
8
|
+
|
|
9
|
+
Barriers include bare expression statements (a function call on its own line such as
|
|
10
|
+
``sys.path.insert(0, str(ROOT))``), ``if`` / ``for`` / ``while`` / ``with`` blocks,
|
|
11
|
+
``import`` statements, and similar. A barrier splits the surrounding definitions into
|
|
12
|
+
independent segments, each sorted on its own.
|
|
13
|
+
|
|
14
|
+
********************
|
|
15
|
+
Why barriers exist
|
|
16
|
+
********************
|
|
17
|
+
|
|
18
|
+
A statement sitting between definitions may depend on one of them, or be depended upon,
|
|
19
|
+
in ways that reordering would break. There are two cases, and only the first is visible
|
|
20
|
+
to a static tool:
|
|
21
|
+
|
|
22
|
+
1. The statement *references* a definition that would otherwise move after it:
|
|
23
|
+
|
|
24
|
+
.. code-block:: python
|
|
25
|
+
|
|
26
|
+
ROOT = Path(__file__).resolve().parent
|
|
27
|
+
sys.path.insert(0, str(ROOT)) # uses ROOT
|
|
28
|
+
|
|
29
|
+
If ``ROOT`` were sorted after the ``sys.path.insert`` call, the module would raise
|
|
30
|
+
``NameError`` on import.
|
|
31
|
+
|
|
32
|
+
2. A later definition depends on the statement's *side effect*, which no name reference
|
|
33
|
+
reveals:
|
|
34
|
+
|
|
35
|
+
.. code-block:: python
|
|
36
|
+
|
|
37
|
+
configure_settings()
|
|
38
|
+
DEFAULT_TIMEOUT = settings.get("timeout") # reads what configure_settings() set up
|
|
39
|
+
|
|
40
|
+
``DEFAULT_TIMEOUT`` does not mention ``configure_settings`` by name, yet it must run
|
|
41
|
+
after it. Moving the constant ahead of the call would silently read an unconfigured
|
|
42
|
+
value — a wrong result rather than a crash.
|
|
43
|
+
|
|
44
|
+
Because side effects are opaque, CodeSorter cannot prove that crossing an arbitrary
|
|
45
|
+
statement is safe, so it treats every non-definition statement as a barrier.
|
|
46
|
+
|
|
47
|
+
**********************
|
|
48
|
+
Relocating a barrier
|
|
49
|
+
**********************
|
|
50
|
+
|
|
51
|
+
The cost of this rule is small: a barrier that genuinely sits in the middle of a block
|
|
52
|
+
of definitions keeps the definitions on either side from sorting together. If a
|
|
53
|
+
statement legitimately should *not* separate your definitions — you know it has no
|
|
54
|
+
ordering relationship with them — move it yourself so it no longer sits between them.
|
|
55
|
+
For example, hoist a one-off call to the top of the module (just below the imports) or
|
|
56
|
+
to the bottom.
|
|
57
|
+
|
|
58
|
+
**Before** — the call sits between the classes, splitting them into two segments, so
|
|
59
|
+
``Alpha`` and ``Beta`` cannot sort together:
|
|
60
|
+
|
|
61
|
+
.. code-block:: python
|
|
62
|
+
:class: codesorter-before
|
|
63
|
+
|
|
64
|
+
class Beta: ...
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
warnings.filterwarnings("ignore")
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class Alpha: ...
|
|
71
|
+
|
|
72
|
+
**After** — relocate the call above both classes; ``Alpha`` and ``Beta`` now form a
|
|
73
|
+
single segment and sort into order:
|
|
74
|
+
|
|
75
|
+
.. code-block:: python
|
|
76
|
+
:class: codesorter-after
|
|
77
|
+
|
|
78
|
+
warnings.filterwarnings("ignore")
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class Alpha: ...
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class Beta: ...
|
|
85
|
+
|
|
86
|
+
CodeSorter will not perform this move for you, precisely because it cannot prove the
|
|
87
|
+
move preserves behavior — only you know whether the statement is safe to relocate.
|
|
@@ -16,8 +16,7 @@ docs = [
|
|
|
16
16
|
"sphinx-autodoc-typehints>=2.5.0"
|
|
17
17
|
]
|
|
18
18
|
lint = [
|
|
19
|
-
"pre-commit>=4.6.0"
|
|
20
|
-
"ruff>=0.15.17"
|
|
19
|
+
"pre-commit>=4.6.0"
|
|
21
20
|
]
|
|
22
21
|
test = [
|
|
23
22
|
"coverage>=7.14.1",
|
|
@@ -50,7 +49,8 @@ classifiers = [
|
|
|
50
49
|
]
|
|
51
50
|
dependencies = [
|
|
52
51
|
"libcst>=1.8.6,<2.0.0",
|
|
53
|
-
"pathspec>=1.1.1"
|
|
52
|
+
"pathspec>=1.1.1",
|
|
53
|
+
"ruff>=0.1.2"
|
|
54
54
|
]
|
|
55
55
|
description = "A Python codemod that sorts and organizes code in your files."
|
|
56
56
|
dynamic = ["version"]
|
|
@@ -190,6 +190,7 @@ source = { editable = "." }
|
|
|
190
190
|
dependencies = [
|
|
191
191
|
{ name = "libcst" },
|
|
192
192
|
{ name = "pathspec" },
|
|
193
|
+
{ name = "ruff" },
|
|
193
194
|
]
|
|
194
195
|
|
|
195
196
|
[package.dev-dependencies]
|
|
@@ -199,7 +200,6 @@ dev = [
|
|
|
199
200
|
{ name = "pre-commit" },
|
|
200
201
|
{ name = "pyright" },
|
|
201
202
|
{ name = "pytest" },
|
|
202
|
-
{ name = "ruff" },
|
|
203
203
|
{ name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" },
|
|
204
204
|
{ name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" },
|
|
205
205
|
{ name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" },
|
|
@@ -219,7 +219,6 @@ docs = [
|
|
|
219
219
|
]
|
|
220
220
|
lint = [
|
|
221
221
|
{ name = "pre-commit" },
|
|
222
|
-
{ name = "ruff" },
|
|
223
222
|
]
|
|
224
223
|
test = [
|
|
225
224
|
{ name = "coverage" },
|
|
@@ -235,6 +234,7 @@ type = [
|
|
|
235
234
|
requires-dist = [
|
|
236
235
|
{ name = "libcst", specifier = ">=1.8.6,<2.0.0" },
|
|
237
236
|
{ name = "pathspec", specifier = ">=1.1.1" },
|
|
237
|
+
{ name = "ruff", specifier = ">=0.1.2" },
|
|
238
238
|
]
|
|
239
239
|
|
|
240
240
|
[package.metadata.requires-dev]
|
|
@@ -244,7 +244,6 @@ dev = [
|
|
|
244
244
|
{ name = "pre-commit", specifier = ">=4.6.0" },
|
|
245
245
|
{ name = "pyright", specifier = ">=1.1.410" },
|
|
246
246
|
{ name = "pytest", specifier = ">=9.0.3" },
|
|
247
|
-
{ name = "ruff", specifier = ">=0.15.17" },
|
|
248
247
|
{ name = "sphinx", specifier = ">=8.1.3" },
|
|
249
248
|
{ name = "sphinx-autodoc-typehints", specifier = ">=2.5.0" },
|
|
250
249
|
{ name = "tox-uv", specifier = ">=1.35.2" },
|
|
@@ -254,10 +253,7 @@ docs = [
|
|
|
254
253
|
{ name = "sphinx", specifier = ">=8.1.3" },
|
|
255
254
|
{ name = "sphinx-autodoc-typehints", specifier = ">=2.5.0" },
|
|
256
255
|
]
|
|
257
|
-
lint = [
|
|
258
|
-
{ name = "pre-commit", specifier = ">=4.6.0" },
|
|
259
|
-
{ name = "ruff", specifier = ">=0.15.17" },
|
|
260
|
-
]
|
|
256
|
+
lint = [{ name = "pre-commit", specifier = ">=4.6.0" }]
|
|
261
257
|
test = [
|
|
262
258
|
{ name = "coverage", specifier = ">=7.14.1" },
|
|
263
259
|
{ name = "pytest", specifier = ">=9.0.3" },
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
# String that LibCST should look for in code which indicates that the
|
|
2
|
-
# module is generated code.
|
|
3
|
-
generated_code_marker: '@generated'
|
|
4
|
-
# Command line and arguments for invoking a code formatter. Anything
|
|
5
|
-
# specified here must be capable of taking code via stdin and returning
|
|
6
|
-
# formatted code via stdout.
|
|
7
|
-
formatter: ['ruff', 'format', '-']
|
|
8
|
-
# List of regex patterns which LibCST will evaluate against filenames to
|
|
9
|
-
# determine if the module should be touched.
|
|
10
|
-
blacklist_patterns:
|
|
11
|
-
- '.*/\.bzr/.*'
|
|
12
|
-
- '.*/\.direnv/.*'
|
|
13
|
-
- '.*/\.eggs/.*'
|
|
14
|
-
- '.*/\.git/.*'
|
|
15
|
-
- '.*/\.hg/.*'
|
|
16
|
-
- '.*/\.mypy_cache/.*'
|
|
17
|
-
- '.*/\.nox/.*'
|
|
18
|
-
- '.*/\.pytest_cache/.*'
|
|
19
|
-
- '.*/\.ruff_cache/.*'
|
|
20
|
-
- '.*/\.svn/.*'
|
|
21
|
-
- '.*/\.tox/.*'
|
|
22
|
-
- '.*/\.venv/.*'
|
|
23
|
-
- '.*/__pycache__/.*'
|
|
24
|
-
- '.*/__pypackages__/.*'
|
|
25
|
-
- '.*/build/.*'
|
|
26
|
-
- '.*/dist/.*'
|
|
27
|
-
- '.*/env/.*'
|
|
28
|
-
- '.*/node_modules/.*'
|
|
29
|
-
- '.*/venv/.*'
|
|
30
|
-
# List of modules that contain codemods inside of them.
|
|
31
|
-
modules:
|
|
32
|
-
- 'codesorter'
|
|
33
|
-
# Absolute or relative path of the repository root, used for providing
|
|
34
|
-
# full-repo metadata. Relative paths should be specified with this file
|
|
35
|
-
# location as the base.
|
|
36
|
-
repo_root: '.'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|