objectstate 1.0.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 (62) hide show
  1. objectstate-1.0.0/.github/badges/coverage.svg +1 -0
  2. objectstate-1.0.0/.github/workflows/ci.yml +101 -0
  3. objectstate-1.0.0/.github/workflows/coverage-pages.yml +118 -0
  4. objectstate-1.0.0/.github/workflows/publish.yml +51 -0
  5. objectstate-1.0.0/.gitignore +48 -0
  6. objectstate-1.0.0/.readthedocs.yaml +20 -0
  7. objectstate-1.0.0/BADGE_SETUP.md +94 -0
  8. objectstate-1.0.0/DOCUMENTATION_AUDIT.md +81 -0
  9. objectstate-1.0.0/DOCUMENTATION_FIXES.md +285 -0
  10. objectstate-1.0.0/LICENSE +21 -0
  11. objectstate-1.0.0/PKG-INFO +588 -0
  12. objectstate-1.0.0/README.md +554 -0
  13. objectstate-1.0.0/docs/.gitignore +8 -0
  14. objectstate-1.0.0/docs/Makefile +18 -0
  15. objectstate-1.0.0/docs/api/modules.rst +123 -0
  16. objectstate-1.0.0/docs/architectural_fixes.rst +281 -0
  17. objectstate-1.0.0/docs/architecture.rst +494 -0
  18. objectstate-1.0.0/docs/conf.py +85 -0
  19. objectstate-1.0.0/docs/examples/atomic_operations.rst +160 -0
  20. objectstate-1.0.0/docs/examples/basic.rst +273 -0
  21. objectstate-1.0.0/docs/examples/dual_axis.rst +294 -0
  22. objectstate-1.0.0/docs/examples/index.rst +12 -0
  23. objectstate-1.0.0/docs/examples/ui.rst +368 -0
  24. objectstate-1.0.0/docs/index.rst +131 -0
  25. objectstate-1.0.0/docs/make.bat +35 -0
  26. objectstate-1.0.0/docs/quickstart.rst +245 -0
  27. objectstate-1.0.0/docs/state_management.rst +68 -0
  28. objectstate-1.0.0/docs/undo_redo.rst +49 -0
  29. objectstate-1.0.0/paper.bib +191 -0
  30. objectstate-1.0.0/paper.md +177 -0
  31. objectstate-1.0.0/pyproject.toml +71 -0
  32. objectstate-1.0.0/scripts/release.py +63 -0
  33. objectstate-1.0.0/scripts/update_and_release.py +114 -0
  34. objectstate-1.0.0/scripts/update_version.py +101 -0
  35. objectstate-1.0.0/scripts/verify_release_ready.py +274 -0
  36. objectstate-1.0.0/src/objectstate/__init__.py +249 -0
  37. objectstate-1.0.0/src/objectstate/collection_containers.py +38 -0
  38. objectstate-1.0.0/src/objectstate/config.py +57 -0
  39. objectstate-1.0.0/src/objectstate/context_manager.py +1215 -0
  40. objectstate-1.0.0/src/objectstate/docs/configuration_framework.rst +316 -0
  41. objectstate-1.0.0/src/objectstate/docs/context_system.rst +313 -0
  42. objectstate-1.0.0/src/objectstate/docs/object_state_lifecycle.rst +66 -0
  43. objectstate-1.0.0/src/objectstate/dual_axis_resolver.py +343 -0
  44. objectstate-1.0.0/src/objectstate/global_config.py +121 -0
  45. objectstate-1.0.0/src/objectstate/lazy_factory.py +1321 -0
  46. objectstate-1.0.0/src/objectstate/live_context_resolver.py +150 -0
  47. objectstate-1.0.0/src/objectstate/object_state.py +3127 -0
  48. objectstate-1.0.0/src/objectstate/parametric_axes.py +148 -0
  49. objectstate-1.0.0/src/objectstate/placeholder.py +175 -0
  50. objectstate-1.0.0/src/objectstate/reified_generics.py +312 -0
  51. objectstate-1.0.0/src/objectstate/snapshot_model.py +145 -0
  52. objectstate-1.0.0/src/objectstate/token_cache.py +182 -0
  53. objectstate-1.0.0/tests/__init__.py +1 -0
  54. objectstate-1.0.0/tests/conftest.py +78 -0
  55. objectstate-1.0.0/tests/test_config.py +47 -0
  56. objectstate-1.0.0/tests/test_context_manager.py +86 -0
  57. objectstate-1.0.0/tests/test_global_config.py +65 -0
  58. objectstate-1.0.0/tests/test_integration.py +128 -0
  59. objectstate-1.0.0/tests/test_lazy_factory.py +132 -0
  60. objectstate-1.0.0/tests/test_parametric_axes.py +323 -0
  61. objectstate-1.0.0/tests/test_placeholder.py +61 -0
  62. objectstate-1.0.0/tests/test_reified_generics.py +187 -0
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="114" height="20" role="img" aria-label="coverage: 30.32%"><title>coverage: 30.32%</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="114" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="61" height="20" fill="#555"/><rect x="61" width="53" height="20" fill="#e05d44"/><rect width="114" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="315" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="510">coverage</text><text x="315" y="140" transform="scale(.1)" fill="#fff" textLength="510">coverage</text><text aria-hidden="true" x="865" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="430">30.32%</text><text x="865" y="140" transform="scale(.1)" fill="#fff" textLength="430">30.32%</text></g></svg>
@@ -0,0 +1,101 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main, master, claude/**]
6
+ pull_request:
7
+ branches: [main, master]
8
+ workflow_dispatch:
9
+
10
+ jobs:
11
+ # Test across Python versions and OSes
12
+ test:
13
+ runs-on: ${{ matrix.os }}
14
+ strategy:
15
+ fail-fast: false
16
+ matrix:
17
+ python-version: ["3.11", "3.12", "3.13"]
18
+ os: [ubuntu-latest, windows-latest, macos-latest]
19
+
20
+ steps:
21
+ - name: Checkout
22
+ uses: actions/checkout@v4
23
+
24
+ - name: Setup Python ${{ matrix.python-version }}
25
+ uses: actions/setup-python@v5
26
+ with:
27
+ python-version: ${{ matrix.python-version }}
28
+
29
+ - name: Install dependencies
30
+ run: |
31
+ python -m pip install --upgrade pip
32
+ pip install -e ".[dev]"
33
+
34
+ - name: Run tests with coverage
35
+ run: |
36
+ pytest --cov=hieraconf --cov-report=xml --cov-report=html --cov-report=term-missing -v
37
+
38
+ - name: Upload coverage to Codecov
39
+ if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12'
40
+ uses: codecov/codecov-action@v3
41
+ with:
42
+ file: ./coverage.xml
43
+ fail_ci_if_error: false
44
+
45
+ # Code quality checks
46
+ code-quality:
47
+ runs-on: ubuntu-latest
48
+
49
+ steps:
50
+ - name: Checkout
51
+ uses: actions/checkout@v4
52
+
53
+ - name: Setup Python
54
+ uses: actions/setup-python@v5
55
+ with:
56
+ python-version: "3.12"
57
+
58
+ - name: Install dependencies
59
+ run: |
60
+ python -m pip install --upgrade pip
61
+ pip install ruff black mypy
62
+
63
+ - name: Run ruff (linting)
64
+ run: |
65
+ ruff check src/ --output-format=github
66
+
67
+ - name: Run black (formatting check)
68
+ run: |
69
+ black --check src/
70
+
71
+ - name: Run mypy (type checking)
72
+ run: |
73
+ mypy src/ --ignore-missing-imports
74
+
75
+ # Documentation build check
76
+ docs:
77
+ runs-on: ubuntu-latest
78
+
79
+ steps:
80
+ - name: Checkout
81
+ uses: actions/checkout@v4
82
+
83
+ - name: Setup Python
84
+ uses: actions/setup-python@v5
85
+ with:
86
+ python-version: "3.12"
87
+
88
+ - name: Install dependencies
89
+ run: |
90
+ python -m pip install --upgrade pip
91
+ pip install -e ".[docs]"
92
+
93
+ - name: Build documentation
94
+ run: |
95
+ cd docs
96
+ make html
97
+
98
+ - name: Check for build warnings
99
+ run: |
100
+ cd docs
101
+ make html SPHINXOPTS="-W --keep-going"
@@ -0,0 +1,118 @@
1
+ name: Tests, Coverage and GitHub Pages
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ contents: write # Needed for badge commit
10
+ pages: write
11
+ id-token: write
12
+
13
+ concurrency:
14
+ group: "pages"
15
+ cancel-in-progress: true
16
+
17
+ jobs:
18
+ test-and-deploy:
19
+ runs-on: ubuntu-latest
20
+ environment:
21
+ name: github-pages
22
+ url: ${{ steps.deployment.outputs.page_url }}
23
+ steps:
24
+ - name: Checkout
25
+ uses: actions/checkout@v4
26
+
27
+ - name: Setup Python
28
+ uses: actions/setup-python@v5
29
+ with:
30
+ python-version: "3.12"
31
+
32
+ - name: Install dependencies
33
+ run: |
34
+ python -m pip install --upgrade pip
35
+ pip install -e ".[dev]"
36
+ pip install genbadge[coverage]
37
+
38
+ - name: Run tests with coverage
39
+ # Continue even if tests fail - we want coverage reports regardless
40
+ # This workflow is for reporting only; the CI workflow enforces test success
41
+ continue-on-error: true
42
+ run: |
43
+ mkdir -p site
44
+ python -m pytest --cov=hieraconf \
45
+ --cov-report=xml \
46
+ --cov-report=html:site/coverage \
47
+ tests/
48
+
49
+ - name: Generate coverage badge
50
+ run: |
51
+ mkdir -p .github/badges
52
+ genbadge coverage -i coverage.xml -o .github/badges/coverage.svg
53
+
54
+ - name: Create index.html and README
55
+ run: |
56
+ # Create index.html for redirection
57
+ cat > site/index.html << 'EOF'
58
+ <!DOCTYPE html>
59
+ <html>
60
+ <head>
61
+ <meta http-equiv="refresh" content="0; url=./coverage/">
62
+ <title>Redirecting to coverage report...</title>
63
+ </head>
64
+ <body>
65
+ <p>Redirecting to coverage report... <a href="./coverage/">Click here if not redirected</a></p>
66
+ </body>
67
+ </html>
68
+ EOF
69
+
70
+ # Create README.md in the site directory
71
+ cat > site/README.md << 'EOF'
72
+ # hieraconf Code Coverage Reports
73
+
74
+ This site contains the code coverage reports for the [hieraconf](https://github.com/trissim/hieraconf) project.
75
+
76
+ ## Navigation
77
+
78
+ - [Coverage Report](./coverage/): View the HTML coverage report
79
+
80
+ ## About
81
+
82
+ These reports are automatically generated by GitHub Actions whenever changes are pushed to the main branch.
83
+ They show the percentage of code that is covered by automated tests.
84
+ EOF
85
+
86
+ - name: Commit and push if coverage badge changed
87
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
88
+ run: |
89
+ git config --local user.email "github-actions[bot]@users.noreply.github.com"
90
+ git config --local user.name "github-actions[bot]"
91
+ git add .github/badges/coverage.svg -f
92
+ # Only commit if there are changes
93
+ if git diff --staged --quiet; then
94
+ echo "No changes to coverage badge"
95
+ else
96
+ git commit -m "chore: update coverage badge [skip ci]"
97
+ git push
98
+ fi
99
+
100
+ - name: Check GitHub Pages status
101
+ run: |
102
+ echo "⚠️ IMPORTANT: Make sure GitHub Pages is enabled in your repository settings!"
103
+ echo "Go to https://github.com/trissim/hieraconf/settings/pages"
104
+ echo "Set 'Source' to 'GitHub Actions' to enable GitHub Pages deployment."
105
+
106
+ - name: Setup Pages
107
+ uses: actions/configure-pages@v4
108
+
109
+ - name: Upload Pages artifact
110
+ uses: actions/upload-pages-artifact@v3
111
+ with:
112
+ path: 'site'
113
+ retention-days: 1
114
+
115
+ - name: Deploy to GitHub Pages
116
+ id: deployment
117
+ uses: actions/deploy-pages@v4
118
+ timeout-minutes: 10
@@ -0,0 +1,51 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ permissions:
9
+ contents: write
10
+ id-token: write # Required for trusted publishing
11
+
12
+ jobs:
13
+ build-and-publish:
14
+ name: Build and publish to PyPI
15
+ runs-on: ubuntu-latest
16
+ environment:
17
+ name: pypi
18
+ url: https://pypi.org/p/objectstate
19
+
20
+ steps:
21
+ - name: Checkout code
22
+ uses: actions/checkout@v4
23
+
24
+ - name: Set up Python
25
+ uses: actions/setup-python@v5
26
+ with:
27
+ python-version: "3.12"
28
+
29
+ - name: Install build dependencies
30
+ run: |
31
+ python -m pip install --upgrade pip
32
+ pip install build
33
+
34
+ - name: Build package
35
+ run: python -m build
36
+
37
+ - name: Check distribution
38
+ run: |
39
+ pip install twine
40
+ twine check dist/*
41
+
42
+ - name: Create GitHub Release
43
+ uses: softprops/action-gh-release@v2
44
+ with:
45
+ files: dist/*
46
+ generate_release_notes: true
47
+ env:
48
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
49
+
50
+ - name: Publish to PyPI
51
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,48 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ lib/
14
+ lib64/
15
+ parts/
16
+ sdist/
17
+ var/
18
+ wheels/
19
+ *.egg-info/
20
+ .installed.cfg
21
+ *.egg
22
+
23
+ # Virtual environments
24
+ venv/
25
+ ENV/
26
+ env/
27
+ .venv
28
+
29
+ # Testing
30
+ .pytest_cache/
31
+ .coverage
32
+ htmlcov/
33
+ .tox/
34
+
35
+ # IDEs
36
+ .vscode/
37
+ .idea/
38
+ *.swp
39
+ *.swo
40
+ *~
41
+
42
+ # Documentation
43
+ docs/_build/
44
+ site/
45
+
46
+ # OS
47
+ .DS_Store
48
+ Thumbs.db
@@ -0,0 +1,20 @@
1
+ # Read the Docs configuration file
2
+ # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
3
+
4
+ version: 2
5
+
6
+ build:
7
+ os: ubuntu-22.04
8
+ tools:
9
+ python: "3.12"
10
+
11
+ sphinx:
12
+ configuration: docs/conf.py
13
+ fail_on_warning: false
14
+
15
+ python:
16
+ install:
17
+ - method: pip
18
+ path: .
19
+ extra_requirements:
20
+ - docs
@@ -0,0 +1,94 @@
1
+ # Badge and Documentation Setup
2
+
3
+ This document explains the badges added to the README and the manual setup steps required.
4
+
5
+ ## Badges Added
6
+
7
+ ### 1. Read the Docs Badge
8
+ ```markdown
9
+ [![Documentation Status](https://readthedocs.org/projects/objectstate/badge/?version=latest)](https://objectstate.readthedocs.io/en/latest/?badge=latest)
10
+ ```
11
+ - **Status**: Should work automatically if objectstate is registered on ReadTheDocs
12
+ - **Link**: https://objectstate.readthedocs.io
13
+ - **Configuration**: `.readthedocs.yaml` is already configured
14
+
15
+ ### 2. Code Coverage Badge
16
+ ```markdown
17
+ [![Coverage](https://raw.githubusercontent.com/trissim/objectstate/main/.github/badges/coverage.svg)](https://trissim.github.io/objectstate/coverage/)
18
+ ```
19
+ - **Status**: Will be automatically updated by GitHub Actions workflow
20
+ - **Link**: https://trissim.github.io/objectstate/coverage/
21
+ - **Workflow**: `.github/workflows/coverage-pages.yml`
22
+
23
+ ## Manual Setup Required
24
+
25
+ ### 1. Enable GitHub Pages
26
+ The coverage badge and reports require GitHub Pages to be enabled:
27
+
28
+ 1. Go to: https://github.com/trissim/objectstate/settings/pages
29
+ 2. Under "Build and deployment":
30
+ - **Source**: Select "GitHub Actions"
31
+ 3. Save the settings
32
+
33
+ Once enabled, the coverage reports will be available at:
34
+ - Badge SVG: https://raw.githubusercontent.com/trissim/objectstate/main/.github/badges/coverage.svg
35
+ - Coverage Report: https://trissim.github.io/objectstate/coverage/
36
+
37
+ ### 2. Update Repository Description (Optional but Recommended)
38
+ To match the problem statement requirement:
39
+
40
+ 1. Go to: https://github.com/trissim/objectstate
41
+ 2. Click the ⚙️ (settings) icon next to "About"
42
+ 3. Add or update:
43
+ - **Description**: Generic lazy dataclass configuration framework with dual-axis inheritance
44
+ - **Website**: https://objectstate.readthedocs.io
45
+ - **Topics**: Add relevant tags like `python`, `configuration`, `dataclass`, etc.
46
+ 4. Save changes
47
+
48
+ ### 3. Verify ReadTheDocs Integration
49
+ Ensure the repository is properly linked to ReadTheDocs:
50
+
51
+ 1. Go to: https://readthedocs.org/dashboard/
52
+ 2. Verify `objectstate` project exists
53
+ 3. Check webhook is configured at: https://github.com/trissim/objectstate/settings/hooks
54
+ 4. Trigger a build to ensure documentation is up to date
55
+
56
+ ## How the Coverage Badge Works
57
+
58
+ The coverage badge is similar to the ezstitcher repository setup:
59
+
60
+ 1. On every push to `main` branch, the `coverage-pages.yml` workflow:
61
+ - Runs tests with coverage
62
+ - Generates a coverage badge SVG at `.github/badges/coverage.svg`
63
+ - Commits the badge back to the repository
64
+ - Deploys HTML coverage reports to GitHub Pages
65
+
66
+ 2. The badge in README.md links to:
67
+ - SVG file from the `main` branch (always up-to-date)
68
+ - Coverage report hosted on GitHub Pages
69
+
70
+ ## Testing the Setup
71
+
72
+ After enabling GitHub Pages:
73
+
74
+ 1. Push a commit to the `main` branch
75
+ 2. Wait for the "Tests, Coverage and GitHub Pages" workflow to complete
76
+ 3. Check that:
77
+ - The badge SVG was updated in `.github/badges/coverage.svg`
78
+ - The coverage report is available at https://trissim.github.io/objectstate/coverage/
79
+ - The badge in README shows the correct coverage percentage
80
+
81
+ ## Differences from Codecov
82
+
83
+ This setup uses GitHub Pages for coverage reports instead of Codecov.io:
84
+
85
+ **Advantages:**
86
+ - No external service account required
87
+ - No API tokens needed
88
+ - Works out of the box
89
+ - Reports hosted on your GitHub Pages
90
+
91
+ **CI Workflow:**
92
+ - The existing `ci.yml` workflow still uploads to Codecov if configured
93
+ - The new `coverage-pages.yml` workflow generates the badge and GitHub Pages
94
+ - Both can coexist - Codecov for CI checks, GitHub Pages for the badge
@@ -0,0 +1,81 @@
1
+ # ObjectState Documentation Audit
2
+
3
+ ## Summary
4
+ Found **3 critical documentation bugs** in README.md where examples reference non-existent API methods.
5
+
6
+ ## Issues Found
7
+
8
+ ### ❌ Issue 1: `undo()` and `redo()` methods don't exist
9
+ **Location**: README.md lines 124-125
10
+ **Current (WRONG)**:
11
+ ```python
12
+ ObjectStateRegistry.undo()
13
+ ObjectStateRegistry.redo()
14
+ ```
15
+
16
+ **Actual API**:
17
+ ```python
18
+ ObjectStateRegistry.time_travel_back() # Go one step back
19
+ ObjectStateRegistry.time_travel_forward() # Go one step forward
20
+ ```
21
+
22
+ **Fix**: Replace with correct method names
23
+
24
+ ---
25
+
26
+ ### ❌ Issue 2: `get_branch_history()` returns Snapshot objects, not with `.id` attribute
27
+ **Location**: README.md line 133
28
+ **Current (CORRECT)**: `history = ObjectStateRegistry.get_branch_history()`
29
+ **But line 134 is WRONG**:
30
+ ```python
31
+ ObjectStateRegistry.time_travel_to_snapshot(history[5].id)
32
+ ```
33
+
34
+ **Actual**: `Snapshot` objects DO have `.id` attribute ✓ (This is correct)
35
+
36
+ ---
37
+
38
+ ### ❌ Issue 3: Missing `atomic()` context manager documentation
39
+ **Location**: README.md lines 128-130
40
+ **Current**: Shows `atomic()` usage
41
+ **Status**: ✓ CORRECT - `atomic()` method exists and works as documented
42
+
43
+ ---
44
+
45
+ ## Additional Findings
46
+
47
+ ### ✓ Correct API Methods (verified in code):
48
+ - `ObjectStateRegistry.register(state)` ✓
49
+ - `ObjectStateRegistry.unregister(state)` ✓
50
+ - `ObjectStateRegistry.get_by_scope(scope_id)` ✓
51
+ - `ObjectStateRegistry.get_all()` ✓
52
+ - `state.update_parameter(field, value)` ✓
53
+ - `state.save()` ✓
54
+ - `state.restore_saved()` ✓
55
+ - `ObjectStateRegistry.atomic(label)` ✓
56
+ - `ObjectStateRegistry.get_branch_history()` ✓
57
+ - `ObjectStateRegistry.time_travel_to_snapshot(id)` ✓
58
+ - `ObjectStateRegistry.time_travel_to_head()` ✓
59
+ - `ObjectStateRegistry.create_branch(name, description)` ✓
60
+ - `ObjectStateRegistry.switch_branch(name)` ✓
61
+ - `ObjectStateRegistry.list_branches()` ✓
62
+ - `ObjectStateRegistry.export_history_to_dict()` ✓
63
+ - `ObjectStateRegistry.import_history_from_dict(data)` ✓
64
+ - `ObjectStateRegistry.save_history_to_file(path)` ✓
65
+ - `ObjectStateRegistry.load_history_from_file(path)` ✓
66
+
67
+ ### ✓ ObjectState class methods (verified):
68
+ - `state.dirty_fields` ✓
69
+ - `state.save()` ✓
70
+ - `state.restore_saved()` ✓
71
+ - `state.update_parameter(field, value)` ✓
72
+
73
+ ## Recommended Fixes
74
+
75
+ 1. **Replace `undo()`/`redo()` with `time_travel_back()`/`time_travel_forward()`**
76
+ 2. **Add note about time-travel semantics** (not traditional undo/redo)
77
+ 3. **Consider adding convenience aliases** if backward compatibility needed
78
+
79
+ ## Status
80
+ Ready for implementation
81
+