Python Bindings¶
GenPython produces one .py file per package containing
typing.Protocol classes. Three annotation styles are supported.
Generated Artifacts¶
$ python -m ml_hpi generate --spec spec.yaml --outdir gen/ --lang python
$ python -m ml_hpi generate --spec spec.yaml --outdir gen/ --lang python \
--python-style annotated
Annotation Styles¶
Plain (default) – bare Python types:
class RegIf(typing.Protocol):
async def write32(self, addr: int, data: int) -> None: ...
async def read32(self, addr: int) -> int: ...
def reset(self) -> None: ...
Annotated – Annotated[int, ...] aliases that preserve ml-hpi type
width information:
from typing import Annotated
Addr64 = Annotated[int, "addr64"]
UInt32 = Annotated[int, "uint32"]
class RegIf(typing.Protocol):
async def write32(self, addr: Addr64, data: UInt32) -> None: ...
async def read32(self, addr: Addr64) -> UInt32: ...
def reset(self) -> None: ...
ctypes – ctypes.c_* types for FFI-oriented code:
import ctypes
class RegIf(typing.Protocol):
async def write32(self, addr: ctypes.c_uint64, data: ctypes.c_uint32) -> None: ...
async def read32(self, addr: ctypes.c_uint64) -> ctypes.c_uint32: ...
def reset(self) -> None: ...
Method Mapping¶
ml-hpi construct |
Python output |
|---|---|
Method (non-blocking) |
|
Method (blocking) |
|
Member (field) |
|
Member (array) |
def {name}_at(self, idx: int) -> IfType: ...def {name}_size(self) -> int: ... |
Inheritance |
|
Type Mapping¶
ml-hpi |
Plain |
Annotated |
ctypes |
|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Python Parser¶
ParsePython uses Python’s ast module to parse Protocol classes back
to an MlHpiDoc. The parser auto-detects the annotation style from
imports.
$ python -m ml_hpi parse --lang python --input pkg.py --output recovered.yaml
Limitations:
Plain-style
intis ambiguous (could be any integer width); the parser defaults toint32and emits a warning. Use the annotated style for lossless round-trip fidelity.target/solveattributes are not expressible in Python and default to unset.The parser performs static analysis only; it does not execute the file.