wexample-wex-addon-dev-python 10.1.1__tar.gz → 11.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_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/PKG-INFO +10 -10
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/README.md +5 -5
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/pyproject.toml +5 -5
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/commands/code/check/mypy.py +4 -3
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/commands/code/check/pylint.py +25 -19
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/commands/code/check/pyright.py +18 -14
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/commands/code/check.py +4 -7
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/commands/code/format/black.py +14 -15
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/commands/code/format/isort.py +14 -15
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/commands/code/format.py +8 -5
- wexample_wex_addon_dev_python-11.0.0/src/wexample_wex_addon_dev_python/commands/code/rename.py +134 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/commands/examples/validate.py +1 -2
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/common/pypi_registry_gateway.py +5 -3
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/config_value/python_package_readme_config_value.py +2 -8
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/file/python_app_iml_file.py +3 -2
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/file/python_pyproject_toml_file.py +7 -7
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/helpers/pdm.py +3 -2
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/middleware/each_python_file_middleware.py +12 -14
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/python_addon_manager.py +12 -1
- wexample_wex_addon_dev_python-11.0.0/src/wexample_wex_addon_dev_python/refactor/__init__.py +7 -0
- wexample_wex_addon_dev_python-11.0.0/src/wexample_wex_addon_dev_python/refactor/python_package_rename_handler.py +215 -0
- wexample_wex_addon_dev_python-11.0.0/src/wexample_wex_addon_dev_python/refactor/symbol_kind.py +19 -0
- {wexample_wex_addon_dev_python-10.1.1/src/wexample_wex_addon_dev_python/services → wexample_wex_addon_dev_python-11.0.0/src/wexample_wex_addon_dev_python/selection}/__init__.py +0 -0
- wexample_wex_addon_dev_python-11.0.0/src/wexample_wex_addon_dev_python/selection/abstract_python_code_selection.py +58 -0
- wexample_wex_addon_dev_python-11.0.0/src/wexample_wex_addon_dev_python/selection/python_code_performance_selection.py +171 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/services/python/commands/service/install.py +7 -10
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/services/python/commands/service/setup.py +5 -3
- {wexample_wex_addon_dev_python-10.1.1/tests/helpers → wexample_wex_addon_dev_python-11.0.0/src/wexample_wex_addon_dev_python/workdir/mixin}/__init__.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/workdir/mixin/with_profiling_python_workdir_mixin.py +15 -16
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/workdir/python_package_workdir.py +47 -58
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/workdir/python_packages_suite_workdir.py +2 -3
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/workdir/python_workdir.py +93 -31
- wexample_wex_addon_dev_python-11.0.0/tests/helpers/__init__.py +0 -0
- wexample_wex_addon_dev_python-11.0.0/tests/unit/__init__.py +0 -0
- wexample_wex_addon_dev_python-11.0.0/tests/unit/helpers/__init__.py +0 -0
- wexample_wex_addon_dev_python-11.0.0/tests/unit/helpers/test_pdm.py +7 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/__init__.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/__pycache__/__init__.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/commands/__init__.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/commands/code/__init__.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/commands/code/check/__init__.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/commands/code/format/__init__.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/commands/examples/__init__.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/commands/examples/utils/__init__.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/commands/examples/utils/some_example_type.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/commands/release/__init__.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/common/__init__.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/config_value/__init__.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/config_value/__pycache__/__init__.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/const/__init__.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/const/__pycache__/__init__.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/const/package.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/const/python.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/const/tags.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/file/__init__.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/file/__pycache__/__init__.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/helpers/__init__.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/middleware/__init__.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/middleware/__pycache__/__init__.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/py.typed +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/resources/.wex.yml +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/resources/docker/Dockerfile.python-profiling +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/resources/package_publish_gitlab.yml +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/resources/readme_templates/tests.md.j2 +0 -0
- {wexample_wex_addon_dev_python-10.1.1/src/wexample_wex_addon_dev_python/services/python → wexample_wex_addon_dev_python-11.0.0/src/wexample_wex_addon_dev_python/services}/__init__.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1/src/wexample_wex_addon_dev_python/services/python/commands → wexample_wex_addon_dev_python-11.0.0/src/wexample_wex_addon_dev_python/services/python}/__init__.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/services/python/app_service.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1/src/wexample_wex_addon_dev_python/services/python/commands/service → wexample_wex_addon_dev_python-11.0.0/src/wexample_wex_addon_dev_python/services/python/commands}/__init__.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1/src/wexample_wex_addon_dev_python/services/python/samples → wexample_wex_addon_dev_python-11.0.0/src/wexample_wex_addon_dev_python/services/python/commands/service}/__init__.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/services/python/docker/.wex.yml +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/services/python/docker/docker-compose.yml +0 -0
- {wexample_wex_addon_dev_python-10.1.1/src/wexample_wex_addon_dev_python/services/python/samples/docker → wexample_wex_addon_dev_python-11.0.0/src/wexample_wex_addon_dev_python/services/python/samples}/__init__.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1/src/wexample_wex_addon_dev_python/services/python/samples/docker/images → wexample_wex_addon_dev_python-11.0.0/src/wexample_wex_addon_dev_python/services/python/samples/docker}/__init__.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/services/python/samples/docker/docker-compose.yml +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/services/python/samples/docker/entrypoint.sh +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/services/python/samples/docker/images/Dockerfile.base +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/services/python/samples/docker/images/Dockerfile.develop +0 -0
- {wexample_wex_addon_dev_python-10.1.1/src/wexample_wex_addon_dev_python/workdir → wexample_wex_addon_dev_python-11.0.0/src/wexample_wex_addon_dev_python/services/python/samples/docker/images}/__init__.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/src/wexample_wex_addon_dev_python/services/python/service.yml +0 -0
- {wexample_wex_addon_dev_python-10.1.1/src/wexample_wex_addon_dev_python/workdir/__pycache__ → wexample_wex_addon_dev_python-11.0.0/src/wexample_wex_addon_dev_python/workdir}/__init__.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1/src/wexample_wex_addon_dev_python/workdir/mixin → wexample_wex_addon_dev_python-11.0.0/src/wexample_wex_addon_dev_python/workdir/__pycache__}/__init__.py +0 -0
- {wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/tests/helpers/test_pdm.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: wexample-wex-addon-dev-python
|
|
3
|
-
Version:
|
|
3
|
+
Version: 11.0.0
|
|
4
4
|
Summary: Python dev addon for wex
|
|
5
5
|
Author-Email: weeger <contact@wexample.com>
|
|
6
6
|
License: MIT
|
|
@@ -15,10 +15,10 @@ Requires-Dist: griffe>=2.0.2
|
|
|
15
15
|
Requires-Dist: networkx
|
|
16
16
|
Requires-Dist: pylint
|
|
17
17
|
Requires-Dist: pyright
|
|
18
|
-
Requires-Dist: wexample-api>=6.
|
|
19
|
-
Requires-Dist: wexample-filestate-python>=
|
|
20
|
-
Requires-Dist: wexample-wex-addon-ai>=
|
|
21
|
-
Requires-Dist: wexample-wex-addon-app>=25.
|
|
18
|
+
Requires-Dist: wexample-api>=6.6.0
|
|
19
|
+
Requires-Dist: wexample-filestate-python>=8.1.0
|
|
20
|
+
Requires-Dist: wexample-wex-addon-ai>=11.1.0
|
|
21
|
+
Requires-Dist: wexample-wex-addon-app>=25.4.0
|
|
22
22
|
Provides-Extra: dev
|
|
23
23
|
Requires-Dist: pytest; extra == "dev"
|
|
24
24
|
Requires-Dist: pytest-cov; extra == "dev"
|
|
@@ -26,7 +26,7 @@ Description-Content-Type: text/markdown
|
|
|
26
26
|
|
|
27
27
|
# wex_addon_dev_python
|
|
28
28
|
|
|
29
|
-
Version:
|
|
29
|
+
Version: 11.0.0
|
|
30
30
|
|
|
31
31
|
Python dev addon for wex
|
|
32
32
|
|
|
@@ -112,10 +112,10 @@ Visit the [Wexample Suite documentation](https://docs.wexample.com) for the comp
|
|
|
112
112
|
- networkx:
|
|
113
113
|
- pylint:
|
|
114
114
|
- pyright:
|
|
115
|
-
- wexample-api: >=6.
|
|
116
|
-
- wexample-filestate-python: >=
|
|
117
|
-
- wexample-wex-addon-ai: >=
|
|
118
|
-
- wexample-wex-addon-app: >=25.
|
|
115
|
+
- wexample-api: >=6.6.0
|
|
116
|
+
- wexample-filestate-python: >=8.1.0
|
|
117
|
+
- wexample-wex-addon-ai: >=11.1.0
|
|
118
|
+
- wexample-wex-addon-app: >=25.4.0
|
|
119
119
|
|
|
120
120
|
## Versioning & Compatibility Policy
|
|
121
121
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# wex_addon_dev_python
|
|
2
2
|
|
|
3
|
-
Version:
|
|
3
|
+
Version: 11.0.0
|
|
4
4
|
|
|
5
5
|
Python dev addon for wex
|
|
6
6
|
|
|
@@ -86,10 +86,10 @@ Visit the [Wexample Suite documentation](https://docs.wexample.com) for the comp
|
|
|
86
86
|
- networkx:
|
|
87
87
|
- pylint:
|
|
88
88
|
- pyright:
|
|
89
|
-
- wexample-api: >=6.
|
|
90
|
-
- wexample-filestate-python: >=
|
|
91
|
-
- wexample-wex-addon-ai: >=
|
|
92
|
-
- wexample-wex-addon-app: >=25.
|
|
89
|
+
- wexample-api: >=6.6.0
|
|
90
|
+
- wexample-filestate-python: >=8.1.0
|
|
91
|
+
- wexample-wex-addon-ai: >=11.1.0
|
|
92
|
+
- wexample-wex-addon-app: >=25.4.0
|
|
93
93
|
|
|
94
94
|
## Versioning & Compatibility Policy
|
|
95
95
|
|
{wexample_wex_addon_dev_python-10.1.1 → wexample_wex_addon_dev_python-11.0.0}/pyproject.toml
RENAMED
|
@@ -6,7 +6,7 @@ build-backend = "pdm.backend"
|
|
|
6
6
|
|
|
7
7
|
[project]
|
|
8
8
|
name = "wexample-wex-addon-dev-python"
|
|
9
|
-
version = "
|
|
9
|
+
version = "11.0.0"
|
|
10
10
|
description = "Python dev addon for wex"
|
|
11
11
|
authors = [
|
|
12
12
|
{ name = "weeger", email = "contact@wexample.com" },
|
|
@@ -24,10 +24,10 @@ dependencies = [
|
|
|
24
24
|
"networkx",
|
|
25
25
|
"pylint",
|
|
26
26
|
"pyright",
|
|
27
|
-
"wexample-api>=6.
|
|
28
|
-
"wexample-filestate-python>=
|
|
29
|
-
"wexample-wex-addon-ai>=
|
|
30
|
-
"wexample-wex-addon-app>=25.
|
|
27
|
+
"wexample-api>=6.6.0",
|
|
28
|
+
"wexample-filestate-python>=8.1.0",
|
|
29
|
+
"wexample-wex-addon-ai>=11.1.0",
|
|
30
|
+
"wexample-wex-addon-app>=25.4.0",
|
|
31
31
|
]
|
|
32
32
|
|
|
33
33
|
[project.readme]
|
|
@@ -35,12 +35,13 @@ def _code_check_mypy(kernel: Kernel, file_path: str) -> bool:
|
|
|
35
35
|
# Build and check the file
|
|
36
36
|
source = BuildSource(path=file_path, module=None, text=None)
|
|
37
37
|
result = build.build(sources=[source], options=options, alt_lib_path=None)
|
|
38
|
-
|
|
38
|
+
errors = result.errors
|
|
39
|
+
if errors:
|
|
39
40
|
kernel.io.log_indent_up()
|
|
40
|
-
kernel.io.error(
|
|
41
|
+
kernel.io.error("Mypy errors:")
|
|
41
42
|
kernel.io.log_indent_up()
|
|
42
43
|
|
|
43
|
-
for error in
|
|
44
|
+
for error in errors:
|
|
44
45
|
kernel.io.error(message=error, symbol=False)
|
|
45
46
|
|
|
46
47
|
kernel.io.log_indent_down(number=2)
|
|
@@ -5,6 +5,16 @@ from typing import TYPE_CHECKING
|
|
|
5
5
|
if TYPE_CHECKING:
|
|
6
6
|
from wexample_cli.context.execution_context import ExecutionContext
|
|
7
7
|
|
|
8
|
+
# Pre-computed once at import time; avoids list allocation + join on every call.
|
|
9
|
+
_PYLINT_DISABLE_FLAG = "--disable=" + ",".join([
|
|
10
|
+
"missing-module-docstring",
|
|
11
|
+
"import-outside-toplevel",
|
|
12
|
+
"no-name-in-module",
|
|
13
|
+
"broad-exception-caught",
|
|
14
|
+
"c-extension-no-member",
|
|
15
|
+
"line-too-long",
|
|
16
|
+
])
|
|
17
|
+
|
|
8
18
|
|
|
9
19
|
def _code_check_pylint(context: ExecutionContext, file_path: str) -> bool:
|
|
10
20
|
"""Check a Python file using pylint for code quality.
|
|
@@ -22,23 +32,13 @@ def _code_check_pylint(context: ExecutionContext, file_path: str) -> bool:
|
|
|
22
32
|
|
|
23
33
|
# Use subprocess to capture pylint output
|
|
24
34
|
# This avoids issues with pylint's direct printing to stdout
|
|
25
|
-
# List of warnings to disable
|
|
26
|
-
disabled_warnings = [
|
|
27
|
-
"missing-module-docstring",
|
|
28
|
-
"import-outside-toplevel",
|
|
29
|
-
"no-name-in-module",
|
|
30
|
-
"broad-exception-caught",
|
|
31
|
-
"c-extension-no-member",
|
|
32
|
-
"line-too-long",
|
|
33
|
-
]
|
|
34
|
-
|
|
35
35
|
cmd = [
|
|
36
36
|
sys.executable,
|
|
37
37
|
"-m",
|
|
38
38
|
"pylint",
|
|
39
39
|
file_path,
|
|
40
40
|
"--output-format=json",
|
|
41
|
-
|
|
41
|
+
_PYLINT_DISABLE_FLAG,
|
|
42
42
|
]
|
|
43
43
|
process = subprocess.run(cmd, capture_output=True, text=True, check=False)
|
|
44
44
|
|
|
@@ -53,19 +53,25 @@ def _code_check_pylint(context: ExecutionContext, file_path: str) -> bool:
|
|
|
53
53
|
# Parse the JSON output
|
|
54
54
|
results = json.loads(json_output)
|
|
55
55
|
|
|
56
|
-
#
|
|
57
|
-
errors = [
|
|
58
|
-
warnings = [
|
|
59
|
-
conventions = [
|
|
60
|
-
|
|
61
|
-
|
|
56
|
+
# Categorise messages in a single pass instead of three separate comprehensions.
|
|
57
|
+
errors: list = []
|
|
58
|
+
warnings: list = []
|
|
59
|
+
conventions: list = []
|
|
60
|
+
for msg in results:
|
|
61
|
+
t = msg.get("type")
|
|
62
|
+
if t in ("error", "fatal"):
|
|
63
|
+
errors.append(msg)
|
|
64
|
+
elif t == "warning":
|
|
65
|
+
warnings.append(msg)
|
|
66
|
+
elif t in ("convention", "refactor", "info"):
|
|
67
|
+
conventions.append(msg)
|
|
62
68
|
|
|
63
69
|
# Display results if any issues found
|
|
64
70
|
if errors or warnings or conventions:
|
|
65
71
|
# Display errors
|
|
66
72
|
if errors:
|
|
67
73
|
context.io.log_indent_up()
|
|
68
|
-
context.io.error(
|
|
74
|
+
context.io.error("Pylint errors:")
|
|
69
75
|
context.io.log_indent_up()
|
|
70
76
|
|
|
71
77
|
for error in errors:
|
|
@@ -80,7 +86,7 @@ def _code_check_pylint(context: ExecutionContext, file_path: str) -> bool:
|
|
|
80
86
|
# Display warnings with detailed logging
|
|
81
87
|
if warnings:
|
|
82
88
|
context.io.log_indent_up()
|
|
83
|
-
context.io.warning(
|
|
89
|
+
context.io.warning("Pylint warnings:")
|
|
84
90
|
context.io.log_indent_up()
|
|
85
91
|
|
|
86
92
|
for warning in warnings:
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import json
|
|
4
|
+
import subprocess
|
|
5
|
+
import sys
|
|
3
6
|
from typing import TYPE_CHECKING
|
|
4
7
|
|
|
5
8
|
if TYPE_CHECKING:
|
|
@@ -16,10 +19,6 @@ def _code_check_pyright(kernel: Kernel, file_path: str) -> bool:
|
|
|
16
19
|
Returns:
|
|
17
20
|
bool: True if check passes, False otherwise
|
|
18
21
|
"""
|
|
19
|
-
import json
|
|
20
|
-
import subprocess
|
|
21
|
-
import sys
|
|
22
|
-
|
|
23
22
|
# Use subprocess to run pyright
|
|
24
23
|
cmd = [sys.executable, "-m", "pyright", file_path, "--outputjson"]
|
|
25
24
|
process = subprocess.run(cmd, capture_output=True, text=True, check=False)
|
|
@@ -42,20 +41,25 @@ def _code_check_pyright(kernel: Kernel, file_path: str) -> bool:
|
|
|
42
41
|
# Parse the JSON output
|
|
43
42
|
results = json.loads(json_output)
|
|
44
43
|
|
|
45
|
-
#
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
44
|
+
# Classify diagnostics in a single pass (avoids 3× iteration and repeated .get("severity"))
|
|
45
|
+
errors: list = []
|
|
46
|
+
warnings: list = []
|
|
47
|
+
info: list = []
|
|
48
|
+
for diag in results.get("diagnostics", []):
|
|
49
|
+
sev = diag.get("severity")
|
|
50
|
+
if sev == "error":
|
|
51
|
+
errors.append(diag)
|
|
52
|
+
elif sev == "warning":
|
|
53
|
+
warnings.append(diag)
|
|
54
|
+
elif sev == "information":
|
|
55
|
+
info.append(diag)
|
|
52
56
|
|
|
53
57
|
# Display results if any issues found
|
|
54
58
|
if errors or warnings or info:
|
|
55
59
|
# Display errors
|
|
56
60
|
if errors:
|
|
57
61
|
kernel.io.log_indent_up()
|
|
58
|
-
kernel.io.error(
|
|
62
|
+
kernel.io.error("Pyright errors:")
|
|
59
63
|
|
|
60
64
|
for error in errors:
|
|
61
65
|
line = error.get("range", {}).get("start", {}).get("line", 0) + 1
|
|
@@ -70,7 +74,7 @@ def _code_check_pyright(kernel: Kernel, file_path: str) -> bool:
|
|
|
70
74
|
# Display warnings
|
|
71
75
|
if warnings:
|
|
72
76
|
kernel.io.log_indent_up()
|
|
73
|
-
kernel.io.warning(
|
|
77
|
+
kernel.io.warning("Pyright warnings:")
|
|
74
78
|
|
|
75
79
|
for warning in warnings:
|
|
76
80
|
line = warning.get("range", {}).get("start", {}).get("line", 0) + 1
|
|
@@ -85,7 +89,7 @@ def _code_check_pyright(kernel: Kernel, file_path: str) -> bool:
|
|
|
85
89
|
# Display information
|
|
86
90
|
if info:
|
|
87
91
|
kernel.io.log_indent_up()
|
|
88
|
-
kernel.io.info(
|
|
92
|
+
kernel.io.info("Pyright information:")
|
|
89
93
|
kernel.io.log_indent_up()
|
|
90
94
|
|
|
91
95
|
for item in info:
|
|
@@ -74,16 +74,13 @@ def python__code__check(
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
# Determine which tools to run
|
|
77
|
-
|
|
77
|
+
tool_lower = tool.lower() if tool else None
|
|
78
|
+
if tool_lower and tool_lower in tool_map:
|
|
78
79
|
# Run only the specified tool
|
|
79
|
-
check_functions = [tool_map[
|
|
80
|
+
check_functions = [tool_map[tool_lower]]
|
|
80
81
|
else:
|
|
81
82
|
# Run all tools if no specific tool is specified or if the specified tool is invalid
|
|
82
|
-
check_functions =
|
|
83
|
-
_code_check_mypy,
|
|
84
|
-
_code_check_pylint,
|
|
85
|
-
_code_check_pyright,
|
|
86
|
-
]
|
|
83
|
+
check_functions = list(tool_map.values())
|
|
87
84
|
|
|
88
85
|
# Track overall success
|
|
89
86
|
all_checks_passed = True
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import subprocess
|
|
4
|
+
import sys
|
|
3
5
|
from typing import TYPE_CHECKING
|
|
4
6
|
|
|
5
7
|
if TYPE_CHECKING:
|
|
@@ -16,11 +18,8 @@ def _code_format_black(kernel: Kernel, file_path: str) -> bool:
|
|
|
16
18
|
Returns:
|
|
17
19
|
bool: True if formatting succeeds, False otherwise
|
|
18
20
|
"""
|
|
19
|
-
import subprocess
|
|
20
|
-
import sys
|
|
21
|
-
|
|
22
21
|
# Use subprocess to run black
|
|
23
|
-
cmd =
|
|
22
|
+
cmd = (sys.executable, "-m", "black", file_path)
|
|
24
23
|
process = subprocess.run(cmd, capture_output=True, text=True, check=False)
|
|
25
24
|
|
|
26
25
|
# Check if the command was successful
|
|
@@ -30,17 +29,17 @@ def _code_format_black(kernel: Kernel, file_path: str) -> bool:
|
|
|
30
29
|
else:
|
|
31
30
|
kernel.io.success(f"Black: {file_path} already well formatted")
|
|
32
31
|
return True
|
|
33
|
-
else:
|
|
34
|
-
kernel.io.error(f"Black failed to format {file_path}")
|
|
35
|
-
kernel.io.log_indent_up()
|
|
36
32
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
33
|
+
kernel.io.error(f"Black failed to format {file_path}")
|
|
34
|
+
kernel.io.log_indent_up()
|
|
35
|
+
|
|
36
|
+
if process.stderr:
|
|
37
|
+
kernel.io.error(f"Error: {process.stderr}", symbol=False)
|
|
38
|
+
if process.stdout:
|
|
39
|
+
kernel.io.error(f"Output: {process.stdout}", symbol=False)
|
|
41
40
|
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
# Add detailed error properties
|
|
42
|
+
kernel.io.properties({"returncode": process.returncode, "command": cmd})
|
|
44
43
|
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
kernel.io.log_indent_down()
|
|
45
|
+
return False
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import subprocess
|
|
4
|
+
import sys
|
|
3
5
|
from typing import TYPE_CHECKING
|
|
4
6
|
|
|
5
7
|
if TYPE_CHECKING:
|
|
@@ -16,13 +18,10 @@ def _code_format_isort(kernel: Kernel, file_path: str) -> bool:
|
|
|
16
18
|
Returns:
|
|
17
19
|
bool: True if formatting succeeds, False otherwise
|
|
18
20
|
"""
|
|
19
|
-
import subprocess
|
|
20
|
-
import sys
|
|
21
|
-
|
|
22
21
|
# Use subprocess to run isort
|
|
23
22
|
# --profile=black ensures compatibility with Black formatter
|
|
24
23
|
cmd = [sys.executable, "-m", "isort", "--profile=black", file_path]
|
|
25
|
-
process = subprocess.run(cmd, capture_output=True, text=True
|
|
24
|
+
process = subprocess.run(cmd, capture_output=True, text=True)
|
|
26
25
|
|
|
27
26
|
# Check if the command was successful
|
|
28
27
|
if process.returncode == 0:
|
|
@@ -31,17 +30,17 @@ def _code_format_isort(kernel: Kernel, file_path: str) -> bool:
|
|
|
31
30
|
else:
|
|
32
31
|
kernel.io.success(f"isort successfully reformatted imports in {file_path}")
|
|
33
32
|
return True
|
|
34
|
-
else:
|
|
35
|
-
kernel.io.error(f"isort failed to format imports in {file_path}")
|
|
36
|
-
kernel.io.log_indent_up()
|
|
37
33
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
34
|
+
kernel.io.error(f"isort failed to format imports in {file_path}")
|
|
35
|
+
kernel.io.log_indent_up()
|
|
36
|
+
|
|
37
|
+
if process.stderr:
|
|
38
|
+
kernel.io.error(f"Error: {process.stderr}", symbol=False)
|
|
39
|
+
if process.stdout:
|
|
40
|
+
kernel.io.error(f"Output: {process.stdout}", symbol=False)
|
|
42
41
|
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
# Add detailed error properties
|
|
43
|
+
kernel.io.properties({"returncode": process.returncode, "command": cmd})
|
|
45
44
|
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
kernel.io.log_indent_down()
|
|
46
|
+
return False
|
|
@@ -61,13 +61,16 @@ def python__code__format(
|
|
|
61
61
|
"isort": _code_format_isort,
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
# Normalise once to avoid repeated .lower() calls
|
|
65
|
+
tool_lower = tool.lower() if tool else None
|
|
66
|
+
|
|
64
67
|
# Determine which tools to run
|
|
65
|
-
if
|
|
68
|
+
if tool_lower in tool_map:
|
|
66
69
|
# Run only the specified tool
|
|
67
|
-
format_functions = [tool_map[
|
|
70
|
+
format_functions = [tool_map[tool_lower]]
|
|
68
71
|
else:
|
|
69
|
-
#
|
|
70
|
-
if
|
|
72
|
+
# In the else branch, a truthy tool_lower is already known to be absent from tool_map
|
|
73
|
+
if tool_lower:
|
|
71
74
|
kernel.io.warning(f"Unknown tool '{tool}', running all available tools")
|
|
72
75
|
|
|
73
76
|
# Run isort first, then black (recommended order)
|
|
@@ -85,7 +88,7 @@ def python__code__format(
|
|
|
85
88
|
format_result = format_function(kernel, file)
|
|
86
89
|
|
|
87
90
|
# Update overall success status
|
|
88
|
-
all_formats_passed
|
|
91
|
+
all_formats_passed &= format_result
|
|
89
92
|
|
|
90
93
|
# Stop if a format fails and stop_on_failure is True
|
|
91
94
|
if not format_result and stop_on_failure:
|
wexample_wex_addon_dev_python-11.0.0/src/wexample_wex_addon_dev_python/commands/code/rename.py
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
from wexample_cli.const.tags import AudienceTag, EffectTag, ScopeTag
|
|
6
|
+
from wexample_cli.decorator.command import command
|
|
7
|
+
from wexample_cli.decorator.middleware import middleware
|
|
8
|
+
from wexample_cli.decorator.option import option
|
|
9
|
+
from wexample_wex_addon_app.middleware.app_middleware import AppMiddleware
|
|
10
|
+
from wexample_wex_core.const.globals import COMMAND_TYPE_ADDON
|
|
11
|
+
|
|
12
|
+
from wexample_wex_addon_dev_python.const.tags import DomainTag
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from wexample_app.response.abstract_response import AbstractResponse
|
|
16
|
+
from wexample_cli.context.execution_context import ExecutionContext
|
|
17
|
+
from wexample_wex_addon_app.workdir.managed_workdir import ManagedWorkdir
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@option(
|
|
21
|
+
name="source",
|
|
22
|
+
type=str,
|
|
23
|
+
required=True,
|
|
24
|
+
description="Dotted source name to rename (e.g. 'mylib.helpers').",
|
|
25
|
+
)
|
|
26
|
+
@option(
|
|
27
|
+
name="target",
|
|
28
|
+
type=str,
|
|
29
|
+
required=True,
|
|
30
|
+
description="Dotted target name (e.g. 'mylib.helper').",
|
|
31
|
+
)
|
|
32
|
+
@option(
|
|
33
|
+
name="kind",
|
|
34
|
+
type=str,
|
|
35
|
+
required=False,
|
|
36
|
+
default="package",
|
|
37
|
+
description="Symbol kind to rename. Step 1 supports only 'package'.",
|
|
38
|
+
)
|
|
39
|
+
@option(
|
|
40
|
+
name="dry_run",
|
|
41
|
+
type=bool,
|
|
42
|
+
is_flag=True,
|
|
43
|
+
default=False,
|
|
44
|
+
description="Preview impacted files without writing. Default: changes are applied.",
|
|
45
|
+
)
|
|
46
|
+
@middleware(middleware=AppMiddleware)
|
|
47
|
+
@command(
|
|
48
|
+
type=COMMAND_TYPE_ADDON,
|
|
49
|
+
description=(
|
|
50
|
+
"Rename a Python package directory and propagate the change to every "
|
|
51
|
+
"import statement in the workdir. Dry-run by default."
|
|
52
|
+
),
|
|
53
|
+
tags=[
|
|
54
|
+
DomainTag.LANGUAGE_PYTHON,
|
|
55
|
+
EffectTag.WRITE,
|
|
56
|
+
AudienceTag.AGENT_SAFE,
|
|
57
|
+
ScopeTag.LOCAL,
|
|
58
|
+
ScopeTag.PACKAGE,
|
|
59
|
+
],
|
|
60
|
+
)
|
|
61
|
+
def python__code__rename(
|
|
62
|
+
context: ExecutionContext,
|
|
63
|
+
app_workdir: ManagedWorkdir,
|
|
64
|
+
source: str,
|
|
65
|
+
target: str,
|
|
66
|
+
kind: str = "package",
|
|
67
|
+
dry_run: bool = False,
|
|
68
|
+
) -> AbstractResponse:
|
|
69
|
+
from wexample_app.response.failure_response import FailureResponse
|
|
70
|
+
from wexample_app.response.table_response import TableResponse
|
|
71
|
+
|
|
72
|
+
from wexample_wex_addon_dev_python.refactor.python_package_rename_handler import (
|
|
73
|
+
PythonPackageRenameHandler,
|
|
74
|
+
)
|
|
75
|
+
from wexample_wex_addon_dev_python.refactor.symbol_kind import SymbolKind
|
|
76
|
+
|
|
77
|
+
try:
|
|
78
|
+
kind_enum = SymbolKind(kind)
|
|
79
|
+
except ValueError:
|
|
80
|
+
return FailureResponse(
|
|
81
|
+
kernel=context.kernel,
|
|
82
|
+
message=(
|
|
83
|
+
f"Unknown --kind {kind!r}. Valid: "
|
|
84
|
+
f"{', '.join([k.value for k in SymbolKind])}"
|
|
85
|
+
),
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
if kind_enum is not SymbolKind.PACKAGE:
|
|
89
|
+
return FailureResponse(
|
|
90
|
+
kernel=context.kernel,
|
|
91
|
+
message=(
|
|
92
|
+
f"--kind {kind_enum.value} not implemented yet "
|
|
93
|
+
"(step 1 covers 'package' only)."
|
|
94
|
+
),
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
workdir_path = app_workdir.get_path()
|
|
98
|
+
handler = PythonPackageRenameHandler(
|
|
99
|
+
workdir_path=workdir_path,
|
|
100
|
+
source=source,
|
|
101
|
+
target=target,
|
|
102
|
+
dry_run=dry_run,
|
|
103
|
+
)
|
|
104
|
+
try:
|
|
105
|
+
report = handler.run()
|
|
106
|
+
except FileNotFoundError:
|
|
107
|
+
return FailureResponse(
|
|
108
|
+
kernel=context.kernel,
|
|
109
|
+
message=(
|
|
110
|
+
f"No Python package matching '{source}' under {workdir_path}. "
|
|
111
|
+
"Check the dotted name (e.g. 'mylib.helpers') and that you're "
|
|
112
|
+
"in the right workdir."
|
|
113
|
+
),
|
|
114
|
+
)
|
|
115
|
+
except ValueError as e:
|
|
116
|
+
# Raised on ambiguous match (multiple packages) or invalid dotted name.
|
|
117
|
+
return FailureResponse(kernel=context.kernel, message=str(e))
|
|
118
|
+
|
|
119
|
+
mode = "APPLIED" if not dry_run else "DRY-RUN"
|
|
120
|
+
context.io.log(
|
|
121
|
+
f"[{mode}] {report.package_dir_old} → {report.package_dir_new}"
|
|
122
|
+
)
|
|
123
|
+
context.io.log(
|
|
124
|
+
f"[{mode}] scanned={report.files_scanned} changed={len(report.files_changed)}"
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
rows = [
|
|
128
|
+
[str(p.relative_to(workdir_path))] for p in report.files_changed
|
|
129
|
+
]
|
|
130
|
+
return TableResponse(
|
|
131
|
+
kernel=context.kernel,
|
|
132
|
+
content=rows,
|
|
133
|
+
headers=["File"],
|
|
134
|
+
)
|
|
@@ -27,5 +27,4 @@ def python__examples__validate(
|
|
|
27
27
|
ExamplePydanticClassWithPublicVarInternallyDefined,
|
|
28
28
|
)
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
context.kernel.log(example_class)
|
|
30
|
+
context.kernel.log(ExamplePydanticClassWithPublicVarInternallyDefined())
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import base64
|
|
4
|
+
|
|
3
5
|
from wexample_api.common.abstract_gateway import AbstractGateway
|
|
4
6
|
from wexample_helpers.classes.field import public_field
|
|
5
7
|
from wexample_helpers.decorator.base_class import base_class
|
|
6
8
|
|
|
9
|
+
_HAS_VERSION_STATUS_CODES: tuple[int, ...] = (200, 404)
|
|
10
|
+
|
|
7
11
|
|
|
8
12
|
@base_class
|
|
9
13
|
class PypiRegistryGateway(AbstractGateway):
|
|
@@ -27,8 +31,6 @@ class PypiRegistryGateway(AbstractGateway):
|
|
|
27
31
|
def __attrs_post_init__(self) -> None:
|
|
28
32
|
super().__attrs_post_init__()
|
|
29
33
|
if self.token:
|
|
30
|
-
import base64
|
|
31
|
-
|
|
32
34
|
credentials = base64.b64encode(
|
|
33
35
|
f"{self.username or '__token__'}:{self.token}".encode()
|
|
34
36
|
).decode()
|
|
@@ -43,7 +45,7 @@ class PypiRegistryGateway(AbstractGateway):
|
|
|
43
45
|
"""
|
|
44
46
|
response = self.make_request(
|
|
45
47
|
endpoint=f"simple/{package}/",
|
|
46
|
-
expected_status_codes=
|
|
48
|
+
expected_status_codes=_HAS_VERSION_STATUS_CODES,
|
|
47
49
|
fatal_if_unexpected=False,
|
|
48
50
|
quiet=True,
|
|
49
51
|
)
|
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import TYPE_CHECKING
|
|
4
|
-
|
|
5
3
|
from wexample_helpers.decorator.base_class import base_class
|
|
6
4
|
from wexample_wex_addon_app.config_value.app_readme_config_value import (
|
|
7
5
|
AppReadmeConfigValue,
|
|
8
6
|
)
|
|
9
7
|
|
|
10
|
-
if TYPE_CHECKING:
|
|
11
|
-
pass
|
|
12
|
-
|
|
13
8
|
|
|
14
9
|
@base_class
|
|
15
10
|
class PythonPackageReadmeContentConfigValue(AppReadmeConfigValue):
|
|
@@ -22,9 +17,8 @@ class PythonPackageReadmeContentConfigValue(AppReadmeConfigValue):
|
|
|
22
17
|
def _get_app_homepage(self) -> str:
|
|
23
18
|
"""Extract homepage URL from pyproject.toml."""
|
|
24
19
|
project = self.workdir.get_app_config()
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
)
|
|
20
|
+
raw_urls = project.get("urls", {})
|
|
21
|
+
urls = raw_urls if isinstance(raw_urls, dict) else {}
|
|
28
22
|
return urls.get("homepage") or urls.get("Homepage") or ""
|
|
29
23
|
|
|
30
24
|
def _get_project_license(self) -> str | None:
|
|
@@ -29,13 +29,14 @@ class PythonAppImlFile(ImlFile):
|
|
|
29
29
|
return ({"@type": "sourceFolder", "@forTests": "false"},)
|
|
30
30
|
|
|
31
31
|
def _default_source_folders(self) -> Iterable[dict[str, Any]]:
|
|
32
|
+
base = self.MODULE_DIR_URL
|
|
32
33
|
return (
|
|
33
34
|
{
|
|
34
|
-
"@url": f"{
|
|
35
|
+
"@url": f"{base}/src",
|
|
35
36
|
"@isTestSource": "false",
|
|
36
37
|
},
|
|
37
38
|
{
|
|
38
|
-
"@url": f"{
|
|
39
|
+
"@url": f"{base}/tests",
|
|
39
40
|
"@isTestSource": "true",
|
|
40
41
|
},
|
|
41
42
|
)
|