wexample-wex-addon-dev-python 0.1.1__py3-none-any.whl → 0.2.0__py3-none-any.whl
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/resources/docker/Dockerfile.python-profiling +11 -0
- wexample_wex_addon_dev_python/resources/docker/__init__.py +0 -0
- wexample_wex_addon_dev_python/workdir/mixin/__init__.py +0 -0
- wexample_wex_addon_dev_python/workdir/mixin/with_profiling_python_workdir_mixin.py +93 -0
- wexample_wex_addon_dev_python/workdir/python_workdir.py +4 -1
- {wexample_wex_addon_dev_python-0.1.1.dist-info → wexample_wex_addon_dev_python-0.2.0.dist-info}/METADATA +4 -4
- {wexample_wex_addon_dev_python-0.1.1.dist-info → wexample_wex_addon_dev_python-0.2.0.dist-info}/RECORD +9 -5
- {wexample_wex_addon_dev_python-0.1.1.dist-info → wexample_wex_addon_dev_python-0.2.0.dist-info}/WHEEL +0 -0
- {wexample_wex_addon_dev_python-0.1.1.dist-info → wexample_wex_addon_dev_python-0.2.0.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
FROM python:3.12-slim
|
|
2
|
+
|
|
3
|
+
RUN pip install --no-cache-dir pytest pytest-benchmark
|
|
4
|
+
|
|
5
|
+
# The container runs as the host user (arbitrary UID/GID via docker run --user).
|
|
6
|
+
# Set HOME to /tmp so pip and other tools have a writable directory.
|
|
7
|
+
ENV HOME=/tmp
|
|
8
|
+
|
|
9
|
+
WORKDIR /app
|
|
10
|
+
|
|
11
|
+
CMD ["tail", "-f", "/dev/null"]
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from wexample_wex_addon_app.workdir.mixin.abstract_profiling_workdir_mixin import (
|
|
4
|
+
AbstractProfilingWorkdirMixin,
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class WithProfilingPythonWorkdirMixin(AbstractProfilingWorkdirMixin):
|
|
9
|
+
"""Mixin that adds pytest-benchmark profiling capability to a Python workdir.
|
|
10
|
+
|
|
11
|
+
Runs benchmarks in the workdir's local venv so that local (unpublished)
|
|
12
|
+
dependencies are available — no Docker required.
|
|
13
|
+
|
|
14
|
+
Requires the workdir to have benchmark tests written with pytest-benchmark:
|
|
15
|
+
def test_my_function(benchmark):
|
|
16
|
+
benchmark(my_function, ...)
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
_BENCH_OUTPUT_FILENAME = ".wex_bench.json"
|
|
20
|
+
|
|
21
|
+
def run_profiling(self) -> dict:
|
|
22
|
+
import json
|
|
23
|
+
import subprocess
|
|
24
|
+
|
|
25
|
+
bench_output_path = self.get_path() / self._BENCH_OUTPUT_FILENAME
|
|
26
|
+
python = self._get_profiling_python()
|
|
27
|
+
|
|
28
|
+
bench_result = subprocess.run(
|
|
29
|
+
[
|
|
30
|
+
str(python),
|
|
31
|
+
"-m",
|
|
32
|
+
"pytest",
|
|
33
|
+
self.get_benchmark_dir(),
|
|
34
|
+
"--benchmark-only",
|
|
35
|
+
f"--benchmark-json={bench_output_path}",
|
|
36
|
+
"-q",
|
|
37
|
+
],
|
|
38
|
+
capture_output=True,
|
|
39
|
+
text=True,
|
|
40
|
+
cwd=str(self.get_path()),
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
if not bench_output_path.exists():
|
|
44
|
+
return {
|
|
45
|
+
"error": (
|
|
46
|
+
"No benchmark output produced.\n"
|
|
47
|
+
f"pytest stdout:\n{bench_result.stdout}\n"
|
|
48
|
+
f"pytest stderr:\n{bench_result.stderr}"
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
try:
|
|
53
|
+
content = bench_output_path.read_text().strip()
|
|
54
|
+
if not content:
|
|
55
|
+
return {
|
|
56
|
+
"error": (
|
|
57
|
+
"No benchmark tests found. Add tests using pytest-benchmark:\n"
|
|
58
|
+
" def test_my_function(benchmark):\n"
|
|
59
|
+
" benchmark(my_function, ...)"
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
raw = json.loads(content)
|
|
63
|
+
finally:
|
|
64
|
+
bench_output_path.unlink(missing_ok=True)
|
|
65
|
+
|
|
66
|
+
return self._parse_profiling_output(raw)
|
|
67
|
+
|
|
68
|
+
def _get_profiling_python(self) -> Path:
|
|
69
|
+
import sys
|
|
70
|
+
from pathlib import Path
|
|
71
|
+
|
|
72
|
+
return Path(sys.executable)
|
|
73
|
+
|
|
74
|
+
def _parse_profiling_output(self, raw: dict) -> dict:
|
|
75
|
+
entries = []
|
|
76
|
+
for bench in raw.get("benchmarks", []):
|
|
77
|
+
stats = bench.get("stats", {})
|
|
78
|
+
entries.append(
|
|
79
|
+
{
|
|
80
|
+
"name": bench.get("name"),
|
|
81
|
+
"min_ms": round(stats.get("min", 0) * 1000, 3),
|
|
82
|
+
"mean_ms": round(stats.get("mean", 0) * 1000, 3),
|
|
83
|
+
"median_ms": round(stats.get("median", 0) * 1000, 3),
|
|
84
|
+
"max_ms": round(stats.get("max", 0) * 1000, 3),
|
|
85
|
+
"rounds": stats.get("rounds", 0),
|
|
86
|
+
}
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
"language": "python",
|
|
91
|
+
"tool": "pytest-benchmark",
|
|
92
|
+
"entries": entries,
|
|
93
|
+
}
|
|
@@ -25,6 +25,9 @@ from wexample_wex_addon_dev_python.const.python import (
|
|
|
25
25
|
PYTHON_PYTEST_COV_REPORT_DIR,
|
|
26
26
|
)
|
|
27
27
|
from wexample_wex_addon_dev_python.file.python_app_iml_file import PythonAppImlFile
|
|
28
|
+
from wexample_wex_addon_dev_python.workdir.mixin.with_profiling_python_workdir_mixin import (
|
|
29
|
+
WithProfilingPythonWorkdirMixin,
|
|
30
|
+
)
|
|
28
31
|
|
|
29
32
|
if TYPE_CHECKING:
|
|
30
33
|
from wexample_config.const.types import DictConfig
|
|
@@ -44,7 +47,7 @@ if TYPE_CHECKING:
|
|
|
44
47
|
)
|
|
45
48
|
|
|
46
49
|
|
|
47
|
-
class PythonWorkdir(CodeBaseWorkdir):
|
|
50
|
+
class PythonWorkdir(WithProfilingPythonWorkdirMixin, CodeBaseWorkdir):
|
|
48
51
|
def app_install(self, env: str | None = None, force: bool = False) -> Path:
|
|
49
52
|
from wexample_wex_addon_app.helpers.python import (
|
|
50
53
|
python_ensure_pip_or_fail,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: wexample-wex-addon-dev-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Python dev addon for wex
|
|
5
5
|
Author-Email: weeger <contact@wexample.com>
|
|
6
6
|
License: MIT
|
|
@@ -16,7 +16,7 @@ Requires-Dist: networkx
|
|
|
16
16
|
Requires-Dist: pylint
|
|
17
17
|
Requires-Dist: pyright
|
|
18
18
|
Requires-Dist: wexample-filestate-python>=0.1.0
|
|
19
|
-
Requires-Dist: wexample-wex-addon-app>=1.
|
|
19
|
+
Requires-Dist: wexample-wex-addon-app>=1.2.0
|
|
20
20
|
Provides-Extra: dev
|
|
21
21
|
Requires-Dist: pytest; extra == "dev"
|
|
22
22
|
Requires-Dist: pytest-cov; extra == "dev"
|
|
@@ -24,7 +24,7 @@ Description-Content-Type: text/markdown
|
|
|
24
24
|
|
|
25
25
|
# wex_addon_dev_python
|
|
26
26
|
|
|
27
|
-
Version: 0.
|
|
27
|
+
Version: 0.2.0
|
|
28
28
|
|
|
29
29
|
Python dev addon for wex
|
|
30
30
|
|
|
@@ -110,7 +110,7 @@ Visit the [Wexample Suite documentation](https://docs.wexample.com) for the comp
|
|
|
110
110
|
- pylint:
|
|
111
111
|
- pyright:
|
|
112
112
|
- wexample-filestate-python: >=0.1.0
|
|
113
|
-
- wexample-wex-addon-app: >=1.
|
|
113
|
+
- wexample-wex-addon-app: >=1.2.0
|
|
114
114
|
|
|
115
115
|
## Versioning & Compatibility Policy
|
|
116
116
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
wexample_wex_addon_dev_python-0.
|
|
2
|
-
wexample_wex_addon_dev_python-0.
|
|
3
|
-
wexample_wex_addon_dev_python-0.
|
|
1
|
+
wexample_wex_addon_dev_python-0.2.0.dist-info/METADATA,sha256=-caaJ6PC3xVChhXy7hkL-utlQSiTxULrqBXAnVcir7c,6259
|
|
2
|
+
wexample_wex_addon_dev_python-0.2.0.dist-info/WHEEL,sha256=Z36eTX6lG3PITRleSd5hAZHCcz52yg3c0JQVxKBbLW0,90
|
|
3
|
+
wexample_wex_addon_dev_python-0.2.0.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
|
|
4
4
|
wexample_wex_addon_dev_python/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
wexample_wex_addon_dev_python/__pycache__/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
6
|
wexample_wex_addon_dev_python/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -36,12 +36,16 @@ wexample_wex_addon_dev_python/middleware/each_python_file_middleware.py,sha256=U
|
|
|
36
36
|
wexample_wex_addon_dev_python/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
37
37
|
wexample_wex_addon_dev_python/python_addon_manager.py,sha256=Mmr9F5lOS2gbb8JTB4-vTri4Qn5Cd2Jukjk7uiTr1Hs,582
|
|
38
38
|
wexample_wex_addon_dev_python/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
39
|
+
wexample_wex_addon_dev_python/resources/docker/Dockerfile.python-profiling,sha256=5ujzXfWNN2nv8qQzCLel6dlOwLQ1XhIGZuqplCNB_vQ,290
|
|
40
|
+
wexample_wex_addon_dev_python/resources/docker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
39
41
|
wexample_wex_addon_dev_python/resources/package_publish_gitlab.yml,sha256=WVMj-DeFedQak5s5FraEnM1Rx1-ut4KgPodvAVv25ZM,304
|
|
40
42
|
wexample_wex_addon_dev_python/resources/readme_templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
41
43
|
wexample_wex_addon_dev_python/resources/readme_templates/tests.md.j2,sha256=tKLcDwx7jhQkryXIxWr12AK-hKEaP6Rusu2MrluiABs,1289
|
|
42
44
|
wexample_wex_addon_dev_python/workdir/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
43
45
|
wexample_wex_addon_dev_python/workdir/__pycache__/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
46
|
+
wexample_wex_addon_dev_python/workdir/mixin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
47
|
+
wexample_wex_addon_dev_python/workdir/mixin/with_profiling_python_workdir_mixin.py,sha256=rWf_AMq4YM_vvKYZiXyhFeAz2xg0KMt_u-1FJACtvjc,3042
|
|
44
48
|
wexample_wex_addon_dev_python/workdir/python_package_workdir.py,sha256=Fd2A7Qpsy_jstE4zj6AD4PPbMSOGkoBibhCFLDAZrXo,17637
|
|
45
49
|
wexample_wex_addon_dev_python/workdir/python_packages_suite_workdir.py,sha256=ICHHewLpsXiheYzGDEahphBryH98ZVezWzSAy6A5w5I,2874
|
|
46
|
-
wexample_wex_addon_dev_python/workdir/python_workdir.py,sha256=
|
|
47
|
-
wexample_wex_addon_dev_python-0.
|
|
50
|
+
wexample_wex_addon_dev_python/workdir/python_workdir.py,sha256=V6RB-Qm7HM5k_1qc7yL6a1y4EKjBsvy4V5VkXhcR37c,18244
|
|
51
|
+
wexample_wex_addon_dev_python-0.2.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|