wexample-filestate-python 6.4.5__tar.gz → 6.5.0__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.
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/PKG-INFO +4 -4
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/README.md +2 -2
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/pyproject.toml +2 -2
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/option/python/add_return_types_option.py +8 -7
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/option/python/fix_attrs_option.py +4 -4
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/option/python/fix_blank_lines_option.py +4 -4
- wexample_filestate_python-6.5.0/src/wexample_filestate_python/option/python/format_option.py +48 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/option/python/order_class_attributes_option.py +4 -4
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/option/python/order_class_docstring_option.py +4 -4
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/option/python/order_class_methods_option.py +4 -4
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/option/python/order_constants_option.py +4 -4
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/option/python/order_main_guard_option.py +4 -4
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/option/python/order_module_docstring_option.py +4 -2
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/option/python/order_module_functions_option.py +4 -4
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/option/python/order_module_metadata_option.py +4 -4
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/option/python/order_type_checking_block_option.py +4 -4
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/option/python/relocate_imports_option.py +4 -2
- wexample_filestate_python-6.5.0/src/wexample_filestate_python/option/python/remove_unused_option.py +38 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/option/python/unquote_annotations_option.py +5 -2
- wexample_filestate_python-6.5.0/src/wexample_filestate_python/utils/cst_cache.py +37 -0
- wexample_filestate_python-6.4.5/src/wexample_filestate_python/option/python/format_option.py +0 -34
- wexample_filestate_python-6.4.5/src/wexample_filestate_python/option/python/remove_unused_option.py +0 -45
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/__init__.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/__pycache__/__init__.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/common/__init__.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/common/__pycache__/__init__.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/common/pipy_gateway.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/config_option/__init__.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/config_option/__pycache__/__init__.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/config_option/mixin/__init__.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/config_option/mixin/__pycache__/__init__.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/config_option/mixin/with_stdout_wrapping_mixin.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/config_value/__init__.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/config_value/__pycache__/__init__.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/config_value/python_config_value.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/const/__init__.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/const/__pycache__/__init__.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/const/name_pattern.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/const/path.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/const/python_file.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/event/__init__.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/event/src/__init__.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/event/src/wexample_event/__init__.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/file/__init__.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/file/__pycache__/__init__.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/file/python_file.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/helpers/__init__.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/helpers/__pycache__/__init__.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/helpers/package.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/helpers/python/__init__.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/helpers/toml.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/option/__init__.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/option/__pycache__/__init__.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/option/python/__init__.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/option/python/abstract_python_file_content_option.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/option/python/add_future_annotations_option.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/option/python/class_name_matches_file_name_option.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/option/python/fstringify_option.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/option/python/modernize_typing_option.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/option/python/order_iterable_items_option.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/option/python/sort_imports_option.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/option/python_option.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/options_provider/__init__.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/options_provider/__pycache__/__init__.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/options_provider/python_options_provider.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/py.typed +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/utils/__init__.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/utils/__pycache__/__init__.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/utils/python_attrs_utils.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/utils/python_blank_lines_utils.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/utils/python_class_attributes_utils.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/utils/python_class_docstring_utils.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/utils/python_class_methods_utils.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/utils/python_constants_utils.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/utils/python_docstring_utils.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/utils/python_functions_utils.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/utils/python_iterable_utils.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/utils/python_main_guard_utils.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/utils/python_module_metadata_utils.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/utils/python_type_checking_utils.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/utils/relocate_imports/__init__.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/utils/relocate_imports/__pycache__/__init__.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/utils/relocate_imports/python_import_rewriter.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/utils/relocate_imports/python_localize_runtime_imports.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/utils/relocate_imports/python_parser_import_index.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/utils/relocate_imports/python_runtime_symbol_collector.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/src/wexample_filestate_python/utils/relocate_imports/python_usage_collector.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/tests/tests/__init__.py +0 -0
- {wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/tests/wexample_tests/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: wexample-filestate-python
|
|
3
|
-
Version: 6.
|
|
3
|
+
Version: 6.5.0
|
|
4
4
|
Summary: Helpers for Python.
|
|
5
5
|
Author-Email: weeger <contact@wexample.com>
|
|
6
6
|
License: MIT
|
|
@@ -20,7 +20,7 @@ Requires-Dist: packaging
|
|
|
20
20
|
Requires-Dist: pyupgrade
|
|
21
21
|
Requires-Dist: tomli
|
|
22
22
|
Requires-Dist: wexample-api>=6.1.0
|
|
23
|
-
Requires-Dist: wexample-filestate>=
|
|
23
|
+
Requires-Dist: wexample-filestate>=9.0.0
|
|
24
24
|
Provides-Extra: dev
|
|
25
25
|
Requires-Dist: pytest; extra == "dev"
|
|
26
26
|
Requires-Dist: pytest-cov; extra == "dev"
|
|
@@ -28,7 +28,7 @@ Description-Content-Type: text/markdown
|
|
|
28
28
|
|
|
29
29
|
# filestate_python
|
|
30
30
|
|
|
31
|
-
Version: 6.
|
|
31
|
+
Version: 6.5.0
|
|
32
32
|
|
|
33
33
|
Helpers for Python.
|
|
34
34
|
|
|
@@ -119,7 +119,7 @@ Visit the [Wexample Suite documentation](https://docs.wexample.com) for the comp
|
|
|
119
119
|
- pyupgrade:
|
|
120
120
|
- tomli:
|
|
121
121
|
- wexample-api: >=6.1.0
|
|
122
|
-
- wexample-filestate: >=
|
|
122
|
+
- wexample-filestate: >=9.0.0
|
|
123
123
|
|
|
124
124
|
## Versioning & Compatibility Policy
|
|
125
125
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# filestate_python
|
|
2
2
|
|
|
3
|
-
Version: 6.
|
|
3
|
+
Version: 6.5.0
|
|
4
4
|
|
|
5
5
|
Helpers for Python.
|
|
6
6
|
|
|
@@ -91,7 +91,7 @@ Visit the [Wexample Suite documentation](https://docs.wexample.com) for the comp
|
|
|
91
91
|
- pyupgrade:
|
|
92
92
|
- tomli:
|
|
93
93
|
- wexample-api: >=6.1.0
|
|
94
|
-
- wexample-filestate: >=
|
|
94
|
+
- wexample-filestate: >=9.0.0
|
|
95
95
|
|
|
96
96
|
## Versioning & Compatibility Policy
|
|
97
97
|
|
|
@@ -6,7 +6,7 @@ build-backend = "pdm.backend"
|
|
|
6
6
|
|
|
7
7
|
[project]
|
|
8
8
|
name = "wexample-filestate-python"
|
|
9
|
-
version = "6.
|
|
9
|
+
version = "6.5.0"
|
|
10
10
|
description = "Helpers for Python."
|
|
11
11
|
authors = [
|
|
12
12
|
{ name = "weeger", email = "contact@wexample.com" },
|
|
@@ -29,7 +29,7 @@ dependencies = [
|
|
|
29
29
|
"pyupgrade",
|
|
30
30
|
"tomli",
|
|
31
31
|
"wexample-api>=6.1.0",
|
|
32
|
-
"wexample-filestate>=
|
|
32
|
+
"wexample-filestate>=9.0.0",
|
|
33
33
|
]
|
|
34
34
|
|
|
35
35
|
[project.readme]
|
|
@@ -22,7 +22,14 @@ class AddReturnTypesOption(AbstractPythonFileContentOption):
|
|
|
22
22
|
statements in a function agree on one of these literal types."""
|
|
23
23
|
import libcst as cst
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
from wexample_filestate_python.utils.cst_cache import (
|
|
26
|
+
get_python_source_and_module,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
try:
|
|
30
|
+
src, module = get_python_source_and_module(target)
|
|
31
|
+
except Exception:
|
|
32
|
+
return target.get_local_file().read()
|
|
26
33
|
|
|
27
34
|
# We implement type inference and rewriting using LibCST to ensure
|
|
28
35
|
# robust, formatting-preserving edits. We extend inference to:
|
|
@@ -251,12 +258,6 @@ class AddReturnTypesOption(AbstractPythonFileContentOption):
|
|
|
251
258
|
)
|
|
252
259
|
return updated_node
|
|
253
260
|
|
|
254
|
-
try:
|
|
255
|
-
module = cst.parse_module(src)
|
|
256
|
-
except Exception:
|
|
257
|
-
# If parsing fails for any reason, return the original source unchanged
|
|
258
|
-
return src
|
|
259
|
-
|
|
260
261
|
# Collect known simple type names from the module
|
|
261
262
|
ktc = _KnownTypesCollector()
|
|
262
263
|
module.visit(ktc)
|
|
@@ -24,14 +24,14 @@ class FixAttrsOption(AbstractPythonFileContentOption):
|
|
|
24
24
|
- Ensure @attrs.define always uses kw_only=True
|
|
25
25
|
- Ensure @attr.s always uses kw_only=True
|
|
26
26
|
"""
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
from wexample_filestate_python.utils.cst_cache import (
|
|
28
|
+
get_python_source_and_module,
|
|
29
|
+
)
|
|
29
30
|
from wexample_filestate_python.utils.python_attrs_utils import (
|
|
30
31
|
fix_attrs_kw_only,
|
|
31
32
|
)
|
|
32
33
|
|
|
33
|
-
src = target
|
|
34
|
-
module = cst.parse_module(src)
|
|
34
|
+
src, module = get_python_source_and_module(target)
|
|
35
35
|
|
|
36
36
|
modified = fix_attrs_kw_only(module)
|
|
37
37
|
return modified.code
|
|
@@ -34,14 +34,14 @@ class FixBlankLinesOption(AbstractPythonFileContentOption):
|
|
|
34
34
|
|
|
35
35
|
Note: Module-level spacing (between classes/functions/imports) is handled by Black.
|
|
36
36
|
"""
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
from wexample_filestate_python.utils.cst_cache import (
|
|
38
|
+
get_python_source_and_module,
|
|
39
|
+
)
|
|
39
40
|
from wexample_filestate_python.utils.python_blank_lines_utils import (
|
|
40
41
|
fix_function_blank_lines,
|
|
41
42
|
)
|
|
42
43
|
|
|
43
|
-
src = target
|
|
44
|
-
module = cst.parse_module(src)
|
|
44
|
+
src, module = get_python_source_and_module(target)
|
|
45
45
|
|
|
46
46
|
modified = fix_function_blank_lines(module)
|
|
47
47
|
return modified.code
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, ClassVar
|
|
4
|
+
|
|
5
|
+
from wexample_filestate.option.mixin.with_batch_option_mixin import (
|
|
6
|
+
WithBatchOptionMixin,
|
|
7
|
+
)
|
|
8
|
+
from wexample_helpers.decorator.base_class import base_class
|
|
9
|
+
|
|
10
|
+
from .abstract_python_file_content_option import AbstractPythonFileContentOption
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
|
|
15
|
+
from wexample_filestate.const.types_state_items import TargetFileOrDirectoryType
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@base_class
|
|
19
|
+
class FormatOption(WithBatchOptionMixin, AbstractPythonFileContentOption):
|
|
20
|
+
_line_length: ClassVar[int] = 88
|
|
21
|
+
|
|
22
|
+
def get_description(self) -> str:
|
|
23
|
+
return "Format the Python file content using Black."
|
|
24
|
+
|
|
25
|
+
def _apply_content_change(self, target: TargetFileOrDirectoryType) -> str:
|
|
26
|
+
cache = self._get_or_build_batch_cache(target)
|
|
27
|
+
path_key = str(target.get_path())
|
|
28
|
+
if path_key in cache:
|
|
29
|
+
return cache[path_key]
|
|
30
|
+
return target.read_text()
|
|
31
|
+
|
|
32
|
+
def _run_batch_on_paths(
|
|
33
|
+
self,
|
|
34
|
+
reference_target: TargetFileOrDirectoryType,
|
|
35
|
+
paths: list[Path],
|
|
36
|
+
) -> None:
|
|
37
|
+
import black
|
|
38
|
+
|
|
39
|
+
mode = black.Mode(line_length=self._line_length)
|
|
40
|
+
for path in paths:
|
|
41
|
+
src = path.read_text()
|
|
42
|
+
try:
|
|
43
|
+
formatted = black.format_file_contents(src, fast=False, mode=mode)
|
|
44
|
+
if formatted != src:
|
|
45
|
+
path.write_text(formatted)
|
|
46
|
+
except black.NothingChanged:
|
|
47
|
+
pass
|
|
48
|
+
return None
|
|
@@ -21,14 +21,14 @@ class OrderClassAttributesOption(AbstractPythonFileContentOption):
|
|
|
21
21
|
Special include __slots__, __match_args__, and inner class Config. Operates on
|
|
22
22
|
contiguous attribute blocks and preserves comments attached to each attribute.
|
|
23
23
|
"""
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
from wexample_filestate_python.utils.cst_cache import (
|
|
25
|
+
get_python_source_and_module,
|
|
26
|
+
)
|
|
26
27
|
from wexample_filestate_python.utils.python_class_attributes_utils import (
|
|
27
28
|
ensure_order_class_attributes_in_module,
|
|
28
29
|
)
|
|
29
30
|
|
|
30
|
-
src = target
|
|
31
|
-
module = cst.parse_module(src)
|
|
31
|
+
src, module = get_python_source_and_module(target)
|
|
32
32
|
|
|
33
33
|
modified = ensure_order_class_attributes_in_module(module)
|
|
34
34
|
return modified.code
|
|
@@ -23,14 +23,14 @@ class OrderClassDocstringOption(AbstractPythonFileContentOption):
|
|
|
23
23
|
decorators and the class header). Normalizes to double quotes. Avoids
|
|
24
24
|
whitespace-only diffs when already correct.
|
|
25
25
|
"""
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
from wexample_filestate_python.utils.cst_cache import (
|
|
27
|
+
get_python_source_and_module,
|
|
28
|
+
)
|
|
28
29
|
from wexample_filestate_python.utils.python_class_docstring_utils import (
|
|
29
30
|
ensure_all_classes_docstring_first,
|
|
30
31
|
)
|
|
31
32
|
|
|
32
|
-
src = target
|
|
33
|
-
module = cst.parse_module(src)
|
|
33
|
+
src, module = get_python_source_and_module(target)
|
|
34
34
|
|
|
35
35
|
modified = ensure_all_classes_docstring_first(module)
|
|
36
36
|
return modified.code
|
|
@@ -24,14 +24,14 @@ class OrderClassMethodsOption(AbstractPythonFileContentOption):
|
|
|
24
24
|
- Properties grouped by base name (getter/setter/deleter together), groups A–Z
|
|
25
25
|
- Instance methods: public A–Z, then private/protected A–Z
|
|
26
26
|
"""
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
from wexample_filestate_python.utils.cst_cache import (
|
|
28
|
+
get_python_source_and_module,
|
|
29
|
+
)
|
|
29
30
|
from wexample_filestate_python.utils.python_class_methods_utils import (
|
|
30
31
|
ensure_order_class_methods_in_module,
|
|
31
32
|
)
|
|
32
33
|
|
|
33
|
-
src = target
|
|
34
|
-
module = cst.parse_module(src)
|
|
34
|
+
src, module = get_python_source_and_module(target)
|
|
35
35
|
|
|
36
36
|
modified = ensure_order_class_methods_in_module(module)
|
|
37
37
|
return modified.code
|
|
@@ -22,14 +22,14 @@ class OrderConstantsOption(AbstractPythonFileContentOption):
|
|
|
22
22
|
A block is a contiguous sequence of simple UPPER_CASE assignments (no blank line between).
|
|
23
23
|
Non-flagged constants and other contexts are ignored.
|
|
24
24
|
"""
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
from wexample_filestate_python.utils.cst_cache import (
|
|
26
|
+
get_python_source_and_module,
|
|
27
|
+
)
|
|
27
28
|
from wexample_filestate_python.utils.python_constants_utils import (
|
|
28
29
|
reorder_flagged_constants_everywhere,
|
|
29
30
|
)
|
|
30
31
|
|
|
31
|
-
src = target
|
|
32
|
-
module = cst.parse_module(src)
|
|
32
|
+
src, module = get_python_source_and_module(target)
|
|
33
33
|
|
|
34
34
|
modified = reorder_flagged_constants_everywhere(module, src)
|
|
35
35
|
return modified.code
|
|
@@ -21,16 +21,16 @@ class OrderMainGuardOption(AbstractPythonFileContentOption):
|
|
|
21
21
|
Moves any top-level main-guard blocks to be the last non-empty statement in the
|
|
22
22
|
module (before trailing blank lines), preserving content and spacing as much as possible.
|
|
23
23
|
"""
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
from wexample_filestate_python.utils.cst_cache import (
|
|
25
|
+
get_python_source_and_module,
|
|
26
|
+
)
|
|
26
27
|
from wexample_filestate_python.utils.python_main_guard_utils import (
|
|
27
28
|
find_main_guard_blocks,
|
|
28
29
|
is_main_guard_at_end,
|
|
29
30
|
move_main_guard_to_end,
|
|
30
31
|
)
|
|
31
32
|
|
|
32
|
-
src = target
|
|
33
|
-
module = cst.parse_module(src)
|
|
33
|
+
src, module = get_python_source_and_module(target)
|
|
34
34
|
|
|
35
35
|
# No main guard present => nothing to do
|
|
36
36
|
if not find_main_guard_blocks(module):
|
|
@@ -23,14 +23,16 @@ class OrderModuleDocstringOption(AbstractPythonFileContentOption):
|
|
|
23
23
|
"""
|
|
24
24
|
import libcst as cst
|
|
25
25
|
|
|
26
|
+
from wexample_filestate_python.utils.cst_cache import (
|
|
27
|
+
get_python_source_and_module,
|
|
28
|
+
)
|
|
26
29
|
from wexample_filestate_python.utils.python_docstring_utils import (
|
|
27
30
|
find_module_docstring,
|
|
28
31
|
is_module_docstring_at_top,
|
|
29
32
|
move_docstring_to_top,
|
|
30
33
|
)
|
|
31
34
|
|
|
32
|
-
src = target
|
|
33
|
-
module = cst.parse_module(src)
|
|
35
|
+
src, module = get_python_source_and_module(target)
|
|
34
36
|
|
|
35
37
|
# Check if there's a docstring and if it needs to be moved
|
|
36
38
|
docstring_node, position = find_module_docstring(module)
|
|
@@ -21,15 +21,15 @@ class OrderModuleFunctionsOption(AbstractPythonFileContentOption):
|
|
|
21
21
|
- Keeps @overload groups attached to their implementation.
|
|
22
22
|
- Preserves spacing/comments by keeping each group's first function's leading_lines.
|
|
23
23
|
"""
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
from wexample_filestate_python.utils.cst_cache import (
|
|
25
|
+
get_python_source_and_module,
|
|
26
|
+
)
|
|
26
27
|
from wexample_filestate_python.utils.python_functions_utils import (
|
|
27
28
|
module_functions_sorted_before_classes,
|
|
28
29
|
reorder_module_functions,
|
|
29
30
|
)
|
|
30
31
|
|
|
31
|
-
src = target
|
|
32
|
-
module = cst.parse_module(src)
|
|
32
|
+
src, module = get_python_source_and_module(target)
|
|
33
33
|
|
|
34
34
|
# Quick no-op detection: if there are no functions, or functions already sorted
|
|
35
35
|
# and placed before classes, the transformation may be a noop.
|
|
@@ -23,16 +23,16 @@ class OrderModuleMetadataOption(AbstractPythonFileContentOption):
|
|
|
23
23
|
|
|
24
24
|
Placement: after imports and `if TYPE_CHECKING:` blocks, before other module-level code.
|
|
25
25
|
"""
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
from wexample_filestate_python.utils.cst_cache import (
|
|
27
|
+
get_python_source_and_module,
|
|
28
|
+
)
|
|
28
29
|
from wexample_filestate_python.utils.python_module_metadata_utils import (
|
|
29
30
|
find_module_metadata_statements,
|
|
30
31
|
group_and_sort_module_metadata,
|
|
31
32
|
target_index_for_module_metadata,
|
|
32
33
|
)
|
|
33
34
|
|
|
34
|
-
src = target
|
|
35
|
-
module = cst.parse_module(src)
|
|
35
|
+
src, module = get_python_source_and_module(target)
|
|
36
36
|
|
|
37
37
|
found = find_module_metadata_statements(module)
|
|
38
38
|
if not found:
|
|
@@ -22,16 +22,16 @@ class OrderTypeCheckingBlockOption(AbstractPythonFileContentOption):
|
|
|
22
22
|
after the last regular import section (or after `from __future__ import ...`
|
|
23
23
|
if no regular imports exist). Keeps spacing minimal and preserves content.
|
|
24
24
|
"""
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
from wexample_filestate_python.utils.cst_cache import (
|
|
26
|
+
get_python_source_and_module,
|
|
27
|
+
)
|
|
27
28
|
from wexample_filestate_python.utils.python_type_checking_utils import (
|
|
28
29
|
find_type_checking_blocks,
|
|
29
30
|
move_type_checking_blocks_after_imports,
|
|
30
31
|
target_index_for_type_checking,
|
|
31
32
|
)
|
|
32
33
|
|
|
33
|
-
src = target
|
|
34
|
-
module = cst.parse_module(src)
|
|
34
|
+
src, module = get_python_source_and_module(target)
|
|
35
35
|
|
|
36
36
|
blocks = find_type_checking_blocks(module)
|
|
37
37
|
if not blocks:
|
|
@@ -35,6 +35,9 @@ class RelocateImportsOption(AbstractPythonFileContentOption):
|
|
|
35
35
|
|
|
36
36
|
import libcst as cst
|
|
37
37
|
|
|
38
|
+
from wexample_filestate_python.utils.cst_cache import (
|
|
39
|
+
get_python_source_and_module,
|
|
40
|
+
)
|
|
38
41
|
from wexample_filestate_python.utils.relocate_imports.python_import_rewriter import (
|
|
39
42
|
PythonImportRewriter,
|
|
40
43
|
)
|
|
@@ -51,8 +54,7 @@ class RelocateImportsOption(AbstractPythonFileContentOption):
|
|
|
51
54
|
PythonUsageCollector,
|
|
52
55
|
)
|
|
53
56
|
|
|
54
|
-
src = target
|
|
55
|
-
module = cst.parse_module(src)
|
|
57
|
+
src, module = get_python_source_and_module(target)
|
|
56
58
|
|
|
57
59
|
# Index current imports using shared utility
|
|
58
60
|
idx = PythonParserImportIndex()
|
wexample_filestate_python-6.5.0/src/wexample_filestate_python/option/python/remove_unused_option.py
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
from wexample_helpers.decorator.base_class import base_class
|
|
6
|
+
|
|
7
|
+
from .abstract_python_file_content_option import AbstractPythonFileContentOption
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from wexample_filestate.const.types_state_items import TargetFileOrDirectoryType
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@base_class
|
|
14
|
+
class RemoveUnusedOption(AbstractPythonFileContentOption):
|
|
15
|
+
def get_description(self) -> str:
|
|
16
|
+
return "Remove unused imports from the Python file using autoflake."
|
|
17
|
+
|
|
18
|
+
def _apply_content_change(self, target: TargetFileOrDirectoryType) -> str:
|
|
19
|
+
"""Remove unused Python imports using autoflake's in-process API.
|
|
20
|
+
|
|
21
|
+
Previously shelled out to `autoflake --stdout` per file, costing ~80ms
|
|
22
|
+
of subprocess + Python startup overhead each call (≈20s on a 268-file
|
|
23
|
+
project).
|
|
24
|
+
"""
|
|
25
|
+
from autoflake import fix_code
|
|
26
|
+
|
|
27
|
+
src = target.get_local_file().read()
|
|
28
|
+
try:
|
|
29
|
+
return fix_code(
|
|
30
|
+
src,
|
|
31
|
+
remove_all_unused_imports=True,
|
|
32
|
+
remove_unused_variables=True,
|
|
33
|
+
expand_star_imports=True,
|
|
34
|
+
remove_duplicate_keys=True,
|
|
35
|
+
)
|
|
36
|
+
except Exception as e:
|
|
37
|
+
target.io.error(f"Autoflake error: {e}\n\n")
|
|
38
|
+
return src
|
|
@@ -21,7 +21,11 @@ class UnquoteAnnotationsOption(AbstractPythonFileContentOption):
|
|
|
21
21
|
|
|
22
22
|
import libcst as cst
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
from wexample_filestate_python.utils.cst_cache import (
|
|
25
|
+
get_python_source_and_module,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
src, module = get_python_source_and_module(target)
|
|
25
29
|
|
|
26
30
|
class _Unquoter(cst.CSTTransformer):
|
|
27
31
|
@staticmethod
|
|
@@ -80,6 +84,5 @@ class UnquoteAnnotationsOption(AbstractPythonFileContentOption):
|
|
|
80
84
|
return updated_node.with_changes(annotation=expr)
|
|
81
85
|
return updated_node
|
|
82
86
|
|
|
83
|
-
module = cst.parse_module(src)
|
|
84
87
|
new_mod = module.visit(_Unquoter())
|
|
85
88
|
return new_mod.code
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""Per-target libcst parse cache.
|
|
2
|
+
|
|
3
|
+
Within a single rectification scan, a Python file's disk content does not
|
|
4
|
+
change — yet historically each option parsed the libcst module independently,
|
|
5
|
+
multiplying the parse cost by the number of content options (~15). This
|
|
6
|
+
helper caches the `(src, module)` pair on the target item so all options on
|
|
7
|
+
the same file share a single parse.
|
|
8
|
+
|
|
9
|
+
The cache is naturally invalidated between rectification passes (a new
|
|
10
|
+
workdir means new target instances).
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
from typing import TYPE_CHECKING
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
import libcst as cst
|
|
19
|
+
from wexample_filestate.const.types_state_items import TargetFileOrDirectoryType
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
_CACHE_ATTR = "_cst_cache"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def get_python_source_and_module(
|
|
26
|
+
target: TargetFileOrDirectoryType,
|
|
27
|
+
) -> tuple[str, cst.Module]:
|
|
28
|
+
cached = getattr(target, _CACHE_ATTR, None)
|
|
29
|
+
if cached is not None:
|
|
30
|
+
return cached
|
|
31
|
+
|
|
32
|
+
import libcst as cst
|
|
33
|
+
|
|
34
|
+
src = target.get_local_file().read()
|
|
35
|
+
module = cst.parse_module(src)
|
|
36
|
+
setattr(target, _CACHE_ATTR, (src, module))
|
|
37
|
+
return src, module
|
wexample_filestate_python-6.4.5/src/wexample_filestate_python/option/python/format_option.py
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from typing import TYPE_CHECKING, ClassVar
|
|
4
|
-
|
|
5
|
-
from wexample_helpers.decorator.base_class import base_class
|
|
6
|
-
|
|
7
|
-
from .abstract_python_file_content_option import AbstractPythonFileContentOption
|
|
8
|
-
|
|
9
|
-
if TYPE_CHECKING:
|
|
10
|
-
from wexample_filestate.const.types_state_items import TargetFileOrDirectoryType
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
@base_class
|
|
14
|
-
class FormatOption(AbstractPythonFileContentOption):
|
|
15
|
-
# Use ClassVar to avoid Pydantic treating it as a model field/private attr
|
|
16
|
-
_line_length: ClassVar[int] = 88
|
|
17
|
-
|
|
18
|
-
def get_description(self) -> str:
|
|
19
|
-
return "Format the Python file content using Black."
|
|
20
|
-
|
|
21
|
-
def _apply_content_change(self, target: TargetFileOrDirectoryType) -> str:
|
|
22
|
-
"""Format Python files using Black."""
|
|
23
|
-
import black
|
|
24
|
-
|
|
25
|
-
src = target.get_local_file().read()
|
|
26
|
-
mode = black.Mode(line_length=self._line_length)
|
|
27
|
-
|
|
28
|
-
try:
|
|
29
|
-
formatted = black.format_file_contents(src, fast=False, mode=mode)
|
|
30
|
-
return formatted
|
|
31
|
-
except black.NothingChanged:
|
|
32
|
-
return src
|
|
33
|
-
except Exception as e:
|
|
34
|
-
raise e
|
wexample_filestate_python-6.4.5/src/wexample_filestate_python/option/python/remove_unused_option.py
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from typing import TYPE_CHECKING
|
|
4
|
-
|
|
5
|
-
from wexample_helpers.decorator.base_class import base_class
|
|
6
|
-
|
|
7
|
-
from .abstract_python_file_content_option import AbstractPythonFileContentOption
|
|
8
|
-
|
|
9
|
-
if TYPE_CHECKING:
|
|
10
|
-
from wexample_filestate.const.types_state_items import TargetFileOrDirectoryType
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
@base_class
|
|
14
|
-
class RemoveUnusedOption(AbstractPythonFileContentOption):
|
|
15
|
-
def get_description(self) -> str:
|
|
16
|
-
return "Remove unused imports from the Python file using autoflake."
|
|
17
|
-
|
|
18
|
-
def _apply_content_change(self, target: TargetFileOrDirectoryType) -> str:
|
|
19
|
-
"""Remove unused Python imports using autoflake."""
|
|
20
|
-
from wexample_helpers.helpers.shell import shell_run
|
|
21
|
-
from wexample_helpers.helpers.system import system_get_venv_bin_path
|
|
22
|
-
|
|
23
|
-
result = shell_run(
|
|
24
|
-
cmd=[
|
|
25
|
-
f"{system_get_venv_bin_path()}/autoflake",
|
|
26
|
-
"--stdout",
|
|
27
|
-
"--remove-all-unused-imports",
|
|
28
|
-
"--remove-unused-variables",
|
|
29
|
-
"--expand-star-imports",
|
|
30
|
-
"--remove-duplicate-keys",
|
|
31
|
-
str(target.get_path()),
|
|
32
|
-
],
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
if result.returncode != 0:
|
|
36
|
-
# Double line return is important to keep message visible event last line is erased by parent process.
|
|
37
|
-
target.io.error(f"Autoflake error: {result.stderr}\n\n")
|
|
38
|
-
return target.get_local_file().read() # Return original content on error
|
|
39
|
-
|
|
40
|
-
modified_content = result.stdout
|
|
41
|
-
|
|
42
|
-
if not modified_content.strip():
|
|
43
|
-
return target.get_local_file().read() # Return original content if empty
|
|
44
|
-
|
|
45
|
-
return modified_content
|
|
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
|
{wexample_filestate_python-6.4.5 → wexample_filestate_python-6.5.0}/tests/wexample_tests/__init__.py
RENAMED
|
File without changes
|