regkit 0.3.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.
- regkit-0.3.0/.github/copilot-instructions.md +53 -0
- regkit-0.3.0/.github/workflows/ci.yml +53 -0
- regkit-0.3.0/.github/workflows/docs.yml +59 -0
- regkit-0.3.0/.github/workflows/publish.yml +85 -0
- regkit-0.3.0/.gitignore +66 -0
- regkit-0.3.0/.python-version +1 -0
- regkit-0.3.0/CHANGELOG.md +78 -0
- regkit-0.3.0/LICENSE +21 -0
- regkit-0.3.0/PKG-INFO +178 -0
- regkit-0.3.0/README.md +160 -0
- regkit-0.3.0/docs/api.md +5 -0
- regkit-0.3.0/docs/index.md +27 -0
- regkit-0.3.0/mkdocs.yml +22 -0
- regkit-0.3.0/pyproject.toml +43 -0
- regkit-0.3.0/src/regkit/__init__.py +3 -0
- regkit-0.3.0/src/regkit/py.typed +0 -0
- regkit-0.3.0/src/regkit/registry.py +635 -0
- regkit-0.3.0/tests/__init__.py +0 -0
- regkit-0.3.0/tests/conftest.py +125 -0
- regkit-0.3.0/tests/fakewinreg.py +408 -0
- regkit-0.3.0/tests/test_fakewinreg_api.py +587 -0
- regkit-0.3.0/tests/test_key_class.py +803 -0
- regkit-0.3.0/uv.lock +771 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Copilot Instructions for regkit
|
|
2
|
+
|
|
3
|
+
## Project context
|
|
4
|
+
- `regkit` is a small Python library around Windows Registry operations.
|
|
5
|
+
- Main implementation lives in `src/regkit/`.
|
|
6
|
+
- Tests rely heavily on `tests/fakewinreg.py` to validate behavior on non-Windows and to compare against real `winreg` when available.
|
|
7
|
+
|
|
8
|
+
## Tech and tooling
|
|
9
|
+
- Python version target: **3.11+**.
|
|
10
|
+
- Packaging/build: `hatchling` (`pyproject.toml`).
|
|
11
|
+
- Environment/dependency workflow uses **uv**.
|
|
12
|
+
- Version management should use `uv version` (e.g. `uv version --bump patch`, `uv version 0.0.1rc1`) instead of manually editing `pyproject.toml`.
|
|
13
|
+
- Type checking uses **mypy strict mode** on `src/regkit`.
|
|
14
|
+
- Linting/import order uses **ruff** with import sorting (`I`).
|
|
15
|
+
|
|
16
|
+
## Code style and implementation rules
|
|
17
|
+
- Keep changes minimal and focused; do not refactor unrelated code.
|
|
18
|
+
- Preserve existing API shape and naming unless explicitly asked.
|
|
19
|
+
- Prefer explicit type annotations that satisfy strict mypy.
|
|
20
|
+
- Follow existing patterns:
|
|
21
|
+
- `Key` methods raise `KeyError` for missing values/keys where the library API currently does so.
|
|
22
|
+
- Low-level backend exceptions (`FileNotFoundError`, `OSError`, `PermissionError`) are translated only where the current code already translates them.
|
|
23
|
+
- Keep compatibility with both real `winreg` and `tests.fakewinreg` behavior.
|
|
24
|
+
- Avoid platform-specific assumptions that would break tests on non-Windows.
|
|
25
|
+
|
|
26
|
+
## Testing expectations
|
|
27
|
+
- Run targeted tests first for touched behavior, then broader tests.
|
|
28
|
+
- Typical commands:
|
|
29
|
+
- `uv sync --dev`
|
|
30
|
+
- `pytest`
|
|
31
|
+
- If type-significant code is changed, also run:
|
|
32
|
+
- `uv run mypy src/regkit`
|
|
33
|
+
|
|
34
|
+
## File-specific guidance
|
|
35
|
+
- `src/regkit/registry.py` is the core behavior surface; changes here should preserve context-manager and handle lifecycle semantics (`open`, `close`, `opened`, `create`, `delete`).
|
|
36
|
+
- `tests/fakewinreg.py` is a behavioral compatibility shim. If production behavior changes, update tests and shim only when required by the requested change.
|
|
37
|
+
- CLI (`src/regkit/cli.py`) is intentionally minimal currently; do not expand it unless requested.
|
|
38
|
+
|
|
39
|
+
## When adding or changing code
|
|
40
|
+
- Add/adjust tests in `tests/` for any behavior change.
|
|
41
|
+
- Keep imports sorted and remove unused imports.
|
|
42
|
+
- Keep docstrings concise and consistent with existing style.
|
|
43
|
+
- Prefer straightforward implementations over abstractions.
|
|
44
|
+
- Update `CHANGELOG.md` for release-worthy changes (including `rc`/pre-release tags).
|
|
45
|
+
- Keep changelog entries concise and user-facing; avoid listing individual development bug-fix details.
|
|
46
|
+
|
|
47
|
+
## Things to double-check before finishing
|
|
48
|
+
- No accidental public API breaks in `regkit.__init__` exports.
|
|
49
|
+
- Tests pass locally.
|
|
50
|
+
- New code passes strict typing.
|
|
51
|
+
- Run `uvx ruff check` and `uvx ruff format --check` before pushing.
|
|
52
|
+
- For any version bump via `uv version`, ensure `uv.lock` is updated, committed, and pushed with the release changes.
|
|
53
|
+
- No unrelated formatting-only churn.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- master
|
|
7
|
+
- main
|
|
8
|
+
tags:
|
|
9
|
+
- "v*"
|
|
10
|
+
pull_request:
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
test:
|
|
14
|
+
name: ${{ matrix.os }} / py${{ matrix.python-version }}
|
|
15
|
+
runs-on: ${{ matrix.os }}
|
|
16
|
+
strategy:
|
|
17
|
+
fail-fast: false
|
|
18
|
+
matrix:
|
|
19
|
+
os: [ubuntu-latest, windows-latest]
|
|
20
|
+
python-version: ["3.11", "3.12", "3.13", "3.14"]
|
|
21
|
+
exclude:
|
|
22
|
+
- os: windows-latest
|
|
23
|
+
python-version: "3.11"
|
|
24
|
+
- os: windows-latest
|
|
25
|
+
python-version: "3.12"
|
|
26
|
+
- os: windows-latest
|
|
27
|
+
python-version: "3.13"
|
|
28
|
+
|
|
29
|
+
steps:
|
|
30
|
+
- name: Checkout
|
|
31
|
+
uses: actions/checkout@v4
|
|
32
|
+
|
|
33
|
+
- name: Install uv
|
|
34
|
+
uses: astral-sh/setup-uv@v7
|
|
35
|
+
with:
|
|
36
|
+
python-version: ${{ matrix.python-version }}
|
|
37
|
+
enable-cache: true
|
|
38
|
+
|
|
39
|
+
- name: Lint (ruff)
|
|
40
|
+
run: uvx ruff check
|
|
41
|
+
|
|
42
|
+
- name: Format check (ruff)
|
|
43
|
+
run: uvx ruff format --check
|
|
44
|
+
|
|
45
|
+
- name: Sync dependencies
|
|
46
|
+
run: uv sync --locked --dev
|
|
47
|
+
|
|
48
|
+
- name: Run tests
|
|
49
|
+
run: uv run pytest
|
|
50
|
+
|
|
51
|
+
- name: Type check (mypy)
|
|
52
|
+
if: runner.os == 'Windows'
|
|
53
|
+
run: uv run mypy src/regkit
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
name: Docs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- master
|
|
7
|
+
- main
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
pages: write
|
|
13
|
+
id-token: write
|
|
14
|
+
|
|
15
|
+
concurrency:
|
|
16
|
+
group: pages
|
|
17
|
+
cancel-in-progress: true
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
build:
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
|
|
23
|
+
steps:
|
|
24
|
+
- name: Checkout
|
|
25
|
+
uses: actions/checkout@v4
|
|
26
|
+
|
|
27
|
+
- name: Set up Python
|
|
28
|
+
uses: actions/setup-python@v5
|
|
29
|
+
with:
|
|
30
|
+
python-version: "3.12"
|
|
31
|
+
|
|
32
|
+
- name: Install uv
|
|
33
|
+
uses: astral-sh/setup-uv@v7
|
|
34
|
+
with:
|
|
35
|
+
python-version: "3.12"
|
|
36
|
+
enable-cache: true
|
|
37
|
+
|
|
38
|
+
- name: Sync docs dependencies
|
|
39
|
+
run: uv sync --group docs
|
|
40
|
+
|
|
41
|
+
- name: Build docs
|
|
42
|
+
run: uv run mkdocs build --strict
|
|
43
|
+
|
|
44
|
+
- name: Upload Pages artifact
|
|
45
|
+
uses: actions/upload-pages-artifact@v3
|
|
46
|
+
with:
|
|
47
|
+
path: site
|
|
48
|
+
|
|
49
|
+
deploy:
|
|
50
|
+
environment:
|
|
51
|
+
name: github-pages
|
|
52
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
53
|
+
runs-on: ubuntu-latest
|
|
54
|
+
needs: build
|
|
55
|
+
|
|
56
|
+
steps:
|
|
57
|
+
- name: Deploy to GitHub Pages
|
|
58
|
+
id: deployment
|
|
59
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_run:
|
|
5
|
+
workflows:
|
|
6
|
+
- CI
|
|
7
|
+
types:
|
|
8
|
+
- completed
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
detect-tag:
|
|
12
|
+
if: github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'push'
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
outputs:
|
|
15
|
+
publish_tag: ${{ steps.tag.outputs.publish_tag }}
|
|
16
|
+
commit_sha: ${{ steps.sha.outputs.commit_sha }}
|
|
17
|
+
|
|
18
|
+
steps:
|
|
19
|
+
- name: Checkout
|
|
20
|
+
uses: actions/checkout@v4
|
|
21
|
+
with:
|
|
22
|
+
fetch-depth: 0
|
|
23
|
+
|
|
24
|
+
- name: Capture CI commit SHA
|
|
25
|
+
id: sha
|
|
26
|
+
run: echo "commit_sha=${{ github.event.workflow_run.head_sha }}" >> "$GITHUB_OUTPUT"
|
|
27
|
+
|
|
28
|
+
- name: Detect version tag at CI commit
|
|
29
|
+
id: tag
|
|
30
|
+
run: |
|
|
31
|
+
git fetch --tags --force
|
|
32
|
+
TAG=$(git tag --points-at "${{ github.event.workflow_run.head_sha }}" | grep '^v' | head -n 1 || true)
|
|
33
|
+
echo "publish_tag=$TAG" >> "$GITHUB_OUTPUT"
|
|
34
|
+
|
|
35
|
+
publish:
|
|
36
|
+
needs: detect-tag
|
|
37
|
+
if: needs.detect-tag.outputs.publish_tag != ''
|
|
38
|
+
runs-on: ubuntu-latest
|
|
39
|
+
permissions:
|
|
40
|
+
id-token: write
|
|
41
|
+
contents: write
|
|
42
|
+
|
|
43
|
+
environment:
|
|
44
|
+
name: pypi
|
|
45
|
+
|
|
46
|
+
steps:
|
|
47
|
+
- name: Checkout
|
|
48
|
+
uses: actions/checkout@v4
|
|
49
|
+
with:
|
|
50
|
+
ref: ${{ needs.detect-tag.outputs.commit_sha }}
|
|
51
|
+
|
|
52
|
+
- name: Install uv
|
|
53
|
+
uses: astral-sh/setup-uv@v7
|
|
54
|
+
with:
|
|
55
|
+
python-version: "3.12"
|
|
56
|
+
enable-cache: true
|
|
57
|
+
|
|
58
|
+
- name: Build distributions
|
|
59
|
+
run: uv build
|
|
60
|
+
|
|
61
|
+
- name: Verify built artifacts
|
|
62
|
+
run: ls -la dist
|
|
63
|
+
|
|
64
|
+
- name: Publish to PyPI
|
|
65
|
+
run: uv publish
|
|
66
|
+
|
|
67
|
+
- name: Create GitHub Release
|
|
68
|
+
env:
|
|
69
|
+
GH_TOKEN: ${{ github.token }}
|
|
70
|
+
TAG: ${{ needs.detect-tag.outputs.publish_tag }}
|
|
71
|
+
run: |
|
|
72
|
+
gh release view "$TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1 && exit 0
|
|
73
|
+
|
|
74
|
+
PRERELEASE_FLAG=""
|
|
75
|
+
case "$TAG" in
|
|
76
|
+
*a*|*b*|*rc*|*dev*) PRERELEASE_FLAG="--prerelease" ;;
|
|
77
|
+
esac
|
|
78
|
+
|
|
79
|
+
gh release create "$TAG" dist/* \
|
|
80
|
+
--repo "$GITHUB_REPOSITORY" \
|
|
81
|
+
--verify-tag \
|
|
82
|
+
--title "$TAG" \
|
|
83
|
+
--generate-notes \
|
|
84
|
+
--notes "See CHANGELOG.md for curated release details." \
|
|
85
|
+
$PRERELEASE_FLAG
|
regkit-0.3.0/.gitignore
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.pyo
|
|
5
|
+
*.pyd
|
|
6
|
+
*.pyc
|
|
7
|
+
|
|
8
|
+
# Distribution / packaging
|
|
9
|
+
.Python
|
|
10
|
+
build/
|
|
11
|
+
dist/
|
|
12
|
+
site/
|
|
13
|
+
*.egg-info/
|
|
14
|
+
.eggs/
|
|
15
|
+
*.egg
|
|
16
|
+
|
|
17
|
+
# Installer logs
|
|
18
|
+
pip-log.txt
|
|
19
|
+
pip-delete-this-directory.txt
|
|
20
|
+
|
|
21
|
+
# Unit test / coverage reports
|
|
22
|
+
htmlcov/
|
|
23
|
+
.tox/
|
|
24
|
+
.nox/
|
|
25
|
+
.coverage
|
|
26
|
+
.coverage.*
|
|
27
|
+
.cache
|
|
28
|
+
nosetests.xml
|
|
29
|
+
coverage.xml
|
|
30
|
+
*.cover
|
|
31
|
+
*.py,cover
|
|
32
|
+
.hypothesis/
|
|
33
|
+
.pytest_cache/
|
|
34
|
+
|
|
35
|
+
# Jupyter Notebook
|
|
36
|
+
.ipynb_checkpoints
|
|
37
|
+
|
|
38
|
+
# VS Code
|
|
39
|
+
.vscode/
|
|
40
|
+
|
|
41
|
+
# Environments
|
|
42
|
+
.env
|
|
43
|
+
.venv
|
|
44
|
+
env/
|
|
45
|
+
venv/
|
|
46
|
+
ENV/
|
|
47
|
+
|
|
48
|
+
# mypy
|
|
49
|
+
.mypy_cache/
|
|
50
|
+
.dmypy.json
|
|
51
|
+
|
|
52
|
+
# Ruff
|
|
53
|
+
.ruff_cache/
|
|
54
|
+
|
|
55
|
+
# Other
|
|
56
|
+
*.log
|
|
57
|
+
*.pot
|
|
58
|
+
*.mo
|
|
59
|
+
*.swp
|
|
60
|
+
*.swo
|
|
61
|
+
|
|
62
|
+
# Mac
|
|
63
|
+
.DS_Store
|
|
64
|
+
|
|
65
|
+
# Windows
|
|
66
|
+
Thumbs.db
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.14
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## Unreleased
|
|
6
|
+
|
|
7
|
+
No tracked entries yet.
|
|
8
|
+
|
|
9
|
+
## 0.3.0 - 2026-02-24
|
|
10
|
+
|
|
11
|
+
Minor release for package and project rename.
|
|
12
|
+
|
|
13
|
+
- Renamed package distribution from `winregkit` to `regkit`.
|
|
14
|
+
- Renamed source package path from `src/winregkit` to `src/regkit`.
|
|
15
|
+
- Updated docs, CI, tests, and project metadata references to `regkit`.
|
|
16
|
+
- Updated repository/docs URLs to `kristjanvalur/regkit`.
|
|
17
|
+
|
|
18
|
+
## 0.2.1 - 2026-02-22
|
|
19
|
+
|
|
20
|
+
Patch release refining canonical path identity semantics.
|
|
21
|
+
|
|
22
|
+
- Canonical comparison/hashing now always derives the root label from the root handle.
|
|
23
|
+
- Root-node lexical labels are normalized away for canonical identity (for example, `Key(100, "foo")` and `Key(100, "bar")` now compare/hash the same at root level).
|
|
24
|
+
|
|
25
|
+
## 0.2.0 - 2026-02-22
|
|
26
|
+
|
|
27
|
+
Minor release extending pathlib-style key path ergonomics.
|
|
28
|
+
|
|
29
|
+
- Added `Key.parent` and `Key.parents()` for lexical ancestor navigation.
|
|
30
|
+
- Added `Key.parts` plus `Key.from_parts(...)` / `Key.from_path(...)` for path round-tripping.
|
|
31
|
+
- Simplified rooted-key construction internals (`from_parts(...)` now uses direct rooted construction).
|
|
32
|
+
- **Breaking:** `Key.name` now returns only the final lexical segment; internal full relative path storage is kept private.
|
|
33
|
+
- Added `Key.iterdir()`, `Key.joinpath(...)`, `/` operator composition, and `Key.walk(...)` traversal (`os.walk`-like).
|
|
34
|
+
|
|
35
|
+
## 0.1.3 - 2026-02-22
|
|
36
|
+
|
|
37
|
+
Patch release adding traversal and pathlib-style path ergonomics.
|
|
38
|
+
|
|
39
|
+
- Added `Key.walk(...)` with `os.walk`-like semantics for key-tree traversal.
|
|
40
|
+
- Added `Key.iterdir()` as a pathlib-style alias for subkey iteration.
|
|
41
|
+
- Added `Key.joinpath(...)` and `/` operator support for key path composition.
|
|
42
|
+
- Expanded README method reference and examples for new traversal/path APIs.
|
|
43
|
+
|
|
44
|
+
## 0.1.2 - 2026-02-21
|
|
45
|
+
|
|
46
|
+
Patch release adding typing metadata for downstream type checkers.
|
|
47
|
+
|
|
48
|
+
- Added `py.typed` marker to declare inline typing support in `regkit` (PEP 561).
|
|
49
|
+
|
|
50
|
+
## 0.1.1 - 2026-02-21
|
|
51
|
+
|
|
52
|
+
Patch release to validate automated GitHub Release notes.
|
|
53
|
+
|
|
54
|
+
- Publish workflow now uses GitHub-generated release notes for tag releases.
|
|
55
|
+
|
|
56
|
+
## 0.1.0 - 2026-02-21
|
|
57
|
+
|
|
58
|
+
First stable 0.1 release.
|
|
59
|
+
|
|
60
|
+
- Finalizes the 0.1 API surface for key traversal, typed value operations, and path-based key construction.
|
|
61
|
+
- Strengthens test coverage across fake and real backends, with backend-selective test flags for CI and local runs.
|
|
62
|
+
- Enforces formatting checks in CI alongside linting, tests, and Windows mypy checks.
|
|
63
|
+
|
|
64
|
+
## 0.1.0rc2 - 2026-02-21
|
|
65
|
+
|
|
66
|
+
Second release candidate for the 0.1 line.
|
|
67
|
+
|
|
68
|
+
- Publish workflow now creates a basic GitHub Release alongside PyPI publication.
|
|
69
|
+
- Release automation now avoids duplicate publish attempts from branch-triggered CI runs.
|
|
70
|
+
|
|
71
|
+
## 0.1.0rc1 - 2026-02-21
|
|
72
|
+
|
|
73
|
+
Initial release candidate for the 0.1 line.
|
|
74
|
+
|
|
75
|
+
- API surface refined for clearer typed value access and iteration naming.
|
|
76
|
+
- Cross-platform test strategy stabilized for real Windows `winreg` and fake backend coverage.
|
|
77
|
+
- CI and publish workflows aligned around `uv` tooling with release-tag-driven publishing.
|
|
78
|
+
- Project release/version workflow standardized on `uv version`.
|
regkit-0.3.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Kristján Valur Jónsson
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
regkit-0.3.0/PKG-INFO
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: regkit
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: A modern, pythonic interface to the Windows registry.
|
|
5
|
+
Project-URL: Homepage, https://github.com/kristjanvalur/regkit
|
|
6
|
+
Project-URL: Repository, https://github.com/kristjanvalur/regkit
|
|
7
|
+
Project-URL: Documentation, https://kristjanvalur.github.io/regkit/
|
|
8
|
+
Project-URL: Changelog, https://github.com/kristjanvalur/regkit/blob/main/CHANGELOG.md
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
16
|
+
Requires-Python: >=3.11
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
|
|
19
|
+
# regkit
|
|
20
|
+
|
|
21
|
+
[](https://github.com/kristjanvalur/regkit/actions/workflows/ci.yml)
|
|
22
|
+
|
|
23
|
+
A modern, pythonic interface to the Windows registry.
|
|
24
|
+
|
|
25
|
+
## Introduction
|
|
26
|
+
|
|
27
|
+
Python comes with `winreg` for registry operations, but it is a thin wrapper over
|
|
28
|
+
Win32 APIs and can be cumbersome for day-to-day usage.
|
|
29
|
+
|
|
30
|
+
`regkit` provides a higher-level, object-oriented interface with simple tree
|
|
31
|
+
navigation, dict-like value access, and context-manager support.
|
|
32
|
+
|
|
33
|
+
## Features
|
|
34
|
+
- Easy-to-use API for reading and writing Windows Registry keys
|
|
35
|
+
- Python 3.11+
|
|
36
|
+
- Windows platform
|
|
37
|
+
- MIT License
|
|
38
|
+
- Managed and built with [uv](https://github.com/astral-sh/uv)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
## Installation
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
pip install regkit
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Or the equivalent command in your preferred package manager.
|
|
48
|
+
|
|
49
|
+
## Usage
|
|
50
|
+
|
|
51
|
+
### Library
|
|
52
|
+
```python
|
|
53
|
+
from regkit import current_user
|
|
54
|
+
import winreg
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
# open for read
|
|
58
|
+
with current_user.subkey("Software", "MyApp").open() as key:
|
|
59
|
+
print(key["name"])
|
|
60
|
+
print(key.get("missing", "default"))
|
|
61
|
+
|
|
62
|
+
# open for write (subkeys can be passed directly to open as a convenience)
|
|
63
|
+
with current_user.open("Software", "MyApp", write=True) as key:
|
|
64
|
+
key["name"] = "regkit"
|
|
65
|
+
key["enabled"] = 1
|
|
66
|
+
|
|
67
|
+
# pathlib-style path concatenation is also supported via "/"
|
|
68
|
+
with (current_user / "Software" / "MyApp").open(write=True) as key:
|
|
69
|
+
key["theme"] = "dark"
|
|
70
|
+
|
|
71
|
+
# create/open for write (create is shorthand for open(create=True, write=True))
|
|
72
|
+
with current_user.create("Software", "MyApp") as key:
|
|
73
|
+
key["name"] = "regkit"
|
|
74
|
+
key["enabled"] = 1
|
|
75
|
+
|
|
76
|
+
# the Key object provides dict access and values can be iterated over:
|
|
77
|
+
with current_user.open("Software", "MyApp") as key:
|
|
78
|
+
for name, value in key.items():
|
|
79
|
+
print(name, value)
|
|
80
|
+
|
|
81
|
+
# the underlying type of a value can be retrieved, and a custom type can be
|
|
82
|
+
# set, overriding default conversions:
|
|
83
|
+
with current_user.open("Software", "MyApp", write=True) as key:
|
|
84
|
+
value, value_type = key.get_typed("enabled")
|
|
85
|
+
print(value, value_type)
|
|
86
|
+
|
|
87
|
+
key.set_typed("payload", b"\x00\x01\x02", winreg.REG_BINARY)
|
|
88
|
+
|
|
89
|
+
# existence checks are available on keys:
|
|
90
|
+
app_key = current_user.subkey("Software", "MyApp")
|
|
91
|
+
print(app_key.exists())
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
`subkey(...)` is optional convenience for pre-building a path. You can either
|
|
96
|
+
chain with `subkey(...)` first, or pass subkeys directly to `open(...)` / `create(...)`.
|
|
97
|
+
|
|
98
|
+
### Typical workflow
|
|
99
|
+
- Use root factories (`current_user`, `local_machine`, etc.)
|
|
100
|
+
- Navigate with `subkey(...)` (optional)
|
|
101
|
+
- Open with `open(...)` or `create(...)` and a context manager
|
|
102
|
+
- Use dict-style value access (`key[name]`, `key[name] = value`)
|
|
103
|
+
- Use `get_typed` / `set_typed` only when explicit registry types are needed
|
|
104
|
+
|
|
105
|
+
### Using registry paths
|
|
106
|
+
`Key` supports constructing and round-tripping full registry paths.
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
from regkit import Key
|
|
110
|
+
|
|
111
|
+
# Construct from explicit path parts
|
|
112
|
+
key = Key.from_parts(("HKCU", "Software", "MyApp"))
|
|
113
|
+
|
|
114
|
+
# Construct from a full path string (either HKCU or HKEY_CURRENT_USER style)
|
|
115
|
+
same_key = Key.from_path(r"HKEY_CURRENT_USER\Software\MyApp")
|
|
116
|
+
|
|
117
|
+
# Read parts back (root token + subkey parts)
|
|
118
|
+
assert key.parts == ("HKCU", "Software", "MyApp")
|
|
119
|
+
|
|
120
|
+
# name is the final lexical segment
|
|
121
|
+
assert key.name == "MyApp"
|
|
122
|
+
|
|
123
|
+
# parents() returns lexical ancestors from nearest parent upward
|
|
124
|
+
assert [ancestor.name for ancestor in key.parents()] == ["Software", "HKCU"]
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Use `from_parts(...)` when you already have tokenized components, and
|
|
128
|
+
`from_path(...)` when parsing user-provided registry path strings.
|
|
129
|
+
|
|
130
|
+
### `Key` methods at a glance
|
|
131
|
+
- `subkey(*parts)`: build a child key path without opening it
|
|
132
|
+
- `open(...)`: return a new opened key for read/write access
|
|
133
|
+
- `create(*parts)`: shorthand for creating/opening a key for writing
|
|
134
|
+
- `exists()`: check whether a key exists
|
|
135
|
+
- `walk(...)`: traverse a key tree, yielding `(key, subkey_names, value_names)` (similar to `os.walk()`)
|
|
136
|
+
- `keys()`, `values()`, `items()`: iterate value names, values, or `(name, value)` pairs
|
|
137
|
+
- `name`: final lexical path segment for this key
|
|
138
|
+
- `parts`: tuple of key path components, including root token when present
|
|
139
|
+
- `parent`: lexical parent key (or `None` at registry root)
|
|
140
|
+
- `parents()`: tuple of lexical ancestors from immediate parent up to root
|
|
141
|
+
- `get(name, ...)`: read a value with fallback default
|
|
142
|
+
- `get_typed(...)` / `set_typed(...)`: read/write values with explicit registry type
|
|
143
|
+
- `value_del(name)` or `del key[name]`: delete a value
|
|
144
|
+
- `delete(...)`: delete a key (optionally recursively)
|
|
145
|
+
- `as_dict()` / `from_dict(data)`: export/import a subtree structure
|
|
146
|
+
|
|
147
|
+
### Default value name
|
|
148
|
+
The registry's default (unnamed) value is represented by the empty string (`""`).
|
|
149
|
+
|
|
150
|
+
- Iteration methods (`items()`, `items_typed()`, `keys()`) return `""` for the default value name.
|
|
151
|
+
- Set/delete helpers also accept `None` as an equivalent.
|
|
152
|
+
|
|
153
|
+
## Development
|
|
154
|
+
|
|
155
|
+
This project uses the [uv](https://docs.astral.sh/uv/) package manager.
|
|
156
|
+
|
|
157
|
+
- Install uv, e.g. using `pip install uv`
|
|
158
|
+
|
|
159
|
+
- Install dev dependencies:
|
|
160
|
+
```sh
|
|
161
|
+
uv sync --dev
|
|
162
|
+
```
|
|
163
|
+
- Run tests:
|
|
164
|
+
```sh
|
|
165
|
+
uv run pytest
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
- Build docs:
|
|
169
|
+
```sh
|
|
170
|
+
uv sync --group docs
|
|
171
|
+
uv run mkdocs build --strict
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## License
|
|
175
|
+
MIT License. See `LICENSE` for details.
|
|
176
|
+
|
|
177
|
+
## Changelog
|
|
178
|
+
See `CHANGELOG.md` for release history and policy.
|