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.
- blakemere_wraptools-0.1.0/.external-links-ignore +9 -0
- blakemere_wraptools-0.1.0/.github/ISSUE_TEMPLATE/bug-report.yml +30 -0
- blakemere_wraptools-0.1.0/.github/ISSUE_TEMPLATE/docs-or-release-question.yml +26 -0
- blakemere_wraptools-0.1.0/.github/pull_request_template.md +22 -0
- blakemere_wraptools-0.1.0/.github/workflows/ci.yml +61 -0
- blakemere_wraptools-0.1.0/.github/workflows/publish.yml +112 -0
- blakemere_wraptools-0.1.0/.gitignore +22 -0
- blakemere_wraptools-0.1.0/.pre-commit-config.yaml +16 -0
- blakemere_wraptools-0.1.0/CHANGELOG.md +104 -0
- blakemere_wraptools-0.1.0/CONTRIBUTING.md +163 -0
- blakemere_wraptools-0.1.0/DOGFOOD.md +51 -0
- blakemere_wraptools-0.1.0/GOAL.md +87 -0
- blakemere_wraptools-0.1.0/LICENSE +21 -0
- blakemere_wraptools-0.1.0/PKG-INFO +355 -0
- blakemere_wraptools-0.1.0/PLAN.md +164 -0
- blakemere_wraptools-0.1.0/README.md +322 -0
- blakemere_wraptools-0.1.0/RELEASE.md +235 -0
- blakemere_wraptools-0.1.0/TODO.md +894 -0
- blakemere_wraptools-0.1.0/docs/API_DESIGN.md +62 -0
- blakemere_wraptools-0.1.0/docs/API_REFERENCE.md +161 -0
- blakemere_wraptools-0.1.0/docs/PUBLIC_API.md +283 -0
- blakemere_wraptools-0.1.0/docs/__init__.py +0 -0
- blakemere_wraptools-0.1.0/docs/cache_result.md +365 -0
- blakemere_wraptools-0.1.0/docs/circuit_breaker.md +90 -0
- blakemere_wraptools-0.1.0/docs/composition.md +163 -0
- blakemere_wraptools-0.1.0/docs/deprecated.md +130 -0
- blakemere_wraptools-0.1.0/docs/disk_cache_backend.md +764 -0
- blakemere_wraptools-0.1.0/docs/docs_index_exemptions.md +13 -0
- blakemere_wraptools-0.1.0/docs/docs_site_plan.md +34 -0
- blakemere_wraptools-0.1.0/docs/examples/__init__.py +0 -0
- blakemere_wraptools-0.1.0/docs/examples/circuit_breaker_examples.py +80 -0
- blakemere_wraptools-0.1.0/docs/examples/cli_examples.py +60 -0
- blakemere_wraptools-0.1.0/docs/examples/composition_examples.py +125 -0
- blakemere_wraptools-0.1.0/docs/examples/deprecated_examples.py +36 -0
- blakemere_wraptools-0.1.0/docs/examples/disk_cache_backend_examples.py +277 -0
- blakemere_wraptools-0.1.0/docs/examples/log_calls_examples.py +71 -0
- blakemere_wraptools-0.1.0/docs/examples/measure_time_examples.py +66 -0
- blakemere_wraptools-0.1.0/docs/examples/observability_integration_examples.py +164 -0
- blakemere_wraptools-0.1.0/docs/examples/public_exception_examples.py +134 -0
- blakemere_wraptools-0.1.0/docs/examples/rate_limit_examples.py +66 -0
- blakemere_wraptools-0.1.0/docs/examples/readme_examples.py +192 -0
- blakemere_wraptools-0.1.0/docs/examples/require_env_examples.py +60 -0
- blakemere_wraptools-0.1.0/docs/examples/retry_examples.py +71 -0
- blakemere_wraptools-0.1.0/docs/examples/retry_idempotency_examples.py +54 -0
- blakemere_wraptools-0.1.0/docs/examples/timeout_examples.py +49 -0
- blakemere_wraptools-0.1.0/docs/examples/validate_types_examples.py +50 -0
- blakemere_wraptools-0.1.0/docs/examples/web_framework_examples.py +98 -0
- blakemere_wraptools-0.1.0/docs/exceptions.md +172 -0
- blakemere_wraptools-0.1.0/docs/future_extension_decisions.md +34 -0
- blakemere_wraptools-0.1.0/docs/index.md +66 -0
- blakemere_wraptools-0.1.0/docs/log_calls.md +73 -0
- blakemere_wraptools-0.1.0/docs/markdown_anchor_policy.md +12 -0
- blakemere_wraptools-0.1.0/docs/measure_time.md +85 -0
- blakemere_wraptools-0.1.0/docs/observability_integrations.md +26 -0
- blakemere_wraptools-0.1.0/docs/quality_gates.md +64 -0
- blakemere_wraptools-0.1.0/docs/rate_limit.md +83 -0
- blakemere_wraptools-0.1.0/docs/redis_backend_design.md +115 -0
- blakemere_wraptools-0.1.0/docs/release_note_template.md +19 -0
- blakemere_wraptools-0.1.0/docs/require_env.md +55 -0
- blakemere_wraptools-0.1.0/docs/retry.md +89 -0
- blakemere_wraptools-0.1.0/docs/security_hardening.md +117 -0
- blakemere_wraptools-0.1.0/docs/sync_timeout_decision.md +23 -0
- blakemere_wraptools-0.1.0/docs/timeout.md +81 -0
- blakemere_wraptools-0.1.0/docs/validate_types.md +59 -0
- blakemere_wraptools-0.1.0/docs/web_frameworks.md +38 -0
- blakemere_wraptools-0.1.0/docs/writing_style_audit.md +156 -0
- blakemere_wraptools-0.1.0/dogfood/service_client.py +125 -0
- blakemere_wraptools-0.1.0/pyproject.toml +104 -0
- blakemere_wraptools-0.1.0/scripts/benchmark_decorators.py +91 -0
- blakemere_wraptools-0.1.0/scripts/check_docs_example_index.py +45 -0
- blakemere_wraptools-0.1.0/scripts/check_external_links.py +405 -0
- blakemere_wraptools-0.1.0/scripts/check_package_name_availability.py +70 -0
- blakemere_wraptools-0.1.0/scripts/coverage_summary.py +28 -0
- blakemere_wraptools-0.1.0/scripts/docs-policy.sh +5 -0
- blakemere_wraptools-0.1.0/scripts/dogfood_external_project.py +112 -0
- blakemere_wraptools-0.1.0/scripts/dogfood_local_wheel.py +51 -0
- blakemere_wraptools-0.1.0/scripts/smoke_examples.py +34 -0
- blakemere_wraptools-0.1.0/scripts/smoke_imports.py +27 -0
- blakemere_wraptools-0.1.0/scripts/smoke_wheel_install.py +46 -0
- blakemere_wraptools-0.1.0/scripts/stress_disk_cache_concurrency.py +63 -0
- blakemere_wraptools-0.1.0/src/pydecorators/__init__.py +98 -0
- blakemere_wraptools-0.1.0/src/pydecorators/_core.py +70 -0
- blakemere_wraptools-0.1.0/src/pydecorators/_typing.py +30 -0
- blakemere_wraptools-0.1.0/src/pydecorators/cache_result.py +1225 -0
- blakemere_wraptools-0.1.0/src/pydecorators/circuit_breaker.py +171 -0
- blakemere_wraptools-0.1.0/src/pydecorators/deprecated.py +169 -0
- blakemere_wraptools-0.1.0/src/pydecorators/exceptions.py +47 -0
- blakemere_wraptools-0.1.0/src/pydecorators/log_calls.py +304 -0
- blakemere_wraptools-0.1.0/src/pydecorators/measure_time.py +183 -0
- blakemere_wraptools-0.1.0/src/pydecorators/py.typed +0 -0
- blakemere_wraptools-0.1.0/src/pydecorators/rate_limit.py +138 -0
- blakemere_wraptools-0.1.0/src/pydecorators/redis_backend.py +250 -0
- blakemere_wraptools-0.1.0/src/pydecorators/require_env.py +133 -0
- blakemere_wraptools-0.1.0/src/pydecorators/retry.py +207 -0
- blakemere_wraptools-0.1.0/src/pydecorators/timeout.py +64 -0
- blakemere_wraptools-0.1.0/src/pydecorators/validate_types.py +162 -0
- blakemere_wraptools-0.1.0/tests/__init__.py +0 -0
- blakemere_wraptools-0.1.0/tests/docs_example_policy_helpers.py +73 -0
- blakemere_wraptools-0.1.0/tests/docs_policy_helpers.py +86 -0
- blakemere_wraptools-0.1.0/tests/test_benchmark_script.py +41 -0
- blakemere_wraptools-0.1.0/tests/test_cache_backend_conformance.py +214 -0
- blakemere_wraptools-0.1.0/tests/test_cache_directory.py +44 -0
- blakemere_wraptools-0.1.0/tests/test_cache_result.py +720 -0
- blakemere_wraptools-0.1.0/tests/test_cache_result_design_docs.py +84 -0
- blakemere_wraptools-0.1.0/tests/test_cache_result_support.py +170 -0
- blakemere_wraptools-0.1.0/tests/test_circuit_breaker.py +160 -0
- blakemere_wraptools-0.1.0/tests/test_core.py +99 -0
- blakemere_wraptools-0.1.0/tests/test_deprecated.py +130 -0
- blakemere_wraptools-0.1.0/tests/test_disk_cache_backend.py +868 -0
- blakemere_wraptools-0.1.0/tests/test_disk_cache_backend_design_docs.py +400 -0
- blakemere_wraptools-0.1.0/tests/test_docs_examples.py +406 -0
- blakemere_wraptools-0.1.0/tests/test_docs_policy.py +1226 -0
- blakemere_wraptools-0.1.0/tests/test_dogfood_harness.py +35 -0
- blakemere_wraptools-0.1.0/tests/test_import.py +5 -0
- blakemere_wraptools-0.1.0/tests/test_log_calls.py +177 -0
- blakemere_wraptools-0.1.0/tests/test_measure_time.py +163 -0
- blakemere_wraptools-0.1.0/tests/test_package_name_availability.py +65 -0
- blakemere_wraptools-0.1.0/tests/test_project_metadata.py +44 -0
- blakemere_wraptools-0.1.0/tests/test_public_api.py +38 -0
- blakemere_wraptools-0.1.0/tests/test_public_api_policy.py +22 -0
- blakemere_wraptools-0.1.0/tests/test_public_exception_policy.py +60 -0
- blakemere_wraptools-0.1.0/tests/test_quality_gates.py +124 -0
- blakemere_wraptools-0.1.0/tests/test_rate_limit.py +183 -0
- blakemere_wraptools-0.1.0/tests/test_redis_backend.py +141 -0
- blakemere_wraptools-0.1.0/tests/test_redis_optional_dependency.py +21 -0
- blakemere_wraptools-0.1.0/tests/test_release_checklist.py +125 -0
- blakemere_wraptools-0.1.0/tests/test_release_workflow.py +40 -0
- blakemere_wraptools-0.1.0/tests/test_require_env.py +148 -0
- blakemere_wraptools-0.1.0/tests/test_retry.py +248 -0
- blakemere_wraptools-0.1.0/tests/test_timeout.py +90 -0
- blakemere_wraptools-0.1.0/tests/test_validate_types.py +126 -0
- 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.
|