wexample-wex-addon-dev-python 0.0.45__tar.gz → 0.0.48__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-0.0.45 → wexample_wex_addon_dev_python-0.0.48}/PKG-INFO +12 -10
- {wexample_wex_addon_dev_python-0.0.45 → wexample_wex_addon_dev_python-0.0.48}/README.md +6 -5
- {wexample_wex_addon_dev_python-0.0.45 → wexample_wex_addon_dev_python-0.0.48}/pyproject.toml +6 -8
- {wexample_wex_addon_dev_python-0.0.45 → wexample_wex_addon_dev_python-0.0.48}/src/wexample_wex_addon_dev_python/commands/code/check/mypy.py +4 -2
- {wexample_wex_addon_dev_python-0.0.45 → wexample_wex_addon_dev_python-0.0.48}/src/wexample_wex_addon_dev_python/commands/code/check/pyright.py +4 -1
- {wexample_wex_addon_dev_python-0.0.45 → wexample_wex_addon_dev_python-0.0.48}/src/wexample_wex_addon_dev_python/commands/code/check.py +2 -4
- {wexample_wex_addon_dev_python-0.0.45 → wexample_wex_addon_dev_python-0.0.48}/src/wexample_wex_addon_dev_python/commands/code/format/black.py +4 -1
- {wexample_wex_addon_dev_python-0.0.45 → wexample_wex_addon_dev_python-0.0.48}/src/wexample_wex_addon_dev_python/commands/code/format/isort.py +4 -1
- {wexample_wex_addon_dev_python-0.0.45 → wexample_wex_addon_dev_python-0.0.48}/src/wexample_wex_addon_dev_python/commands/code/format.py +5 -1
- {wexample_wex_addon_dev_python-0.0.45 → wexample_wex_addon_dev_python-0.0.48}/src/wexample_wex_addon_dev_python/config_value/python_package_readme_config_value.py +33 -22
- {wexample_wex_addon_dev_python-0.0.45 → wexample_wex_addon_dev_python-0.0.48}/src/wexample_wex_addon_dev_python/const/package.py +9 -8
- {wexample_wex_addon_dev_python-0.0.45 → wexample_wex_addon_dev_python-0.0.48}/src/wexample_wex_addon_dev_python/file/python_package_toml_file.py +125 -126
- {wexample_wex_addon_dev_python-0.0.45 → wexample_wex_addon_dev_python-0.0.48}/src/wexample_wex_addon_dev_python/middleware/each_python_file_middleware.py +16 -18
- {wexample_wex_addon_dev_python-0.0.45 → wexample_wex_addon_dev_python-0.0.48}/src/wexample_wex_addon_dev_python/python_addon_manager.py +5 -1
- {wexample_wex_addon_dev_python-0.0.45 → wexample_wex_addon_dev_python-0.0.48}/src/wexample_wex_addon_dev_python/workdir/python_package_workdir.py +108 -100
- {wexample_wex_addon_dev_python-0.0.45 → wexample_wex_addon_dev_python-0.0.48}/src/wexample_wex_addon_dev_python/workdir/python_packages_suite_workdir.py +49 -56
- {wexample_wex_addon_dev_python-0.0.45 → wexample_wex_addon_dev_python-0.0.48}/src/wexample_wex_addon_dev_python/workdir/python_workdir.py +93 -73
- wexample_wex_addon_dev_python-0.0.45/src/wexample_wex_addon_dev_python/commands/examples/classes/example_pydantic_class_with_public_var_internaly_defined.py +0 -42
- wexample_wex_addon_dev_python-0.0.45/src/wexample_wex_addon_dev_python/workdir/__init__.py +0 -0
- {wexample_wex_addon_dev_python-0.0.45 → wexample_wex_addon_dev_python-0.0.48}/src/wexample_wex_addon_dev_python/__init__.py +0 -0
- {wexample_wex_addon_dev_python-0.0.45 → wexample_wex_addon_dev_python-0.0.48}/src/wexample_wex_addon_dev_python/commands/__init__.py +0 -0
- {wexample_wex_addon_dev_python-0.0.45 → wexample_wex_addon_dev_python-0.0.48}/src/wexample_wex_addon_dev_python/commands/code/__init__.py +0 -0
- {wexample_wex_addon_dev_python-0.0.45 → wexample_wex_addon_dev_python-0.0.48}/src/wexample_wex_addon_dev_python/commands/code/check/__init__.py +0 -0
- {wexample_wex_addon_dev_python-0.0.45 → wexample_wex_addon_dev_python-0.0.48}/src/wexample_wex_addon_dev_python/commands/code/check/pylint.py +0 -0
- {wexample_wex_addon_dev_python-0.0.45 → wexample_wex_addon_dev_python-0.0.48}/src/wexample_wex_addon_dev_python/commands/code/format/__init__.py +0 -0
- {wexample_wex_addon_dev_python-0.0.45 → wexample_wex_addon_dev_python-0.0.48}/src/wexample_wex_addon_dev_python/commands/examples/__init__.py +0 -0
- {wexample_wex_addon_dev_python-0.0.45/src/wexample_wex_addon_dev_python/commands/examples/classes → wexample_wex_addon_dev_python-0.0.48/src/wexample_wex_addon_dev_python/commands/examples/utils}/__init__.py +0 -0
- {wexample_wex_addon_dev_python-0.0.45 → wexample_wex_addon_dev_python-0.0.48}/src/wexample_wex_addon_dev_python/commands/examples/utils/some_example_type.py +0 -0
- {wexample_wex_addon_dev_python-0.0.45 → wexample_wex_addon_dev_python-0.0.48}/src/wexample_wex_addon_dev_python/commands/examples/validate.py +0 -0
- {wexample_wex_addon_dev_python-0.0.45/src/wexample_wex_addon_dev_python/commands/examples/utils → wexample_wex_addon_dev_python-0.0.48/src/wexample_wex_addon_dev_python/commands/release}/__init__.py +0 -0
- {wexample_wex_addon_dev_python-0.0.45/src/wexample_wex_addon_dev_python/commands/release → wexample_wex_addon_dev_python-0.0.48/src/wexample_wex_addon_dev_python/config_value}/__init__.py +0 -0
- {wexample_wex_addon_dev_python-0.0.45/src/wexample_wex_addon_dev_python/config_value → wexample_wex_addon_dev_python-0.0.48/src/wexample_wex_addon_dev_python/const}/__init__.py +0 -0
- {wexample_wex_addon_dev_python-0.0.45/src/wexample_wex_addon_dev_python/const → wexample_wex_addon_dev_python-0.0.48/src/wexample_wex_addon_dev_python/file}/__init__.py +0 -0
- {wexample_wex_addon_dev_python-0.0.45/src/wexample_wex_addon_dev_python/file → wexample_wex_addon_dev_python-0.0.48/src/wexample_wex_addon_dev_python/middleware}/__init__.py +0 -0
- {wexample_wex_addon_dev_python-0.0.45 → wexample_wex_addon_dev_python-0.0.48}/src/wexample_wex_addon_dev_python/py.typed +0 -0
- {wexample_wex_addon_dev_python-0.0.45/src/wexample_wex_addon_dev_python/middleware → wexample_wex_addon_dev_python-0.0.48/src/wexample_wex_addon_dev_python/workdir}/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: wexample-wex-addon-dev-python
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.48
|
|
4
4
|
Summary: Python dev addon for wex
|
|
5
5
|
Author-Email: weeger <contact@wexample.com>
|
|
6
6
|
License: MIT
|
|
@@ -9,12 +9,13 @@ Classifier: License :: OSI Approved :: MIT License
|
|
|
9
9
|
Classifier: Operating System :: OS Independent
|
|
10
10
|
Project-URL: homepage, https://github.com/wexample/python-wex-dev-python
|
|
11
11
|
Requires-Python: >=3.10
|
|
12
|
-
Requires-Dist:
|
|
12
|
+
Requires-Dist: attrs>=23.1.0
|
|
13
|
+
Requires-Dist: cattrs>=23.1.0
|
|
13
14
|
Requires-Dist: pylint
|
|
14
15
|
Requires-Dist: pyright
|
|
15
|
-
Requires-Dist: wexample-filestate-python==0.0.
|
|
16
|
-
Requires-Dist: wexample-wex-addon-app==0.0.
|
|
17
|
-
Requires-Dist: wexample-wex-core==6.0.
|
|
16
|
+
Requires-Dist: wexample-filestate-python==0.0.44
|
|
17
|
+
Requires-Dist: wexample-wex-addon-app==0.0.46
|
|
18
|
+
Requires-Dist: wexample-wex-core==6.0.48
|
|
18
19
|
Provides-Extra: dev
|
|
19
20
|
Requires-Dist: pytest; extra == "dev"
|
|
20
21
|
Description-Content-Type: text/markdown
|
|
@@ -23,7 +24,7 @@ Description-Content-Type: text/markdown
|
|
|
23
24
|
|
|
24
25
|
Python dev addon for wex
|
|
25
26
|
|
|
26
|
-
Version: 0.0.
|
|
27
|
+
Version: 0.0.46
|
|
27
28
|
|
|
28
29
|
## Requirements
|
|
29
30
|
|
|
@@ -31,12 +32,13 @@ Version: 0.0.45
|
|
|
31
32
|
|
|
32
33
|
## Dependencies
|
|
33
34
|
|
|
34
|
-
-
|
|
35
|
+
- attrs>=23.1.0
|
|
36
|
+
- cattrs>=23.1.0
|
|
35
37
|
- pylint
|
|
36
38
|
- pyright
|
|
37
|
-
- wexample-filestate-python==0.0.
|
|
38
|
-
- wexample-wex-addon-app==0.0.
|
|
39
|
-
- wexample-wex-core==6.0.
|
|
39
|
+
- wexample-filestate-python==0.0.42
|
|
40
|
+
- wexample-wex-addon-app==0.0.44
|
|
41
|
+
- wexample-wex-core==6.0.46
|
|
40
42
|
|
|
41
43
|
## Installation
|
|
42
44
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Python dev addon for wex
|
|
4
4
|
|
|
5
|
-
Version: 0.0.
|
|
5
|
+
Version: 0.0.46
|
|
6
6
|
|
|
7
7
|
## Requirements
|
|
8
8
|
|
|
@@ -10,12 +10,13 @@ Version: 0.0.45
|
|
|
10
10
|
|
|
11
11
|
## Dependencies
|
|
12
12
|
|
|
13
|
-
-
|
|
13
|
+
- attrs>=23.1.0
|
|
14
|
+
- cattrs>=23.1.0
|
|
14
15
|
- pylint
|
|
15
16
|
- pyright
|
|
16
|
-
- wexample-filestate-python==0.0.
|
|
17
|
-
- wexample-wex-addon-app==0.0.
|
|
18
|
-
- wexample-wex-core==6.0.
|
|
17
|
+
- wexample-filestate-python==0.0.42
|
|
18
|
+
- wexample-wex-addon-app==0.0.44
|
|
19
|
+
- wexample-wex-core==6.0.46
|
|
19
20
|
|
|
20
21
|
## Installation
|
|
21
22
|
|
{wexample_wex_addon_dev_python-0.0.45 → wexample_wex_addon_dev_python-0.0.48}/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 = "0.0.
|
|
9
|
+
version = "0.0.48"
|
|
10
10
|
description = "Python dev addon for wex"
|
|
11
11
|
authors = [
|
|
12
12
|
{ name = "weeger", email = "contact@wexample.com" },
|
|
@@ -18,12 +18,13 @@ classifiers = [
|
|
|
18
18
|
"Operating System :: OS Independent",
|
|
19
19
|
]
|
|
20
20
|
dependencies = [
|
|
21
|
-
"
|
|
21
|
+
"attrs>=23.1.0",
|
|
22
|
+
"cattrs>=23.1.0",
|
|
22
23
|
"pylint",
|
|
23
24
|
"pyright",
|
|
24
|
-
"wexample-filestate-python==0.0.
|
|
25
|
-
"wexample-wex-addon-app==0.0.
|
|
26
|
-
"wexample-wex-core==6.0.
|
|
25
|
+
"wexample-filestate-python==0.0.44",
|
|
26
|
+
"wexample-wex-addon-app==0.0.46",
|
|
27
|
+
"wexample-wex-core==6.0.48",
|
|
27
28
|
]
|
|
28
29
|
|
|
29
30
|
[project.readme]
|
|
@@ -45,9 +46,6 @@ dev = [
|
|
|
45
46
|
distribution = true
|
|
46
47
|
|
|
47
48
|
[tool.pdm.build]
|
|
48
|
-
includes = [
|
|
49
|
-
"src/wexample_wex_addon_dev_python/*",
|
|
50
|
-
]
|
|
51
49
|
package-dir = "src"
|
|
52
50
|
packages = [
|
|
53
51
|
{ include = "wexample_wex_addon_dev_python", from = "src" },
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
if TYPE_CHECKING:
|
|
6
|
+
from wexample_wex_core.common.kernel import Kernel
|
|
4
7
|
|
|
5
8
|
|
|
6
9
|
def _code_check_mypy(kernel: Kernel, file_path: str) -> bool:
|
|
@@ -15,7 +18,6 @@ def _code_check_mypy(kernel: Kernel, file_path: str) -> bool:
|
|
|
15
18
|
"""
|
|
16
19
|
import sys
|
|
17
20
|
|
|
18
|
-
# Import mypy modules
|
|
19
21
|
from mypy import build
|
|
20
22
|
from mypy.modulefinder import BuildSource
|
|
21
23
|
from mypy.options import Options
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
if TYPE_CHECKING:
|
|
6
|
+
from wexample_wex_core.common.kernel import Kernel
|
|
4
7
|
|
|
5
8
|
|
|
6
9
|
def _code_check_pyright(kernel: Kernel, file_path: str) -> bool:
|
|
@@ -43,7 +43,7 @@ def python__code__check(
|
|
|
43
43
|
parallel: bool = True,
|
|
44
44
|
) -> bool:
|
|
45
45
|
"""Check a Python file using various code quality tools."""
|
|
46
|
-
from
|
|
46
|
+
from wexample_app.response.failure_response import FailureResponse
|
|
47
47
|
from wexample_wex_addon_dev_python.commands.code.check.mypy import _code_check_mypy
|
|
48
48
|
from wexample_wex_addon_dev_python.commands.code.check.pylint import (
|
|
49
49
|
_code_check_pylint,
|
|
@@ -80,7 +80,7 @@ def python__code__check(
|
|
|
80
80
|
context.io.log_indent_up()
|
|
81
81
|
|
|
82
82
|
context.io.log(
|
|
83
|
-
f"🐍 Python: {
|
|
83
|
+
f"🐍 Python: {context.kernel.host_workdir.render_display_path(file)}"
|
|
84
84
|
)
|
|
85
85
|
|
|
86
86
|
check_result = check_function(context, file)
|
|
@@ -95,8 +95,6 @@ def python__code__check(
|
|
|
95
95
|
if not check_result and stop_on_failure:
|
|
96
96
|
context.io.error("One check failed")
|
|
97
97
|
|
|
98
|
-
from wexample_app.response.failure_response import FailureResponse
|
|
99
|
-
|
|
100
98
|
context.io.log_indent_down()
|
|
101
99
|
|
|
102
100
|
return FailureResponse(message="One check failed", kernel=context.kernel)
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
if TYPE_CHECKING:
|
|
6
|
+
from wexample_wex_core.common.kernel import Kernel
|
|
4
7
|
|
|
5
8
|
|
|
6
9
|
def _code_format_black(kernel: Kernel, file_path: str) -> bool:
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
if TYPE_CHECKING:
|
|
6
|
+
from wexample_wex_core.common.kernel import Kernel
|
|
4
7
|
|
|
5
8
|
|
|
6
9
|
def _code_format_isort(kernel: Kernel, file_path: str) -> bool:
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
4
5
|
from wexample_wex_core.decorator.command import command
|
|
5
6
|
from wexample_wex_core.decorator.middleware import middleware
|
|
6
7
|
from wexample_wex_core.decorator.option import option
|
|
7
8
|
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from wexample_wex_core.common.kernel import Kernel
|
|
11
|
+
|
|
8
12
|
|
|
9
13
|
@option(
|
|
10
14
|
name="tool",
|
|
@@ -1,38 +1,28 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
4
5
|
|
|
5
6
|
from wexample_filestate.config_value.readme_content_config_value import (
|
|
6
7
|
ReadmeContentConfigValue,
|
|
7
8
|
)
|
|
9
|
+
from wexample_helpers.classes.field import public_field
|
|
10
|
+
from wexample_helpers.decorator.base_class import base_class
|
|
8
11
|
from wexample_wex_addon_dev_python.workdir.python_package_workdir import (
|
|
9
12
|
PythonPackageWorkdir,
|
|
10
13
|
)
|
|
11
14
|
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from wexample_wex_addon_dev_python.workdir.python_package_workdir import (
|
|
17
|
+
PythonPackageWorkdir,
|
|
18
|
+
)
|
|
12
19
|
|
|
13
|
-
class PythonPackageReadmeContentConfigValue(ReadmeContentConfigValue):
|
|
14
|
-
workdir: PythonPackageWorkdir
|
|
15
|
-
|
|
16
|
-
def _get_doc_path(self, section: str) -> str:
|
|
17
|
-
"""
|
|
18
|
-
Returns the path to a documentation section file
|
|
19
|
-
"""
|
|
20
|
-
return os.path.join(
|
|
21
|
-
self.workdir.get_path(), ".wex", "doc", "readme", f"{section}.md"
|
|
22
|
-
)
|
|
23
|
-
|
|
24
|
-
def _add_section_if_exists(self, section: str) -> str:
|
|
25
|
-
"""
|
|
26
|
-
Returns section content if the documentation file exists
|
|
27
|
-
"""
|
|
28
|
-
doc_path = self._get_doc_path(section)
|
|
29
20
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
return ""
|
|
21
|
+
@base_class
|
|
22
|
+
class PythonPackageReadmeContentConfigValue(ReadmeContentConfigValue):
|
|
23
|
+
workdir: PythonPackageWorkdir = public_field(
|
|
24
|
+
description="The python package workdir"
|
|
25
|
+
)
|
|
36
26
|
|
|
37
27
|
def get_templates(self) -> list[str] | None:
|
|
38
28
|
# Use TOMLDocument from the workdir
|
|
@@ -79,3 +69,24 @@ class PythonPackageReadmeContentConfigValue(ReadmeContentConfigValue):
|
|
|
79
69
|
"## License\n\n"
|
|
80
70
|
f"{license_info}"
|
|
81
71
|
]
|
|
72
|
+
|
|
73
|
+
def _add_section_if_exists(self, section: str) -> str:
|
|
74
|
+
"""
|
|
75
|
+
Returns section content if the documentation file exists
|
|
76
|
+
"""
|
|
77
|
+
doc_path = self._get_doc_path(section)
|
|
78
|
+
|
|
79
|
+
if os.path.exists(doc_path):
|
|
80
|
+
with open(doc_path, encoding="utf-8") as file:
|
|
81
|
+
content = file.read()
|
|
82
|
+
return f"## {section.title()}\n\n{content}\n\n"
|
|
83
|
+
|
|
84
|
+
return ""
|
|
85
|
+
|
|
86
|
+
def _get_doc_path(self, section: str) -> str:
|
|
87
|
+
"""
|
|
88
|
+
Returns the path to a documentation section file
|
|
89
|
+
"""
|
|
90
|
+
return os.path.join(
|
|
91
|
+
self.workdir.get_path(), ".wex", "doc", "readme", f"{section}.md"
|
|
92
|
+
)
|
|
@@ -3,18 +3,19 @@ from __future__ import annotations
|
|
|
3
3
|
# Names of dev/build tools to remove from runtime [project.dependencies]
|
|
4
4
|
# Keep this list in sync with tooling expectations.
|
|
5
5
|
RUNTIME_DEPENDENCY_REMOVE_NAMES: set[str] = {
|
|
6
|
-
|
|
7
|
-
"pip-tools",
|
|
6
|
+
# filestate: python-iterable-sort
|
|
8
7
|
"black",
|
|
9
|
-
"
|
|
8
|
+
"build",
|
|
9
|
+
"coverage",
|
|
10
10
|
"flake8",
|
|
11
|
-
"mypy",
|
|
12
11
|
"isort",
|
|
13
|
-
"
|
|
14
|
-
"build",
|
|
15
|
-
"twine",
|
|
12
|
+
"mypy",
|
|
16
13
|
"pip",
|
|
14
|
+
"pip-tools",
|
|
15
|
+
"pytest",
|
|
16
|
+
"ruff",
|
|
17
17
|
"setuptools",
|
|
18
|
-
"
|
|
18
|
+
"twine",
|
|
19
19
|
"typing-extensions",
|
|
20
|
+
"wheel",
|
|
20
21
|
}
|
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
from typing import TYPE_CHECKING
|
|
4
4
|
|
|
5
5
|
from wexample_filestate.item.file.toml_file import TomlFile
|
|
6
|
+
from wexample_helpers.decorator.base_class import base_class
|
|
6
7
|
from wexample_wex_core.workdir.mixin.as_suite_package_item import (
|
|
7
8
|
AsSuitePackageItem,
|
|
8
9
|
)
|
|
@@ -14,79 +15,8 @@ if TYPE_CHECKING:
|
|
|
14
15
|
)
|
|
15
16
|
|
|
16
17
|
|
|
18
|
+
@base_class
|
|
17
19
|
class PythonPackageTomlFile(AsSuitePackageItem, TomlFile):
|
|
18
|
-
|
|
19
|
-
def _project_table(self):
|
|
20
|
-
"""Ensure and return the [project] table."""
|
|
21
|
-
from wexample_filestate_python.helpers.toml import toml_ensure_table
|
|
22
|
-
|
|
23
|
-
doc = self.read_parsed()
|
|
24
|
-
project, _ = toml_ensure_table(doc, ["project"])
|
|
25
|
-
return project
|
|
26
|
-
|
|
27
|
-
def _dependencies_array(self):
|
|
28
|
-
"""Ensure and return project.dependencies as a multi-line TOML array."""
|
|
29
|
-
from wexample_filestate_python.helpers.toml import (
|
|
30
|
-
toml_ensure_array,
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
project = self._project_table()
|
|
34
|
-
deps, _ = toml_ensure_array(project, "dependencies")
|
|
35
|
-
deps.multiline(True)
|
|
36
|
-
return deps
|
|
37
|
-
|
|
38
|
-
def _optional_group_array(self, group: str):
|
|
39
|
-
"""Ensure and return project.optional-dependencies[group] as multi-line array."""
|
|
40
|
-
from wexample_filestate_python.helpers.toml import (
|
|
41
|
-
toml_ensure_array,
|
|
42
|
-
toml_ensure_table,
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
project = self._project_table()
|
|
46
|
-
opt, _ = toml_ensure_table(project, ["optional-dependencies"])
|
|
47
|
-
arr, _ = toml_ensure_array(opt, group)
|
|
48
|
-
arr.multiline(True)
|
|
49
|
-
return arr
|
|
50
|
-
|
|
51
|
-
# --- Unified dependency accessors (runtime vs optional) ---
|
|
52
|
-
def _get_deps_array(self, optional: bool = False, group: str = "dev"):
|
|
53
|
-
"""Return TOML array for runtime deps or optional group (multiline)."""
|
|
54
|
-
return (
|
|
55
|
-
self._optional_group_array(group)
|
|
56
|
-
if optional
|
|
57
|
-
else self._dependencies_array()
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
def list_dependencies(
|
|
61
|
-
self, optional: bool = False, group: str = "dev"
|
|
62
|
-
) -> list[str]:
|
|
63
|
-
deps = self._get_deps_array(optional=optional, group=group)
|
|
64
|
-
return [str(x) for x in list(deps)]
|
|
65
|
-
|
|
66
|
-
def list_dependency_names(
|
|
67
|
-
self,
|
|
68
|
-
canonicalize_names: bool = True,
|
|
69
|
-
optional: bool = False,
|
|
70
|
-
group: str = "dev",
|
|
71
|
-
) -> list[str]:
|
|
72
|
-
"""Return dependency package names derived from list_dependencies().
|
|
73
|
-
|
|
74
|
-
If canonicalize_names is True, names are normalized using packaging's
|
|
75
|
-
canonicalize_name for robust comparisons (dash/underscore, case, etc.).
|
|
76
|
-
"""
|
|
77
|
-
from packaging.requirements import Requirement
|
|
78
|
-
from packaging.utils import canonicalize_name
|
|
79
|
-
|
|
80
|
-
names: list[str] = []
|
|
81
|
-
for spec in self.list_dependencies(optional=optional, group=group):
|
|
82
|
-
try:
|
|
83
|
-
name = Requirement(spec).name
|
|
84
|
-
names.append(canonicalize_name(name) if canonicalize_names else name)
|
|
85
|
-
except Exception:
|
|
86
|
-
# Skip unparsable entries when deriving names
|
|
87
|
-
continue
|
|
88
|
-
return names
|
|
89
|
-
|
|
90
20
|
def add_dependency(
|
|
91
21
|
self, spec: str, optional: bool = False, group: str = "dev"
|
|
92
22
|
) -> bool:
|
|
@@ -109,44 +39,6 @@ class PythonPackageTomlFile(AsSuitePackageItem, TomlFile):
|
|
|
109
39
|
|
|
110
40
|
return removed
|
|
111
41
|
|
|
112
|
-
def remove_dependency_by_name(
|
|
113
|
-
self, package_name: str, optional: bool = False, group: str = "dev"
|
|
114
|
-
) -> bool:
|
|
115
|
-
"""Remove all dependency entries that match the given package name.
|
|
116
|
-
|
|
117
|
-
The provided package_name can be raw; it will be canonicalized to ensure
|
|
118
|
-
consistent matching against entries parsed from list_dependencies().
|
|
119
|
-
"""
|
|
120
|
-
from packaging.requirements import Requirement
|
|
121
|
-
from packaging.utils import canonicalize_name
|
|
122
|
-
|
|
123
|
-
deps = self._get_deps_array(optional=optional, group=group)
|
|
124
|
-
|
|
125
|
-
target = canonicalize_name(package_name)
|
|
126
|
-
filtered: list[str] = []
|
|
127
|
-
for existing in list(deps):
|
|
128
|
-
try:
|
|
129
|
-
existing_name = canonicalize_name(Requirement(str(existing)).name)
|
|
130
|
-
except Exception:
|
|
131
|
-
# Keep unparsable entries untouched
|
|
132
|
-
filtered.append(existing)
|
|
133
|
-
continue
|
|
134
|
-
if existing_name != target:
|
|
135
|
-
filtered.append(existing)
|
|
136
|
-
|
|
137
|
-
if len(filtered) != len(deps):
|
|
138
|
-
deps.clear()
|
|
139
|
-
deps.extend(filtered)
|
|
140
|
-
return True
|
|
141
|
-
return False
|
|
142
|
-
|
|
143
|
-
def find_package_workdir(self) -> CodeBaseWorkdir | None:
|
|
144
|
-
from wexample_wex_core.workdir.code_base_workdir import (
|
|
145
|
-
CodeBaseWorkdir,
|
|
146
|
-
)
|
|
147
|
-
|
|
148
|
-
return self.find_closest(CodeBaseWorkdir)
|
|
149
|
-
|
|
150
42
|
def dumps(self, content: TOMLDocument | dict | None = None) -> str:
|
|
151
43
|
"""Serialize a TOMLDocument (preferred) or a plain dict to TOML.
|
|
152
44
|
Using tomlkit.dumps preserves comments/formatting when content is a TOMLDocument.
|
|
@@ -154,10 +46,8 @@ class PythonPackageTomlFile(AsSuitePackageItem, TomlFile):
|
|
|
154
46
|
from tomlkit import dumps, table
|
|
155
47
|
from wexample_filestate_python.helpers.package import package_normalize_name
|
|
156
48
|
from wexample_filestate_python.helpers.toml import (
|
|
157
|
-
toml_ensure_array_multiline,
|
|
158
49
|
toml_ensure_table,
|
|
159
50
|
toml_get_string_value,
|
|
160
|
-
toml_set_array_multiline,
|
|
161
51
|
toml_sort_string_array,
|
|
162
52
|
)
|
|
163
53
|
from wexample_wex_addon_dev_python.const.package import (
|
|
@@ -192,20 +82,18 @@ class PythonPackageTomlFile(AsSuitePackageItem, TomlFile):
|
|
|
192
82
|
tool_tbl, _ = toml_ensure_table(content, ["tool"])
|
|
193
83
|
pdm_tbl, _ = toml_ensure_table(tool_tbl, ["pdm"])
|
|
194
84
|
build_pdm_tbl, _ = toml_ensure_table(pdm_tbl, ["build"])
|
|
195
|
-
includes_arr, _ = toml_ensure_array_multiline(build_pdm_tbl, "includes")
|
|
196
85
|
|
|
197
86
|
pdm_tbl["distribution"] = True
|
|
198
|
-
# Enforce src layout
|
|
87
|
+
# Enforce src layout and packages (remove includes to avoid conflicts)
|
|
199
88
|
if build_pdm_tbl.get("package-dir") != "src":
|
|
200
89
|
build_pdm_tbl["package-dir"] = "src"
|
|
201
90
|
if import_name:
|
|
202
91
|
desired_pkgs = [{"include": import_name, "from": "src"}]
|
|
203
92
|
if build_pdm_tbl.get("packages") != desired_pkgs:
|
|
204
93
|
build_pdm_tbl["packages"] = desired_pkgs
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
toml_set_array_multiline(build_pdm_tbl, "includes", desired_includes)
|
|
94
|
+
# Remove includes to avoid conflicts with packages declaration
|
|
95
|
+
if "includes" in build_pdm_tbl:
|
|
96
|
+
del build_pdm_tbl["includes"]
|
|
209
97
|
|
|
210
98
|
# --- [project] table and basic fields ---
|
|
211
99
|
project_tbl, _ = toml_ensure_table(content, ["project"])
|
|
@@ -246,13 +134,13 @@ class PythonPackageTomlFile(AsSuitePackageItem, TomlFile):
|
|
|
246
134
|
exclude_add = {str(x).strip().lower() for x in ex_list}
|
|
247
135
|
|
|
248
136
|
# Remove unwanted dev/build tools from runtime deps (unless kept)
|
|
249
|
-
|
|
250
137
|
def _should_remove(item: object) -> bool:
|
|
251
138
|
name = package_normalize_name(toml_get_string_value(item))
|
|
252
139
|
if name in keep_names:
|
|
253
140
|
return False
|
|
254
141
|
if name == "typing-extensions":
|
|
255
|
-
# Safe to drop when
|
|
142
|
+
# Safe to drop when py
|
|
143
|
+
# thon >= 3.10 and we manage deps
|
|
256
144
|
return True
|
|
257
145
|
return name in RUNTIME_DEPENDENCY_REMOVE_NAMES
|
|
258
146
|
|
|
@@ -265,14 +153,17 @@ class PythonPackageTomlFile(AsSuitePackageItem, TomlFile):
|
|
|
265
153
|
deps_arr.extend(to_keep)
|
|
266
154
|
toml_sort_string_array(deps_arr)
|
|
267
155
|
|
|
268
|
-
# Normalize
|
|
156
|
+
# Normalize attrs/cattrs dependencies
|
|
269
157
|
normalized = False
|
|
270
158
|
new_deps = []
|
|
271
159
|
for it in list(deps_arr):
|
|
272
160
|
val = toml_get_string_value(it).strip()
|
|
273
161
|
base = package_normalize_name(val)
|
|
274
|
-
if base == "
|
|
275
|
-
new_deps.append("
|
|
162
|
+
if base == "attrs":
|
|
163
|
+
new_deps.append("attrs>=23.1.0")
|
|
164
|
+
normalized = True
|
|
165
|
+
elif base == "cattrs":
|
|
166
|
+
new_deps.append("cattrs>=23.1.0")
|
|
276
167
|
normalized = True
|
|
277
168
|
else:
|
|
278
169
|
new_deps.append(it)
|
|
@@ -281,12 +172,15 @@ class PythonPackageTomlFile(AsSuitePackageItem, TomlFile):
|
|
|
281
172
|
deps_arr.extend(new_deps)
|
|
282
173
|
toml_sort_string_array(deps_arr)
|
|
283
174
|
|
|
284
|
-
# Ensure
|
|
175
|
+
# Ensure attrs and cattrs are present unless excluded
|
|
285
176
|
existing_norm = {
|
|
286
177
|
package_normalize_name(toml_get_string_value(it)) for it in list(deps_arr)
|
|
287
178
|
}
|
|
288
|
-
if "
|
|
289
|
-
deps_arr.append("
|
|
179
|
+
if "attrs" not in exclude_add and "attrs" not in existing_norm:
|
|
180
|
+
deps_arr.append("attrs>=23.1.0")
|
|
181
|
+
toml_sort_string_array(deps_arr)
|
|
182
|
+
if "cattrs" not in exclude_add and "cattrs" not in existing_norm:
|
|
183
|
+
deps_arr.append("cattrs>=23.1.0")
|
|
290
184
|
toml_sort_string_array(deps_arr)
|
|
291
185
|
|
|
292
186
|
# Ensure optional dev group contains pytest unless already in runtime deps
|
|
@@ -302,3 +196,108 @@ class PythonPackageTomlFile(AsSuitePackageItem, TomlFile):
|
|
|
302
196
|
toml_sort_string_array(dev_arr)
|
|
303
197
|
|
|
304
198
|
return dumps(content)
|
|
199
|
+
|
|
200
|
+
def find_package_workdir(self) -> CodeBaseWorkdir | None:
|
|
201
|
+
from wexample_wex_core.workdir.code_base_workdir import CodeBaseWorkdir
|
|
202
|
+
|
|
203
|
+
return self.find_closest(CodeBaseWorkdir)
|
|
204
|
+
|
|
205
|
+
def list_dependencies(
|
|
206
|
+
self, optional: bool = False, group: str = "dev"
|
|
207
|
+
) -> list[str]:
|
|
208
|
+
deps = self._get_deps_array(optional=optional, group=group)
|
|
209
|
+
return [str(x) for x in list(deps)]
|
|
210
|
+
|
|
211
|
+
def list_dependency_names(
|
|
212
|
+
self,
|
|
213
|
+
canonicalize_names: bool = True,
|
|
214
|
+
optional: bool = False,
|
|
215
|
+
group: str = "dev",
|
|
216
|
+
) -> list[str]:
|
|
217
|
+
"""Return dependency package names derived from list_dependencies().
|
|
218
|
+
|
|
219
|
+
If canonicalize_names is True, names are normalized using packaging's
|
|
220
|
+
canonicalize_name for robust comparisons (dash/underscore, case, etc.).
|
|
221
|
+
"""
|
|
222
|
+
from packaging.requirements import Requirement
|
|
223
|
+
from packaging.utils import canonicalize_name
|
|
224
|
+
|
|
225
|
+
names: list[str] = []
|
|
226
|
+
for spec in self.list_dependencies(optional=optional, group=group):
|
|
227
|
+
try:
|
|
228
|
+
name = Requirement(spec).name
|
|
229
|
+
names.append(canonicalize_name(name) if canonicalize_names else name)
|
|
230
|
+
except Exception:
|
|
231
|
+
# Skip unparsable entries when deriving names
|
|
232
|
+
continue
|
|
233
|
+
return names
|
|
234
|
+
|
|
235
|
+
def remove_dependency_by_name(
|
|
236
|
+
self, package_name: str, optional: bool = False, group: str = "dev"
|
|
237
|
+
) -> bool:
|
|
238
|
+
"""Remove all dependency entries that match the given package name.
|
|
239
|
+
|
|
240
|
+
The provided package_name can be raw; it will be canonicalized to ensure
|
|
241
|
+
consistent matching against entries parsed from list_dependencies().
|
|
242
|
+
"""
|
|
243
|
+
from packaging.requirements import Requirement
|
|
244
|
+
from packaging.utils import canonicalize_name
|
|
245
|
+
|
|
246
|
+
deps = self._get_deps_array(optional=optional, group=group)
|
|
247
|
+
|
|
248
|
+
target = canonicalize_name(package_name)
|
|
249
|
+
filtered: list[str] = []
|
|
250
|
+
for existing in list(deps):
|
|
251
|
+
try:
|
|
252
|
+
existing_name = canonicalize_name(Requirement(str(existing)).name)
|
|
253
|
+
except Exception:
|
|
254
|
+
# Keep unparsable entries untouched
|
|
255
|
+
filtered.append(existing)
|
|
256
|
+
continue
|
|
257
|
+
if existing_name != target:
|
|
258
|
+
filtered.append(existing)
|
|
259
|
+
|
|
260
|
+
if len(filtered) != len(deps):
|
|
261
|
+
deps.clear()
|
|
262
|
+
deps.extend(filtered)
|
|
263
|
+
return True
|
|
264
|
+
return False
|
|
265
|
+
|
|
266
|
+
def _dependencies_array(self):
|
|
267
|
+
"""Ensure and return project.dependencies as a multi-line TOML array."""
|
|
268
|
+
from wexample_filestate_python.helpers.toml import toml_ensure_array
|
|
269
|
+
|
|
270
|
+
project = self._project_table()
|
|
271
|
+
deps, _ = toml_ensure_array(project, "dependencies")
|
|
272
|
+
deps.multiline(True)
|
|
273
|
+
return deps
|
|
274
|
+
|
|
275
|
+
# --- Unified dependency accessors (runtime vs optional) ---
|
|
276
|
+
def _get_deps_array(self, optional: bool = False, group: str = "dev"):
|
|
277
|
+
"""Return TOML array for runtime deps or optional group (multiline)."""
|
|
278
|
+
return (
|
|
279
|
+
self._optional_group_array(group)
|
|
280
|
+
if optional
|
|
281
|
+
else self._dependencies_array()
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
def _optional_group_array(self, group: str):
|
|
285
|
+
"""Ensure and return project.optional-dependencies[group] as multi-line array."""
|
|
286
|
+
from wexample_filestate_python.helpers.toml import (
|
|
287
|
+
toml_ensure_array,
|
|
288
|
+
toml_ensure_table,
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
project = self._project_table()
|
|
292
|
+
opt, _ = toml_ensure_table(project, ["optional-dependencies"])
|
|
293
|
+
arr, _ = toml_ensure_array(opt, group)
|
|
294
|
+
arr.multiline(True)
|
|
295
|
+
return arr
|
|
296
|
+
|
|
297
|
+
def _project_table(self):
|
|
298
|
+
"""Ensure and return the [project] table."""
|
|
299
|
+
from wexample_filestate_python.helpers.toml import toml_ensure_table
|
|
300
|
+
|
|
301
|
+
doc = self.read_parsed()
|
|
302
|
+
project, _ = toml_ensure_table(doc, ["project"])
|
|
303
|
+
return project
|