A correctness-first incremental query engine for Python.
Project description
pyinc
pip install pyinc
Python is mutable by default, identity-heavy, and full of hidden side effects. These properties make incremental computation unsound in practice: cached results silently depend on mutated state, untracked file reads, and object identity that the cache cannot see.
pyinc is a correctness-first incremental computation engine that solves this problem. It is a pure-Python, stdlib-only query kernel in the design space of Salsa, Jane Street Incremental, and Bazel/Skyframe — but designed specifically for the challenges Python creates.
v1.0.0 is the first stable release. The v1 kernel contract and public integration surface are stable under semver, within the soundness envelope documented in docs/kernel-contract.md.
Quick example
from pyinc import Database, FileResource, query
_FILES = FileResource()
@query
def read_config(db, path):
return _FILES.read(db, path) # tracked file read
@query
def parse_names(db, path):
text = read_config(db, path)
return [line.strip() for line in text.splitlines() if line.strip()]
db = Database(mode="strict")
result = db.get(parse_names, "/tmp/names.txt") # computes from scratch
result = db.get(parse_names, "/tmp/names.txt") # reuses memo — file unchanged
# Edit the file: only affected queries re-execute.
# Comment-only edits can be backdated (early cutoff) with a cutoff= function.
# Raw open() inside a query raises UntrackedReadError.
# In strict mode, returned values are frozen — mutation raises TypeError.
See examples/correctness_demo.py for a full walkthrough of backdating (early cutoff), mutation protection, untracked read enforcement, and provenance inspection. examples/undeclared_imports.py, examples/applicable_requirements.py, and examples/symbol_lookup.py demonstrate three of the shipped integrations end-to-end on self-contained tempdir workspaces.
What pyinc guarantees
pyinc guarantees from-scratch consistency — the result of incremental evaluation matches a fresh evaluation on the same declared inputs and resources — when:
- Value boundary ownership: all values crossing cached boundaries are snapshot-safe (frozen)
- Tracked ambient reads: all external state reads go through the Resource API
- Deterministic queries: given the same tracked dependencies, queries return semantically equal values
The full contract, including explicit limitations and escape hatches, is in docs/kernel-contract.md.
Current scope
@queryfor derived values,Inputfor explicit base leaves- optional
eq=andcutoff=policies for custom equivalence and backdating (early cutoff) ValueAdapterfor custom snapshot-safe boundary typesFileResource,FileStatResource,EnvResource, andDirectoryResourcefor tracked external reads- pull-based recomputation with revisions, dependency capture, red-green verification, and backdating (early cutoff)
strict,checked, andfastexecution modes with explicit boundary semantics- optional bounded query memoization via
Database(max_query_nodes=...) Database.set_many(...)for atomic batch invalidation of multiple inputs (single revision bump)Database.dependency_graph()for machine-readable graph export of all nodes and edgesDatabase.inspect(...)for structured provenance andDatabase.explain(...)for human-readable formattingDatabase.statistics()for aggregate counters andDatabase.query_profile()for per-query timing
Integrations
pyinc.integrations.python_source— workspace-local module discovery, top-level imports/definitions, simple assignment tracking for export surfaces, conservative import resolution withworkspace/stdlib/installed/missing/ambiguousoutcomes (stdlib and installed classification via composition withinstalled_packages; installed imports'resolved_pathis populated viadeep_module_resolution).pyinc.integrations.toml_config— single-file TOML inspection: section/key extraction, dependency and optional-dependency discovery, tool config discovery.pyinc.integrations.requirements_txt— narrow requirements parsing: normalized requirement specs, file references, index directives, editable installs, URL requirements. Includesdeep_requirements_analysisfor recursive-r/--requirementfile following with cycle detection.pyinc.integrations.installed_packages— installed package discovery viaimportlib.metadata-compatible.dist-infodirectories, stdlib module identification viasys.stdlib_module_names, and import name resolution (stdlib/installed/unknown).pyinc.integrations.deep_module_resolution— deep module path resolution:sys.pathwalking,.pthfile processing with backdating on whitespace/comment edits, PEP 420 namespace package collection, and dotted-name → file resolution. Exposesresolve_module_pathfor per-module queries anddeep_module_resolution_analysisfor a workspace-wide snapshot.pyinc.integrations.json_config— single-file JSON inspection: section/key extraction with type detection, nested object traversal, parse error diagnostics.pyinc.integrations.dependency_check— cross-integration dependency validation: composesinstalled_packagesandpython_sourceto detect undeclared imports and missing packages.pyinc.integrations.env_file—.envfile parsing: key-value extraction with quoted/unquoted values,exportprefix handling, interpolation reference detection.pyinc.integrations.xml_config— XML file inspection viaxml.etree.ElementTree: element/attribute extraction, dot-path traversal, namespace-aware tag normalization.pyinc.integrations.csv_data— CSV/TSV structural analysis via stdlibcsv: header detection, column discovery, delimiter sniffing, row counting, inconsistent column diagnostics.pyinc.integrations.requirement_evaluation— PEP 440 version specifier satisfaction and PEP 508 environment marker evaluation; composes withrequirements_txtandinstalled_packagesto surface the effective applicable/satisfied requirement set for the current Python environment. Exposesevaluate_markers,evaluate_version_specifier, andapplicable_requirements.pyinc.integrations.symbol_resolution— workspace-wide symbol tables (module-level + class-level), cross-module re-export following with cycle detection, and type-annotation text extraction viaast.unparse(no type evaluation). Exposesmodule_symbol_table,resolve_symbol, andworkspace_symbol_index.
pyinc.integrations re-exports only the stable dataclass/result types and high-level entrypoints for these integrations. Low-level payload queries, decode helpers, and resource helpers remain experimental in their defining submodules.
Verification
- The runtime contract is summarized in docs/kernel-contract.md.
- The repo includes dedicated test modules for value semantics, runtime behavior, provenance/explanation formatting, property-based from-scratch consistency, and each shipped integration.
- The integration suites exercise
strict,checked, andfastmodes and compare incremental results against fresh recomputation over edit sequences.
The integration boundary is summarized in docs/integration-contract.md.
Gotchas
Database.inspect(...)is observational. It returns the last recorded provenance tree for that query key and does not force a fresh revalidation pass by itself.- Query identity includes the function definition payload. If you capture ambient values, those captures are part of the query fingerprint, and mutable closure/global captures are rejected.
Database.report_untracked_read(...)is an explicit impurity escape hatch. It marks that query as always re-executing and disables backdating for that node.- The package ships inline typing metadata via
py.typed.
Not supported
- LSP wiring
- File watchers (push-based filesystem invalidation)
These are architectural non-goals for v1. pyinc is a pull-based kernel; LSP servers
and push-based watchers belong to a consumer tool built on top of pyinc, not to the
kernel itself. See docs/architecture.md:80-82 for the v1 scope boundary.
Development
python3 -m venv .venv
. .venv/bin/activate
python3 -m pip install -e '.[dev]'
pytest -q
python3 -m mypy src tests
python3 -m ruff check src tests
The runtime contract is summarized in docs/kernel-contract.md. Integration API boundaries are summarized in docs/integration-contract.md. A guide for building new integrations is at docs/integration-authoring.md.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyinc-1.0.0.tar.gz.
File metadata
- Download URL: pyinc-1.0.0.tar.gz
- Upload date:
- Size: 123.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2c51cd145cfc9319c7bb298743074023d497f65da6af4c31b7b0977eb3817862
|
|
| MD5 |
511e8c75a06b333d64ad253712d540aa
|
|
| BLAKE2b-256 |
b30ae06b8cf93a3ef99ae90400468c8e2610fd1c2f718f5905bb2bad9c52a6ad
|
Provenance
The following attestation bundles were made for pyinc-1.0.0.tar.gz:
Publisher:
release.yml on Brumbelow/pyinc
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyinc-1.0.0.tar.gz -
Subject digest:
2c51cd145cfc9319c7bb298743074023d497f65da6af4c31b7b0977eb3817862 - Sigstore transparency entry: 1339383216
- Sigstore integration time:
-
Permalink:
Brumbelow/pyinc@7dcc6c41ca0bc680c0ce4321c8246c16fed6504f -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/Brumbelow
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@7dcc6c41ca0bc680c0ce4321c8246c16fed6504f -
Trigger Event:
push
-
Statement type:
File details
Details for the file pyinc-1.0.0-py3-none-any.whl.
File metadata
- Download URL: pyinc-1.0.0-py3-none-any.whl
- Upload date:
- Size: 71.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3743bbfb76a4eb1b43d73dfc72becf4fd71051ee3da1c426980eacd2153c4ba9
|
|
| MD5 |
b0d04a1fc833942c69fcb520aff42007
|
|
| BLAKE2b-256 |
8434bc5839bfbed19e9dcedd76de7847f5bd5eb1a4ea2ead72e28f26e61e8735
|
Provenance
The following attestation bundles were made for pyinc-1.0.0-py3-none-any.whl:
Publisher:
release.yml on Brumbelow/pyinc
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyinc-1.0.0-py3-none-any.whl -
Subject digest:
3743bbfb76a4eb1b43d73dfc72becf4fd71051ee3da1c426980eacd2153c4ba9 - Sigstore transparency entry: 1339383222
- Sigstore integration time:
-
Permalink:
Brumbelow/pyinc@7dcc6c41ca0bc680c0ce4321c8246c16fed6504f -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/Brumbelow
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@7dcc6c41ca0bc680c0ce4321c8246c16fed6504f -
Trigger Event:
push
-
Statement type: