wexample-filestate-python 6.8.7__tar.gz → 8.0.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.8.7 → wexample_filestate_python-8.0.0}/PKG-INFO +6 -8
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/README.md +3 -4
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/pyproject.toml +3 -4
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/config_option/mixin/with_stdout_wrapping_mixin.py +7 -11
- wexample_filestate_python-8.0.0/src/wexample_filestate_python/config_value/python_config_value.py +210 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/file/python_file.py +1 -1
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/helpers/package.py +19 -26
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/helpers/toml.py +8 -12
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/option/python/add_future_annotations_option.py +11 -9
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/option/python/add_return_types_option.py +40 -64
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/option/python/class_name_matches_file_name_option.py +10 -9
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/option/python/fix_attrs_option.py +1 -1
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/option/python/fix_blank_lines_option.py +2 -3
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/option/python/format_option.py +4 -3
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/option/python/fstringify_option.py +1 -6
- wexample_filestate_python-8.0.0/src/wexample_filestate_python/option/python/modernize_typing_option.py +77 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/option/python/order_class_attributes_option.py +5 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/option/python/order_class_docstring_option.py +2 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/option/python/order_class_methods_option.py +5 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/option/python/order_constants_option.py +5 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/option/python/order_iterable_items_option.py +1 -2
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/option/python/order_main_guard_option.py +2 -6
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/option/python/order_module_docstring_option.py +3 -10
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/option/python/order_module_functions_option.py +6 -9
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/option/python/order_module_metadata_option.py +8 -12
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/option/python/order_type_checking_block_option.py +5 -5
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/option/python/relocate_imports_option.py +10 -21
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/option/python/remove_unused_option.py +7 -11
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/option/python/sort_imports_option.py +10 -4
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/option/python/unquote_annotations_option.py +12 -9
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/option/python_option.py +5 -4
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/options_provider/python_options_provider.py +3 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/utils/cst_cache.py +3 -2
- wexample_filestate_python-8.0.0/src/wexample_filestate_python/utils/python_attrs_utils.py +95 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/utils/python_blank_lines_utils.py +24 -80
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/utils/python_class_attributes_utils.py +13 -11
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/utils/python_class_docstring_utils.py +14 -17
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/utils/python_class_methods_utils.py +64 -85
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/utils/python_constants_utils.py +15 -19
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/utils/python_docstring_utils.py +3 -8
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/utils/python_functions_utils.py +73 -49
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/utils/python_iterable_utils.py +49 -56
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/utils/python_main_guard_utils.py +7 -13
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/utils/python_module_metadata_utils.py +26 -27
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/utils/python_type_checking_utils.py +7 -11
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/utils/relocate_imports/python_import_rewriter.py +25 -35
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/utils/relocate_imports/python_localize_runtime_imports.py +8 -14
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/utils/relocate_imports/python_parser_import_index.py +6 -6
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/utils/relocate_imports/python_runtime_symbol_collector.py +17 -14
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/utils/relocate_imports/python_usage_collector.py +30 -31
- {wexample_filestate_python-6.8.7/tests/tests → wexample_filestate_python-8.0.0/tests/helpers}/__init__.py +0 -0
- wexample_filestate_python-8.0.0/tests/helpers/test_package.py +94 -0
- wexample_filestate_python-8.0.0/tests/helpers/test_toml.py +149 -0
- wexample_filestate_python-8.0.0/tests/wexample_tests/__init__.py +0 -0
- wexample_filestate_python-6.8.7/src/wexample_filestate_python/config_value/python_config_value.py +0 -195
- wexample_filestate_python-6.8.7/src/wexample_filestate_python/option/python/modernize_typing_option.py +0 -25
- wexample_filestate_python-6.8.7/src/wexample_filestate_python/utils/python_attrs_utils.py +0 -112
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/__init__.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/__pycache__/__init__.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/common/__init__.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/common/__pycache__/__init__.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/common/pipy_gateway.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/config_option/__init__.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/config_option/__pycache__/__init__.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/config_option/mixin/__init__.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/config_option/mixin/__pycache__/__init__.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/config_value/__init__.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/config_value/__pycache__/__init__.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/const/__init__.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/const/__pycache__/__init__.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/const/name_pattern.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/const/path.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/const/python_file.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/event/__init__.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/event/src/__init__.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/event/src/wexample_event/__init__.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/file/__init__.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/file/__pycache__/__init__.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/helpers/__init__.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/helpers/__pycache__/__init__.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/helpers/python/__init__.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/option/__init__.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/option/__pycache__/__init__.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/option/python/__init__.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/option/python/abstract_python_file_content_option.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/options_provider/__init__.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/options_provider/__pycache__/__init__.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/py.typed +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/utils/__init__.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/utils/__pycache__/__init__.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/utils/relocate_imports/__init__.py +0 -0
- {wexample_filestate_python-6.8.7 → wexample_filestate_python-8.0.0}/src/wexample_filestate_python/utils/relocate_imports/__pycache__/__init__.py +0 -0
- {wexample_filestate_python-6.8.7/tests/wexample_tests → wexample_filestate_python-8.0.0/tests/tests}/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: wexample-filestate-python
|
|
3
|
-
Version:
|
|
3
|
+
Version: 8.0.0
|
|
4
4
|
Summary: Helpers for Python.
|
|
5
5
|
Author-Email: weeger <contact@wexample.com>
|
|
6
6
|
License: MIT
|
|
@@ -17,10 +17,9 @@ Requires-Dist: flynt
|
|
|
17
17
|
Requires-Dist: isort
|
|
18
18
|
Requires-Dist: libcst
|
|
19
19
|
Requires-Dist: packaging
|
|
20
|
-
Requires-Dist: pyupgrade
|
|
21
20
|
Requires-Dist: tomli
|
|
22
|
-
Requires-Dist: wexample-api>=6.
|
|
23
|
-
Requires-Dist: wexample-filestate>=
|
|
21
|
+
Requires-Dist: wexample-api>=6.5.0
|
|
22
|
+
Requires-Dist: wexample-filestate>=13.0.0
|
|
24
23
|
Provides-Extra: dev
|
|
25
24
|
Requires-Dist: pytest; extra == "dev"
|
|
26
25
|
Requires-Dist: pytest-cov; extra == "dev"
|
|
@@ -28,7 +27,7 @@ Description-Content-Type: text/markdown
|
|
|
28
27
|
|
|
29
28
|
# filestate_python
|
|
30
29
|
|
|
31
|
-
Version:
|
|
30
|
+
Version: 8.0.0
|
|
32
31
|
|
|
33
32
|
Helpers for Python.
|
|
34
33
|
|
|
@@ -116,10 +115,9 @@ Visit the [Wexample Suite documentation](https://docs.wexample.com) for the comp
|
|
|
116
115
|
- isort:
|
|
117
116
|
- libcst:
|
|
118
117
|
- packaging:
|
|
119
|
-
- pyupgrade:
|
|
120
118
|
- tomli:
|
|
121
|
-
- wexample-api: >=6.
|
|
122
|
-
- wexample-filestate: >=
|
|
119
|
+
- wexample-api: >=6.5.0
|
|
120
|
+
- wexample-filestate: >=13.0.0
|
|
123
121
|
|
|
124
122
|
## Versioning & Compatibility Policy
|
|
125
123
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# filestate_python
|
|
2
2
|
|
|
3
|
-
Version:
|
|
3
|
+
Version: 8.0.0
|
|
4
4
|
|
|
5
5
|
Helpers for Python.
|
|
6
6
|
|
|
@@ -88,10 +88,9 @@ Visit the [Wexample Suite documentation](https://docs.wexample.com) for the comp
|
|
|
88
88
|
- isort:
|
|
89
89
|
- libcst:
|
|
90
90
|
- packaging:
|
|
91
|
-
- pyupgrade:
|
|
92
91
|
- tomli:
|
|
93
|
-
- wexample-api: >=6.
|
|
94
|
-
- wexample-filestate: >=
|
|
92
|
+
- wexample-api: >=6.5.0
|
|
93
|
+
- wexample-filestate: >=13.0.0
|
|
95
94
|
|
|
96
95
|
## Versioning & Compatibility Policy
|
|
97
96
|
|
|
@@ -6,7 +6,7 @@ build-backend = "pdm.backend"
|
|
|
6
6
|
|
|
7
7
|
[project]
|
|
8
8
|
name = "wexample-filestate-python"
|
|
9
|
-
version = "
|
|
9
|
+
version = "8.0.0"
|
|
10
10
|
description = "Helpers for Python."
|
|
11
11
|
authors = [
|
|
12
12
|
{ name = "weeger", email = "contact@wexample.com" },
|
|
@@ -26,10 +26,9 @@ dependencies = [
|
|
|
26
26
|
"isort",
|
|
27
27
|
"libcst",
|
|
28
28
|
"packaging",
|
|
29
|
-
"pyupgrade",
|
|
30
29
|
"tomli",
|
|
31
|
-
"wexample-api>=6.
|
|
32
|
-
"wexample-filestate>=
|
|
30
|
+
"wexample-api>=6.5.0",
|
|
31
|
+
"wexample-filestate>=13.0.0",
|
|
33
32
|
]
|
|
34
33
|
|
|
35
34
|
[project.readme]
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import io
|
|
4
|
+
import sys
|
|
5
|
+
|
|
3
6
|
|
|
4
7
|
class WithStdoutWrappingMixin:
|
|
5
8
|
@classmethod
|
|
@@ -15,9 +18,6 @@ class WithStdoutWrappingMixin:
|
|
|
15
18
|
Returns:
|
|
16
19
|
The return value of the callback function
|
|
17
20
|
"""
|
|
18
|
-
import io
|
|
19
|
-
import sys
|
|
20
|
-
|
|
21
21
|
old_stdout = sys.stdout
|
|
22
22
|
old_stderr = sys.stderr
|
|
23
23
|
captured_stdout = io.StringIO()
|
|
@@ -34,13 +34,9 @@ class WithStdoutWrappingMixin:
|
|
|
34
34
|
stdout_content = captured_stdout.getvalue()
|
|
35
35
|
stderr_content = captured_stderr.getvalue()
|
|
36
36
|
|
|
37
|
-
if stdout_content.strip():
|
|
38
|
-
sys.stdout.write(stdout_content.rstrip())
|
|
39
|
-
|
|
40
|
-
sys.
|
|
41
|
-
if stderr_content.strip():
|
|
42
|
-
sys.stderr.write(stderr_content.rstrip())
|
|
43
|
-
sys.stderr.write("\n")
|
|
44
|
-
sys.stderr.write("\n")
|
|
37
|
+
if stdout_content and stdout_content.strip():
|
|
38
|
+
sys.stdout.write(stdout_content.rstrip() + "\n\n")
|
|
39
|
+
if stderr_content and stderr_content.strip():
|
|
40
|
+
sys.stderr.write(stderr_content.rstrip() + "\n\n")
|
|
45
41
|
|
|
46
42
|
return result
|
wexample_filestate_python-8.0.0/src/wexample_filestate_python/config_value/python_config_value.py
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from wexample_config.config_value.config_value import ConfigValue
|
|
6
|
+
from wexample_helpers.classes.field import public_field
|
|
7
|
+
from wexample_helpers.decorator.base_class import base_class
|
|
8
|
+
|
|
9
|
+
# Cached mapping: option-name → self attribute name.
|
|
10
|
+
# Built once on first call to to_option_raw_value() so the 22 deferred
|
|
11
|
+
# imports and get_name() class-method calls are paid only once per process.
|
|
12
|
+
_OPTION_NAME_TO_ATTR: dict[str, str] | None = None
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _build_option_name_to_attr() -> dict[str, str]:
|
|
16
|
+
from wexample_filestate_python.config_option.add_future_annotations_config_option import (
|
|
17
|
+
AddFutureAnnotationsConfigOption,
|
|
18
|
+
)
|
|
19
|
+
from wexample_filestate_python.config_option.add_return_types_config_option import (
|
|
20
|
+
AddReturnTypesConfigOption,
|
|
21
|
+
)
|
|
22
|
+
from wexample_filestate_python.config_option.fix_attrs_config_option import (
|
|
23
|
+
FixAttrsConfigOption,
|
|
24
|
+
)
|
|
25
|
+
from wexample_filestate_python.config_option.fix_blank_lines_config_option import (
|
|
26
|
+
FixBlankLinesConfigOption,
|
|
27
|
+
)
|
|
28
|
+
from wexample_filestate_python.config_option.format_config_option import (
|
|
29
|
+
FormatConfigOption,
|
|
30
|
+
)
|
|
31
|
+
from wexample_filestate_python.config_option.fstringify_config_option import (
|
|
32
|
+
FstringifyConfigOption,
|
|
33
|
+
)
|
|
34
|
+
from wexample_filestate_python.config_option.modernize_typing_config_option import (
|
|
35
|
+
ModernizeTypingConfigOption,
|
|
36
|
+
)
|
|
37
|
+
from wexample_filestate_python.config_option.order_class_attributes_config_option import (
|
|
38
|
+
OrderClassAttributesConfigOption,
|
|
39
|
+
)
|
|
40
|
+
from wexample_filestate_python.config_option.order_class_docstring_config_option import (
|
|
41
|
+
OrderClassDocstringConfigOption,
|
|
42
|
+
)
|
|
43
|
+
from wexample_filestate_python.config_option.order_class_methods_config_option import (
|
|
44
|
+
OrderClassMethodsConfigOption,
|
|
45
|
+
)
|
|
46
|
+
from wexample_filestate_python.config_option.order_constants_config_option import (
|
|
47
|
+
OrderConstantsConfigOption,
|
|
48
|
+
)
|
|
49
|
+
from wexample_filestate_python.config_option.order_iterable_items_config_option import (
|
|
50
|
+
OrderIterableItemsConfigOption,
|
|
51
|
+
)
|
|
52
|
+
from wexample_filestate_python.config_option.order_main_guard_config_option import (
|
|
53
|
+
OrderMainGuardConfigOption,
|
|
54
|
+
)
|
|
55
|
+
from wexample_filestate_python.config_option.order_module_docstring_config_option import (
|
|
56
|
+
OrderModuleDocstringConfigOption,
|
|
57
|
+
)
|
|
58
|
+
from wexample_filestate_python.config_option.order_module_functions_config_option import (
|
|
59
|
+
OrderModuleFunctionsConfigOption,
|
|
60
|
+
)
|
|
61
|
+
from wexample_filestate_python.config_option.order_module_metadata_config_option import (
|
|
62
|
+
OrderModuleMetadataConfigOption,
|
|
63
|
+
)
|
|
64
|
+
from wexample_filestate_python.config_option.order_spacing_config_option import (
|
|
65
|
+
OrderSpacingConfigOption,
|
|
66
|
+
)
|
|
67
|
+
from wexample_filestate_python.config_option.order_type_checking_block_config_option import (
|
|
68
|
+
OrderTypeCheckingBlockConfigOption,
|
|
69
|
+
)
|
|
70
|
+
from wexample_filestate_python.config_option.relocate_imports_config_option import (
|
|
71
|
+
RelocateImportsConfigOption,
|
|
72
|
+
)
|
|
73
|
+
from wexample_filestate_python.config_option.remove_unused_config_option import (
|
|
74
|
+
RemoveUnusedConfigOption,
|
|
75
|
+
)
|
|
76
|
+
from wexample_filestate_python.config_option.sort_imports_config_option import (
|
|
77
|
+
SortImportsConfigOption,
|
|
78
|
+
)
|
|
79
|
+
from wexample_filestate_python.config_option.unquote_annotations_config_option import (
|
|
80
|
+
UnquoteAnnotationsConfigOption,
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
AddFutureAnnotationsConfigOption.get_name(): "add_future_annotations",
|
|
85
|
+
AddReturnTypesConfigOption.get_name(): "add_return_types",
|
|
86
|
+
FixAttrsConfigOption.get_name(): "fix_attrs",
|
|
87
|
+
FixBlankLinesConfigOption.get_name(): "fix_blank_lines",
|
|
88
|
+
FormatConfigOption.get_name(): "format",
|
|
89
|
+
FstringifyConfigOption.get_name(): "fstringify",
|
|
90
|
+
ModernizeTypingConfigOption.get_name(): "modernize_typing",
|
|
91
|
+
OrderClassAttributesConfigOption.get_name(): "order_class_attributes",
|
|
92
|
+
OrderClassDocstringConfigOption.get_name(): "order_class_docstring",
|
|
93
|
+
OrderClassMethodsConfigOption.get_name(): "order_class_methods",
|
|
94
|
+
OrderConstantsConfigOption.get_name(): "order_constants",
|
|
95
|
+
OrderIterableItemsConfigOption.get_name(): "order_iterable_items",
|
|
96
|
+
OrderMainGuardConfigOption.get_name(): "order_main_guard",
|
|
97
|
+
OrderModuleDocstringConfigOption.get_name(): "order_module_docstring",
|
|
98
|
+
OrderModuleFunctionsConfigOption.get_name(): "order_module_functions",
|
|
99
|
+
OrderModuleMetadataConfigOption.get_name(): "order_module_metadata",
|
|
100
|
+
OrderSpacingConfigOption.get_name(): "order_spacing",
|
|
101
|
+
OrderTypeCheckingBlockConfigOption.get_name(): "order_type_checking_block",
|
|
102
|
+
RelocateImportsConfigOption.get_name(): "relocate_imports",
|
|
103
|
+
RemoveUnusedConfigOption.get_name(): "remove_unused",
|
|
104
|
+
SortImportsConfigOption.get_name(): "sort_imports",
|
|
105
|
+
UnquoteAnnotationsConfigOption.get_name(): "unquote_annotations",
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
@base_class
|
|
110
|
+
class PythonConfigValue(ConfigValue):
|
|
111
|
+
add_future_annotations: bool | None = public_field(
|
|
112
|
+
default=None,
|
|
113
|
+
description="Add `from __future__ import annotations`",
|
|
114
|
+
)
|
|
115
|
+
add_return_types: bool | None = public_field(
|
|
116
|
+
default=None,
|
|
117
|
+
description="Add return type annotations",
|
|
118
|
+
)
|
|
119
|
+
fix_attrs: bool | None = public_field(
|
|
120
|
+
default=None,
|
|
121
|
+
description="Fix attrs usage (ensure kw_only=True, etc.)",
|
|
122
|
+
)
|
|
123
|
+
fix_blank_lines: bool | None = public_field(
|
|
124
|
+
default=None,
|
|
125
|
+
description="Fix blank lines in Python files",
|
|
126
|
+
)
|
|
127
|
+
format: bool | None = public_field(
|
|
128
|
+
default=None,
|
|
129
|
+
description="Format Python code",
|
|
130
|
+
)
|
|
131
|
+
fstringify: bool | None = public_field(
|
|
132
|
+
default=None,
|
|
133
|
+
description="Convert string formatting to f-strings",
|
|
134
|
+
)
|
|
135
|
+
modernize_typing: bool | None = public_field(
|
|
136
|
+
default=None,
|
|
137
|
+
description="Modernize typing annotations",
|
|
138
|
+
)
|
|
139
|
+
order_class_attributes: bool | None = public_field(
|
|
140
|
+
default=None,
|
|
141
|
+
description="Sort class attributes: special first, then public A–Z, then private/protected A–Z",
|
|
142
|
+
)
|
|
143
|
+
order_class_docstring: bool | None = public_field(
|
|
144
|
+
default=None,
|
|
145
|
+
description="Ensure class docstring is first statement after header/decorators",
|
|
146
|
+
)
|
|
147
|
+
order_class_methods: bool | None = public_field(
|
|
148
|
+
default=None,
|
|
149
|
+
description="Order class methods (dunders sequence, class/staticmethods, properties, instances)",
|
|
150
|
+
)
|
|
151
|
+
order_constants: bool | None = public_field(
|
|
152
|
+
default=None,
|
|
153
|
+
description="Sort flagged UPPER_CASE constant blocks at module level",
|
|
154
|
+
)
|
|
155
|
+
order_iterable_items: bool | None = public_field(
|
|
156
|
+
default=None,
|
|
157
|
+
description="Sort items inside flagged iterable literals (lists/dicts)",
|
|
158
|
+
)
|
|
159
|
+
order_main_guard: bool | None = public_field(
|
|
160
|
+
default=None,
|
|
161
|
+
description="Ensure if __name__ == '__main__' block is at the very end",
|
|
162
|
+
)
|
|
163
|
+
order_module_docstring: bool | None = public_field(
|
|
164
|
+
default=None,
|
|
165
|
+
description="Order module docstring to be at the top of the file",
|
|
166
|
+
)
|
|
167
|
+
order_module_functions: bool | None = public_field(
|
|
168
|
+
default=None,
|
|
169
|
+
description="Order module-level functions (public A–Z, then private)",
|
|
170
|
+
)
|
|
171
|
+
order_module_metadata: bool | None = public_field(
|
|
172
|
+
default=None,
|
|
173
|
+
description="Group and sort module metadata at module level",
|
|
174
|
+
)
|
|
175
|
+
order_spacing: bool | None = public_field(
|
|
176
|
+
default=None,
|
|
177
|
+
description="Normalize blank lines between program structures (spacing rules)",
|
|
178
|
+
)
|
|
179
|
+
order_type_checking_block: bool | None = public_field(
|
|
180
|
+
default=None,
|
|
181
|
+
description="Move TYPE_CHECKING blocks to after regular imports",
|
|
182
|
+
)
|
|
183
|
+
raw: Any = public_field(
|
|
184
|
+
default=None, description="Disabled raw value for this config."
|
|
185
|
+
)
|
|
186
|
+
relocate_imports: bool | None = public_field(
|
|
187
|
+
default=None,
|
|
188
|
+
description="Relocate imports by usage (runtime-in-method, class property types, type-only)",
|
|
189
|
+
)
|
|
190
|
+
remove_unused: bool | None = public_field(
|
|
191
|
+
default=None,
|
|
192
|
+
description="Remove unused imports",
|
|
193
|
+
)
|
|
194
|
+
sort_imports: bool | None = public_field(
|
|
195
|
+
default=None,
|
|
196
|
+
description="Sort imports",
|
|
197
|
+
)
|
|
198
|
+
unquote_annotations: bool | None = public_field(
|
|
199
|
+
default=None,
|
|
200
|
+
description="Unquote annotations (remove string annotations)",
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
def to_option_raw_value(self) -> Any:
|
|
204
|
+
global _OPTION_NAME_TO_ATTR
|
|
205
|
+
if _OPTION_NAME_TO_ATTR is None:
|
|
206
|
+
_OPTION_NAME_TO_ATTR = _build_option_name_to_attr()
|
|
207
|
+
return {
|
|
208
|
+
name: getattr(self, attr)
|
|
209
|
+
for name, attr in _OPTION_NAME_TO_ATTR.items()
|
|
210
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import ast
|
|
4
|
+
import re
|
|
4
5
|
from typing import TYPE_CHECKING
|
|
5
6
|
|
|
6
7
|
import tomli
|
|
@@ -19,31 +20,21 @@ def package_get_dependencies(root_dir: str | Path) -> dict[str, set[str]]:
|
|
|
19
20
|
if not packages_root.exists() or not packages_root.is_dir():
|
|
20
21
|
raise ValueError(f"Error: {packages_root} does not exist or is not a directory")
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
# First pass: collect all local packages
|
|
25
|
-
for package_dir in packages_root.iterdir():
|
|
26
|
-
if not package_dir.is_dir():
|
|
27
|
-
continue
|
|
28
|
-
|
|
29
|
-
package_info = package_get_info(package_dir)
|
|
30
|
-
if package_info:
|
|
31
|
-
name, _ = package_info
|
|
32
|
-
dependencies[name] = set()
|
|
33
|
-
|
|
34
|
-
# Second pass: analyze dependencies
|
|
35
|
-
for package_dir in packages_root.iterdir():
|
|
36
|
-
if not package_dir.is_dir():
|
|
37
|
-
continue
|
|
23
|
+
# Filter to directories once; avoids repeated is_dir() calls in two passes.
|
|
24
|
+
all_dirs = [e for e in packages_root.iterdir() if e.is_dir()]
|
|
38
25
|
|
|
26
|
+
# Single pass: collect all local package infos (name → raw deps).
|
|
27
|
+
pkg_infos: dict[str, set[str]] = {}
|
|
28
|
+
for package_dir in all_dirs:
|
|
39
29
|
package_info = package_get_info(package_dir)
|
|
40
30
|
if package_info:
|
|
41
31
|
name, deps = package_info
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
32
|
+
pkg_infos[name] = deps
|
|
33
|
+
|
|
34
|
+
local_names: set[str] = set(pkg_infos) # O(1) membership for filtering
|
|
45
35
|
|
|
46
|
-
|
|
36
|
+
# Keep only deps that resolve to a local package (set intersection).
|
|
37
|
+
return {name: deps & local_names for name, deps in pkg_infos.items()}
|
|
47
38
|
|
|
48
39
|
|
|
49
40
|
def package_get_info(package_dir: Path) -> tuple[str, set[str]] | None:
|
|
@@ -71,10 +62,8 @@ def package_get_info(package_dir: Path) -> tuple[str, set[str]] | None:
|
|
|
71
62
|
|
|
72
63
|
|
|
73
64
|
def package_normalize_name(val: str) -> str:
|
|
74
|
-
import re as _re
|
|
75
|
-
|
|
76
65
|
# strip extras, versions, markers
|
|
77
|
-
base =
|
|
66
|
+
base = re.split(r"[\s<>=!~;\[]", val, maxsplit=1)[0]
|
|
78
67
|
return base.strip().lower()
|
|
79
68
|
|
|
80
69
|
|
|
@@ -94,11 +83,15 @@ def package_parse_setup(path: Path) -> dict:
|
|
|
94
83
|
):
|
|
95
84
|
result = {}
|
|
96
85
|
for kw in node.keywords:
|
|
97
|
-
if isinstance(kw.value, ast.
|
|
98
|
-
|
|
86
|
+
if isinstance(kw.value, ast.Constant) and isinstance(
|
|
87
|
+
kw.value.value, str
|
|
88
|
+
):
|
|
89
|
+
result[kw.arg] = kw.value.value
|
|
99
90
|
elif isinstance(kw.value, ast.List):
|
|
100
91
|
result[kw.arg] = [
|
|
101
|
-
elt.
|
|
92
|
+
elt.value
|
|
93
|
+
for elt in kw.value.elts
|
|
94
|
+
if isinstance(elt, ast.Constant) and isinstance(elt.value, str)
|
|
102
95
|
]
|
|
103
96
|
return result
|
|
104
97
|
return {}
|
|
@@ -49,7 +49,7 @@ def toml_ensure_table(doc: Any, path: list[str]) -> tuple[Any, bool]:
|
|
|
49
49
|
current = doc
|
|
50
50
|
for key in path:
|
|
51
51
|
tbl = current.get(key) if isinstance(current, dict) else None
|
|
52
|
-
if
|
|
52
|
+
if tbl is None or not isinstance(tbl, dict):
|
|
53
53
|
tbl = table()
|
|
54
54
|
current[key] = tbl
|
|
55
55
|
changed = True
|
|
@@ -96,21 +96,17 @@ def toml_sort_string_array(arr: Any) -> bool:
|
|
|
96
96
|
if not items or not all(isinstance(i, String) for i in items):
|
|
97
97
|
return False
|
|
98
98
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
for _, x in sorted(zip([v.lower() for v in values], items), key=lambda t: t[0])
|
|
103
|
-
]
|
|
104
|
-
|
|
105
|
-
if items == sorted_items:
|
|
99
|
+
keys = [i.value.lower() for i in items]
|
|
100
|
+
sorted_keys = sorted(keys)
|
|
101
|
+
if keys == sorted_keys:
|
|
106
102
|
return False
|
|
107
103
|
|
|
108
|
-
|
|
104
|
+
sorted_items = sorted(items, key=lambda i: i.value.lower())
|
|
105
|
+
multiline_flag = arr._multiline
|
|
109
106
|
# Clear and re-append to preserve tomlkit item identity
|
|
110
|
-
while
|
|
107
|
+
while arr:
|
|
111
108
|
arr.pop()
|
|
112
109
|
for item in sorted_items:
|
|
113
110
|
arr.append(item)
|
|
114
|
-
|
|
115
|
-
arr.multiline(multiline_flag)
|
|
111
|
+
arr.multiline(multiline_flag)
|
|
116
112
|
return True
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import ast
|
|
4
|
+
import re
|
|
3
5
|
from typing import TYPE_CHECKING
|
|
4
6
|
|
|
5
7
|
from wexample_helpers.decorator.base_class import base_class
|
|
@@ -9,6 +11,10 @@ from .abstract_python_file_content_option import AbstractPythonFileContentOption
|
|
|
9
11
|
if TYPE_CHECKING:
|
|
10
12
|
from wexample_filestate.const.types_state_items import TargetFileOrDirectoryType
|
|
11
13
|
|
|
14
|
+
# PEP 263 encoding cookie matcher. Compiled once at import time, reused
|
|
15
|
+
# across every file the rectifier touches.
|
|
16
|
+
_ENCODING_COOKIE_RE = re.compile(r"^#.*coding[:=]\s*([-_.a-zA-Z0-9]+)")
|
|
17
|
+
|
|
12
18
|
|
|
13
19
|
@base_class
|
|
14
20
|
class AddFutureAnnotationsOption(AbstractPythonFileContentOption):
|
|
@@ -23,9 +29,6 @@ class AddFutureAnnotationsOption(AbstractPythonFileContentOption):
|
|
|
23
29
|
if "from __future__ import annotations" in src:
|
|
24
30
|
return src
|
|
25
31
|
|
|
26
|
-
import ast
|
|
27
|
-
import re
|
|
28
|
-
|
|
29
32
|
lines = src.splitlines(keepends=True)
|
|
30
33
|
|
|
31
34
|
# Detect shebang and encoding cookie positions
|
|
@@ -33,9 +36,8 @@ class AddFutureAnnotationsOption(AbstractPythonFileContentOption):
|
|
|
33
36
|
if lines and lines[0].startswith("#!"):
|
|
34
37
|
idx = 1
|
|
35
38
|
# Encoding cookie can be on first or second line (after shebang)
|
|
36
|
-
enc_re = re.compile(r"^#.*coding[:=]\s*([-_.a-zA-Z0-9]+)")
|
|
37
39
|
for i in range(idx, min(idx + 2, len(lines))):
|
|
38
|
-
if
|
|
40
|
+
if _ENCODING_COOKIE_RE.match(lines[i]):
|
|
39
41
|
idx = i + 1
|
|
40
42
|
|
|
41
43
|
# Parse to find module docstring span
|
|
@@ -45,11 +47,11 @@ class AddFutureAnnotationsOption(AbstractPythonFileContentOption):
|
|
|
45
47
|
# If parsing fails, be conservative: insert after header block
|
|
46
48
|
insert_at = idx
|
|
47
49
|
else:
|
|
48
|
-
body =
|
|
50
|
+
body = tree.body
|
|
49
51
|
if (
|
|
50
52
|
body
|
|
51
53
|
and isinstance(body[0], ast.Expr)
|
|
52
|
-
and isinstance(
|
|
54
|
+
and isinstance(body[0].value, ast.Constant)
|
|
53
55
|
and isinstance(body[0].value.value, str)
|
|
54
56
|
):
|
|
55
57
|
# Module docstring present; insert after its end_lineno
|
|
@@ -59,7 +61,7 @@ class AddFutureAnnotationsOption(AbstractPythonFileContentOption):
|
|
|
59
61
|
insert_at = idx
|
|
60
62
|
|
|
61
63
|
# lines is 0-based; insert_at is 1-based line count from AST
|
|
62
|
-
insert_index =
|
|
64
|
+
insert_index = min(len(lines), insert_at)
|
|
63
65
|
|
|
64
66
|
# Ensure there is a newline after the inserted import if needed
|
|
65
67
|
future_line = "from __future__ import annotations\n"
|
|
@@ -70,7 +72,7 @@ class AddFutureAnnotationsOption(AbstractPythonFileContentOption):
|
|
|
70
72
|
# If there isn't a blank line after the future import and next line is not blank, add one for readability
|
|
71
73
|
j = insert_index + 1
|
|
72
74
|
if j < len(lines):
|
|
73
|
-
if lines[j].strip()
|
|
75
|
+
if lines[j].strip():
|
|
74
76
|
lines.insert(j, "\n")
|
|
75
77
|
|
|
76
78
|
return "".join(lines)
|