codesorter 0.2.5__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.
Files changed (82) hide show
  1. {codesorter-0.2.5 → codesorter-0.2.6}/CHANGES.rst +17 -0
  2. {codesorter-0.2.5 → codesorter-0.2.6}/PKG-INFO +32 -15
  3. {codesorter-0.2.5 → codesorter-0.2.6}/README.rst +31 -14
  4. {codesorter-0.2.5 → codesorter-0.2.6}/codesorter/const.py +1 -1
  5. codesorter-0.2.6/docs/_static/custom.css +26 -0
  6. {codesorter-0.2.5 → codesorter-0.2.6}/docs/code_overview/sort_code.rst +4 -3
  7. {codesorter-0.2.5 → codesorter-0.2.6}/docs/conf.py +2 -0
  8. {codesorter-0.2.5 → codesorter-0.2.6}/docs/index.rst +6 -0
  9. codesorter-0.2.6/docs/usage/barriers.rst +87 -0
  10. {codesorter-0.2.5 → codesorter-0.2.6}/.github/dependabot.yml +0 -0
  11. {codesorter-0.2.5 → codesorter-0.2.6}/.github/workflows/ci.yml +0 -0
  12. {codesorter-0.2.5 → codesorter-0.2.6}/.github/workflows/pre-commit_autoupdate.yml +0 -0
  13. {codesorter-0.2.5 → codesorter-0.2.6}/.github/workflows/prepare_release.yml +0 -0
  14. {codesorter-0.2.5 → codesorter-0.2.6}/.github/workflows/pypi.yml +0 -0
  15. {codesorter-0.2.5 → codesorter-0.2.6}/.github/workflows/scorecard.yml +0 -0
  16. {codesorter-0.2.5 → codesorter-0.2.6}/.github/workflows/stale_action.yml +0 -0
  17. {codesorter-0.2.5 → codesorter-0.2.6}/.github/workflows/tag_release.yml +0 -0
  18. {codesorter-0.2.5 → codesorter-0.2.6}/.gitignore +0 -0
  19. {codesorter-0.2.5 → codesorter-0.2.6}/.pre-commit-config.yaml +0 -0
  20. {codesorter-0.2.5 → codesorter-0.2.6}/.pre-commit-hooks.yaml +0 -0
  21. {codesorter-0.2.5 → codesorter-0.2.6}/.python-version +0 -0
  22. {codesorter-0.2.5 → codesorter-0.2.6}/.readthedocs.yaml +0 -0
  23. {codesorter-0.2.5 → codesorter-0.2.6}/LICENSE.txt +0 -0
  24. {codesorter-0.2.5 → codesorter-0.2.6}/codesorter/__init__.py +0 -0
  25. {codesorter-0.2.5 → codesorter-0.2.6}/codesorter/cli.py +0 -0
  26. {codesorter-0.2.5 → codesorter-0.2.6}/codesorter/py.typed +0 -0
  27. {codesorter-0.2.5 → codesorter-0.2.6}/codesorter/sort_code.py +0 -0
  28. {codesorter-0.2.5 → codesorter-0.2.6}/docs/Makefile +0 -0
  29. {codesorter-0.2.5 → codesorter-0.2.6}/docs/contributing/pre_commit.rst +0 -0
  30. {codesorter-0.2.5 → codesorter-0.2.6}/docs/docutils.conf +0 -0
  31. {codesorter-0.2.5 → codesorter-0.2.6}/docs/genindex.rst +0 -0
  32. {codesorter-0.2.5 → codesorter-0.2.6}/docs/make.bat +0 -0
  33. {codesorter-0.2.5 → codesorter-0.2.6}/docs/package_info/change_log.rst +0 -0
  34. {codesorter-0.2.5 → codesorter-0.2.6}/examples/after_example.py +0 -0
  35. {codesorter-0.2.5 → codesorter-0.2.6}/examples/before_example.py +0 -0
  36. {codesorter-0.2.5 → codesorter-0.2.6}/pyproject.toml +0 -0
  37. {codesorter-0.2.5 → codesorter-0.2.6}/tests/__init__.py +0 -0
  38. {codesorter-0.2.5 → codesorter-0.2.6}/tests/conftest.py +0 -0
  39. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/alias_function_input.py +0 -0
  40. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/alias_function_output.py +0 -0
  41. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/augmented_assignment_input.py +0 -0
  42. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/augmented_assignment_output.py +0 -0
  43. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/barrier_input.py +0 -0
  44. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/barrier_output.py +0 -0
  45. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/basic_function_input.py +0 -0
  46. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/basic_function_output.py +0 -0
  47. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/class_global_dependency_input.py +0 -0
  48. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/class_global_dependency_output.py +0 -0
  49. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/class_inheritance_input.py +0 -0
  50. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/class_inheritance_output.py +0 -0
  51. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/class_method_input.py +0 -0
  52. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/class_method_output.py +0 -0
  53. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/classmethod_input.py +0 -0
  54. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/classmethod_output.py +0 -0
  55. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/comprehension_dependency_input.py +0 -0
  56. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/comprehension_dependency_output.py +0 -0
  57. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/comprehensive_input.py +0 -0
  58. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/comprehensive_output.py +0 -0
  59. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/constant_ordering_input.py +0 -0
  60. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/constant_ordering_output.py +0 -0
  61. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/custom_decorators_input.py +0 -0
  62. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/custom_decorators_output.py +0 -0
  63. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/keyword_arguments_input.py +0 -0
  64. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/keyword_arguments_output.py +0 -0
  65. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/lazy_annotation_cycle_input.py +0 -0
  66. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/lazy_annotation_cycle_output.py +0 -0
  67. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/mixed_decorators_input.py +0 -0
  68. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/mixed_decorators_output.py +0 -0
  69. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/name_rebinding_input.py +0 -0
  70. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/name_rebinding_output.py +0 -0
  71. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/order_sensitive_input.py +0 -0
  72. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/order_sensitive_output.py +0 -0
  73. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/property_input.py +0 -0
  74. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/property_output.py +0 -0
  75. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/pytest_fixtures_input.py +0 -0
  76. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/pytest_fixtures_output.py +0 -0
  77. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/staticmethod_input.py +0 -0
  78. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/staticmethod_output.py +0 -0
  79. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/underscore_ordering_input.py +0 -0
  80. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_files/underscore_ordering_output.py +0 -0
  81. {codesorter-0.2.5 → codesorter-0.2.6}/tests/test_sort_code.py +0 -0
  82. {codesorter-0.2.5 → codesorter-0.2.6}/uv.lock +0 -0
@@ -4,6 +4,23 @@
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
+
7
24
  ********************
8
25
  0.2.5 (2026/06/14)
9
26
  ********************
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codesorter
3
- Version: 0.2.5
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/
@@ -60,6 +60,15 @@ Description-Content-Type: text/x-rst
60
60
 
61
61
  CodeSorter is a LibCST codemod that automatically sorts and organizes Python code.
62
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
+
63
72
  **********
64
73
  Features
65
74
  **********
@@ -85,10 +94,10 @@ From PyPI:
85
94
 
86
95
  .. code-block:: bash
87
96
 
88
- # using uv and add to the lint dependency group
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
89
100
  uv add --group lint codesorter
90
- # or using pip
91
- pip install codesorter
92
101
 
93
102
  From Source:
94
103
 
@@ -96,7 +105,7 @@ From Source:
96
105
 
97
106
  git clone https://github.com/praw-dev/CodeSorter.git
98
107
  cd CodeSorter
99
- uv pip install -e .
108
+ uv tool install .
100
109
 
101
110
  Development Installation:
102
111
 
@@ -137,7 +146,7 @@ commit:
137
146
  # .pre-commit-config.yaml
138
147
  repos:
139
148
  - repo: https://github.com/praw-dev/CodeSorter
140
- rev: v0.0.3
149
+ rev: v0.2.5
141
150
  hooks:
142
151
  - id: codesorter
143
152
 
@@ -147,7 +156,7 @@ Or use the check-only variant, which fails the hook without modifying files:
147
156
 
148
157
  repos:
149
158
  - repo: https://github.com/praw-dev/CodeSorter
150
- rev: v0.0.3
159
+ rev: v0.2.5
151
160
  hooks:
152
161
  - id: codesorter-check
153
162
 
@@ -195,10 +204,18 @@ Function Sorting
195
204
  Class Method Sorting
196
205
  ====================
197
206
 
198
- - Methods are sorted with special consideration for decorators: - ``@property`` methods
199
- (getters, setters, deleters) - ``@staticmethod`` methods - ``@classmethod`` methods -
200
- Regular instance methods
201
- - Methods within classes maintain their logical grouping
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
202
219
 
203
220
  Pytest Fixture Sorting
204
221
  ======================
@@ -231,14 +248,14 @@ Example Transformation
231
248
  .. code-block:: python
232
249
 
233
250
  class MyClass:
234
- @property
235
- def a_property(self):
236
- pass
237
-
238
251
  @staticmethod
239
252
  def b_static():
240
253
  pass
241
254
 
255
+ @property
256
+ def a_property(self):
257
+ pass
258
+
242
259
  def z_method(self):
243
260
  pass
244
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
- # using uv and add to the lint dependency group
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 pip install -e .
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.0.3
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.0.3
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 sorted with special consideration for decorators: - ``@property`` methods
143
- (getters, setters, deleters) - ``@staticmethod`` methods - ``@classmethod`` methods -
144
- Regular instance methods
145
- - Methods within classes maintain their logical grouping
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
 
@@ -39,4 +39,4 @@ PLAIN_DECORATOR_PARTS = 1
39
39
 
40
40
  PROPERTY_DECORATOR_PARTS = 2
41
41
 
42
- __version__ = "0.2.5"
42
+ __version__ = "0.2.6"
@@ -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. It is
6
- applied by the CLI, but can also be used directly as a libcst codemod (for example via
7
- ``python -m libcst.tool codemod codesorter.sort_code.SortCodeCommand``).
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
 
@@ -16,6 +16,8 @@ extensions = [
16
16
  "sphinx.ext.intersphinx",
17
17
  "sphinx_autodoc_typehints",
18
18
  ]
19
+ html_css_files = ["custom.css"]
20
+ html_static_path = ["_static"]
19
21
  html_theme = "furo"
20
22
  intersphinx_mapping = {
21
23
  "python": ("https://docs.python.org/3", None),
@@ -1,5 +1,11 @@
1
1
  .. include:: ../README.rst
2
2
 
3
+ .. toctree::
4
+ :hidden:
5
+ :caption: Usage
6
+
7
+ usage/barriers
8
+
3
9
  .. toctree::
4
10
  :hidden:
5
11
  :caption: Code Overview
@@ -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.
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