undersort 0.1.2__tar.gz → 0.1.4__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.
- {undersort-0.1.2 → undersort-0.1.4}/PKG-INFO +57 -5
- {undersort-0.1.2 → undersort-0.1.4}/README.md +56 -4
- {undersort-0.1.2 → undersort-0.1.4}/pyproject.toml +1 -1
- undersort-0.1.4/tests/test_nosort.py +190 -0
- {undersort-0.1.2 → undersort-0.1.4}/undersort/__init__.py +1 -1
- {undersort-0.1.2 → undersort-0.1.4}/undersort/sorter.py +68 -4
- {undersort-0.1.2 → undersort-0.1.4}/uv.lock +1 -1
- {undersort-0.1.2 → undersort-0.1.4}/.github/workflows/ci.yml +0 -0
- {undersort-0.1.2 → undersort-0.1.4}/.gitignore +0 -0
- {undersort-0.1.2 → undersort-0.1.4}/.pre-commit-config.yaml +0 -0
- {undersort-0.1.2 → undersort-0.1.4}/.pre-commit-hooks.yaml +0 -0
- {undersort-0.1.2 → undersort-0.1.4}/.python-version +0 -0
- {undersort-0.1.2 → undersort-0.1.4}/.vscode/settings.json +0 -0
- {undersort-0.1.2 → undersort-0.1.4}/LICENSE +0 -0
- {undersort-0.1.2 → undersort-0.1.4}/Makefile +0 -0
- {undersort-0.1.2 → undersort-0.1.4}/tests/__init__.py +0 -0
- {undersort-0.1.2 → undersort-0.1.4}/tests/test_config.py +0 -0
- {undersort-0.1.2 → undersort-0.1.4}/tests/test_main.py +0 -0
- {undersort-0.1.2 → undersort-0.1.4}/tests/test_sorter.py +0 -0
- {undersort-0.1.2 → undersort-0.1.4}/undersort/config.py +0 -0
- {undersort-0.1.2 → undersort-0.1.4}/undersort/logger.py +0 -0
- {undersort-0.1.2 → undersort-0.1.4}/undersort/main.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: undersort
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.4
|
|
4
4
|
Summary: A tool to sort class methods by visibility (public, protected, private)
|
|
5
5
|
Project-URL: Homepage, https://github.com/kivicode/undersort
|
|
6
6
|
Project-URL: Repository, https://github.com/kivicode/undersort
|
|
@@ -43,10 +43,15 @@ A Python tool that automatically sorts class methods by visibility (public, prot
|
|
|
43
43
|
|
|
44
44
|
```bash
|
|
45
45
|
# Using uv (recommended)
|
|
46
|
-
uv
|
|
46
|
+
uv add undersort
|
|
47
47
|
|
|
48
48
|
# Using pip
|
|
49
|
-
pip install
|
|
49
|
+
pip install undersort
|
|
50
|
+
|
|
51
|
+
# For development
|
|
52
|
+
git clone https://github.com/kivicode/undersort
|
|
53
|
+
cd undersort
|
|
54
|
+
uv sync
|
|
50
55
|
```
|
|
51
56
|
|
|
52
57
|
## Configuration
|
|
@@ -85,6 +90,7 @@ Methods are sorted in two levels:
|
|
|
85
90
|
2. **Secondary**: Within each visibility level, by method type (instance → class → static by default)
|
|
86
91
|
|
|
87
92
|
The sorting algorithm **minimizes movement** to preserve the original order as much as possible:
|
|
93
|
+
|
|
88
94
|
- Methods that need to move DOWN (to a later section) are placed at the **beginning** of their target section
|
|
89
95
|
- Methods that need to move UP (to an earlier section) are placed at the **end** of their target section
|
|
90
96
|
- Methods already in the correct section maintain their relative order
|
|
@@ -101,6 +107,51 @@ Example order with default configuration:
|
|
|
101
107
|
8. Private class methods
|
|
102
108
|
9. Private static methods
|
|
103
109
|
|
|
110
|
+
### Skipping Sorting with `# nosort`
|
|
111
|
+
|
|
112
|
+
You can prevent sorting at different levels using `# nosort` comments (case-insensitive):
|
|
113
|
+
|
|
114
|
+
**File-level**: Skip entire file
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
# nosort: file
|
|
118
|
+
class Example:
|
|
119
|
+
def _protected(self):
|
|
120
|
+
pass
|
|
121
|
+
def public(self):
|
|
122
|
+
pass # File won't be sorted
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Class-level**: Skip specific class
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
class Example: # nosort
|
|
129
|
+
def _protected(self):
|
|
130
|
+
pass
|
|
131
|
+
def public(self):
|
|
132
|
+
pass # This class won't be sorted
|
|
133
|
+
|
|
134
|
+
class Other:
|
|
135
|
+
def _protected(self):
|
|
136
|
+
pass
|
|
137
|
+
def public(self):
|
|
138
|
+
pass # This class WILL be sorted
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**Method-level**: Keep method in its current position
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
class Example:
|
|
145
|
+
def public_a(self):
|
|
146
|
+
pass
|
|
147
|
+
|
|
148
|
+
def _protected(self): # nosort
|
|
149
|
+
pass # Stays here, between public methods
|
|
150
|
+
|
|
151
|
+
def public_b(self):
|
|
152
|
+
pass # Will move up, but _protected stays in place
|
|
153
|
+
```
|
|
154
|
+
|
|
104
155
|
## Usage
|
|
105
156
|
|
|
106
157
|
### Command Line
|
|
@@ -148,9 +199,10 @@ repos:
|
|
|
148
199
|
hooks:
|
|
149
200
|
- id: undersort
|
|
150
201
|
name: undersort
|
|
151
|
-
entry:
|
|
152
|
-
language:
|
|
202
|
+
entry: undersort
|
|
203
|
+
language: python
|
|
153
204
|
types: [python]
|
|
205
|
+
additional_dependencies: ["undersort"]
|
|
154
206
|
```
|
|
155
207
|
|
|
156
208
|
Then install the hook:
|
|
@@ -16,10 +16,15 @@ A Python tool that automatically sorts class methods by visibility (public, prot
|
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
18
|
# Using uv (recommended)
|
|
19
|
-
uv
|
|
19
|
+
uv add undersort
|
|
20
20
|
|
|
21
21
|
# Using pip
|
|
22
|
-
pip install
|
|
22
|
+
pip install undersort
|
|
23
|
+
|
|
24
|
+
# For development
|
|
25
|
+
git clone https://github.com/kivicode/undersort
|
|
26
|
+
cd undersort
|
|
27
|
+
uv sync
|
|
23
28
|
```
|
|
24
29
|
|
|
25
30
|
## Configuration
|
|
@@ -58,6 +63,7 @@ Methods are sorted in two levels:
|
|
|
58
63
|
2. **Secondary**: Within each visibility level, by method type (instance → class → static by default)
|
|
59
64
|
|
|
60
65
|
The sorting algorithm **minimizes movement** to preserve the original order as much as possible:
|
|
66
|
+
|
|
61
67
|
- Methods that need to move DOWN (to a later section) are placed at the **beginning** of their target section
|
|
62
68
|
- Methods that need to move UP (to an earlier section) are placed at the **end** of their target section
|
|
63
69
|
- Methods already in the correct section maintain their relative order
|
|
@@ -74,6 +80,51 @@ Example order with default configuration:
|
|
|
74
80
|
8. Private class methods
|
|
75
81
|
9. Private static methods
|
|
76
82
|
|
|
83
|
+
### Skipping Sorting with `# nosort`
|
|
84
|
+
|
|
85
|
+
You can prevent sorting at different levels using `# nosort` comments (case-insensitive):
|
|
86
|
+
|
|
87
|
+
**File-level**: Skip entire file
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
# nosort: file
|
|
91
|
+
class Example:
|
|
92
|
+
def _protected(self):
|
|
93
|
+
pass
|
|
94
|
+
def public(self):
|
|
95
|
+
pass # File won't be sorted
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Class-level**: Skip specific class
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
class Example: # nosort
|
|
102
|
+
def _protected(self):
|
|
103
|
+
pass
|
|
104
|
+
def public(self):
|
|
105
|
+
pass # This class won't be sorted
|
|
106
|
+
|
|
107
|
+
class Other:
|
|
108
|
+
def _protected(self):
|
|
109
|
+
pass
|
|
110
|
+
def public(self):
|
|
111
|
+
pass # This class WILL be sorted
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Method-level**: Keep method in its current position
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
class Example:
|
|
118
|
+
def public_a(self):
|
|
119
|
+
pass
|
|
120
|
+
|
|
121
|
+
def _protected(self): # nosort
|
|
122
|
+
pass # Stays here, between public methods
|
|
123
|
+
|
|
124
|
+
def public_b(self):
|
|
125
|
+
pass # Will move up, but _protected stays in place
|
|
126
|
+
```
|
|
127
|
+
|
|
77
128
|
## Usage
|
|
78
129
|
|
|
79
130
|
### Command Line
|
|
@@ -121,9 +172,10 @@ repos:
|
|
|
121
172
|
hooks:
|
|
122
173
|
- id: undersort
|
|
123
174
|
name: undersort
|
|
124
|
-
entry:
|
|
125
|
-
language:
|
|
175
|
+
entry: undersort
|
|
176
|
+
language: python
|
|
126
177
|
types: [python]
|
|
178
|
+
additional_dependencies: ["undersort"]
|
|
127
179
|
```
|
|
128
180
|
|
|
129
181
|
Then install the hook:
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "undersort"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.4"
|
|
8
8
|
description = "A tool to sort class methods by visibility (public, protected, private)"
|
|
9
9
|
authors = [{ name = "KiviCode", email = "kivicode.dev@gmail.com" }]
|
|
10
10
|
readme = "README.md"
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
"""Tests for nosort comment directives."""
|
|
2
|
+
|
|
3
|
+
import tempfile
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
from undersort.sorter import sort_file
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TestNosortDirectives:
|
|
10
|
+
"""Tests for # nosort comment functionality."""
|
|
11
|
+
|
|
12
|
+
def test_file_level_nosort(self) -> None:
|
|
13
|
+
"""Test that file-level nosort prevents all sorting."""
|
|
14
|
+
source = """# nosort: file
|
|
15
|
+
class Example:
|
|
16
|
+
def _protected(self):
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
def public(self):
|
|
20
|
+
pass
|
|
21
|
+
"""
|
|
22
|
+
with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as f:
|
|
23
|
+
f.write(source)
|
|
24
|
+
temp_path = Path(f.name)
|
|
25
|
+
|
|
26
|
+
try:
|
|
27
|
+
order = ["public", "protected", "private"]
|
|
28
|
+
was_modified = sort_file(temp_path, order)
|
|
29
|
+
|
|
30
|
+
assert was_modified is False
|
|
31
|
+
|
|
32
|
+
with open(temp_path) as f:
|
|
33
|
+
result = f.read()
|
|
34
|
+
|
|
35
|
+
assert result == source
|
|
36
|
+
finally:
|
|
37
|
+
temp_path.unlink()
|
|
38
|
+
|
|
39
|
+
def test_class_level_nosort(self) -> None:
|
|
40
|
+
"""Test that class-level nosort prevents sorting that class."""
|
|
41
|
+
source = """class Example: # nosort
|
|
42
|
+
def _protected(self):
|
|
43
|
+
pass
|
|
44
|
+
|
|
45
|
+
def public(self):
|
|
46
|
+
pass
|
|
47
|
+
"""
|
|
48
|
+
with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as f:
|
|
49
|
+
f.write(source)
|
|
50
|
+
temp_path = Path(f.name)
|
|
51
|
+
|
|
52
|
+
try:
|
|
53
|
+
order = ["public", "protected", "private"]
|
|
54
|
+
was_modified = sort_file(temp_path, order)
|
|
55
|
+
|
|
56
|
+
assert was_modified is False
|
|
57
|
+
|
|
58
|
+
with open(temp_path) as f:
|
|
59
|
+
result = f.read()
|
|
60
|
+
|
|
61
|
+
assert result == source
|
|
62
|
+
finally:
|
|
63
|
+
temp_path.unlink()
|
|
64
|
+
|
|
65
|
+
def test_method_level_nosort(self) -> None:
|
|
66
|
+
"""Test that method-level nosort keeps that method in place."""
|
|
67
|
+
source = """class Example:
|
|
68
|
+
def public_a(self):
|
|
69
|
+
pass
|
|
70
|
+
|
|
71
|
+
def _protected_x(self): # nosort
|
|
72
|
+
pass
|
|
73
|
+
|
|
74
|
+
def public_b(self):
|
|
75
|
+
pass
|
|
76
|
+
"""
|
|
77
|
+
with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as f:
|
|
78
|
+
f.write(source)
|
|
79
|
+
temp_path = Path(f.name)
|
|
80
|
+
|
|
81
|
+
try:
|
|
82
|
+
order = ["public", "protected", "private"]
|
|
83
|
+
was_modified = sort_file(temp_path, order)
|
|
84
|
+
|
|
85
|
+
assert was_modified is False
|
|
86
|
+
|
|
87
|
+
with open(temp_path) as f:
|
|
88
|
+
result = f.read()
|
|
89
|
+
|
|
90
|
+
protected_idx = result.find("def _protected_x")
|
|
91
|
+
public_a_idx = result.find("def public_a")
|
|
92
|
+
public_b_idx = result.find("def public_b")
|
|
93
|
+
|
|
94
|
+
assert public_a_idx < protected_idx < public_b_idx
|
|
95
|
+
finally:
|
|
96
|
+
temp_path.unlink()
|
|
97
|
+
|
|
98
|
+
def test_multiple_nosort_methods(self) -> None:
|
|
99
|
+
"""Test multiple methods with nosort."""
|
|
100
|
+
source = """class Example:
|
|
101
|
+
def public_a(self):
|
|
102
|
+
pass
|
|
103
|
+
|
|
104
|
+
def _protected_x(self): # nosort
|
|
105
|
+
pass
|
|
106
|
+
|
|
107
|
+
def public_b(self): # nosort
|
|
108
|
+
pass
|
|
109
|
+
|
|
110
|
+
def _protected_y(self):
|
|
111
|
+
pass
|
|
112
|
+
"""
|
|
113
|
+
with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as f:
|
|
114
|
+
f.write(source)
|
|
115
|
+
temp_path = Path(f.name)
|
|
116
|
+
|
|
117
|
+
try:
|
|
118
|
+
order = ["public", "protected", "private"]
|
|
119
|
+
was_modified = sort_file(temp_path, order)
|
|
120
|
+
|
|
121
|
+
assert was_modified is False
|
|
122
|
+
|
|
123
|
+
with open(temp_path) as f:
|
|
124
|
+
result = f.read()
|
|
125
|
+
|
|
126
|
+
assert result == source
|
|
127
|
+
finally:
|
|
128
|
+
temp_path.unlink()
|
|
129
|
+
|
|
130
|
+
def test_nosort_case_insensitive(self) -> None:
|
|
131
|
+
"""Test that NOSORT and NoSort also work."""
|
|
132
|
+
source = """class Example: # NOSORT
|
|
133
|
+
def _protected(self):
|
|
134
|
+
pass
|
|
135
|
+
|
|
136
|
+
def public(self):
|
|
137
|
+
pass
|
|
138
|
+
"""
|
|
139
|
+
with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as f:
|
|
140
|
+
f.write(source)
|
|
141
|
+
temp_path = Path(f.name)
|
|
142
|
+
|
|
143
|
+
try:
|
|
144
|
+
order = ["public", "protected", "private"]
|
|
145
|
+
was_modified = sort_file(temp_path, order)
|
|
146
|
+
|
|
147
|
+
assert was_modified is False
|
|
148
|
+
finally:
|
|
149
|
+
temp_path.unlink()
|
|
150
|
+
|
|
151
|
+
def test_nosort_with_other_classes(self) -> None:
|
|
152
|
+
"""Test that nosort on one class doesn't affect others."""
|
|
153
|
+
source = """class First: # nosort
|
|
154
|
+
def _protected(self):
|
|
155
|
+
pass
|
|
156
|
+
|
|
157
|
+
def public(self):
|
|
158
|
+
pass
|
|
159
|
+
|
|
160
|
+
class Second:
|
|
161
|
+
def _protected(self):
|
|
162
|
+
pass
|
|
163
|
+
|
|
164
|
+
def public(self):
|
|
165
|
+
pass
|
|
166
|
+
"""
|
|
167
|
+
with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as f:
|
|
168
|
+
f.write(source)
|
|
169
|
+
temp_path = Path(f.name)
|
|
170
|
+
|
|
171
|
+
try:
|
|
172
|
+
order = ["public", "protected", "private"]
|
|
173
|
+
was_modified = sort_file(temp_path, order)
|
|
174
|
+
|
|
175
|
+
assert was_modified is True
|
|
176
|
+
|
|
177
|
+
with open(temp_path) as f:
|
|
178
|
+
result = f.read()
|
|
179
|
+
|
|
180
|
+
first_protected_idx = result.find("class First")
|
|
181
|
+
first_protected_method_idx = result.find("def _protected", first_protected_idx)
|
|
182
|
+
first_public_idx = result.find("def public", first_protected_idx)
|
|
183
|
+
second_class_idx = result.find("class Second")
|
|
184
|
+
second_public_idx = result.find("def public", second_class_idx)
|
|
185
|
+
second_protected_idx = result.find("def _protected", second_class_idx)
|
|
186
|
+
|
|
187
|
+
assert first_protected_method_idx < first_public_idx
|
|
188
|
+
assert second_public_idx < second_protected_idx
|
|
189
|
+
finally:
|
|
190
|
+
temp_path.unlink()
|
|
@@ -9,6 +9,46 @@ import libcst as cst
|
|
|
9
9
|
from undersort import logger
|
|
10
10
|
|
|
11
11
|
|
|
12
|
+
def has_nosort_comment(node: cst.FunctionDef | cst.ClassDef) -> bool:
|
|
13
|
+
"""Check if a node has a nosort comment.
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
node: The node to check
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
True if the node has a # nosort comment
|
|
20
|
+
"""
|
|
21
|
+
if hasattr(node, "leading_lines"):
|
|
22
|
+
for line in node.leading_lines:
|
|
23
|
+
if isinstance(line, cst.EmptyLine) and line.comment and "nosort" in line.comment.value.lower():
|
|
24
|
+
return True
|
|
25
|
+
|
|
26
|
+
return bool(
|
|
27
|
+
hasattr(node, "body")
|
|
28
|
+
and hasattr(node.body, "header")
|
|
29
|
+
and isinstance(node.body.header, cst.TrailingWhitespace)
|
|
30
|
+
and node.body.header.comment
|
|
31
|
+
and "nosort" in node.body.header.comment.value.lower()
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def file_has_nosort(module: cst.Module) -> bool:
|
|
36
|
+
"""Check if a file has a file-level nosort directive.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
module: The module to check
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
True if the file has a # nosort: file comment
|
|
43
|
+
"""
|
|
44
|
+
for line in module.header:
|
|
45
|
+
if isinstance(line, cst.EmptyLine) and line.comment:
|
|
46
|
+
comment_text = line.comment.value.lower()
|
|
47
|
+
if "nosort" in comment_text and "file" in comment_text:
|
|
48
|
+
return True
|
|
49
|
+
return False
|
|
50
|
+
|
|
51
|
+
|
|
12
52
|
def get_method_visibility(method_name: str) -> Literal["public", "private", "protected"]:
|
|
13
53
|
"""Determine method visibility based on naming convention.
|
|
14
54
|
|
|
@@ -71,7 +111,9 @@ class MethodSorter(cst.CSTTransformer):
|
|
|
71
111
|
self.modified = False
|
|
72
112
|
|
|
73
113
|
def leave_ClassDef( # noqa: PLR0912, PLR0915
|
|
74
|
-
self,
|
|
114
|
+
self,
|
|
115
|
+
original_node: cst.ClassDef,
|
|
116
|
+
updated_node: cst.ClassDef, # noqa: ARG002
|
|
75
117
|
) -> cst.ClassDef:
|
|
76
118
|
"""Sort methods within a class definition.
|
|
77
119
|
|
|
@@ -82,6 +124,9 @@ class MethodSorter(cst.CSTTransformer):
|
|
|
82
124
|
Returns:
|
|
83
125
|
ClassDef with sorted methods
|
|
84
126
|
"""
|
|
127
|
+
if has_nosort_comment(updated_node):
|
|
128
|
+
return updated_node
|
|
129
|
+
|
|
85
130
|
methods = []
|
|
86
131
|
non_methods = []
|
|
87
132
|
|
|
@@ -94,7 +139,17 @@ class MethodSorter(cst.CSTTransformer):
|
|
|
94
139
|
if not methods:
|
|
95
140
|
return updated_node
|
|
96
141
|
|
|
97
|
-
|
|
142
|
+
sortable_methods = []
|
|
143
|
+
nosort_methods = []
|
|
144
|
+
|
|
145
|
+
for i, method in enumerate(methods):
|
|
146
|
+
if has_nosort_comment(method):
|
|
147
|
+
nosort_methods.append((i, method))
|
|
148
|
+
else:
|
|
149
|
+
sortable_methods.append((i, method))
|
|
150
|
+
|
|
151
|
+
if not sortable_methods:
|
|
152
|
+
return updated_node
|
|
98
153
|
|
|
99
154
|
method_groups: dict[str, dict[str, list[tuple[int, cst.FunctionDef]]]] = {
|
|
100
155
|
"public": {"class": [], "static": [], "instance": []},
|
|
@@ -102,7 +157,7 @@ class MethodSorter(cst.CSTTransformer):
|
|
|
102
157
|
"private": {"class": [], "static": [], "instance": []},
|
|
103
158
|
}
|
|
104
159
|
|
|
105
|
-
for idx, method in
|
|
160
|
+
for idx, method in sortable_methods:
|
|
106
161
|
visibility = get_method_visibility(method.name.value)
|
|
107
162
|
method_type = get_method_type(method)
|
|
108
163
|
method_groups[visibility][method_type].append((idx, method))
|
|
@@ -145,9 +200,15 @@ class MethodSorter(cst.CSTTransformer):
|
|
|
145
200
|
|
|
146
201
|
current_position += len(group)
|
|
147
202
|
|
|
148
|
-
|
|
203
|
+
all_sorted = sorted_methods[:]
|
|
204
|
+
for orig_idx, nosort_method in sorted(nosort_methods, key=lambda x: x[0]):
|
|
205
|
+
all_sorted.insert(orig_idx, nosort_method)
|
|
206
|
+
|
|
207
|
+
if methods != all_sorted:
|
|
149
208
|
self.modified = True
|
|
150
209
|
|
|
210
|
+
sorted_methods = all_sorted
|
|
211
|
+
|
|
151
212
|
leading_non_methods = []
|
|
152
213
|
trailing_non_methods = []
|
|
153
214
|
found_method = False
|
|
@@ -193,6 +254,9 @@ def sort_file(
|
|
|
193
254
|
except cst.ParserSyntaxError as e:
|
|
194
255
|
raise ValueError(f"Syntax error in {file_path}: {e}")
|
|
195
256
|
|
|
257
|
+
if file_has_nosort(tree):
|
|
258
|
+
return False
|
|
259
|
+
|
|
196
260
|
sorter = MethodSorter(order, method_type_order)
|
|
197
261
|
new_tree = tree.visit(sorter)
|
|
198
262
|
|
|
@@ -905,7 +905,7 @@ wheels = [
|
|
|
905
905
|
|
|
906
906
|
[[package]]
|
|
907
907
|
name = "undersort"
|
|
908
|
-
version = "0.1.
|
|
908
|
+
version = "0.1.4"
|
|
909
909
|
source = { editable = "." }
|
|
910
910
|
dependencies = [
|
|
911
911
|
{ name = "libcst", version = "1.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" },
|
|
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
|