wexample-wex-addon-dev-python 0.0.64__py3-none-any.whl → 0.1.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.
@@ -0,0 +1,8 @@
1
+ publish:
2
+ stage: deploy
3
+ image: python:3.12-slim
4
+ script:
5
+ - pip install pdm --quiet
6
+ - pdm publish --repository "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/pypi" --username gitlab-ci-token --password "${CI_JOB_TOKEN}"
7
+ rules:
8
+ - if: '$CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+$/'
@@ -27,10 +27,34 @@ class PythonPackageWorkdir(PythonWorkdir):
27
27
 
28
28
  def prepare_value(self, raw_value: DictConfig | None = None) -> DictConfig:
29
29
  from wexample_helpers.helpers.array import array_dict_get_by
30
+ from wexample_helpers.helpers.file import file_read
31
+ from wexample_helpers.helpers.module import module_get_path
32
+
33
+ import wexample_wex_addon_dev_python
30
34
 
31
35
  raw_value = super().prepare_value(raw_value=raw_value)
32
36
  children = raw_value.get("children")
33
37
 
38
+ # Add .gitlab-ci.yml for private GitLab registry packages.
39
+ # Both callbacks are evaluated after configure() completes, so base_name
40
+ # and runtime config are fully available at that point.
41
+ children.append(
42
+ {
43
+ "name": ".gitlab-ci.yml",
44
+ "type": DiskItemType.FILE,
45
+ "should_exist": lambda _target, _self=self: bool(
46
+ _self.search_app_or_suite_runtime_config(
47
+ "pdm.repository.url", default=None
48
+ ).get_str_or_none()
49
+ ),
50
+ "content": lambda _: file_read(
51
+ module_get_path(wexample_wex_addon_dev_python)
52
+ / "resources"
53
+ / "package_publish_gitlab.yml"
54
+ ),
55
+ }
56
+ )
57
+
34
58
  children.append(
35
59
  {
36
60
  "name": "examples",
@@ -139,6 +163,42 @@ class PythonPackageWorkdir(PythonWorkdir):
139
163
 
140
164
  return found
141
165
 
166
+ def _classify_version_bump(self, last_tag: str) -> str:
167
+ from wexample_helpers.const.types import (
168
+ UPGRADE_TYPE_INTERMEDIATE,
169
+ UPGRADE_TYPE_MAJOR,
170
+ UPGRADE_TYPE_MINOR,
171
+ )
172
+ from wexample_helpers_git.helpers.git import git_has_changes_since_tag
173
+
174
+ if not git_has_changes_since_tag(last_tag, "src", cwd=self.get_path()):
175
+ return UPGRADE_TYPE_MINOR
176
+
177
+ try:
178
+ import griffe
179
+
180
+ module_name = self.get_package_name().replace("-", "_")
181
+ repo_path = str(self.get_path())
182
+
183
+ previous = griffe.load_git(
184
+ module_name,
185
+ ref=last_tag,
186
+ repo=repo_path,
187
+ search_paths=["src"],
188
+ )
189
+ current = griffe.load(
190
+ module_name,
191
+ search_paths=[str(self.get_path() / "src")],
192
+ )
193
+
194
+ if list(griffe.find_breaking_changes(previous, current)):
195
+ return UPGRADE_TYPE_MAJOR
196
+
197
+ return UPGRADE_TYPE_INTERMEDIATE
198
+
199
+ except Exception:
200
+ return UPGRADE_TYPE_MAJOR
201
+
142
202
  def _collect_suite_dependencies(
143
203
  self,
144
204
  direct_dependencies: list[str],
@@ -180,6 +240,9 @@ class PythonPackageWorkdir(PythonWorkdir):
180
240
 
181
241
  return suite_deps_ordered
182
242
 
243
+ def _get_critical_directories(self) -> list[str]:
244
+ return ["src"]
245
+
183
246
  def _get_readme_content(self) -> ReadmeContentConfigValue | None:
184
247
  from wexample_wex_addon_dev_python.config_value.python_package_readme_config_value import (
185
248
  PythonPackageReadmeContentConfigValue,
@@ -187,7 +250,7 @@ class PythonPackageWorkdir(PythonWorkdir):
187
250
 
188
251
  return PythonPackageReadmeContentConfigValue(workdir=self)
189
252
 
190
- def _get_suite_package_workdir_class(self) -> type[FrameworkPackageSuiteWorkdir]:
253
+ def _get_suite_workdir_class(self) -> type[FrameworkPackageSuiteWorkdir]:
191
254
  from wexample_wex_addon_dev_python.workdir.python_packages_suite_workdir import (
192
255
  PythonPackagesSuiteWorkdir,
193
256
  )
@@ -291,47 +354,56 @@ class PythonPackageWorkdir(PythonWorkdir):
291
354
  def _publish(self, force: bool = False) -> None:
292
355
  from wexample_filestate_python.common.pipy_gateway import PipyGateway
293
356
  from wexample_helpers.helpers.shell import shell_run
357
+ from wexample_helpers_git.helpers.git import (
358
+ git_push_tag,
359
+ git_tag_annotated,
360
+ git_tag_exists,
361
+ )
294
362
 
295
- # Retrieve custom repository configuration
296
363
  repository_url = self.search_app_or_suite_runtime_config(
297
364
  "pdm.repository.url", default=None
298
- )
365
+ ).get_str_or_none()
366
+
367
+ package_name = self.get_package_name()
368
+ version = self.get_project_version()
369
+
370
+ # Private GitLab registry: trigger CI by pushing a git tag
371
+ if repository_url:
372
+ remote = self._get_deployment_remote_name()
373
+ tag = f"v{version}"
374
+ cwd = self.get_path()
375
+
376
+ if git_tag_exists(tag, cwd=cwd, inherit_stdio=False):
377
+ self.log(f"Tag {tag} already exists, skipping creation.")
378
+ else:
379
+ git_tag_annotated(tag, f"Release {tag}", cwd=cwd, inherit_stdio=True)
380
+
381
+ git_push_tag(tag, cwd=cwd, remote=remote, inherit_stdio=True)
382
+ return
383
+
384
+ # TODO: align public PyPI packages with the private registry approach — publish
385
+ # via a GitLab CI pipeline triggered by a git tag rather than running
386
+ # `pdm publish` locally.
387
+ # PyPI public: publish locally
388
+ client = PipyGateway(parent_io_handler=self)
389
+ if client.package_release_exists(package_name=package_name, version=version):
390
+ self.warning(
391
+ f'Trying to publish an existing release for package "{package_name}" version {version}'
392
+ )
393
+ if not force:
394
+ return
299
395
 
300
396
  repository_token = self.search_app_or_suite_runtime_config(
301
397
  "pdm.repository.token", default=None
302
- )
398
+ ).get_str_or_none()
303
399
 
304
400
  repository_username = self.search_app_or_suite_runtime_config(
305
401
  "pdm.repository.username", default="__token__"
306
- )
307
-
308
- package_name = self.get_package_name()
309
- version = self.get_project_version()
402
+ ).get_str_or_none()
310
403
 
311
- # Only check if package exists on PyPI if no custom repository is configured
312
- if not repository_url:
313
- client = PipyGateway(parent_io_handler=self)
314
- if client.package_release_exists(
315
- package_name=package_name, version=version
316
- ):
317
- self.warning(
318
- f'Trying to publish an existing release for package "{package_name}" version {version}'
319
- )
320
- if not force:
321
- return
322
-
323
- # Build the publish command
404
+ self.subtitle("Publishing to PyPI")
324
405
  publish_cmd = ["pdm", "publish"]
325
406
 
326
- # Add custom repository URL if provided
327
- if repository_url:
328
- publish_cmd += ["--repository", repository_url]
329
- self.subtitle(f"Publishing to custom repository: {repository_url}")
330
- else:
331
- self.subtitle("Publishing to PyPI")
332
-
333
- # Add credentials
334
- # Priority: custom token > env variable fallback
335
407
  username = repository_username or "__token__"
336
408
  password = repository_token or self.get_env_parameter_or_suite_fallback(
337
409
  "PIPY_TOKEN"
@@ -343,3 +415,70 @@ class PythonPackageWorkdir(PythonWorkdir):
343
415
  publish_cmd += ["--password", password]
344
416
 
345
417
  shell_run(publish_cmd, inherit_stdio=True, cwd=self.get_path())
418
+
419
+ def _wait_for_registry(self) -> None:
420
+ import time
421
+ import urllib.error
422
+ import urllib.request
423
+
424
+ repository_url = self.search_app_or_suite_runtime_config(
425
+ "pdm.repository.url", default=None
426
+ ).get_str_or_none()
427
+
428
+ if not repository_url:
429
+ return # PyPI public — published locally, no polling needed
430
+
431
+ token = self.search_app_or_suite_runtime_config(
432
+ "pdm.repository.token", default=None
433
+ ).get_str_or_none()
434
+
435
+ username = (
436
+ self.search_app_or_suite_runtime_config(
437
+ "pdm.repository.username", default="__token__"
438
+ ).get_str_or_none()
439
+ or "__token__"
440
+ )
441
+
442
+ package = self.get_package_name()
443
+ version = self.get_project_version()
444
+
445
+ base = repository_url.rstrip("/")
446
+ url = f"{base}/simple/{package}/"
447
+
448
+ max_attempts = 40
449
+ delay = 30.0
450
+
451
+ self.log(f"Waiting for {package}=={version} to appear on registry…")
452
+
453
+ for attempt in range(1, max_attempts + 1):
454
+ try:
455
+ req = urllib.request.Request(url)
456
+ if token:
457
+ import base64
458
+
459
+ credentials = base64.b64encode(
460
+ f"{username}:{token}".encode()
461
+ ).decode()
462
+ req.add_header("Authorization", f"Basic {credentials}")
463
+ with urllib.request.urlopen(req, timeout=10) as resp:
464
+ if resp.status == 200:
465
+ content = resp.read().decode()
466
+ if version in content:
467
+ self.success(f"{package}=={version} is available.")
468
+ return
469
+ except urllib.error.HTTPError as e:
470
+ if e.code != 404:
471
+ raise
472
+ except Exception:
473
+ pass
474
+
475
+ self.log(
476
+ f"Not yet available (attempt {attempt}/{max_attempts}), "
477
+ f"retrying in {int(delay)}s…"
478
+ )
479
+ time.sleep(delay)
480
+
481
+ raise RuntimeError(
482
+ f"Timed out waiting for {package}=={version} on registry after "
483
+ f"{max_attempts * int(delay) // 60} minutes."
484
+ )
@@ -243,15 +243,15 @@ class PythonWorkdir(CodeBaseWorkdir):
243
243
 
244
244
  return raw_value
245
245
 
246
- def save_dependency(self, package: CodeBaseWorkdir, version: str) -> bool:
247
- """Add or update a dependency with strict version."""
246
+ def save_dependency(
247
+ self, package: CodeBaseWorkdir, version: str, operator: str = "=="
248
+ ) -> bool:
248
249
  config = self.get_app_config_file()
249
- updated = config.add_dependency(package=package, version=version)
250
-
251
- if updated:
252
- config.write_parsed()
253
-
254
- return updated
250
+ return config.add_dependency_from_string(
251
+ package_name=package.get_package_name(),
252
+ version=version,
253
+ operator=operator,
254
+ )
255
255
 
256
256
  def save_project_config_file(self, config: StructuredData) -> None:
257
257
  """Save the project configuration to pyproject.toml."""
@@ -0,0 +1,177 @@
1
+ Metadata-Version: 2.1
2
+ Name: wexample-wex-addon-dev-python
3
+ Version: 0.1.0
4
+ Summary: Python dev addon for wex
5
+ Author-Email: weeger <contact@wexample.com>
6
+ License: MIT
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Operating System :: OS Independent
10
+ Project-URL: homepage, https://github.com/wexample/python-wex-dev-python
11
+ Requires-Python: >=3.10
12
+ Requires-Dist: attrs>=23.1.0
13
+ Requires-Dist: cattrs>=23.1.0
14
+ Requires-Dist: griffe>=2.0.2
15
+ Requires-Dist: networkx
16
+ Requires-Dist: pylint
17
+ Requires-Dist: pyright
18
+ Requires-Dist: wexample-filestate-python>=0.1.0
19
+ Requires-Dist: wexample-wex-addon-app>=1.0.0
20
+ Provides-Extra: dev
21
+ Requires-Dist: pytest; extra == "dev"
22
+ Requires-Dist: pytest-cov; extra == "dev"
23
+ Description-Content-Type: text/markdown
24
+
25
+ # wex_addon_dev_python
26
+
27
+ Version: 0.1.0
28
+
29
+ Python dev addon for wex
30
+
31
+ ## Table of Contents
32
+
33
+ - [Tests](#tests)
34
+ - [Suite Integration](#suite-integration)
35
+ - [Dependencies](#dependencies)
36
+ - [Versioning](#versioning)
37
+ - [License](#license)
38
+ - [Suite Integration](#suite-integration)
39
+ - [Suite Signature](#suite-signature)
40
+ - [Roadmap](#roadmap)
41
+ - [Status Compatibility](#status-compatibility)
42
+ - [Useful Links](#useful-links)
43
+ - [Migration Notes](#migration-notes)
44
+
45
+ ## Tests
46
+
47
+ This project uses `pytest` for testing and `pytest-cov` for code coverage analysis.
48
+
49
+ ### Installation
50
+
51
+ First, install the required testing dependencies:
52
+ ```bash
53
+ .venv/bin/python -m pip install pytest pytest-cov
54
+ ```
55
+
56
+ ### Basic Usage
57
+
58
+ Run all tests with coverage:
59
+ ```bash
60
+ .venv/bin/python -m pytest --cov --cov-report=html
61
+ ```
62
+
63
+ ### Common Commands
64
+ ```bash
65
+ # Run tests with coverage for a specific module
66
+ .venv/bin/python -m pytest --cov=your_module
67
+
68
+ # Show which lines are not covered
69
+ .venv/bin/python -m pytest --cov=your_module --cov-report=term-missing
70
+
71
+ # Generate an HTML coverage report
72
+ .venv/bin/python -m pytest --cov=your_module --cov-report=html
73
+
74
+ # Combine terminal and HTML reports
75
+ .venv/bin/python -m pytest --cov=your_module --cov-report=term-missing --cov-report=html
76
+
77
+ # Run specific test file with coverage
78
+ .venv/bin/python -m pytest tests/test_file.py --cov=your_module --cov-report=term-missing
79
+ ```
80
+
81
+ ### Viewing HTML Reports
82
+
83
+ After generating an HTML report, open `htmlcov/index.html` in your browser to view detailed line-by-line coverage information.
84
+
85
+ ### Coverage Threshold
86
+
87
+ To enforce a minimum coverage percentage:
88
+ ```bash
89
+ .venv/bin/python -m pytest --cov=your_module --cov-fail-under=80
90
+ ```
91
+
92
+ This will cause the test suite to fail if coverage drops below 80%.
93
+
94
+ ## Integration in the Suite
95
+
96
+ This package is part of the Wexample Suite — a collection of high-quality, modular tools designed to work seamlessly together across multiple languages and environments.
97
+
98
+ ### Related Packages
99
+
100
+ The suite includes packages for configuration management, file handling, prompts, and more. Each package can be used independently or as part of the integrated suite.
101
+
102
+ Visit the [Wexample Suite documentation](https://docs.wexample.com) for the complete package ecosystem.
103
+
104
+ ## Dependencies
105
+
106
+ - attrs: >=23.1.0
107
+ - cattrs: >=23.1.0
108
+ - griffe: >=2.0.2
109
+ - networkx:
110
+ - pylint:
111
+ - pyright:
112
+ - wexample-filestate-python: >=0.1.0
113
+ - wexample-wex-addon-app: >=1.0.0
114
+
115
+ ## Versioning & Compatibility Policy
116
+
117
+ Wexample packages follow **Semantic Versioning** (SemVer):
118
+
119
+ - **MAJOR**: Breaking changes
120
+ - **MINOR**: New features, backward compatible
121
+ - **PATCH**: Bug fixes, backward compatible
122
+
123
+ We maintain backward compatibility within major versions and provide clear migration guides for breaking changes.
124
+
125
+ ## License
126
+
127
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
128
+
129
+ Free to use in both personal and commercial projects.
130
+
131
+ ## Integration in the Suite
132
+
133
+ This package is part of the Wexample Suite — a collection of high-quality, modular tools designed to work seamlessly together across multiple languages and environments.
134
+
135
+ ### Related Packages
136
+
137
+ The suite includes packages for configuration management, file handling, prompts, and more. Each package can be used independently or as part of the integrated suite.
138
+
139
+ Visit the [Wexample Suite documentation](https://docs.wexample.com) for the complete package ecosystem.
140
+
141
+ # About us
142
+
143
+ [Wexample](https://wexample.com) stands as a cornerstone of the digital ecosystem — a collective of seasoned engineers, researchers, and creators driven by a relentless pursuit of technological excellence. More than a media platform, it has grown into a vibrant community where innovation meets craftsmanship, and where every line of code reflects a commitment to clarity, durability, and shared intelligence.
144
+
145
+ This packages suite embodies this spirit. Trusted by professionals and enthusiasts alike, it delivers a consistent, high-quality foundation for modern development — open, elegant, and battle-tested. Its reputation is built on years of collaboration, refinement, and rigorous attention to detail, making it a natural choice for those who demand both robustness and beauty in their tools.
146
+
147
+ Wexample cultivates a culture of mastery. Each package, each contribution carries the mark of a community that values precision, ethics, and innovation — a community proud to shape the future of digital craftsmanship.
148
+
149
+ ## Known Limitations & Roadmap
150
+
151
+ Current limitations and planned features are tracked in the GitHub issues.
152
+
153
+ See the [project roadmap](https://github.com/wexample/python-wex_addon_dev_python/issues) for upcoming features and improvements.
154
+
155
+ ## Status & Compatibility
156
+
157
+ **Maturity**: Production-ready
158
+
159
+ **Python Support**: >=3.10
160
+
161
+ **OS Support**: Linux, macOS, Windows
162
+
163
+ **Status**: Actively maintained
164
+
165
+ ## Useful Links
166
+
167
+ - **Homepage**: https://github.com/wexample/python-wex-addon-dev-python
168
+ - **Documentation**: [docs.wexample.com](https://docs.wexample.com)
169
+ - **Issue Tracker**: https://github.com/wexample/python-wex-addon-dev-python/issues
170
+ - **Discussions**: https://github.com/wexample/python-wex-addon-dev-python/discussions
171
+ - **PyPI**: [pypi.org/project/wex_addon_dev_python](https://pypi.org/project/wex_addon_dev_python/)
172
+
173
+ ## Migration Notes
174
+
175
+ When upgrading between major versions, refer to the migration guides in the documentation.
176
+
177
+ Breaking changes are clearly documented with upgrade paths and examples.
@@ -1,6 +1,6 @@
1
- wexample_wex_addon_dev_python-0.0.64.dist-info/METADATA,sha256=dy01AAsK4CFE28-yfpF9e4bps_j6NfoJLhTDLUZxv54,3128
2
- wexample_wex_addon_dev_python-0.0.64.dist-info/WHEEL,sha256=Wb0ASbVj8JvWHpOiIpPi7ucfIgJeCi__PzivviEAQFc,90
3
- wexample_wex_addon_dev_python-0.0.64.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
1
+ wexample_wex_addon_dev_python-0.1.0.dist-info/METADATA,sha256=Fc49_n_IPbkQvqXpmsXHCGnZL5WqcwMiuDcYJIOmIVQ,6259
2
+ wexample_wex_addon_dev_python-0.1.0.dist-info/WHEEL,sha256=Z36eTX6lG3PITRleSd5hAZHCcz52yg3c0JQVxKBbLW0,90
3
+ wexample_wex_addon_dev_python-0.1.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,11 +36,12 @@ 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/package_publish_gitlab.yml,sha256=WVMj-DeFedQak5s5FraEnM1Rx1-ut4KgPodvAVv25ZM,304
39
40
  wexample_wex_addon_dev_python/resources/readme_templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
41
  wexample_wex_addon_dev_python/resources/readme_templates/tests.md.j2,sha256=tKLcDwx7jhQkryXIxWr12AK-hKEaP6Rusu2MrluiABs,1289
41
42
  wexample_wex_addon_dev_python/workdir/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
42
43
  wexample_wex_addon_dev_python/workdir/__pycache__/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
43
- wexample_wex_addon_dev_python/workdir/python_package_workdir.py,sha256=4jMZRHYGpBg5FqJuYK5j1A9VS7X4spIlDD-MgHKz7b4,12750
44
+ wexample_wex_addon_dev_python/workdir/python_package_workdir.py,sha256=Fd2A7Qpsy_jstE4zj6AD4PPbMSOGkoBibhCFLDAZrXo,17637
44
45
  wexample_wex_addon_dev_python/workdir/python_packages_suite_workdir.py,sha256=ICHHewLpsXiheYzGDEahphBryH98ZVezWzSAy6A5w5I,2874
45
- wexample_wex_addon_dev_python/workdir/python_workdir.py,sha256=jChU8h4fj5NmZxdrI2SP5c6erlmf5WTG_FKk_pjL66w,18084
46
- wexample_wex_addon_dev_python-0.0.64.dist-info/RECORD,,
46
+ wexample_wex_addon_dev_python/workdir/python_workdir.py,sha256=tx6UcaBHnrq9khQ6ndG14BzFPNOlqhl-626iNoL6T1o,18078
47
+ wexample_wex_addon_dev_python-0.1.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: pdm-backend (2.4.7)
2
+ Generator: pdm-backend (2.4.8)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,110 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: wexample-wex-addon-dev-python
3
- Version: 0.0.64
4
- Summary: Python dev addon for wex
5
- Author-Email: weeger <contact@wexample.com>
6
- License: MIT
7
- Classifier: Programming Language :: Python :: 3
8
- Classifier: License :: OSI Approved :: MIT License
9
- Classifier: Operating System :: OS Independent
10
- Project-URL: homepage, https://github.com/wexample/python-wex-dev-python
11
- Requires-Python: >=3.10
12
- Requires-Dist: attrs>=23.1.0
13
- Requires-Dist: cattrs>=23.1.0
14
- Requires-Dist: networkx
15
- Requires-Dist: pylint
16
- Requires-Dist: pyright
17
- Requires-Dist: wexample-filestate-python==0.0.59
18
- Requires-Dist: wexample-wex-addon-app==0.0.56
19
- Provides-Extra: dev
20
- Requires-Dist: pytest; extra == "dev"
21
- Requires-Dist: pytest-cov; extra == "dev"
22
- Description-Content-Type: text/markdown
23
-
24
- # wexample-wex-addon-dev-python
25
-
26
- Version: 0.0.64
27
-
28
- Python dev addon for wex
29
-
30
- ## Table of Contents
31
-
32
- - [Status Compatibility](#status-compatibility)
33
- - [Tests](#tests)
34
- - [Roadmap](#roadmap)
35
- - [Useful Links](#useful-links)
36
-
37
-
38
- ## Status & Compatibility
39
-
40
- **Maturity**: Production-ready
41
-
42
- **Python Support**: >=3.10
43
-
44
- **OS Support**: Linux, macOS, Windows
45
-
46
- **Status**: Actively maintained
47
-
48
- ## Tests
49
-
50
- This project uses `pytest` for testing and `pytest-cov` for code coverage analysis.
51
-
52
- ### Installation
53
-
54
- First, install the required testing dependencies:
55
- ```bash
56
- .venv/bin/python -m pip install pytest pytest-cov
57
- ```
58
-
59
- ### Basic Usage
60
-
61
- Run all tests with coverage:
62
- ```bash
63
- .venv/bin/python -m pytest --cov --cov-report=html
64
- ```
65
-
66
- ### Common Commands
67
- ```bash
68
- # Run tests with coverage for a specific module
69
- .venv/bin/python -m pytest --cov=your_module
70
-
71
- # Show which lines are not covered
72
- .venv/bin/python -m pytest --cov=your_module --cov-report=term-missing
73
-
74
- # Generate an HTML coverage report
75
- .venv/bin/python -m pytest --cov=your_module --cov-report=html
76
-
77
- # Combine terminal and HTML reports
78
- .venv/bin/python -m pytest --cov=your_module --cov-report=term-missing --cov-report=html
79
-
80
- # Run specific test file with coverage
81
- .venv/bin/python -m pytest tests/test_file.py --cov=your_module --cov-report=term-missing
82
- ```
83
-
84
- ### Viewing HTML Reports
85
-
86
- After generating an HTML report, open `htmlcov/index.html` in your browser to view detailed line-by-line coverage information.
87
-
88
- ### Coverage Threshold
89
-
90
- To enforce a minimum coverage percentage:
91
- ```bash
92
- .venv/bin/python -m pytest --cov=your_module --cov-fail-under=80
93
- ```
94
-
95
- This will cause the test suite to fail if coverage drops below 80%.
96
-
97
- ## Known Limitations & Roadmap
98
-
99
- Current limitations and planned features are tracked in the GitHub issues.
100
-
101
- See the [project roadmap](https://github.com/wexample/python-wex_addon_dev_python/issues) for upcoming features and improvements.
102
-
103
- ## Useful Links
104
-
105
- - **Homepage**: https://github.com/wexample/python-wex-addon-dev-python
106
- - **Documentation**: [docs.wexample.com](https://docs.wexample.com)
107
- - **Issue Tracker**: https://github.com/wexample/python-wex-addon-dev-python/issues
108
- - **Discussions**: https://github.com/wexample/python-wex-addon-dev-python/discussions
109
- - **PyPI**: [pypi.org/project/wexample-wex-addon-dev-python](https://pypi.org/project/wexample-wex-addon-dev-python/)
110
-