Metadata-Version: 2.4
Name: pycforge
Version: 0.16.1
Summary: Deterministic bounded Python-to-C source transpiler
License-Expression: GPL-3.0-only
Project-URL: Homepage, https://github.com/lastforkbender/pycforge
Project-URL: Repository, https://github.com/lastforkbender/pycforge
Project-URL: Issues, https://github.com/lastforkbender/pycforge/issues
Project-URL: Changelog, https://github.com/lastforkbender/pycforge/blob/main/CHANGELOG.md
Keywords: python,c,transpiler,pyside6,qt6,desktop
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: X11 Applications :: Qt
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Code Generators
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: PySide6<7,>=6.8
Dynamic: license-file

# PyCForge

[![PyPI](https://img.shields.io/pypi/v/pycforge.svg)](https://pypi.org/project/pycforge/)
[![Python](https://img.shields.io/pypi/pyversions/pycforge.svg)](https://pypi.org/project/pycforge/)
[![CI](https://github.com/lastforkbender/pycforge/actions/workflows/ci.yml/badge.svg)](https://github.com/lastforkbender/pycforge/actions/workflows/ci.yml)
[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://github.com/lastforkbender/pycforge/blob/main/LICENSE)

PyCForge is a deterministic Python-to-C source transpiler with a full PySide6
(Qt 6) desktop workspace, a command-line interface, and a Python API. It
converts a documented, deliberately bounded Python subset into readable C11
source while producing diagnostics, source mappings, decision traces, and
reproducible fingerprints.

This source tree defines the PyCForge `0.16.1` package release contract over
the unchanged `0.16.0` converter contracts. Tagged builds are published only
after the complete release workflow revalidates the source, distributions,
required PySide6 desktop application, and immutable assets.

![PyCForge 0.16.1 blackened-steel workspace showing ForgeLens across multi-module Python source and generated C](https://raw.githubusercontent.com/lastforkbender/pycforge/80cb4fe9b3f08de0a94efe17a5a1338f55863d3c/docs/images/pycforge-workspace-0.16.1.png)

**[Open the 35-page PyCForge 0.16.0 Programmer's Conversion Guide (PDF)](https://raw.githubusercontent.com/lastforkbender/pycforge/ba7ada7b00a975d489cb2cc605cc206b9bf687b1/docs/PyCForge_v0_16_0_Programmers_Conversion_Guide.pdf)**

## Quick start

PyCForge requires Python 3.11 or newer. Install it from PyPI:

```bash
python -m pip install pycforge
```

That one command installs **PySide6 and the desktop application as required
dependencies**. There is no GUI extra and no separate desktop package.
Minimal Debian/Ubuntu installations must also provide the system EGL runtime
(`sudo apt-get install libegl1`); the pinned Linux CI and release runners
install it explicitly before exercising real Qt widgets.

Launch the desktop workspace:

```bash
pycforge-workspace
```

The equivalent module command is:

```bash
python -m pycforge.ide
```

## A 60-second conversion

Save this as `example.py`:

```python
def add(left: int, right: int) -> int:
    return left + right
```

Convert it:

```bash
pycforge convert example.py --output example.c
```

PyCForge produces:

```c
#include <stdint.h>

int64_t add(int64_t left, int64_t right);

int64_t add(int64_t left, int64_t right)
{
    return left + right;
}
```

The generated C is deterministic for the same authenticated source bundle and
converter configuration.

## What PyCForge provides

- A Python-first PySide6/Qt 6 workspace with document tabs, source splitting,
  navigation, search, outline, command palette, and conversion history.
- Persisted 8–48 pt Python-editor text sizing from **Edit → Editor Settings…**
  with a default-on ForgeLens toggle, plus undoable Python-aware
  auto-indentation on Enter.
- Exact, passive ForgeLens Python↔C cross-highlighting and custom blackened-steel
  Open/Save browsers; Open renders readable source pages in memory, while Save
  stays preview-free.
- Explicit source bundles containing 1 to 64 Python documents, including
  bounded cross-module function imports.
- Read-only generated C with clean text presentation plus source mappings,
  overview-rail navigation, diagnostics, conversion summary, decision trace,
  and telemetry inspectors.
- Isolated, cancellable desktop conversion so the converter does not run on
  the GUI thread.
- A headless CLI for scripts and build pipelines.
- A Python API for applications that need structured conversion results.
- Stable diagnostics and fail-closed rejection of unsupported Python.
- Phase 16 proofs for selected branch-defined scalar locals, Python loop
  completion (`while`/`for ... else`), overflow-safe signed-64 `range`
  updates, and one closed bounded UTF-8 file read/write profile.

## Command-line interface

Write generated C to a file:

```bash
pycforge convert input.py --output generated.c
```

Emit the structured result as JSON:

```bash
pycforge --format json convert input.py
```

See all commands and options:

```bash
pycforge --help
```

## Python API

```python
from pycforge import ConversionRequest, PythonToCConverter

source = """\
def add(left: int, right: int) -> int:
    return left + right
"""

result = PythonToCConverter().convert(
    ConversionRequest.from_source(source)
)

if result.generated_c is not None:
    print(result.generated_c)
else:
    for diagnostic in result.diagnostics:
        print(diagnostic)
```

The desktop workspace, CLI, and Python API use the same converter and result
contracts.

## Supported Python

PyCForge is intentionally not a general Python runtime. Its current subset
includes strictly annotated top-level functions using selected scalar values,
arithmetic and comparisons, `if`/`elif`/`else`, bounded `while` and `range`
loops including proved loop `else`, direct eligible function calls, fixed
homogeneous containers, a bounded static-record profile, selective scalar
scope hoisting, and exact bounded UTF-8 file sessions.

Anything outside the documented subset is unsupported by default and is
rejected with diagnostics rather than silently approximated. Read the exact
[supported-Python specification](https://github.com/lastforkbender/pycforge/blob/main/specifications/supported_python.md)
before adopting PyCForge for production input.

### Phase 16 in brief

- A scalar local first assigned below an exhaustive `if` can be declared once
  at C function entry when every reachable use is definitely preceded by a
  compatible `int`, `float`, `bool`, or `str` store. This is selective proof,
  not general Python scope or closure support.
- `else` is supported on admitted `while`, positional `range`, and fixed
  list/tuple/dictionary loops. Natural termination—including zero
  iterations—runs the else suite; only a `break` owned by that exact loop
  suppresses it. Nested breaks, `continue`, and returns retain Python control
  ownership. Phase 16 also guards a signed-64 `range` update before adding its
  step, avoiding C signed overflow at the exhaustion boundary.
- File I/O is limited to a direct one-item `with open(path, 'r' or 'w',
  encoding='utf-8', newline='') as handle` inside a top-level function, with
  one direct `read()` transfer or one `write(text)` statement whose text is an
  already-proved string name or string literal. Effectful write expressions are
  rejected because helper-internal open cannot preserve context-entry ordering.
  An assigned read result must declare a fresh direct local rather than rebind
  a parameter or earlier local. Reads are
  bounded (1 MiB by default, 16 MiB hard maximum), validate UTF-8 and reject
  embedded NUL, and transfer one unique buffer only after close succeeds.
  Writes use borrowed UTF-8 text, require an exact byte count, and propagate
  close failure. Aliasing, rebinding, explicit close, arbitrary modes,
  multiple context items, and general file-object behavior fail closed.

  At the generated-C ABI, the external caller must supply non-null,
  NUL-terminated valid UTF-8 path strings. Borrowed write text has the same
  preconditions and must contain no embedded NUL. The helpers cannot
  independently validate pointer validity, path UTF-8/NUL properties, or an
  embedded NUL beyond the first terminator in write text. Source path literals
  containing NUL reject with `PYC3903`; write literals containing NUL reject
  with `PYC3905`. Runtime codes 5 and 6 describe read file content only.

## Safety boundary

PyCForge parses supplied source as data. Conversion never imports or executes
the input Python, scans the host environment for modules, resolves undeclared
files, or opens a path selected by the source program. It stops after C source
generation. PyCForge never compiles, assembles, links, loads, runs, or executes
the generated C.

Generated C for an admitted Phase 16 file-effect function performs file I/O
only if someone separately builds and runs that C outside PyCForge. Its public
C entry point has one generated final `int64_t *` status parameter; the
external caller owns that writable status storage and must pass a non-null
pointer. Each file-effect entry initializes it to success immediately after
the null guard and before source-controlled work; helpers overwrite it on
failure. A successful read returns a unique `malloc`-owned `char *`; the
external caller owns it and must release it with `free`. Failures return null
for reads or the function's failure value for writes and publish the stable
status code. Source-defined calls to file-effect functions are rejected in the
initial profile so this ABI cannot be bypassed inside transpiled Python.

Python `int` values map to the documented signed 64-bit representation domain;
other supported Python values likewise follow explicit target-C contracts.
Review the
[product boundary](https://github.com/lastforkbender/pycforge/blob/main/specifications/product_boundary.md)
and the Programmer's Conversion Guide for the complete limitations.

## Documentation

- **[Programmer's Conversion Guide - 0.16.0 Reference Edition (PDF)](https://raw.githubusercontent.com/lastforkbender/pycforge/ba7ada7b00a975d489cb2cc605cc206b9bf687b1/docs/PyCForge_v0_16_0_Programmers_Conversion_Guide.pdf)**
- [Supported Python](https://github.com/lastforkbender/pycforge/blob/main/specifications/supported_python.md)
- [Workspace specification](https://github.com/lastforkbender/pycforge/blob/main/specifications/pycforge_workspace.md)
- [UI roadmap](https://github.com/lastforkbender/pycforge/blob/main/ROADMAP.md)
- [Current state](https://github.com/lastforkbender/pycforge/blob/main/CURRENT_STATE.md)
- [Release notes](https://github.com/lastforkbender/pycforge/blob/main/RELEASE_NOTES.md)
- [Changelog](https://github.com/lastforkbender/pycforge/blob/main/CHANGELOG.md)
- [Security policy](https://github.com/lastforkbender/pycforge/blob/main/SECURITY.md)

## Development

```bash
git clone https://github.com/lastforkbender/pycforge.git
cd pycforge
python -m venv .venv
python -m pip install --upgrade pip
python -m pip install -e .
python -m pip install pytest reportlab==4.4.9 pypdf==6.10.0
QT_QPA_PLATFORM=offscreen python -m pytest -q -rs
```

The normal editable installation includes PySide6, matching the package users
receive from PyPI. Automated release checks cover Python 3.11 and 3.12 on
Linux with real PySide6 widgets using Qt's offscreen platform.

## License

PyCForge is free software released under the
[GNU General Public License v3.0 only](https://github.com/lastforkbender/pycforge/blob/main/LICENSE).
