nono-py 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.
- nono_py-0.1.0/.github/workflows/ci.yml +145 -0
- nono_py-0.1.0/.github/workflows/docs-dispatch.yml +19 -0
- nono_py-0.1.0/.github/workflows/publish.yml +170 -0
- nono_py-0.1.0/.github/workflows/release.yml +28 -0
- nono_py-0.1.0/.gitignore +38 -0
- nono_py-0.1.0/.python-version +1 -0
- nono_py-0.1.0/CLAUDE.md +67 -0
- nono_py-0.1.0/Cargo.lock +1026 -0
- nono_py-0.1.0/Cargo.toml +18 -0
- nono_py-0.1.0/DEVELOPMENT.md +320 -0
- nono_py-0.1.0/LICENSE +201 -0
- nono_py-0.1.0/Makefile +101 -0
- nono_py-0.1.0/PKG-INFO +239 -0
- nono_py-0.1.0/README.md +208 -0
- nono_py-0.1.0/assets/nono-py.png +0 -0
- nono_py-0.1.0/docs/assets/nono-py.png +0 -0
- nono_py-0.1.0/docs/docs.json +57 -0
- nono_py-0.1.0/docs/python/api/access-mode.mdx +112 -0
- nono_py-0.1.0/docs/python/api/capability-set.mdx +306 -0
- nono_py-0.1.0/docs/python/api/capability-source.mdx +96 -0
- nono_py-0.1.0/docs/python/api/fs-capability.mdx +166 -0
- nono_py-0.1.0/docs/python/api/functions.mdx +200 -0
- nono_py-0.1.0/docs/python/api/query-context.mdx +254 -0
- nono_py-0.1.0/docs/python/api/sandbox-state.mdx +270 -0
- nono_py-0.1.0/docs/python/api/support-info.mdx +106 -0
- nono_py-0.1.0/docs/python/examples.mdx +368 -0
- nono_py-0.1.0/docs/python/installation.mdx +151 -0
- nono_py-0.1.0/docs/python/overview.mdx +87 -0
- nono_py-0.1.0/docs/python/quickstart.mdx +196 -0
- nono_py-0.1.0/examples/01_basic_sandbox.py +69 -0
- nono_py-0.1.0/examples/02_query_permissions.py +97 -0
- nono_py-0.1.0/examples/03_sandbox_state.py +93 -0
- nono_py-0.1.0/examples/04_capability_inspection.py +121 -0
- nono_py-0.1.0/examples/05_subprocess_sandbox.py +133 -0
- nono_py-0.1.0/examples/06_command_filtering.py +99 -0
- nono_py-0.1.0/examples/07_error_handling.py +190 -0
- nono_py-0.1.0/examples/README.md +101 -0
- nono_py-0.1.0/nono/Cargo.toml +51 -0
- nono_py-0.1.0/nono/crates/nono/Cargo.toml +43 -0
- nono_py-0.1.0/nono/crates/nono/README.md +54 -0
- nono_py-0.1.0/nono/crates/nono/src/capability.rs +1055 -0
- nono_py-0.1.0/nono/crates/nono/src/diagnostic.rs +703 -0
- nono_py-0.1.0/nono/crates/nono/src/error.rs +146 -0
- nono_py-0.1.0/nono/crates/nono/src/keystore.rs +192 -0
- nono_py-0.1.0/nono/crates/nono/src/lib.rs +67 -0
- nono_py-0.1.0/nono/crates/nono/src/query.rs +233 -0
- nono_py-0.1.0/nono/crates/nono/src/sandbox/linux.rs +931 -0
- nono_py-0.1.0/nono/crates/nono/src/sandbox/macos.rs +845 -0
- nono_py-0.1.0/nono/crates/nono/src/sandbox/mod.rs +144 -0
- nono_py-0.1.0/nono/crates/nono/src/state.rs +152 -0
- nono_py-0.1.0/nono/crates/nono/src/supervisor/mod.rs +178 -0
- nono_py-0.1.0/nono/crates/nono/src/supervisor/never_grant.rs +300 -0
- nono_py-0.1.0/nono/crates/nono/src/supervisor/socket.rs +510 -0
- nono_py-0.1.0/nono/crates/nono/src/supervisor/types.rs +95 -0
- nono_py-0.1.0/nono/crates/nono/src/undo/exclusion.rs +284 -0
- nono_py-0.1.0/nono/crates/nono/src/undo/merkle.rs +235 -0
- nono_py-0.1.0/nono/crates/nono/src/undo/mod.rs +17 -0
- nono_py-0.1.0/nono/crates/nono/src/undo/object_store.rs +481 -0
- nono_py-0.1.0/nono/crates/nono/src/undo/snapshot.rs +1020 -0
- nono_py-0.1.0/nono/crates/nono/src/undo/types.rs +283 -0
- nono_py-0.1.0/pyproject.toml +77 -0
- nono_py-0.1.0/python/nono_py/__init__.py +55 -0
- nono_py-0.1.0/python/nono_py/_nono_py.pyi +274 -0
- nono_py-0.1.0/python/nono_py/py.typed +0 -0
- nono_py-0.1.0/src/lib.rs +685 -0
- nono_py-0.1.0/tests/conftest.py +17 -0
- nono_py-0.1.0/tests/test_access_mode.py +56 -0
- nono_py-0.1.0/tests/test_capability_set.py +194 -0
- nono_py-0.1.0/tests/test_query.py +137 -0
- nono_py-0.1.0/tests/test_sandbox_state.py +128 -0
- nono_py-0.1.0/tests/test_support.py +80 -0
- nono_py-0.1.0/uv.lock +440 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
env:
|
|
10
|
+
CARGO_TERM_COLOR: always
|
|
11
|
+
PYTHON_VERSION: "3.12"
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
lint-rust:
|
|
15
|
+
name: Lint Rust
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
19
|
+
|
|
20
|
+
- name: Checkout nono library
|
|
21
|
+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
22
|
+
with:
|
|
23
|
+
repository: always-further/nono
|
|
24
|
+
path: nono
|
|
25
|
+
|
|
26
|
+
- name: Install Rust toolchain
|
|
27
|
+
uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable
|
|
28
|
+
with:
|
|
29
|
+
components: rustfmt, clippy
|
|
30
|
+
|
|
31
|
+
- name: Cache cargo
|
|
32
|
+
uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2.8.2
|
|
33
|
+
|
|
34
|
+
- name: Check formatting
|
|
35
|
+
run: cargo fmt --check
|
|
36
|
+
|
|
37
|
+
- name: Run clippy
|
|
38
|
+
run: cargo clippy -- -D warnings
|
|
39
|
+
|
|
40
|
+
lint-python:
|
|
41
|
+
name: Lint Python
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
steps:
|
|
44
|
+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
45
|
+
|
|
46
|
+
- name: Set up Python
|
|
47
|
+
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
|
48
|
+
with:
|
|
49
|
+
python-version: ${{ env.PYTHON_VERSION }}
|
|
50
|
+
|
|
51
|
+
- name: Install ruff
|
|
52
|
+
run: pip install ruff
|
|
53
|
+
|
|
54
|
+
- name: Check formatting
|
|
55
|
+
run: ruff format --check python/ tests/
|
|
56
|
+
|
|
57
|
+
- name: Run linter
|
|
58
|
+
run: ruff check python/ tests/
|
|
59
|
+
|
|
60
|
+
test:
|
|
61
|
+
name: Test (${{ matrix.os }})
|
|
62
|
+
runs-on: ${{ matrix.os }}
|
|
63
|
+
strategy:
|
|
64
|
+
fail-fast: false
|
|
65
|
+
matrix:
|
|
66
|
+
os: [ubuntu-latest, macos-latest]
|
|
67
|
+
python-version: ["3.9", "3.10", "3.11", "3.12"]
|
|
68
|
+
steps:
|
|
69
|
+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
70
|
+
|
|
71
|
+
- name: Checkout nono library
|
|
72
|
+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
73
|
+
with:
|
|
74
|
+
repository: always-further/nono
|
|
75
|
+
path: nono
|
|
76
|
+
|
|
77
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
78
|
+
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
|
79
|
+
with:
|
|
80
|
+
python-version: ${{ matrix.python-version }}
|
|
81
|
+
|
|
82
|
+
- name: Install Rust toolchain
|
|
83
|
+
uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable
|
|
84
|
+
|
|
85
|
+
- name: Cache cargo
|
|
86
|
+
uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2
|
|
87
|
+
|
|
88
|
+
- name: Create virtual environment
|
|
89
|
+
run: python -m venv .venv
|
|
90
|
+
|
|
91
|
+
- name: Install maturin and pytest
|
|
92
|
+
run: |
|
|
93
|
+
source .venv/bin/activate
|
|
94
|
+
pip install maturin pytest
|
|
95
|
+
|
|
96
|
+
- name: Build and install
|
|
97
|
+
run: |
|
|
98
|
+
source .venv/bin/activate
|
|
99
|
+
maturin develop
|
|
100
|
+
|
|
101
|
+
- name: Run tests
|
|
102
|
+
run: |
|
|
103
|
+
source .venv/bin/activate
|
|
104
|
+
pytest tests/ -v
|
|
105
|
+
|
|
106
|
+
typecheck:
|
|
107
|
+
name: Type Check
|
|
108
|
+
runs-on: ubuntu-latest
|
|
109
|
+
steps:
|
|
110
|
+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
111
|
+
|
|
112
|
+
- name: Checkout nono library
|
|
113
|
+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
114
|
+
with:
|
|
115
|
+
repository: always-further/nono
|
|
116
|
+
path: nono
|
|
117
|
+
|
|
118
|
+
- name: Set up Python
|
|
119
|
+
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
|
120
|
+
with:
|
|
121
|
+
python-version: ${{ env.PYTHON_VERSION }}
|
|
122
|
+
|
|
123
|
+
- name: Install Rust toolchain
|
|
124
|
+
uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable
|
|
125
|
+
|
|
126
|
+
- name: Cache cargo
|
|
127
|
+
uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2
|
|
128
|
+
|
|
129
|
+
- name: Create virtual environment
|
|
130
|
+
run: python -m venv .venv
|
|
131
|
+
|
|
132
|
+
- name: Install dependencies
|
|
133
|
+
run: |
|
|
134
|
+
source .venv/bin/activate
|
|
135
|
+
pip install maturin mypy
|
|
136
|
+
|
|
137
|
+
- name: Build package
|
|
138
|
+
run: |
|
|
139
|
+
source .venv/bin/activate
|
|
140
|
+
maturin develop
|
|
141
|
+
|
|
142
|
+
- name: Run mypy
|
|
143
|
+
run: |
|
|
144
|
+
source .venv/bin/activate
|
|
145
|
+
mypy python/nono_py --ignore-missing-imports
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
name: Trigger Docs Rebuild
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
paths:
|
|
7
|
+
- 'docs/**'
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
dispatch:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- name: Trigger docs repo rebuild
|
|
14
|
+
uses: peter-evans/repository-dispatch@v3
|
|
15
|
+
with:
|
|
16
|
+
token: ${{ secrets.DOCS_PAT }}
|
|
17
|
+
repository: always-further/nono-docs
|
|
18
|
+
event-type: docs-update
|
|
19
|
+
client-payload: '{"repo": "${{ github.repository }}", "sha": "${{ github.sha }}"}'
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
inputs:
|
|
8
|
+
publish_target:
|
|
9
|
+
description: 'Publish target'
|
|
10
|
+
required: true
|
|
11
|
+
default: 'testpypi'
|
|
12
|
+
type: choice
|
|
13
|
+
options:
|
|
14
|
+
- testpypi
|
|
15
|
+
- pypi
|
|
16
|
+
|
|
17
|
+
permissions:
|
|
18
|
+
contents: read
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
build-sdist:
|
|
22
|
+
name: Build source distribution
|
|
23
|
+
runs-on: ubuntu-latest
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
26
|
+
|
|
27
|
+
- name: Checkout nono library
|
|
28
|
+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
29
|
+
with:
|
|
30
|
+
repository: always-further/nono
|
|
31
|
+
path: nono
|
|
32
|
+
|
|
33
|
+
- name: Fix nono path for CI
|
|
34
|
+
run: sed -i 's|path = "../nono/crates/nono"|path = "nono/crates/nono"|' Cargo.toml
|
|
35
|
+
|
|
36
|
+
- name: Build sdist
|
|
37
|
+
uses: PyO3/maturin-action@b1bd829e37fef14c63f19162034228a2f3dc1021 # v1.50.0
|
|
38
|
+
with:
|
|
39
|
+
command: sdist
|
|
40
|
+
args: --out dist
|
|
41
|
+
|
|
42
|
+
- name: Upload sdist
|
|
43
|
+
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
|
44
|
+
with:
|
|
45
|
+
name: dist-sdist
|
|
46
|
+
path: dist/*.tar.gz
|
|
47
|
+
|
|
48
|
+
build-wheels-linux:
|
|
49
|
+
name: Build wheels (Linux ${{ matrix.arch }})
|
|
50
|
+
runs-on: ${{ matrix.runner }}
|
|
51
|
+
strategy:
|
|
52
|
+
fail-fast: false
|
|
53
|
+
matrix:
|
|
54
|
+
include:
|
|
55
|
+
- runner: ubuntu-latest
|
|
56
|
+
arch: x86_64
|
|
57
|
+
target: x86_64
|
|
58
|
+
- runner: ubuntu-24.04-arm
|
|
59
|
+
arch: aarch64
|
|
60
|
+
target: aarch64
|
|
61
|
+
steps:
|
|
62
|
+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
63
|
+
|
|
64
|
+
- name: Checkout nono library
|
|
65
|
+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
66
|
+
with:
|
|
67
|
+
repository: always-further/nono
|
|
68
|
+
path: nono
|
|
69
|
+
|
|
70
|
+
- name: Fix nono path for CI
|
|
71
|
+
run: sed -i 's|path = "../nono/crates/nono"|path = "nono/crates/nono"|' Cargo.toml
|
|
72
|
+
|
|
73
|
+
- name: Build wheels
|
|
74
|
+
uses: PyO3/maturin-action@b1bd829e37fef14c63f19162034228a2f3dc1021 # v1.50.0
|
|
75
|
+
with:
|
|
76
|
+
target: ${{ matrix.target }}
|
|
77
|
+
args: --release --out dist -i python3.9 python3.10 python3.11 python3.12 python3.13
|
|
78
|
+
manylinux: auto
|
|
79
|
+
before-script-linux: |
|
|
80
|
+
if command -v dnf &> /dev/null; then
|
|
81
|
+
dnf install -y dbus-devel pkgconfig
|
|
82
|
+
elif command -v yum &> /dev/null; then
|
|
83
|
+
yum install -y dbus-devel pkgconfig
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
- name: Upload wheels
|
|
87
|
+
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
|
88
|
+
with:
|
|
89
|
+
name: dist-linux-${{ matrix.arch }}
|
|
90
|
+
path: dist/*.whl
|
|
91
|
+
|
|
92
|
+
build-wheels-macos:
|
|
93
|
+
name: Build wheels (macOS ${{ matrix.target }})
|
|
94
|
+
runs-on: macos-latest
|
|
95
|
+
strategy:
|
|
96
|
+
fail-fast: false
|
|
97
|
+
matrix:
|
|
98
|
+
target: [x86_64-apple-darwin, aarch64-apple-darwin]
|
|
99
|
+
steps:
|
|
100
|
+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
101
|
+
|
|
102
|
+
- name: Checkout nono library
|
|
103
|
+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
104
|
+
with:
|
|
105
|
+
repository: always-further/nono
|
|
106
|
+
path: nono
|
|
107
|
+
|
|
108
|
+
- name: Set up Python
|
|
109
|
+
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
|
110
|
+
with:
|
|
111
|
+
python-version: '3.12'
|
|
112
|
+
|
|
113
|
+
- name: Fix nono path for CI
|
|
114
|
+
run: sed -i '' 's|path = "../nono/crates/nono"|path = "nono/crates/nono"|' Cargo.toml
|
|
115
|
+
|
|
116
|
+
- name: Build wheels
|
|
117
|
+
uses: PyO3/maturin-action@b1bd829e37fef14c63f19162034228a2f3dc1021 # v1.50.0
|
|
118
|
+
with:
|
|
119
|
+
target: ${{ matrix.target }}
|
|
120
|
+
args: --release --out dist -i python3.12
|
|
121
|
+
|
|
122
|
+
- name: Upload wheels
|
|
123
|
+
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
|
124
|
+
with:
|
|
125
|
+
name: dist-macos-${{ matrix.target }}
|
|
126
|
+
path: dist/*.whl
|
|
127
|
+
|
|
128
|
+
publish-testpypi:
|
|
129
|
+
name: Publish to TestPyPI
|
|
130
|
+
needs: [build-sdist, build-wheels-linux, build-wheels-macos]
|
|
131
|
+
runs-on: ubuntu-latest
|
|
132
|
+
if: github.event_name == 'workflow_dispatch' && github.event.inputs.publish_target == 'testpypi'
|
|
133
|
+
environment:
|
|
134
|
+
name: testpypi
|
|
135
|
+
url: https://test.pypi.org/p/nono-py
|
|
136
|
+
permissions:
|
|
137
|
+
id-token: write
|
|
138
|
+
steps:
|
|
139
|
+
- name: Download artifacts
|
|
140
|
+
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
|
|
141
|
+
with:
|
|
142
|
+
pattern: dist-*
|
|
143
|
+
path: dist
|
|
144
|
+
merge-multiple: true
|
|
145
|
+
|
|
146
|
+
- name: Publish to TestPyPI
|
|
147
|
+
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # release/v1
|
|
148
|
+
with:
|
|
149
|
+
repository-url: https://test.pypi.org/legacy/
|
|
150
|
+
|
|
151
|
+
publish-pypi:
|
|
152
|
+
name: Publish to PyPI
|
|
153
|
+
needs: [build-sdist, build-wheels-linux, build-wheels-macos]
|
|
154
|
+
runs-on: ubuntu-latest
|
|
155
|
+
if: github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && github.event.inputs.publish_target == 'pypi')
|
|
156
|
+
environment:
|
|
157
|
+
name: pypi
|
|
158
|
+
url: https://pypi.org/p/nono-py
|
|
159
|
+
permissions:
|
|
160
|
+
id-token: write
|
|
161
|
+
steps:
|
|
162
|
+
- name: Download artifacts
|
|
163
|
+
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
|
|
164
|
+
with:
|
|
165
|
+
pattern: dist-*
|
|
166
|
+
path: dist
|
|
167
|
+
merge-multiple: true
|
|
168
|
+
|
|
169
|
+
- name: Publish to PyPI
|
|
170
|
+
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # release/v1
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: write
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
create-release:
|
|
13
|
+
name: Create GitHub Release
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
17
|
+
|
|
18
|
+
- name: Extract version from tag
|
|
19
|
+
id: version
|
|
20
|
+
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
|
|
21
|
+
|
|
22
|
+
- name: Create Release
|
|
23
|
+
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
|
|
24
|
+
with:
|
|
25
|
+
name: Release v${{ steps.version.outputs.VERSION }}
|
|
26
|
+
draft: false
|
|
27
|
+
prerelease: ${{ contains(github.ref, 'alpha') || contains(github.ref, 'beta') || contains(github.ref, 'rc') }}
|
|
28
|
+
generate_release_notes: true
|
nono_py-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Python-generated files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[oc]
|
|
4
|
+
build/
|
|
5
|
+
dist/
|
|
6
|
+
wheels/
|
|
7
|
+
*.egg-info/
|
|
8
|
+
|
|
9
|
+
# Virtual environments
|
|
10
|
+
.venv/
|
|
11
|
+
|
|
12
|
+
# Rust/Cargo artifacts
|
|
13
|
+
target/
|
|
14
|
+
Cargo.lock
|
|
15
|
+
|
|
16
|
+
# Maturin artifacts
|
|
17
|
+
*.so
|
|
18
|
+
*.dylib
|
|
19
|
+
*.pyd
|
|
20
|
+
|
|
21
|
+
# IDE
|
|
22
|
+
.idea/
|
|
23
|
+
.vscode/
|
|
24
|
+
*.swp
|
|
25
|
+
*.swo
|
|
26
|
+
*~
|
|
27
|
+
|
|
28
|
+
# Testing
|
|
29
|
+
.pytest_cache/
|
|
30
|
+
.coverage
|
|
31
|
+
htmlcov/
|
|
32
|
+
.tox/
|
|
33
|
+
|
|
34
|
+
# Type checking
|
|
35
|
+
.mypy_cache/
|
|
36
|
+
|
|
37
|
+
# Linting
|
|
38
|
+
.ruff_cache/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
nono_py-0.1.0/CLAUDE.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## What This Is
|
|
6
|
+
|
|
7
|
+
nono-py provides Python bindings for the [nono](https://github.com/always-further/nono) Rust capability-based sandboxing library. It uses PyO3/maturin to expose Rust code to Python, supporting Landlock (Linux) and Seatbelt (macOS).
|
|
8
|
+
|
|
9
|
+
## Build & Development Commands
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
uv sync # Install all dependencies (creates venv automatically)
|
|
13
|
+
uv run maturin develop # Build native module (debug mode)
|
|
14
|
+
uv run maturin develop --release # Build native module (release mode)
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Testing
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
uv run pytest tests/ -v # All tests
|
|
21
|
+
uv run pytest tests/test_capability_set.py -v # Single file
|
|
22
|
+
uv run pytest tests/test_query.py::TestQueryContextPathQueries -v # Single class
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Linting & Formatting
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
cargo fmt # Format Rust
|
|
29
|
+
cargo clippy -- -D warnings # Lint Rust
|
|
30
|
+
uv run ruff format python/ tests/ # Format Python
|
|
31
|
+
uv run ruff check --fix python/ tests/ # Lint Python (autofix)
|
|
32
|
+
uv run mypy python/nono_py # Type check (strict mode)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`make ci` runs the full suite: fmt-check, lint, test.
|
|
36
|
+
|
|
37
|
+
## Architecture
|
|
38
|
+
|
|
39
|
+
### Binding Layer
|
|
40
|
+
|
|
41
|
+
`src/lib.rs` is the single Rust source file. It wraps the `nono` crate's types using PyO3 `#[pyclass]`/`#[pymethods]` macros. Each Python class holds an inner Rust type (e.g., `CapabilitySet` wraps `RustCapabilitySet`). Rust `NonoError` variants map to Python exceptions: `FileNotFoundError`, `ValueError`, `OSError`, `RuntimeError`, `PermissionError`.
|
|
42
|
+
|
|
43
|
+
### Python Package
|
|
44
|
+
|
|
45
|
+
`python/nono_py/__init__.py` re-exports everything from the native `_nono_py` module. The underscore-prefixed native module is an internal implementation detail.
|
|
46
|
+
|
|
47
|
+
`python/nono_py/_nono_py.pyi` contains type stubs that must stay in sync with the Rust API. This file is the source of truth for IDE autocompletion and mypy.
|
|
48
|
+
|
|
49
|
+
### Key Classes
|
|
50
|
+
|
|
51
|
+
- **CapabilitySet** — mutable builder: `allow_path()`, `allow_file()`, `block_network()`, `allow_command()`, `block_command()`
|
|
52
|
+
- **QueryContext** — test permissions without applying: returns dicts with `status`/`reason` keys
|
|
53
|
+
- **SandboxState** — JSON-serializable snapshot of a CapabilitySet for cross-process transfer
|
|
54
|
+
- **AccessMode** — enum: `READ`, `WRITE`, `READ_WRITE` (frozen)
|
|
55
|
+
- **apply()** — module-level function, **irreversible** OS sandbox enforcement
|
|
56
|
+
|
|
57
|
+
### Nono Dependency
|
|
58
|
+
|
|
59
|
+
`Cargo.toml` references the nono library via local path (`../nono/crates/nono`). Both repos must be sibling directories for local development. CI checks out nono as a sibling automatically.
|
|
60
|
+
|
|
61
|
+
## Conventions
|
|
62
|
+
|
|
63
|
+
- Python: ruff, line-length 100, target py39, strict mypy
|
|
64
|
+
- Rust: edition 2021, rust-version 1.80, clippy with `-D warnings`
|
|
65
|
+
- Frozen PyO3 classes for immutable types (AccessMode, FsCapability, SupportInfo, CapabilitySource)
|
|
66
|
+
- Path validation happens at add-time in Rust (fail fast)
|
|
67
|
+
- Tests use `conftest.py` fixtures `temp_dir` and `temp_file` for filesystem isolation
|