fromscratch-pyos 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.
- fromscratch_pyos-0.3.0/.claude/settings.json +26 -0
- fromscratch_pyos-0.3.0/.github/dependabot.yml +16 -0
- fromscratch_pyos-0.3.0/.github/workflows/ci.yml +14 -0
- fromscratch_pyos-0.3.0/.github/workflows/docs.yml +16 -0
- fromscratch_pyos-0.3.0/.github/workflows/release.yml +58 -0
- fromscratch_pyos-0.3.0/.gitignore +70 -0
- fromscratch_pyos-0.3.0/.pre-commit-config.yaml +56 -0
- fromscratch_pyos-0.3.0/.python-version +1 -0
- fromscratch_pyos-0.3.0/CLAUDE.md +73 -0
- fromscratch_pyos-0.3.0/CONTRIBUTING.md +216 -0
- fromscratch_pyos-0.3.0/LICENSE +21 -0
- fromscratch_pyos-0.3.0/PKG-INFO +205 -0
- fromscratch_pyos-0.3.0/README.md +166 -0
- fromscratch_pyos-0.3.0/conftest.py +21 -0
- fromscratch_pyos-0.3.0/docs/architecture.md +411 -0
- fromscratch_pyos-0.3.0/docs/concepts/binary-loader.md +193 -0
- fromscratch_pyos-0.3.0/docs/concepts/bootloader.md +207 -0
- fromscratch_pyos-0.3.0/docs/concepts/containers.md +164 -0
- fromscratch_pyos-0.3.0/docs/concepts/devices-and-networking.md +659 -0
- fromscratch_pyos-0.3.0/docs/concepts/filesystem.md +699 -0
- fromscratch_pyos-0.3.0/docs/concepts/framebuffer.md +92 -0
- fromscratch_pyos-0.3.0/docs/concepts/inter-machine-networking.md +152 -0
- fromscratch_pyos-0.3.0/docs/concepts/interrupts.md +153 -0
- fromscratch_pyos-0.3.0/docs/concepts/kernel-and-syscalls.md +501 -0
- fromscratch_pyos-0.3.0/docs/concepts/memory.md +509 -0
- fromscratch_pyos-0.3.0/docs/concepts/permissions.md +147 -0
- fromscratch_pyos-0.3.0/docs/concepts/processes.md +538 -0
- fromscratch_pyos-0.3.0/docs/concepts/shell.md +774 -0
- fromscratch_pyos-0.3.0/docs/concepts/synchronization.md +357 -0
- fromscratch_pyos-0.3.0/docs/concepts/tcp.md +219 -0
- fromscratch_pyos-0.3.0/docs/concepts/tui.md +89 -0
- fromscratch_pyos-0.3.0/docs/concepts/tutorials.md +65 -0
- fromscratch_pyos-0.3.0/docs/concepts/users-and-safety.md +268 -0
- fromscratch_pyos-0.3.0/docs/concepts/web-ui.md +59 -0
- fromscratch_pyos-0.3.0/docs/concepts/what-is-an-os.md +167 -0
- fromscratch_pyos-0.3.0/docs/diagrams.md +77 -0
- fromscratch_pyos-0.3.0/docs/index.md +123 -0
- fromscratch_pyos-0.3.0/docs/property-testing.md +378 -0
- fromscratch_pyos-0.3.0/docs/shell-reference.md +214 -0
- fromscratch_pyos-0.3.0/mkdocs.yml +103 -0
- fromscratch_pyos-0.3.0/overrides/main.html +7 -0
- fromscratch_pyos-0.3.0/pyproject.toml +188 -0
- fromscratch_pyos-0.3.0/src/py_os/__init__.py +1 -0
- fromscratch_pyos-0.3.0/src/py_os/__main__.py +5 -0
- fromscratch_pyos-0.3.0/src/py_os/_version.py +24 -0
- fromscratch_pyos-0.3.0/src/py_os/bootloader.py +219 -0
- fromscratch_pyos-0.3.0/src/py_os/completer.py +233 -0
- fromscratch_pyos-0.3.0/src/py_os/containers.py +328 -0
- fromscratch_pyos-0.3.0/src/py_os/env.py +64 -0
- fromscratch_pyos-0.3.0/src/py_os/fs/__init__.py +39 -0
- fromscratch_pyos-0.3.0/src/py_os/fs/fd.py +163 -0
- fromscratch_pyos-0.3.0/src/py_os/fs/filesystem.py +591 -0
- fromscratch_pyos-0.3.0/src/py_os/fs/journal.py +537 -0
- fromscratch_pyos-0.3.0/src/py_os/fs/persistence.py +94 -0
- fromscratch_pyos-0.3.0/src/py_os/fs/procfs.py +329 -0
- fromscratch_pyos-0.3.0/src/py_os/io/__init__.py +91 -0
- fromscratch_pyos-0.3.0/src/py_os/io/bridge.py +327 -0
- fromscratch_pyos-0.3.0/src/py_os/io/devices.py +193 -0
- fromscratch_pyos-0.3.0/src/py_os/io/disk.py +222 -0
- fromscratch_pyos-0.3.0/src/py_os/io/dns.py +111 -0
- fromscratch_pyos-0.3.0/src/py_os/io/framebuffer.py +185 -0
- fromscratch_pyos-0.3.0/src/py_os/io/http.py +282 -0
- fromscratch_pyos-0.3.0/src/py_os/io/interrupts.py +305 -0
- fromscratch_pyos-0.3.0/src/py_os/io/ipc.py +137 -0
- fromscratch_pyos-0.3.0/src/py_os/io/networking.py +301 -0
- fromscratch_pyos-0.3.0/src/py_os/io/shm.py +54 -0
- fromscratch_pyos-0.3.0/src/py_os/io/tcp.py +830 -0
- fromscratch_pyos-0.3.0/src/py_os/io/timer.py +148 -0
- fromscratch_pyos-0.3.0/src/py_os/jobs.py +104 -0
- fromscratch_pyos-0.3.0/src/py_os/kernel.py +3668 -0
- fromscratch_pyos-0.3.0/src/py_os/logging.py +121 -0
- fromscratch_pyos-0.3.0/src/py_os/memory/__init__.py +38 -0
- fromscratch_pyos-0.3.0/src/py_os/memory/manager.py +225 -0
- fromscratch_pyos-0.3.0/src/py_os/memory/mmap.py +52 -0
- fromscratch_pyos-0.3.0/src/py_os/memory/slab.py +481 -0
- fromscratch_pyos-0.3.0/src/py_os/memory/swap.py +438 -0
- fromscratch_pyos-0.3.0/src/py_os/memory/virtual.py +243 -0
- fromscratch_pyos-0.3.0/src/py_os/process/__init__.py +46 -0
- fromscratch_pyos-0.3.0/src/py_os/process/binary.py +389 -0
- fromscratch_pyos-0.3.0/src/py_os/process/pcb.py +382 -0
- fromscratch_pyos-0.3.0/src/py_os/process/scheduler.py +796 -0
- fromscratch_pyos-0.3.0/src/py_os/process/signals.py +93 -0
- fromscratch_pyos-0.3.0/src/py_os/process/threads.py +146 -0
- fromscratch_pyos-0.3.0/src/py_os/py.typed +0 -0
- fromscratch_pyos-0.3.0/src/py_os/repl.py +114 -0
- fromscratch_pyos-0.3.0/src/py_os/shell/__init__.py +64 -0
- fromscratch_pyos-0.3.0/src/py_os/shell/base.py +559 -0
- fromscratch_pyos-0.3.0/src/py_os/shell/commands/__init__.py +25 -0
- fromscratch_pyos-0.3.0/src/py_os/shell/commands/basics.py +106 -0
- fromscratch_pyos-0.3.0/src/py_os/shell/commands/devices.py +375 -0
- fromscratch_pyos-0.3.0/src/py_os/shell/commands/files.py +505 -0
- fromscratch_pyos-0.3.0/src/py_os/shell/commands/isolation.py +272 -0
- fromscratch_pyos-0.3.0/src/py_os/shell/commands/learn.py +31 -0
- fromscratch_pyos-0.3.0/src/py_os/shell/commands/memory.py +485 -0
- fromscratch_pyos-0.3.0/src/py_os/shell/commands/network.py +765 -0
- fromscratch_pyos-0.3.0/src/py_os/shell/commands/processes.py +1035 -0
- fromscratch_pyos-0.3.0/src/py_os/shell/commands/sync.py +460 -0
- fromscratch_pyos-0.3.0/src/py_os/shell/commands/users.py +131 -0
- fromscratch_pyos-0.3.0/src/py_os/sync/__init__.py +30 -0
- fromscratch_pyos-0.3.0/src/py_os/sync/deadlock.py +265 -0
- fromscratch_pyos-0.3.0/src/py_os/sync/inheritance.py +189 -0
- fromscratch_pyos-0.3.0/src/py_os/sync/ordering.py +227 -0
- fromscratch_pyos-0.3.0/src/py_os/sync/primitives.py +725 -0
- fromscratch_pyos-0.3.0/src/py_os/syscalls.py +2502 -0
- fromscratch_pyos-0.3.0/src/py_os/tui/__init__.py +5 -0
- fromscratch_pyos-0.3.0/src/py_os/tui/app.py +127 -0
- fromscratch_pyos-0.3.0/src/py_os/tui/widgets.py +146 -0
- fromscratch_pyos-0.3.0/src/py_os/tutorials.py +783 -0
- fromscratch_pyos-0.3.0/src/py_os/users.py +472 -0
- fromscratch_pyos-0.3.0/src/py_os/web/__init__.py +14 -0
- fromscratch_pyos-0.3.0/src/py_os/web/app.py +92 -0
- fromscratch_pyos-0.3.0/src/py_os/web/static/style.css +77 -0
- fromscratch_pyos-0.3.0/src/py_os/web/static/terminal.js +65 -0
- fromscratch_pyos-0.3.0/src/py_os/web/templates/index.html +21 -0
- fromscratch_pyos-0.3.0/tests/__init__.py +1 -0
- fromscratch_pyos-0.3.0/tests/conftest.py +25 -0
- fromscratch_pyos-0.3.0/tests/fs/__init__.py +1 -0
- fromscratch_pyos-0.3.0/tests/fs/test_fd.py +608 -0
- fromscratch_pyos-0.3.0/tests/fs/test_filesystem.py +316 -0
- fromscratch_pyos-0.3.0/tests/fs/test_journal.py +959 -0
- fromscratch_pyos-0.3.0/tests/fs/test_links.py +946 -0
- fromscratch_pyos-0.3.0/tests/fs/test_persistent_fs.py +185 -0
- fromscratch_pyos-0.3.0/tests/fs/test_procfs.py +588 -0
- fromscratch_pyos-0.3.0/tests/io/__init__.py +1 -0
- fromscratch_pyos-0.3.0/tests/io/test_bridge.py +375 -0
- fromscratch_pyos-0.3.0/tests/io/test_device_integration.py +149 -0
- fromscratch_pyos-0.3.0/tests/io/test_devices.py +139 -0
- fromscratch_pyos-0.3.0/tests/io/test_disk_scheduling.py +267 -0
- fromscratch_pyos-0.3.0/tests/io/test_dns.py +370 -0
- fromscratch_pyos-0.3.0/tests/io/test_framebuffer.py +264 -0
- fromscratch_pyos-0.3.0/tests/io/test_http.py +458 -0
- fromscratch_pyos-0.3.0/tests/io/test_interrupts.py +363 -0
- fromscratch_pyos-0.3.0/tests/io/test_ipc.py +157 -0
- fromscratch_pyos-0.3.0/tests/io/test_networking.py +293 -0
- fromscratch_pyos-0.3.0/tests/io/test_pipes.py +135 -0
- fromscratch_pyos-0.3.0/tests/io/test_shm.py +465 -0
- fromscratch_pyos-0.3.0/tests/io/test_tcp.py +894 -0
- fromscratch_pyos-0.3.0/tests/io/test_timer.py +171 -0
- fromscratch_pyos-0.3.0/tests/memory/__init__.py +1 -0
- fromscratch_pyos-0.3.0/tests/memory/test_memory.py +260 -0
- fromscratch_pyos-0.3.0/tests/memory/test_mmap.py +671 -0
- fromscratch_pyos-0.3.0/tests/memory/test_page_replacement.py +351 -0
- fromscratch_pyos-0.3.0/tests/memory/test_slab.py +565 -0
- fromscratch_pyos-0.3.0/tests/memory/test_swap_integration.py +183 -0
- fromscratch_pyos-0.3.0/tests/memory/test_virtual_memory.py +262 -0
- fromscratch_pyos-0.3.0/tests/process/__init__.py +1 -0
- fromscratch_pyos-0.3.0/tests/process/test_binary.py +360 -0
- fromscratch_pyos-0.3.0/tests/process/test_fork.py +482 -0
- fromscratch_pyos-0.3.0/tests/process/test_process.py +165 -0
- fromscratch_pyos-0.3.0/tests/process/test_scheduler.py +784 -0
- fromscratch_pyos-0.3.0/tests/process/test_signals.py +525 -0
- fromscratch_pyos-0.3.0/tests/process/test_threads.py +315 -0
- fromscratch_pyos-0.3.0/tests/process/test_wait.py +507 -0
- fromscratch_pyos-0.3.0/tests/sync/__init__.py +1 -0
- fromscratch_pyos-0.3.0/tests/sync/test_deadlock.py +488 -0
- fromscratch_pyos-0.3.0/tests/sync/test_ordering.py +343 -0
- fromscratch_pyos-0.3.0/tests/sync/test_priority_inheritance.py +369 -0
- fromscratch_pyos-0.3.0/tests/sync/test_sync.py +940 -0
- fromscratch_pyos-0.3.0/tests/test_acl.py +557 -0
- fromscratch_pyos-0.3.0/tests/test_background.py +254 -0
- fromscratch_pyos-0.3.0/tests/test_benchmark.py +160 -0
- fromscratch_pyos-0.3.0/tests/test_bootloader.py +294 -0
- fromscratch_pyos-0.3.0/tests/test_completer.py +259 -0
- fromscratch_pyos-0.3.0/tests/test_containers.py +524 -0
- fromscratch_pyos-0.3.0/tests/test_dashboard.py +151 -0
- fromscratch_pyos-0.3.0/tests/test_env.py +208 -0
- fromscratch_pyos-0.3.0/tests/test_execution.py +326 -0
- fromscratch_pyos-0.3.0/tests/test_history.py +121 -0
- fromscratch_pyos-0.3.0/tests/test_jobs.py +216 -0
- fromscratch_pyos-0.3.0/tests/test_kernel.py +406 -0
- fromscratch_pyos-0.3.0/tests/test_kernel_mode.py +410 -0
- fromscratch_pyos-0.3.0/tests/test_logging.py +155 -0
- fromscratch_pyos-0.3.0/tests/test_loops.py +483 -0
- fromscratch_pyos-0.3.0/tests/test_model.py +197 -0
- fromscratch_pyos-0.3.0/tests/test_multi_cpu.py +567 -0
- fromscratch_pyos-0.3.0/tests/test_no_runtime_asserts.py +47 -0
- fromscratch_pyos-0.3.0/tests/test_perf_metrics.py +455 -0
- fromscratch_pyos-0.3.0/tests/test_properties.py +178 -0
- fromscratch_pyos-0.3.0/tests/test_redirection.py +350 -0
- fromscratch_pyos-0.3.0/tests/test_repl.py +109 -0
- fromscratch_pyos-0.3.0/tests/test_scripting.py +259 -0
- fromscratch_pyos-0.3.0/tests/test_shell.py +1751 -0
- fromscratch_pyos-0.3.0/tests/test_shell_registry.py +55 -0
- fromscratch_pyos-0.3.0/tests/test_smoke.py +8 -0
- fromscratch_pyos-0.3.0/tests/test_strace.py +436 -0
- fromscratch_pyos-0.3.0/tests/test_syscalls.py +666 -0
- fromscratch_pyos-0.3.0/tests/test_sysinfo.py +122 -0
- fromscratch_pyos-0.3.0/tests/test_tick.py +272 -0
- fromscratch_pyos-0.3.0/tests/test_tutorials.py +558 -0
- fromscratch_pyos-0.3.0/tests/test_user_integration.py +196 -0
- fromscratch_pyos-0.3.0/tests/test_users.py +151 -0
- fromscratch_pyos-0.3.0/tests/test_web.py +155 -0
- fromscratch_pyos-0.3.0/tests/tui/__init__.py +1 -0
- fromscratch_pyos-0.3.0/tests/tui/test_tui.py +152 -0
- fromscratch_pyos-0.3.0/uv.lock +1244 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(git init:*)",
|
|
5
|
+
"Bash(uv venv:*)",
|
|
6
|
+
"Bash(uv pip install:*)",
|
|
7
|
+
"Bash(git add:*)",
|
|
8
|
+
"Bash(git commit:*)",
|
|
9
|
+
"Bash(.venv/bin/pre-commit install:*)",
|
|
10
|
+
"Bash(.venv/bin/pytest)",
|
|
11
|
+
"Bash(.venv/bin/ruff check:*)",
|
|
12
|
+
"Bash(.venv/bin/ruff format:*)",
|
|
13
|
+
"Bash(gh repo create:*)",
|
|
14
|
+
"Bash(gh api:*)",
|
|
15
|
+
"Bash(gh repo edit:*)",
|
|
16
|
+
"Bash(git checkout:*)",
|
|
17
|
+
"Bash(.venv/bin/pre-commit clean:*)",
|
|
18
|
+
"Bash(git push:*)",
|
|
19
|
+
"Bash(gh pr:*)",
|
|
20
|
+
"Bash(git pull:*)",
|
|
21
|
+
"Bash(.venv/bin/pytest:*)",
|
|
22
|
+
"Bash(.venv/bin/pyright:*)",
|
|
23
|
+
"Bash(git rm:*)"
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: "pip"
|
|
4
|
+
directory: "/"
|
|
5
|
+
schedule:
|
|
6
|
+
interval: "weekly"
|
|
7
|
+
open-pull-requests-limit: 10
|
|
8
|
+
labels:
|
|
9
|
+
- "dependencies"
|
|
10
|
+
|
|
11
|
+
- package-ecosystem: "github-actions"
|
|
12
|
+
directory: "/"
|
|
13
|
+
schedule:
|
|
14
|
+
interval: "weekly"
|
|
15
|
+
labels:
|
|
16
|
+
- "ci"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
name: Deploy Docs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
workflow_dispatch: {}
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
docs:
|
|
10
|
+
uses: robcox2910/robcox2910.github.io/.github/workflows/docs.yml@v1
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
pages: write
|
|
14
|
+
id-token: write
|
|
15
|
+
with:
|
|
16
|
+
coverage-report: true
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*.*.*"
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: write
|
|
10
|
+
id-token: write
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
build:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v7
|
|
17
|
+
with:
|
|
18
|
+
fetch-depth: 0
|
|
19
|
+
|
|
20
|
+
- name: Install uv
|
|
21
|
+
uses: astral-sh/setup-uv@v7
|
|
22
|
+
with:
|
|
23
|
+
version: "latest"
|
|
24
|
+
|
|
25
|
+
- name: Set up Python
|
|
26
|
+
run: uv python install 3.14
|
|
27
|
+
|
|
28
|
+
- name: Build distributions
|
|
29
|
+
run: uv build
|
|
30
|
+
|
|
31
|
+
- name: Upload build artifacts
|
|
32
|
+
uses: actions/upload-artifact@v7
|
|
33
|
+
with:
|
|
34
|
+
name: dist
|
|
35
|
+
path: dist/
|
|
36
|
+
|
|
37
|
+
- name: Upload to GitHub Release
|
|
38
|
+
uses: softprops/action-gh-release@v3
|
|
39
|
+
with:
|
|
40
|
+
files: dist/*
|
|
41
|
+
|
|
42
|
+
publish:
|
|
43
|
+
needs: build
|
|
44
|
+
runs-on: ubuntu-latest
|
|
45
|
+
environment:
|
|
46
|
+
name: pypi
|
|
47
|
+
url: https://pypi.org/project/fromscratch-pyos/
|
|
48
|
+
permissions:
|
|
49
|
+
id-token: write
|
|
50
|
+
steps:
|
|
51
|
+
- name: Download build artifacts
|
|
52
|
+
uses: actions/download-artifact@v8
|
|
53
|
+
with:
|
|
54
|
+
name: dist
|
|
55
|
+
path: dist/
|
|
56
|
+
|
|
57
|
+
- name: Publish to PyPI
|
|
58
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,70 @@
|
|
|
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
|
+
venv/
|
|
26
|
+
ENV/
|
|
27
|
+
env/
|
|
28
|
+
|
|
29
|
+
# Testing
|
|
30
|
+
.pytest_cache/
|
|
31
|
+
.coverage
|
|
32
|
+
htmlcov/
|
|
33
|
+
.tox/
|
|
34
|
+
coverage.xml
|
|
35
|
+
*.cover
|
|
36
|
+
|
|
37
|
+
# IDEs
|
|
38
|
+
.vscode/
|
|
39
|
+
.idea/
|
|
40
|
+
*.swp
|
|
41
|
+
*.swo
|
|
42
|
+
*~
|
|
43
|
+
|
|
44
|
+
# OS
|
|
45
|
+
.DS_Store
|
|
46
|
+
Thumbs.db
|
|
47
|
+
|
|
48
|
+
# uv
|
|
49
|
+
.uv/
|
|
50
|
+
|
|
51
|
+
# Environment variables
|
|
52
|
+
.env
|
|
53
|
+
.env.local
|
|
54
|
+
|
|
55
|
+
# Auto-generated version file (hatch-vcs)
|
|
56
|
+
src/py_os/_version.py
|
|
57
|
+
|
|
58
|
+
# Logs
|
|
59
|
+
*.log
|
|
60
|
+
|
|
61
|
+
# MkDocs build output
|
|
62
|
+
site/
|
|
63
|
+
|
|
64
|
+
# Type checking cache
|
|
65
|
+
.mypy_cache/
|
|
66
|
+
.ruff_cache/
|
|
67
|
+
.claude/settings.local.json
|
|
68
|
+
|
|
69
|
+
# Hypothesis example database (local thorough runs)
|
|
70
|
+
.hypothesis/
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
default_language_version:
|
|
2
|
+
python: python3.14
|
|
3
|
+
|
|
4
|
+
repos:
|
|
5
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
6
|
+
rev: v5.0.0
|
|
7
|
+
hooks:
|
|
8
|
+
# Pages paste real pytest output, trailing spaces included.
|
|
9
|
+
- id: trailing-whitespace
|
|
10
|
+
exclude: ^docs/property-testing\.md$
|
|
11
|
+
- id: end-of-file-fixer
|
|
12
|
+
exclude: ^docs/property-testing\.md$
|
|
13
|
+
- id: check-yaml
|
|
14
|
+
args: ['--unsafe']
|
|
15
|
+
- id: check-added-large-files
|
|
16
|
+
- id: check-json
|
|
17
|
+
- id: check-toml
|
|
18
|
+
- id: check-merge-conflict
|
|
19
|
+
- id: debug-statements
|
|
20
|
+
|
|
21
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
22
|
+
rev: v0.15.4
|
|
23
|
+
hooks:
|
|
24
|
+
- id: ruff
|
|
25
|
+
args: [--fix, --exit-non-zero-on-fix]
|
|
26
|
+
- id: ruff-format
|
|
27
|
+
|
|
28
|
+
- repo: https://github.com/RobertCraigie/pyright-python
|
|
29
|
+
rev: v1.1.408
|
|
30
|
+
hooks:
|
|
31
|
+
- id: pyright
|
|
32
|
+
|
|
33
|
+
- repo: local
|
|
34
|
+
hooks:
|
|
35
|
+
- id: pip-audit
|
|
36
|
+
name: pip-audit
|
|
37
|
+
language: system
|
|
38
|
+
pass_filenames: false
|
|
39
|
+
files: ^(pyproject\.toml|uv\.lock)$
|
|
40
|
+
entry: >-
|
|
41
|
+
bash -c 'f=$(mktemp) &&
|
|
42
|
+
uv export --frozen --no-emit-project --all-extras --no-hashes -o "$f" >/dev/null &&
|
|
43
|
+
uvx pip-audit==2.10.0 -r "$f" --disable-pip --no-deps;
|
|
44
|
+
status=$?; rm -f "$f"; exit $status'
|
|
45
|
+
|
|
46
|
+
- repo: https://github.com/rhysd/actionlint
|
|
47
|
+
rev: v1.7.7
|
|
48
|
+
hooks:
|
|
49
|
+
- id: actionlint
|
|
50
|
+
|
|
51
|
+
- repo: https://github.com/commitizen-tools/commitizen
|
|
52
|
+
rev: v4.13.8
|
|
53
|
+
hooks:
|
|
54
|
+
- id: commitizen
|
|
55
|
+
stages: [commit-msg]
|
|
56
|
+
additional_dependencies: [typing_extensions]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.14
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# PyOS
|
|
2
|
+
|
|
3
|
+
<!-- standard:start -->
|
|
4
|
+
## Code Style
|
|
5
|
+
|
|
6
|
+
- All public functions, methods, classes, and modules **must** have a docstring
|
|
7
|
+
- Use imperative mood: "Return the result." not "Returns the result."
|
|
8
|
+
- One-line docstrings for simple functions; multi-line with summary + details for complex ones
|
|
9
|
+
- Follow the Google docstring convention (D211, D212 selected via ruff)
|
|
10
|
+
|
|
11
|
+
## Linting
|
|
12
|
+
|
|
13
|
+
- Ruff enforces a comprehensive rule set -- run `uv run ruff check .` before committing
|
|
14
|
+
- Pyright runs in strict mode -- run `uv run pyright src tests` before committing
|
|
15
|
+
- All violations must be fixed, not ignored. Exceptions are the repo-owned `ignore` and `per-file-ignores` lists in `pyproject.toml`, which belong to this repo; the series sync never edits them
|
|
16
|
+
|
|
17
|
+
## Testing
|
|
18
|
+
|
|
19
|
+
- TDD workflow: Red-Green-Refactor
|
|
20
|
+
- Coverage is enforced by pytest-cov; the floor in `pyproject.toml` is repo-owned
|
|
21
|
+
- Test classes and methods also require docstrings
|
|
22
|
+
- Use named constants instead of magic values (PLR2004)
|
|
23
|
+
- Run `uv run pytest` before committing
|
|
24
|
+
- Property-based tests (Hypothesis) live in `tests/test_properties.py` and `tests/test_model.py`; the shared profiles are in the root `conftest.py` (owned by `series sync`). Run `uv run pytest --hypothesis-profile=thorough` before a release.
|
|
25
|
+
|
|
26
|
+
## Commits
|
|
27
|
+
|
|
28
|
+
- Use conventional commits: `feat:`, `fix:`, `refactor:`, `test:`, `docs:`, `ci:`, `chore:`
|
|
29
|
+
- All changes go via PR from a feature branch (main is protected); merge when CI is green
|
|
30
|
+
|
|
31
|
+
## Dependencies
|
|
32
|
+
|
|
33
|
+
- Package manager: uv
|
|
34
|
+
- Run `uv sync --all-extras` after modifying dependencies
|
|
35
|
+
- `uv.lock` is committed; CI and pre-commit audit it with pip-audit through `uvx`, so pip-audit is not a project dependency
|
|
36
|
+
- Sibling projects, where used, are pinned release tags in `[tool.uv.sources]` (git + tag); never use `path` sources
|
|
37
|
+
|
|
38
|
+
## Releasing
|
|
39
|
+
|
|
40
|
+
- A release is a `vX.Y.Z` tag on main after the PR is merged
|
|
41
|
+
- Docs-only and tooling-only changes do not get a release tag
|
|
42
|
+
- Docs are built with `mkdocs build --strict` and deployed to GitHub Pages by the docs workflow
|
|
43
|
+
<!-- standard:end -->
|
|
44
|
+
|
|
45
|
+
## Project notes
|
|
46
|
+
|
|
47
|
+
PyOS (`py_os`, repo `py-os`, distribution `pyos-learn`) is a teaching operating system simulated in Python: kernel, scheduler, memory, filesystem, IPC, sockets and a shell, written to be read. Source is in `src/py_os`, tests mirror it under `tests/`.
|
|
48
|
+
|
|
49
|
+
### Package layout
|
|
50
|
+
|
|
51
|
+
- `kernel.py` -- the `Kernel` that owns and boots every subsystem; `syscalls.py` -- the `SyscallNumber` table and dispatch; user-facing code only ever sees `SyscallError`.
|
|
52
|
+
- `process/`, `memory/`, `fs/`, `io/`, `sync/` -- subsystem packages (scheduling and PCBs, paging and slab allocator, inodes/journal/procfs, devices/DNS/HTTP/sockets, locks and semaphores).
|
|
53
|
+
- `shell/` -- the command interpreter, `repl.py` -- the interactive loop, `web/` and `tui/` -- optional front-ends (flask / textual extras).
|
|
54
|
+
- `users.py` (accounts, ACLs, `OsPermissionError`), `containers.py`, `env.py`, `jobs.py`, `logging.py`, `tutorials.py`.
|
|
55
|
+
|
|
56
|
+
### The shell package
|
|
57
|
+
|
|
58
|
+
- `shell/base.py` holds `ShellBase` (parsing, pipes, redirection, history, aliases, dispatch). `shell/__init__.py` composes `Shell` from `ShellBase` plus the command-group mixins.
|
|
59
|
+
- Command groups live in `shell/commands/*.py` (files, processes, memory, network, ...). Each group defines handler methods and a `COMMANDS` tuple of `(name, handler)` pairs; `ShellBase.__init__` builds its dispatch dict from every group's `COMMANDS`. To add a command: write the method, add one entry to that group's `COMMANDS`.
|
|
60
|
+
- Shell handlers talk to the kernel only through `kernel.syscall(...)`, never by reaching into subsystems.
|
|
61
|
+
|
|
62
|
+
### The `_missing_subsystem` pattern
|
|
63
|
+
|
|
64
|
+
Kernel subsystems are `None` until boot. Rather than `assert` (banned at runtime, see `tests/test_no_runtime_asserts.py`), code does `if self._scheduler is None: _raise_missing_subsystem("scheduler")`. The helper is typed `NoReturn`, so pyright narrows the attribute afterwards. `kernel.py` raises `RuntimeError`; `syscalls.py` has its own helper raising `SyscallError`. Calling a raising helper (instead of `raise X("literal")`) also keeps ruff's EM101 satisfied.
|
|
65
|
+
|
|
66
|
+
### Complexity
|
|
67
|
+
|
|
68
|
+
Ruff `C90` runs with `max-complexity = 15` (and pylint `max-args = 9`). Split big functions into helpers or table-driven dispatch rather than raising the limit.
|
|
69
|
+
|
|
70
|
+
### Running it
|
|
71
|
+
|
|
72
|
+
- Shell: `uv run pyos` (or `uv run python -m py_os`); web: `uv run pyos-web` (needs `--extra web`); TUI: `uv run pyos-tui` (needs `--extra tui`).
|
|
73
|
+
- Checks: `uv run ruff check .`, `uv run ruff format --check .`, `uv run pyright`, `uv run pytest` (coverage floor 80%).
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# Contributing to PyOS
|
|
2
|
+
|
|
3
|
+
Thanks for your interest in contributing! This guide covers everything you need
|
|
4
|
+
to get started.
|
|
5
|
+
|
|
6
|
+
## Prerequisites
|
|
7
|
+
|
|
8
|
+
| Tool | Version | Install |
|
|
9
|
+
|------|---------|---------|
|
|
10
|
+
| Python | 3.14+ | [python.org](https://www.python.org/downloads/) |
|
|
11
|
+
| uv | latest | `curl -LsSf https://astral.sh/uv/install.sh \| sh` |
|
|
12
|
+
| git | 2.x+ | [git-scm.com](https://git-scm.com/) |
|
|
13
|
+
|
|
14
|
+
## Setup
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# Clone the repo
|
|
18
|
+
git clone https://github.com/robcox2910/py-os.git
|
|
19
|
+
cd py-os
|
|
20
|
+
|
|
21
|
+
# Install all dependencies (including dev tools)
|
|
22
|
+
uv sync --all-extras
|
|
23
|
+
|
|
24
|
+
# Install pre-commit hooks (linting + commit message validation)
|
|
25
|
+
uv run pre-commit install
|
|
26
|
+
uv run pre-commit install --hook-type commit-msg
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Verify everything works:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
uv run pytest --cov # tests pass, >= 80% coverage
|
|
33
|
+
uv run ruff check src/ tests/ # no lint errors
|
|
34
|
+
uv run pyright src tests # no type errors
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## TDD Workflow
|
|
38
|
+
|
|
39
|
+
We follow **Red-Green-Refactor** for every code change:
|
|
40
|
+
|
|
41
|
+
1. **Red** — Write a failing test that describes the behaviour you want.
|
|
42
|
+
2. **Green** — Write the simplest code that makes the test pass.
|
|
43
|
+
3. **Refactor** — Clean up while keeping all tests green.
|
|
44
|
+
|
|
45
|
+
Never skip the red step. If you can't write a failing test first, take a moment
|
|
46
|
+
to think about what the code should actually do.
|
|
47
|
+
|
|
48
|
+
## Branch Naming
|
|
49
|
+
|
|
50
|
+
Create a branch from `main` using one of these prefixes:
|
|
51
|
+
|
|
52
|
+
| Prefix | When to use |
|
|
53
|
+
|--------|-------------|
|
|
54
|
+
| `feat/` | New feature or command |
|
|
55
|
+
| `fix/` | Bug fix |
|
|
56
|
+
| `refactor/` | Restructuring without behaviour change |
|
|
57
|
+
| `test/` | Test-only changes |
|
|
58
|
+
| `docs/` | Documentation updates |
|
|
59
|
+
| `ci/` | CI/CD workflow changes |
|
|
60
|
+
| `chore/` | Dependency bumps, config tweaks |
|
|
61
|
+
|
|
62
|
+
Example: `feat/benchmark-suite`, `fix/scheduler-priority-bug`
|
|
63
|
+
|
|
64
|
+
## Conventional Commits
|
|
65
|
+
|
|
66
|
+
Every commit message must follow [Conventional Commits](https://www.conventionalcommits.org/):
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
<type>: <short description in imperative mood>
|
|
70
|
+
|
|
71
|
+
Optional longer explanation.
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Types match the branch prefixes: `feat:`, `fix:`, `refactor:`, `test:`,
|
|
75
|
+
`docs:`, `ci:`, `chore:`.
|
|
76
|
+
|
|
77
|
+
Good examples:
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
feat: add benchmark command for scheduler comparison
|
|
81
|
+
fix: prevent deadlock when forking with held mutex
|
|
82
|
+
docs: clarify memory paging analogy
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Bad examples:
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
updated stuff # no type, vague description
|
|
89
|
+
feat: adds benchmarks # not imperative mood ("adds" → "add")
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Code Style
|
|
93
|
+
|
|
94
|
+
### Modern Python
|
|
95
|
+
|
|
96
|
+
Use Python 3.14 idioms everywhere:
|
|
97
|
+
|
|
98
|
+
- `X | Y` for union types (not `Union[X, Y]` or `Optional[X]`)
|
|
99
|
+
- `StrEnum` for string enumerations
|
|
100
|
+
- `match/case` instead of if/elif chains where appropriate
|
|
101
|
+
- Direct imports: `from enum import StrEnum` not `import enum`
|
|
102
|
+
|
|
103
|
+
### Docstrings
|
|
104
|
+
|
|
105
|
+
Every public function, method, class, and module needs a docstring:
|
|
106
|
+
|
|
107
|
+
- Use **imperative mood**: "Return the process." not "Returns the process."
|
|
108
|
+
- One-liner for simple functions, multi-line (Google style) for complex ones.
|
|
109
|
+
|
|
110
|
+
```python
|
|
111
|
+
def terminate(self, pid: int) -> bool:
|
|
112
|
+
"""Terminate a process by PID."""
|
|
113
|
+
|
|
114
|
+
def allocate(self, num_pages: int, pid: int) -> list[int]:
|
|
115
|
+
"""Allocate contiguous pages for a process.
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
num_pages: Number of pages to allocate.
|
|
119
|
+
pid: Process requesting the allocation.
|
|
120
|
+
|
|
121
|
+
Returns:
|
|
122
|
+
List of allocated frame numbers.
|
|
123
|
+
|
|
124
|
+
Raises:
|
|
125
|
+
MemoryError: If not enough free frames are available.
|
|
126
|
+
"""
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Named Constants
|
|
130
|
+
|
|
131
|
+
Use named constants instead of magic numbers in tests and source code. Ruff
|
|
132
|
+
rule PLR2004 enforces this.
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
# Good
|
|
136
|
+
EXPECTED_FRAME_COUNT = 64
|
|
137
|
+
assert manager.free_frames == EXPECTED_FRAME_COUNT
|
|
138
|
+
|
|
139
|
+
# Bad
|
|
140
|
+
assert manager.free_frames == 64
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Linting and Type Checking
|
|
144
|
+
|
|
145
|
+
Run these before every commit (pre-commit hooks enforce them automatically):
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
uv run ruff check src/ tests/ # lint
|
|
149
|
+
uv run ruff format src/ tests/ # format (or --check to verify)
|
|
150
|
+
uv run pyright src tests # type check (strict mode)
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Fix all violations. Inline `# noqa:` is acceptable only when tools genuinely
|
|
154
|
+
conflict (e.g., ARG002 vs pyright protocol parameter names).
|
|
155
|
+
|
|
156
|
+
## Testing
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
uv run pytest # run all tests
|
|
160
|
+
uv run pytest --cov # with coverage report
|
|
161
|
+
uv run pytest tests/test_x.py # run a specific file
|
|
162
|
+
uv run pytest -k "test_name" # run tests matching a pattern
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
- Minimum **80% coverage** is enforced.
|
|
166
|
+
- Test classes and methods need docstrings too.
|
|
167
|
+
- Use `pytest.raises` as a context manager for exception testing.
|
|
168
|
+
|
|
169
|
+
## Adding a Shell Command
|
|
170
|
+
|
|
171
|
+
1. **Add the syscall** (if needed) in `src/py_os/syscalls.py`:
|
|
172
|
+
- Add the enum value to `SysCall`
|
|
173
|
+
- Add a handler method `_handle_<name>`
|
|
174
|
+
- Register it in the dispatch table
|
|
175
|
+
|
|
176
|
+
2. **Add the shell command** in `src/py_os/shell.py`:
|
|
177
|
+
- Add `"command_name": self._cmd_name` to the dispatch dict in `__init__`
|
|
178
|
+
- Implement `_cmd_name(self, args: list[str]) -> str`
|
|
179
|
+
|
|
180
|
+
3. **Add tab completion** in `src/py_os/completer.py`:
|
|
181
|
+
- Add `"command_name": ["sub1", "sub2"]` to `_SUBCOMMANDS` (if it has
|
|
182
|
+
subcommands)
|
|
183
|
+
|
|
184
|
+
4. **Write tests** in `tests/test_command_name.py` following TDD.
|
|
185
|
+
|
|
186
|
+
5. **Update docs** — add a row to the shell commands table in `README.md`.
|
|
187
|
+
|
|
188
|
+
## Documentation Style
|
|
189
|
+
|
|
190
|
+
Our docs target a **12-year-old with an interest in computing**. Keep language
|
|
191
|
+
simple, use analogies, and avoid jargon without explanation.
|
|
192
|
+
|
|
193
|
+
Good:
|
|
194
|
+
|
|
195
|
+
> Memory is like a warehouse with numbered shelves. Each shelf (called a
|
|
196
|
+
> "frame") can hold one page of data. When a program needs space, the OS finds
|
|
197
|
+
> empty shelves and assigns them.
|
|
198
|
+
|
|
199
|
+
Bad:
|
|
200
|
+
|
|
201
|
+
> The memory manager implements a demand-paged virtual memory system with
|
|
202
|
+
> frame-based physical allocation.
|
|
203
|
+
|
|
204
|
+
## Pull Request Process
|
|
205
|
+
|
|
206
|
+
1. Create a feature branch from `main`.
|
|
207
|
+
2. Make your changes following TDD.
|
|
208
|
+
3. Ensure all checks pass: `uv run ruff check .`, `uv run pyright src tests`,
|
|
209
|
+
`uv run pytest --cov`.
|
|
210
|
+
4. Push your branch and open a PR against `main`.
|
|
211
|
+
5. PRs are squash-merged to keep history clean.
|
|
212
|
+
|
|
213
|
+
## Questions?
|
|
214
|
+
|
|
215
|
+
Open an issue on [GitHub](https://github.com/robcox2910/py-os/issues) — we're
|
|
216
|
+
happy to help!
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Rob Cox
|
|
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.
|