blakemere-wraptools 0.1.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.
Files changed (132) hide show
  1. blakemere_wraptools-0.1.0/.external-links-ignore +9 -0
  2. blakemere_wraptools-0.1.0/.github/ISSUE_TEMPLATE/bug-report.yml +30 -0
  3. blakemere_wraptools-0.1.0/.github/ISSUE_TEMPLATE/docs-or-release-question.yml +26 -0
  4. blakemere_wraptools-0.1.0/.github/pull_request_template.md +22 -0
  5. blakemere_wraptools-0.1.0/.github/workflows/ci.yml +61 -0
  6. blakemere_wraptools-0.1.0/.github/workflows/publish.yml +112 -0
  7. blakemere_wraptools-0.1.0/.gitignore +22 -0
  8. blakemere_wraptools-0.1.0/.pre-commit-config.yaml +16 -0
  9. blakemere_wraptools-0.1.0/CHANGELOG.md +104 -0
  10. blakemere_wraptools-0.1.0/CONTRIBUTING.md +163 -0
  11. blakemere_wraptools-0.1.0/DOGFOOD.md +51 -0
  12. blakemere_wraptools-0.1.0/GOAL.md +87 -0
  13. blakemere_wraptools-0.1.0/LICENSE +21 -0
  14. blakemere_wraptools-0.1.0/PKG-INFO +355 -0
  15. blakemere_wraptools-0.1.0/PLAN.md +164 -0
  16. blakemere_wraptools-0.1.0/README.md +322 -0
  17. blakemere_wraptools-0.1.0/RELEASE.md +235 -0
  18. blakemere_wraptools-0.1.0/TODO.md +894 -0
  19. blakemere_wraptools-0.1.0/docs/API_DESIGN.md +62 -0
  20. blakemere_wraptools-0.1.0/docs/API_REFERENCE.md +161 -0
  21. blakemere_wraptools-0.1.0/docs/PUBLIC_API.md +283 -0
  22. blakemere_wraptools-0.1.0/docs/__init__.py +0 -0
  23. blakemere_wraptools-0.1.0/docs/cache_result.md +365 -0
  24. blakemere_wraptools-0.1.0/docs/circuit_breaker.md +90 -0
  25. blakemere_wraptools-0.1.0/docs/composition.md +163 -0
  26. blakemere_wraptools-0.1.0/docs/deprecated.md +130 -0
  27. blakemere_wraptools-0.1.0/docs/disk_cache_backend.md +764 -0
  28. blakemere_wraptools-0.1.0/docs/docs_index_exemptions.md +13 -0
  29. blakemere_wraptools-0.1.0/docs/docs_site_plan.md +34 -0
  30. blakemere_wraptools-0.1.0/docs/examples/__init__.py +0 -0
  31. blakemere_wraptools-0.1.0/docs/examples/circuit_breaker_examples.py +80 -0
  32. blakemere_wraptools-0.1.0/docs/examples/cli_examples.py +60 -0
  33. blakemere_wraptools-0.1.0/docs/examples/composition_examples.py +125 -0
  34. blakemere_wraptools-0.1.0/docs/examples/deprecated_examples.py +36 -0
  35. blakemere_wraptools-0.1.0/docs/examples/disk_cache_backend_examples.py +277 -0
  36. blakemere_wraptools-0.1.0/docs/examples/log_calls_examples.py +71 -0
  37. blakemere_wraptools-0.1.0/docs/examples/measure_time_examples.py +66 -0
  38. blakemere_wraptools-0.1.0/docs/examples/observability_integration_examples.py +164 -0
  39. blakemere_wraptools-0.1.0/docs/examples/public_exception_examples.py +134 -0
  40. blakemere_wraptools-0.1.0/docs/examples/rate_limit_examples.py +66 -0
  41. blakemere_wraptools-0.1.0/docs/examples/readme_examples.py +192 -0
  42. blakemere_wraptools-0.1.0/docs/examples/require_env_examples.py +60 -0
  43. blakemere_wraptools-0.1.0/docs/examples/retry_examples.py +71 -0
  44. blakemere_wraptools-0.1.0/docs/examples/retry_idempotency_examples.py +54 -0
  45. blakemere_wraptools-0.1.0/docs/examples/timeout_examples.py +49 -0
  46. blakemere_wraptools-0.1.0/docs/examples/validate_types_examples.py +50 -0
  47. blakemere_wraptools-0.1.0/docs/examples/web_framework_examples.py +98 -0
  48. blakemere_wraptools-0.1.0/docs/exceptions.md +172 -0
  49. blakemere_wraptools-0.1.0/docs/future_extension_decisions.md +34 -0
  50. blakemere_wraptools-0.1.0/docs/index.md +66 -0
  51. blakemere_wraptools-0.1.0/docs/log_calls.md +73 -0
  52. blakemere_wraptools-0.1.0/docs/markdown_anchor_policy.md +12 -0
  53. blakemere_wraptools-0.1.0/docs/measure_time.md +85 -0
  54. blakemere_wraptools-0.1.0/docs/observability_integrations.md +26 -0
  55. blakemere_wraptools-0.1.0/docs/quality_gates.md +64 -0
  56. blakemere_wraptools-0.1.0/docs/rate_limit.md +83 -0
  57. blakemere_wraptools-0.1.0/docs/redis_backend_design.md +115 -0
  58. blakemere_wraptools-0.1.0/docs/release_note_template.md +19 -0
  59. blakemere_wraptools-0.1.0/docs/require_env.md +55 -0
  60. blakemere_wraptools-0.1.0/docs/retry.md +89 -0
  61. blakemere_wraptools-0.1.0/docs/security_hardening.md +117 -0
  62. blakemere_wraptools-0.1.0/docs/sync_timeout_decision.md +23 -0
  63. blakemere_wraptools-0.1.0/docs/timeout.md +81 -0
  64. blakemere_wraptools-0.1.0/docs/validate_types.md +59 -0
  65. blakemere_wraptools-0.1.0/docs/web_frameworks.md +38 -0
  66. blakemere_wraptools-0.1.0/docs/writing_style_audit.md +156 -0
  67. blakemere_wraptools-0.1.0/dogfood/service_client.py +125 -0
  68. blakemere_wraptools-0.1.0/pyproject.toml +104 -0
  69. blakemere_wraptools-0.1.0/scripts/benchmark_decorators.py +91 -0
  70. blakemere_wraptools-0.1.0/scripts/check_docs_example_index.py +45 -0
  71. blakemere_wraptools-0.1.0/scripts/check_external_links.py +405 -0
  72. blakemere_wraptools-0.1.0/scripts/check_package_name_availability.py +70 -0
  73. blakemere_wraptools-0.1.0/scripts/coverage_summary.py +28 -0
  74. blakemere_wraptools-0.1.0/scripts/docs-policy.sh +5 -0
  75. blakemere_wraptools-0.1.0/scripts/dogfood_external_project.py +112 -0
  76. blakemere_wraptools-0.1.0/scripts/dogfood_local_wheel.py +51 -0
  77. blakemere_wraptools-0.1.0/scripts/smoke_examples.py +34 -0
  78. blakemere_wraptools-0.1.0/scripts/smoke_imports.py +27 -0
  79. blakemere_wraptools-0.1.0/scripts/smoke_wheel_install.py +46 -0
  80. blakemere_wraptools-0.1.0/scripts/stress_disk_cache_concurrency.py +63 -0
  81. blakemere_wraptools-0.1.0/src/pydecorators/__init__.py +98 -0
  82. blakemere_wraptools-0.1.0/src/pydecorators/_core.py +70 -0
  83. blakemere_wraptools-0.1.0/src/pydecorators/_typing.py +30 -0
  84. blakemere_wraptools-0.1.0/src/pydecorators/cache_result.py +1225 -0
  85. blakemere_wraptools-0.1.0/src/pydecorators/circuit_breaker.py +171 -0
  86. blakemere_wraptools-0.1.0/src/pydecorators/deprecated.py +169 -0
  87. blakemere_wraptools-0.1.0/src/pydecorators/exceptions.py +47 -0
  88. blakemere_wraptools-0.1.0/src/pydecorators/log_calls.py +304 -0
  89. blakemere_wraptools-0.1.0/src/pydecorators/measure_time.py +183 -0
  90. blakemere_wraptools-0.1.0/src/pydecorators/py.typed +0 -0
  91. blakemere_wraptools-0.1.0/src/pydecorators/rate_limit.py +138 -0
  92. blakemere_wraptools-0.1.0/src/pydecorators/redis_backend.py +250 -0
  93. blakemere_wraptools-0.1.0/src/pydecorators/require_env.py +133 -0
  94. blakemere_wraptools-0.1.0/src/pydecorators/retry.py +207 -0
  95. blakemere_wraptools-0.1.0/src/pydecorators/timeout.py +64 -0
  96. blakemere_wraptools-0.1.0/src/pydecorators/validate_types.py +162 -0
  97. blakemere_wraptools-0.1.0/tests/__init__.py +0 -0
  98. blakemere_wraptools-0.1.0/tests/docs_example_policy_helpers.py +73 -0
  99. blakemere_wraptools-0.1.0/tests/docs_policy_helpers.py +86 -0
  100. blakemere_wraptools-0.1.0/tests/test_benchmark_script.py +41 -0
  101. blakemere_wraptools-0.1.0/tests/test_cache_backend_conformance.py +214 -0
  102. blakemere_wraptools-0.1.0/tests/test_cache_directory.py +44 -0
  103. blakemere_wraptools-0.1.0/tests/test_cache_result.py +720 -0
  104. blakemere_wraptools-0.1.0/tests/test_cache_result_design_docs.py +84 -0
  105. blakemere_wraptools-0.1.0/tests/test_cache_result_support.py +170 -0
  106. blakemere_wraptools-0.1.0/tests/test_circuit_breaker.py +160 -0
  107. blakemere_wraptools-0.1.0/tests/test_core.py +99 -0
  108. blakemere_wraptools-0.1.0/tests/test_deprecated.py +130 -0
  109. blakemere_wraptools-0.1.0/tests/test_disk_cache_backend.py +868 -0
  110. blakemere_wraptools-0.1.0/tests/test_disk_cache_backend_design_docs.py +400 -0
  111. blakemere_wraptools-0.1.0/tests/test_docs_examples.py +406 -0
  112. blakemere_wraptools-0.1.0/tests/test_docs_policy.py +1226 -0
  113. blakemere_wraptools-0.1.0/tests/test_dogfood_harness.py +35 -0
  114. blakemere_wraptools-0.1.0/tests/test_import.py +5 -0
  115. blakemere_wraptools-0.1.0/tests/test_log_calls.py +177 -0
  116. blakemere_wraptools-0.1.0/tests/test_measure_time.py +163 -0
  117. blakemere_wraptools-0.1.0/tests/test_package_name_availability.py +65 -0
  118. blakemere_wraptools-0.1.0/tests/test_project_metadata.py +44 -0
  119. blakemere_wraptools-0.1.0/tests/test_public_api.py +38 -0
  120. blakemere_wraptools-0.1.0/tests/test_public_api_policy.py +22 -0
  121. blakemere_wraptools-0.1.0/tests/test_public_exception_policy.py +60 -0
  122. blakemere_wraptools-0.1.0/tests/test_quality_gates.py +124 -0
  123. blakemere_wraptools-0.1.0/tests/test_rate_limit.py +183 -0
  124. blakemere_wraptools-0.1.0/tests/test_redis_backend.py +141 -0
  125. blakemere_wraptools-0.1.0/tests/test_redis_optional_dependency.py +21 -0
  126. blakemere_wraptools-0.1.0/tests/test_release_checklist.py +125 -0
  127. blakemere_wraptools-0.1.0/tests/test_release_workflow.py +40 -0
  128. blakemere_wraptools-0.1.0/tests/test_require_env.py +148 -0
  129. blakemere_wraptools-0.1.0/tests/test_retry.py +248 -0
  130. blakemere_wraptools-0.1.0/tests/test_timeout.py +90 -0
  131. blakemere_wraptools-0.1.0/tests/test_validate_types.py +126 -0
  132. blakemere_wraptools-0.1.0/tests/test_version.py +10 -0
@@ -0,0 +1,9 @@
1
+ # External HTTP(S) links intentionally skipped by scripts/check_external_links.py.
2
+ #
3
+ # Use one fnmatch-style URL pattern per line, for example:
4
+ # https://status.example.com/*
5
+ #
6
+ # Keep this file small and explain any real ignores in the commit that adds them.
7
+ # Every real ignore pattern must be preceded by a reason comment.
8
+ # Ignore patterns must use http:// or https:// and include a host.
9
+ # Ignore patterns must match at least one current external docs link.
@@ -0,0 +1,30 @@
1
+ name: Bug report
2
+ description: Report behavior that looks incorrect.
3
+ title: "[bug]: "
4
+ labels: [bug]
5
+ body:
6
+ - type: textarea
7
+ id: summary
8
+ attributes:
9
+ label: Summary
10
+ description: What happened, and what did you expect instead?
11
+ validations:
12
+ required: true
13
+ - type: textarea
14
+ id: reproduce
15
+ attributes:
16
+ label: Minimal reproduction
17
+ description: Include a small code sample or command sequence.
18
+ render: python
19
+ validations:
20
+ required: true
21
+ - type: input
22
+ id: version
23
+ attributes:
24
+ label: Package version
25
+ placeholder: pydecorators 0.1.0
26
+ - type: input
27
+ id: python
28
+ attributes:
29
+ label: Python version
30
+ placeholder: Python 3.12
@@ -0,0 +1,26 @@
1
+ name: Docs or release question
2
+ description: Ask about documentation, examples, packaging, or release checks.
3
+ title: "[docs/release]: "
4
+ labels: [documentation]
5
+ body:
6
+ - type: textarea
7
+ id: question
8
+ attributes:
9
+ label: Question
10
+ description: What are you trying to understand or verify?
11
+ validations:
12
+ required: true
13
+ - type: textarea
14
+ id: context
15
+ attributes:
16
+ label: Context
17
+ description: Link the page, command, package version, or release step involved.
18
+ validations:
19
+ required: true
20
+ - type: checkboxes
21
+ id: checks
22
+ attributes:
23
+ label: Before filing
24
+ options:
25
+ - label: I checked README.md and docs/index.md.
26
+ - label: I included the command output or page link when relevant.
@@ -0,0 +1,22 @@
1
+ ## Summary
2
+
3
+ -
4
+
5
+ ## Checks
6
+
7
+ - [ ] Ran the smallest meaningful local verification gate, or explained why not.
8
+ - [ ] Updated `TODO.md` for completed or newly discovered work.
9
+ - [ ] Added or updated tests for behavior changes.
10
+
11
+ ## Documentation checks
12
+
13
+ - [ ] Updated `docs/index.md` if a top-level docs page or executable example was added, removed, or renamed.
14
+ - [ ] Updated executable docs examples and `tests/test_docs_examples.py` together when examples changed.
15
+ - [ ] Used the `docs_policy` pytest marker for documentation policy tests.
16
+ - [ ] Ran `./scripts/docs-policy.sh` when documentation structure, links, release docs, or examples changed.
17
+ - [ ] Confirmed root docs that help users navigate still link to `docs/index.md`.
18
+
19
+ ## Release-impact checks
20
+
21
+ - [ ] Updated `RELEASE.md` if release gates, publishing flow, package metadata, or persistent cache compatibility changed.
22
+ - [ ] Confirmed no secrets, tokens, built distributions, local virtualenvs, or cache databases are included.
@@ -0,0 +1,61 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ pull_request:
6
+
7
+ jobs:
8
+ docs-policy:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v4
12
+ - uses: actions/setup-python@v5
13
+ with:
14
+ python-version: "3.13"
15
+ - name: Install package
16
+ run: python -m pip install -e '.[dev]'
17
+ - name: Documentation policy tests
18
+ run: ./scripts/docs-policy.sh
19
+
20
+ test:
21
+ runs-on: ubuntu-latest
22
+ strategy:
23
+ matrix:
24
+ python-version: ["3.11", "3.12", "3.13"]
25
+ steps:
26
+ - uses: actions/checkout@v4
27
+ - uses: actions/setup-python@v5
28
+ with:
29
+ python-version: ${{ matrix.python-version }}
30
+ - name: Install package
31
+ run: python -m pip install -e '.[dev]'
32
+ - name: Pre-commit hooks
33
+ run: pre-commit run --all-files --show-diff-on-failure
34
+ - name: Ruff lint
35
+ run: ruff check .
36
+ - name: Ruff format check
37
+ run: ruff format --check .
38
+ - name: Mypy
39
+ run: mypy
40
+ - name: Import smoke test
41
+ run: python scripts/smoke_imports.py
42
+ - name: Examples smoke test
43
+ run: python scripts/smoke_examples.py
44
+ - name: Tests
45
+ run: pytest
46
+ - name: Coverage summary
47
+ run: python scripts/coverage_summary.py >> "$GITHUB_STEP_SUMMARY"
48
+ - name: Upload coverage XML
49
+ uses: actions/upload-artifact@v4
50
+ with:
51
+ name: coverage-${{ matrix.python-version }}
52
+ path: coverage.xml
53
+ if-no-files-found: error
54
+ - name: Build package
55
+ run: python -m build
56
+ - name: Wheel install smoke test
57
+ run: python scripts/smoke_wheel_install.py
58
+ - name: Dogfood wheel scenarios
59
+ run: python scripts/dogfood_local_wheel.py
60
+ - name: External project dogfood
61
+ run: python scripts/dogfood_external_project.py
@@ -0,0 +1,112 @@
1
+ name: Release
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ inputs:
6
+ target:
7
+ description: "Package index target"
8
+ required: true
9
+ default: "testpypi"
10
+ type: choice
11
+ options:
12
+ - testpypi
13
+ - pypi
14
+ version:
15
+ description: "Expected package version, for example 0.1.0"
16
+ required: true
17
+ type: string
18
+
19
+ permissions:
20
+ contents: read
21
+
22
+ jobs:
23
+ build:
24
+ name: Build and verify distributions
25
+ runs-on: ubuntu-latest
26
+ outputs:
27
+ version: ${{ steps.version.outputs.version }}
28
+ steps:
29
+ - uses: actions/checkout@v4
30
+ - uses: actions/setup-python@v5
31
+ with:
32
+ python-version: "3.13"
33
+ - name: Install package
34
+ run: python -m pip install -e '.[dev]'
35
+ - name: Verify requested version matches package metadata
36
+ id: version
37
+ shell: bash
38
+ run: |
39
+ actual="$(python -c "import tomllib; from pathlib import Path; print(tomllib.loads(Path('pyproject.toml').read_text())['project']['version'])")"
40
+ echo "version=${actual}" >> "$GITHUB_OUTPUT"
41
+ if [ "$actual" != "${{ inputs.version }}" ]; then
42
+ echo "Requested version ${{ inputs.version }} does not match pyproject.toml version ${actual}" >&2
43
+ exit 1
44
+ fi
45
+ - name: Docs policy
46
+ run: ./scripts/docs-policy.sh
47
+ - name: Ruff lint
48
+ run: ruff check .
49
+ - name: Ruff format check
50
+ run: ruff format --check .
51
+ - name: Mypy
52
+ run: mypy
53
+ - name: Import smoke test
54
+ run: python scripts/smoke_imports.py
55
+ - name: Examples smoke test
56
+ run: python scripts/smoke_examples.py
57
+ - name: Tests
58
+ run: pytest
59
+ - name: Build package
60
+ run: python -m build
61
+ - name: Twine check
62
+ run: python -m twine check dist/*
63
+ - name: Wheel install smoke test
64
+ run: python scripts/smoke_wheel_install.py
65
+ - name: Dogfood wheel scenarios
66
+ run: python scripts/dogfood_local_wheel.py
67
+ - name: External project dogfood
68
+ run: python scripts/dogfood_external_project.py
69
+ - name: Upload distributions
70
+ uses: actions/upload-artifact@v4
71
+ with:
72
+ name: distributions
73
+ path: dist/*
74
+ if-no-files-found: error
75
+
76
+ publish-testpypi:
77
+ name: Publish to TestPyPI
78
+ needs: build
79
+ if: ${{ inputs.target == 'testpypi' }}
80
+ runs-on: ubuntu-latest
81
+ environment: testpypi
82
+ permissions:
83
+ id-token: write
84
+ contents: read
85
+ steps:
86
+ - name: Download distributions
87
+ uses: actions/download-artifact@v4
88
+ with:
89
+ name: distributions
90
+ path: dist
91
+ - name: Publish to TestPyPI
92
+ uses: pypa/gh-action-pypi-publish@release/v1
93
+ with:
94
+ repository-url: https://test.pypi.org/legacy/
95
+
96
+ publish-pypi:
97
+ name: Publish to PyPI
98
+ needs: build
99
+ if: ${{ inputs.target == 'pypi' }}
100
+ runs-on: ubuntu-latest
101
+ environment: pypi
102
+ permissions:
103
+ id-token: write
104
+ contents: read
105
+ steps:
106
+ - name: Download distributions
107
+ uses: actions/download-artifact@v4
108
+ with:
109
+ name: distributions
110
+ path: dist
111
+ - name: Publish to PyPI
112
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,22 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.egg-info/
6
+ build/
7
+ dist/
8
+ .pytest_cache/
9
+ .mypy_cache/
10
+ .ruff_cache/
11
+ .coverage
12
+ coverage.xml
13
+ htmlcov/
14
+
15
+ # Virtual environments
16
+ .venv/
17
+ venv/
18
+
19
+ # Editors and OS junk
20
+ .DS_Store
21
+ .idea/
22
+ .vscode/
@@ -0,0 +1,16 @@
1
+ repos:
2
+ - repo: https://github.com/astral-sh/ruff-pre-commit
3
+ rev: v0.9.10
4
+ hooks:
5
+ - id: ruff
6
+ args: [--fix]
7
+ - id: ruff-format
8
+ - repo: https://github.com/pre-commit/mirrors-mypy
9
+ rev: v1.14.1
10
+ hooks:
11
+ - id: mypy
12
+ pass_filenames: false
13
+ additional_dependencies:
14
+ - pytest>=8.3
15
+ - pytest-asyncio>=0.25
16
+ - pytest-cov>=6.0
@@ -0,0 +1,104 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is inspired by [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project intends to follow semantic versioning once public releases begin.
6
+
7
+ ## [Unreleased]
8
+
9
+ ### Added
10
+
11
+ - Aggregate timestamp diagnostic guidance for future disk-cache inspection reports.
12
+ - Inspection report retention/deletion guidance for future disk-cache support artifacts.
13
+ - Inspection sensitivity-warning design guidance for future disk-cache support tooling.
14
+ - Inspection CLI safe-default design guidance for future disk-cache tooling.
15
+ - Aggregate-only disk-cache inspection report design guidance for future support bundles.
16
+ - Support-bundle metadata sensitivity guidance for no-preview disk-cache inspection reports.
17
+ - No-preview support bundle/CI guidance for future disk-cache inspection tooling.
18
+ - `preview_redactor` callback design guidance for future disk-cache inspection previews.
19
+ - Payload preview redaction guidance for future disk-cache inspection tooling.
20
+ - Bounded payload preview policy guidance for future disk-cache inspection APIs.
21
+ - Disk-cache schema metadata table design guidance for future file-compatibility promises.
22
+ - Supported cache-inspection API design guidance for future disk-cache tooling.
23
+ - SQLite column-stability guidance for disk-cache debugging versus internal implementation details.
24
+ - SQLite inspection example for JSON disk-cache rows.
25
+ - Executable datetime/bytes JSON serializer adapter recipe for disk cache payloads.
26
+ - Opt-in `coalesce_misses=True` request coalescing for duplicate concurrent cache misses.
27
+ - Request coalescing design guidance for duplicate concurrent cache misses.
28
+ - Opt-in `refresh_ttl_on_hit` sliding TTL behavior for memory and disk cache backends.
29
+ - Disk cache integrity-check and maintenance helper design guidance.
30
+ - `DiskCacheBackend(on_drop=...)` diagnostics for rows dropped because of serializer mismatches or corrupt payloads.
31
+ - `JsonCacheSerializer` for simple JSON-compatible persistent cache payloads.
32
+ - README Python code-block extraction and sync policy tests.
33
+ - Release checklist guidance for persistent disk-cache migration and clearing.
34
+ - `DiskCacheBackend` cache versioning and schema-change guidance.
35
+ - `DiskCacheBackend` namespace/key stability documentation.
36
+ - `DiskCacheBackend` persistence documentation example coverage.
37
+ - Stale ignore-pattern validation for the optional external documentation link checker.
38
+ - HTTP(S) URL-shape validation for external link ignore patterns.
39
+ - Reason-comment validation for external link ignore patterns.
40
+ - Verbose reporting for checked and ignored external documentation links.
41
+ - Ignore-file support for the optional external documentation link checker.
42
+ - Retry/backoff support for the optional external documentation link checker.
43
+ - Opt-in external documentation link checker.
44
+ - External HTTP(S) documentation link syntax policy.
45
+ - Duplicate Markdown heading anchor handling.
46
+ - Contributor guidance for documentation index inclusion.
47
+ - README core documentation link policy.
48
+ - Shared documentation policy helper module.
49
+ - Contributor checklist for documentation file updates.
50
+ - Contributor guidance for documentation policy test markers.
51
+ - Pytest marker for documentation policy checks.
52
+ - Dedicated documentation policy test module.
53
+ - Pre-release docs policy script.
54
+ - Release documentation maintenance checklist section.
55
+ - Root documentation index-linking policy documentation.
56
+ - Root docs documentation-index mention policy test.
57
+ - Root documentation local Markdown link validation.
58
+ - All-docs local Markdown link and anchor validation.
59
+ - Local Markdown anchor validation for docs index links.
60
+ - Docs index executable example conventions link policy test.
61
+ - Docs example filename convention policy test.
62
+ - Executable docs example naming conventions.
63
+ - Docs example public-function assertion policy test.
64
+ - Docs example execution coverage policy test.
65
+ - Docs examples index coverage policy test.
66
+ - Docs index coverage policy test for top-level documentation pages.
67
+ - Docs index link validation policy test.
68
+ - Documentation index page linking core API, exception, cache, backend, and example docs.
69
+ - Centralized public exceptions reference page.
70
+ - Public exception executable examples for configuration, key, and serialization errors.
71
+ - Public exception inheritance documentation policy test.
72
+ - Public exception docs policy test.
73
+ - `CacheBackendClosedError` public docs and executable example coverage.
74
+ - `CacheBackendClosedError` README warning for context-managed decorator-bound disk backends.
75
+ - Regression coverage for decorator-bound closed `DiskCacheBackend` usage.
76
+ - `DiskCacheBackend` context-manager documentation example and executable coverage.
77
+ - Executable `DiskCacheBackend` documentation example coverage.
78
+ - `DiskCacheBackend` README lifecycle guidance showing explicit `close()` cleanup.
79
+ - `DiskCacheBackend` README usage example.
80
+ - README guidance for `DiskCacheBackend` concurrency and single-host expectations.
81
+ - `DiskCacheBackend` SQLite WAL/busy-timeout tuning options and tests.
82
+ - `DiskCacheBackend` treats corrupt disk cache payloads as misses and drops the bad row.
83
+ - Reusable cache backend conformance tests for memory and disk backend behavior.
84
+ - `DiskCacheBackend` cache operations, persistence, TTL/LRU behavior, serializer mismatch handling, and closed-backend errors.
85
+ - `DiskCacheBackend` key and payload serialization helpers.
86
+ - `DiskCacheBackend` SQLite schema initialization and constructor tests.
87
+ - `DiskCacheBackend` SQLite storage strategy design.
88
+ - `CacheSerializer` protocol and `PickleCacheSerializer` default implementation.
89
+ - `@cache_result` backend sharing semantics and `namespace=` isolation.
90
+ - `CacheBackend` protocol and `backend=` parameter for `@cache_result`.
91
+ - `MemoryCacheBackend` refactor as the default storage backend for `@cache_result`.
92
+ - `@cache_result` TTL expiry, LRU maxsize eviction, and sync mutation thread-safety coverage.
93
+ - `@cache_result` hardening tests for exception caching, lock behavior, and key canonicalization policy.
94
+ - Sync-core `@cache_result` implementation with key generation, stats, clear, and async rejection.
95
+ - `CacheInfo` and `CacheKeyError` support types for planned `@cache_result`.
96
+ - `@cache_result` API design and implementation strategy.
97
+ - Release checklist for repeatable package publishing.
98
+ - Public API policy, contributor checklist, version consistency check, and executable docs examples.
99
+ - `@deprecated` decorator with sync and async support.
100
+ - Initial project packaging foundation.
101
+ - Empty typed `pydecorators` package.
102
+ - Import smoke test.
103
+ - API design notes and shared internal decorator helpers.
104
+ - Public exception hierarchy.
@@ -0,0 +1,163 @@
1
+ # Contributing
2
+
3
+ ## Documentation style
4
+
5
+ Use `/home/skippy/.openclaw/workspace/WRITING_STYLE.md` as the project writing style when adding or revising documentation.
6
+
7
+ The short version: write like a capable human who understands the system and is trying to be useful. Start with the point. Define fuzzy terms. Name the trade-off. Explain the practical consequence. Prefer concrete examples over vague reassurance.
8
+
9
+ Good documentation for this project should be:
10
+
11
+ - direct, specific, and edited
12
+ - technically credible without sounding academic for sport
13
+ - honest about limits, failure modes, and operating constraints
14
+ - willing to say what not to do
15
+ - dry when the joke helps, not when the reader needs sober warning
16
+
17
+ Avoid vendor fog and AI filler. If a sentence could survive unchanged in a generic product whitepaper, make it confess what it actually means or delete it.
18
+
19
+ ## Adding a new decorator
20
+
21
+ Use this checklist when adding a decorator. Yes, it is mildly bossy. That is the point.
22
+
23
+ 1. Update `TODO.md` or the relevant design document with the intended behavior.
24
+ 2. Decide whether the decorator supports bare usage, configured usage, or both.
25
+ 3. Add implementation under `src/pydecorators/`.
26
+ 4. Use shared helpers from `pydecorators._core` where applicable:
27
+ - `is_async_callable`
28
+ - `mirror_metadata`
29
+ - `monotonic`
30
+ - `sync_sleep`
31
+ - `async_sleep`
32
+ - configuration validators
33
+ 5. Preserve wrapped function metadata.
34
+ 6. Support async functions where practical, or document why not.
35
+ 7. Export the decorator from `pydecorators.__init__` and `__all__` only when it is ready to be public.
36
+ 8. Add tests for:
37
+ - normal behavior
38
+ - invalid configuration
39
+ - metadata preservation
40
+ - sync and async paths, if supported
41
+ - composition or edge cases when relevant
42
+ 9. Add README and per-decorator documentation examples.
43
+ 10. Add executable examples under `docs/examples/` when useful.
44
+ 11. Run the full verification gate:
45
+
46
+ ```bash
47
+ ruff check .
48
+ ruff format --check .
49
+ mypy
50
+ python scripts/smoke_imports.py
51
+ python scripts/smoke_examples.py
52
+ pytest
53
+ python -m build
54
+ python scripts/smoke_wheel_install.py
55
+ python scripts/dogfood_local_wheel.py
56
+ python scripts/dogfood_external_project.py
57
+ ```
58
+
59
+ See [Quality Gates](docs/quality_gates.md) for what each command checks.
60
+
61
+ The project also ships optional pre-commit hooks. Install them with `pre-commit install` if you want local lint/format/type checks before commits. This is optional because surprise Git hooks are how productivity gets mugged in an alley.
62
+
63
+ ## Public API rule
64
+
65
+ If a name is in `pydecorators.__all__`, it is public. Public names need tests and documentation.
66
+
67
+ If a helper is not meant for users, keep it in an underscore-prefixed module.
68
+
69
+ ## Executable documentation examples
70
+
71
+ When adding runnable docs examples, put them under `docs/examples/` and use the naming pattern `<topic>_examples.py`, for example `deprecated_examples.py` or `disk_cache_backend_examples.py`.
72
+
73
+ Keep example modules importable without side effects beyond defining small functions/classes. Public top-level example functions should be directly asserted in `tests/test_docs_examples.py`; if a file is intentionally not executable, document why and exempt it explicitly in the relevant policy test.
74
+
75
+ After adding a new example file:
76
+
77
+ 1. Link it from `docs/index.md`.
78
+ 2. Load it through `load_docs_example(...)` in `tests/test_docs_examples.py`.
79
+ 3. Add at least one assertion for each public top-level example function.
80
+ 4. Run the full verification gate.
81
+
82
+ ## Adding or changing documentation files
83
+
84
+ When adding or changing docs files, use this checklist before calling the slice done:
85
+
86
+ 1. Link new top-level `docs/*.md` pages from `docs/index.md`, unless the file is intentionally exempt and the docs policy test says why.
87
+ 2. Link new executable examples under `docs/examples/` from `docs/index.md`.
88
+ 3. Add or update assertions in `tests/test_docs_examples.py` for public top-level example functions.
89
+ 4. Add `pytest.mark.docs_policy` coverage when the change introduces a new documentation rule.
90
+ 5. Run `./scripts/docs-policy.sh` before the full verification gate.
91
+
92
+ README Python code blocks are extracted by docs policy tests. Keep them syntactically valid and synchronized with the executable examples/policy expectations when changing documented decorator usage.
93
+
94
+ The README is also expected to link the core documentation path for new users and reviewers:
95
+
96
+ - `docs/index.md`
97
+ - `docs/PUBLIC_API.md`
98
+ - `docs/API_DESIGN.md`
99
+ - `docs/exceptions.md`
100
+ - `docs/deprecated.md`
101
+ - `docs/cache_result.md`
102
+ - `docs/disk_cache_backend.md`
103
+
104
+ If that required set changes, update the README and the matching docs policy test in the same branch.
105
+
106
+ External HTTP(S) links are syntax-checked only. The docs policy tests verify that they have an `http://` or `https://` scheme, a host, and no whitespace, but they do not fetch the network or fail builds because somebody else's server hiccuped. Local links and local Markdown anchors are checked for actual existence.
107
+
108
+ If a planning/backlog file such as `GOAL.md`, `PLAN.md`, or `TODO.md` becomes user-facing navigation, update the root documentation link policy at the same time.
109
+
110
+ ## Documentation index inclusion rule
111
+
112
+ Keep `docs/index.md` grouped by purpose: core project docs, decorator docs, cache backend docs, and executable examples. Add new links to the narrowest matching section rather than using the index as a junk drawer with Markdown syntax.
113
+
114
+
115
+ Add a page to `docs/index.md` when it is intended to help users or contributors understand, use, extend, release, or maintain the package. In practice, that includes:
116
+
117
+ - public API, compatibility, exception, or design policy pages
118
+ - per-decorator behavior docs
119
+ - cache backend, serializer, lifecycle, or trust-boundary docs
120
+ - executable documentation examples under `docs/examples/`
121
+ - release, contribution, or documentation-maintenance guidance linked from the docs flow
122
+
123
+ Do not add raw planning/backlog files such as `GOAL.md`, `PLAN.md`, or `TODO.md` to the docs index unless they are deliberately promoted to user-facing documentation. If a docs file is intentionally not indexed, document the exemption in the relevant `docs_policy` test.
124
+
125
+ ## Documentation policy tests
126
+
127
+ Use the `docs_policy` pytest marker for tests that guard documentation maintenance rather than runtime behavior. Mark tests with `@pytest.mark.docs_policy` or a module-level `pytestmark = pytest.mark.docs_policy` when they check things like:
128
+
129
+ - `docs/index.md` coverage and navigation rules
130
+ - executable documentation example indexing, naming, loading, or assertion coverage
131
+ - Markdown local-link or heading-anchor validation
132
+ - root documentation link policy
133
+ - release-checklist documentation maintenance rules
134
+
135
+ Do not use `docs_policy` for normal decorator behavior, backend behavior, public API exports, or version checks unless the test is specifically about documentation upkeep.
136
+
137
+ Run documentation policy checks with:
138
+
139
+ ```bash
140
+ ./scripts/docs-policy.sh
141
+ # or, when using Hatch locally:
142
+ hatch run docs-policy
143
+ ```
144
+
145
+ The Hatch alias intentionally delegates to the same script so local and CI documentation checks do not drift.
146
+
147
+ For the full local release-prep gate, run:
148
+
149
+ ```bash
150
+ hatch run full-gate
151
+ ```
152
+
153
+ That alias chains docs policy, Ruff, formatting checks, mypy, smoke imports, smoke examples, pytest, package build, wheel install smoke, and both dogfood harnesses. It is intentionally boring. Boring gates are how we avoid exciting releases.
154
+
155
+ ## Root documentation links
156
+
157
+ Root docs that help users or contributors navigate the project should link to `docs/index.md`. Today that means:
158
+
159
+ - `README.md`
160
+ - `CONTRIBUTING.md`
161
+ - `RELEASE.md`
162
+
163
+ Planning/backlog docs such as `GOAL.md`, `PLAN.md`, and `TODO.md` are not required to link the docs index unless they grow into user-facing navigation docs.
@@ -0,0 +1,51 @@
1
+ # Dogfood Plan
2
+
3
+ Public publishing is intentionally paused until the package has been used locally enough to expose awkward APIs, decorator-composition problems, documentation gaps, and release-process surprises.
4
+
5
+ The current distribution name is `blakemere-wraptools`; the import package remains `pydecorators`.
6
+
7
+ ## Goals
8
+
9
+ - Install the built wheel in a clean virtual environment.
10
+ - Run realistic scripts from outside the source checkout.
11
+ - Exercise decorator composition instead of only single-decorator happy paths.
12
+ - Record findings before TestPyPI/PyPI release.
13
+
14
+ ## Dogfood harness
15
+
16
+ Run:
17
+
18
+ ```bash
19
+ python scripts/dogfood_local_wheel.py
20
+ python scripts/dogfood_external_project.py
21
+ ```
22
+
23
+ The harness:
24
+
25
+ 1. Builds a local wheel.
26
+ 2. Creates a clean virtual environment.
27
+ 3. Installs the wheel.
28
+ 4. Runs dogfood scripts from `dogfood/` with `PYTHONPATH` cleared.
29
+
30
+ ## Dogfood scenarios
31
+
32
+ - `dogfood/service_client.py`: combines `@require_env`, `@rate_limit`, `@retry`, `@timeout`, `@log_calls`, `@measure_time`, and `@circuit_breaker` in service-client-like sync and async flows.
33
+ - `scripts/dogfood_external_project.py`: runs decorators from the installed wheel against `projects/model-gateway-reliability-mini-lab/gateway_sim.py` without modifying that project.
34
+
35
+ ## Findings log
36
+
37
+ Add findings here as dogfood scripts expose sharp edges.
38
+
39
+ - 2026-05-12: Initial harness added. No API changes required yet; first goal is keeping composition behavior executable from an installed wheel.
40
+ - 2026-05-12: External local-project dogfood against `model-gateway-reliability-mini-lab/gateway_sim.py` passed without API changes. Dynamic wrapping worked, but it reinforced that composition docs should eventually explain decorator order for wrappers that log/retry/measure.
41
+ - 2026-05-12: Resolved the wrapper-order documentation finding by adding `docs/composition.md` and linking it from the docs index and README. No API changes required.
42
+
43
+ ## Release gate
44
+
45
+ Before publishing:
46
+
47
+ - [ ] Run `python scripts/dogfood_local_wheel.py`.
48
+ - [ ] Run `python scripts/dogfood_external_project.py`.
49
+ - [ ] Review this findings log.
50
+ - [x] Resolve or explicitly defer any API/documentation issues found during dogfood use.
51
+ - [ ] Re-check `pydecorators` availability on PyPI/TestPyPI.