API Reference
Core Modules
parser
c2py23.parser
Parser for c2py23 interface definitions.
Handles
- Python dict format (native, no dependency)
- C2PY_BEGIN blocks embedded in C source files
- C function signature parsing
- Expression parsing (for 'when' conditions and 'map' substitutions)
- Building the ModuleDef data model
The entry point is load_c2py(path) which auto-detects the input format.
For programmatic use, from_c2py_dict(raw_dict, path) accepts a Python dict
directly.
ModuleDef
Bases: namedtuple('ModuleDef', ['name', 'sources', 'headers', 'functions', 'constants', 'timing', 'free_threading'])
constants is a dict of {name: int_value} for module-level integer constants. timing is a bool enabling per-function performance profiling. free_threading is a bool; when true, the module declares Py_MOD_GIL_NOT_USED on free-threaded Python builds (prevents GIL re-enablement).
Source code in c2py23/parser.py
FuncDef
Bases: namedtuple('FuncDef', ['name', 'py_params', 'return_type', 'checks', 'overloads', 'default_raise', 'doc', 'gil_release'])
A wrapped Python function definition.
params is an optional dict mapping parameter names to human-readable descriptions, parsed from the interface definition. Keys are validated against py_sig parameter names.
Source code in c2py23/parser.py
COverload
Bases: namedtuple('_COverload', ['sig_str', 'params', 'return_type', 'map_exprs', 'when_expr', 'name', 'group_name', 'variants', 'c_name'])
A C function overload alternative or a dispatch group.
For flat overloads (backward compatible): sig_str, params, return_type, map_exprs, when_expr are populated. name is optional (required if when_expr is static for rebind support). variants is None. c_name is the extracted C function name (no re-parsing needed).
For grouped dispatch
variants is a non-empty list of CVariant. sig_str, params, return_type are None. map_exprs is the shared argument map for all variants in the group. when_expr is the per-call group condition (e.g. data.format == 'f'). group_name is an optional label (for rebind qualifiers, docstrings). c_name is None (variants carry their own c_name).
outputs maps C parameter names to ctypes types (e.g. {'minval': 'double'}). Output params are auto-allocated as 1-element arrays and returned in the tuple.
doc is an optional per-overload or per-group description string.
Source code in c2py23/parser.py
CVariant
Bases: namedtuple('CVariant', ['name', 'sig_str', 'params', 'return_type', 'when_expr', 'outputs', 'c_name'])
A variant within a dispatch group. Inherits map_exprs from the parent group.
name is required for rebind, docstring, and timing identification.
when_expr is the static (CPU feature) dispatch condition, or None for default.
outputs is an optional dict for scalar output parameters (same format as COverload).
doc is an optional per-variant description string.
c_name is the extracted C function name (no re-parsing needed).
default is True if the variant should be auto-selected at init.
Set default: false to make the variant reachable only via rebind
Source code in c2py23/parser.py
PyParam
Bases: namedtuple('PyParam', ['name', 'pytype', 'default'])
pytype is one of 'buffer', 'int', 'float'. default is None for required params, or a numeric value for optional int/float params.
CParam
Bases: namedtuple('CParam', ['name', 'ctype', 'base_type', 'is_const', 'is_pointer', 'array_dims'])
ctype is the full C type string, base_type is the element type. array_dims is a list of dimension values (strings or None for []) from C array notation like gv[][3] (-> [None, '3']). None means the parameter was declared with plain * pointer notation.
Source code in c2py23/parser.py
load_c2py(path)
Load and parse an interface definition, returning a ModuleDef.
Supports two formats, auto-detected: 1. C source (.c, .h): C2PY_BEGIN..C2PY_END blocks embedded in comments (parsed via c2py23.harvester). 2. Python dict (.c2py, .c2py.py): a file containing a Python dict literal (parsed via ast.literal_eval). Lines starting with '#' are stripped as comments.
For .c and .h files, interface definitions are embedded as: / C2PY_BEGIN "module": "mymod", "source": ["mymod.c"], "functions": ... C2PY_END /
Source code in c2py23/parser.py
from_c2py_dict(raw_dict, path='<dict>')
Parse a Python dict (from dict format) into a ModuleDef.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
raw_dict
|
A dict with keys: module, source, headers, functions, constants, timing, free_threading. |
required | |
path
|
A label for error messages (file path or " |
'<dict>'
|
Returns:
| Type | Description |
|---|---|
|
A ModuleDef namedtuple. |
Source code in c2py23/parser.py
generator
c2py23.generator
C code generator for c2py23.
Transpiles a parsed ModuleDef AST into a compilable CPython C extension. Uses the CBuilder class to enforce structural invariants at emit time: buffer acquires are paired with releases, GIL saves with restores, output scalars with NULL checks and PyTuple_SetItem.
CBuilder
Stateful builder for generating C wrapper code.
Tracks buffer acquires, GIL depth, and output-object construction so that cleanup code is always structurally correct.
Source code in c2py23/generator.py
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 | |
acquire_buffer(buf_var, py_var, flags, func_name)
Emits c2py_pin with correct failure path.
First buffer: return NULL on failure (nothing to clean up). Subsequent: goto cleanup on failure.
Source code in c2py23/generator.py
emit_contiguity_checks(buf_params)
Emit contiguity validation for each buffer.
Also emits c2py_slow_axis_buf{name} -- the index of the slowest varying axis (0 for C-contiguous, ndim-1 for F-contiguous). Set to -1 if the buffer is not C or F contiguous (rejected anyway).
Source code in c2py23/generator.py
emit_restrict_checks(buf_params, func)
Emit restrict alias checks between writable buffers.
Source code in c2py23/generator.py
generate(module_def, use_single_header=False)
Generate C wrapper source for a module using CBuilder pattern.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
module_def
|
Parsed ModuleDef AST. |
required | |
use_single_header
|
If True, emit #define C2PY_IMPLEMENTATION + include "c2py.h" instead of #include "c2py_runtime.h". |
False
|
Returns C source string.
Source code in c2py23/generator.py
cli
c2py23.cli
CLI entry point for c2py23 -- generate C wrapper from .c2py interface.
Usage
c2py23 file.c2py -o wrapper.c # generate wrapper to file c2py23 file.c2py # generate to stdout c2py23 --version # print version
generate(c2py_path, output_path=None, use_single_header=False)
Parse a .c2py file and generate the wrapper C file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
c2py_path
|
Path to .c2py interface file. |
required | |
output_path
|
Optional output .c path. If None, returns code. |
None
|
|
use_single_header
|
If True, emit #include "c2py.h" (with C2PY_IMPLEMENTATION) instead of #include "c2py_runtime.h". |
False
|
Returns:
| Type | Description |
|---|---|
|
Generated C code as string. |
Source code in c2py23/cli.py
c2py_loader
c2py23.c2py_loader
c2py_loader - Load a c2py23-native .so by explicit filename.
Convention:
Example files
_mymodule.c2py23-linux_x86_64.so _mymodule.c2py23-linux_ppc64le.so _mymodule.c2py23-linux_aarch64.so _mymodule.c2py23-win_amd64.pyd _mymodule.c2py23-darwin_arm64.so
No monkeypatching of EXTENSION_SUFFIXES. No sys.path hacking. Loads the .so by full path via ExtensionFileLoader (Python 3.x) or imp.load_dynamic (Python 2.7).
Usage in your package's init.py:
from c2py23.c2py_loader import load_native
import os as _os
_mod = load_native(_os.path.dirname(_os.path.abspath(__file__)),
'_mymodule')
# Re-export public names (skip dunders, keep single-underscore API)
for _k, _v in _mod.__dict__.items():
if _k.startswith('__') and _k.endswith('__'):
continue
globals()[_k] = _v
Users who do not want a c2py23 runtime dependency can copy the function body into their own init.py. The code is intentionally small and self-contained.
load_native(package_dir, module_name='_native', tag='c2py23')
Load
package_dir: Absolute path to the package directory containing the .so files. module_name: Base module name (default '_native'). Must match the c2py23 'module:' field. Use a unique name per package (e.g. '_mymodule') to avoid collisions in sys.modules. tag: Tag string inserted in the filename (default 'c2py23').
Returns:
| Type | Description |
|---|---|
|
The loaded module object. The caller should re-export public |
|
|
names from it. |
Example
_mod = load_native(os.path.dirname(file), '_mymodule')
Source code in c2py23/c2py_loader.py
perf
c2py23.perf
c2py23 performance data decoder.
Reads c2py_perf_t data via module-level C accessor functions -- no ctypes
required. Modules built with timing: true expose _c2py_perf_read,
_c2py_perf_meta, _c2py_perf_reset and pointer attributes on the module
so that read_perf() can locate the right perf counter from the wrapper
function object alone.
Usage::
from c2py23.perf import read_perf, reset_perf
import my_timed_module
stats = read_perf(my_timed_module.wsum)
print(stats)
# Switch to CPU cycle counter at runtime (rdtsc/CNTVCT_EL0/mftb):
my_timed_module._c2py_set_tick_source("cycle")
stats = read_perf(my_timed_module.wsum)
# Switch back to wall clock:
my_timed_module._c2py_set_tick_source("clock")
# Read the currently-selected variant's timing:
stats = read_perf(my_timed_module.poly, variant=True)
# Reset counters between benchmark batches:
reset_perf(my_timed_module.wsum)
read_enabled(func)
Return 1 if per-call timing is enabled, 0 otherwise.
Parameters
func : callable
Any wrapper function from a timing-enabled module. The module
is found via func.__self__ (Python 3) or func.__module__
(Python 2.7).
Source code in c2py23/perf.py
read_perf(func, freq_hz=None, variant=None)
Decode a c2py_perf_t counter.
Parameters
func : callable
Wrapper function on a timing-enabled module (e.g. mod.wsum).
The module is found via func.__self__ and the counter pointer
is looked up by func.__name__ on the module.
freq_hz : int or None, optional
Tick source frequency in Hz. When None or 0, the raw tick values
are returned under the _ns keys (correct for the default
clock_gettime source which returns nanoseconds). When provided
and not equal to 1e9, the values are converted and the raw tick
values are additionally returned under _cycles keys.
variant : None, True, or str, optional
Which perf counter to read:
- ``None`` (default) -- wrapper-overhead counter
- ``True`` -- the currently-selected variant (functions with
variant groups only; falls back to wrapper overhead otherwise)
- ``str`` -- a named overload, e.g. ``"weighted_sum"`` for the
counter ``_c2py_ol_ptr_wsum__weighted_sum``
Returns
dict with keys: call_count, t_enter, t_pre_c, t_post_c, t_exit, c_dur_ns, wrap_dur_ns, c_min_ns, c_max_ns, c_mean_ns, wrap_min_ns, wrap_max_ns, wrap_mean_ns, variant, group_idx, variant_name. Additional keys when freq_hz is provided and != 1e9: c_dur_cycles, wrap_dur_cycles, c_min_cycles, c_max_cycles, c_mean_cycles, wrap_min_cycles, wrap_max_cycles, wrap_mean_cycles.
Source code in c2py23/perf.py
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 | |
reset_perf(func, variant=None)
Reset a c2py_perf_t counter to its initial state.
Parameters
func : callable
Wrapper function on a timing-enabled module (e.g. mod.wsum).
variant : None, True, or str, optional
Selects which counter to reset. See :func:read_perf.
Source code in c2py23/perf.py
set_enabled(func, value)
Enable (value=1) or disable (value=0) per-call timing.
Parameters
func : callable
See :func:get_enabled.
value : int
1 to enable, 0 to disable.
Source code in c2py23/perf.py
invariant_checker
c2py23.invariant_checker
Invariant checker for generated C code.
Scans generated C source and verifies structural properties
- Buffer acquire/release pairs in wrapper functions
- GIL save/restore pairs in impl functions
- Output scalar NULL checks + PyTuple_SetItem
- Balanced braces
Raises ValueError with line number on first violation.
verify_c_invariants(code)
Check generated C for structural errors before returning.
Scans the generated C and verifies
- Buffer acquire/release pairs in wrapper functions
- GIL save/restore pairs in impl functions
- Output scalar NULL checks + PyTuple_SetItem
- Balanced braces
Raises ValueError with line number on first violation.
Source code in c2py23/invariant_checker.py
Tools
convert_c2py_to_dict
tools.convert_c2py_to_dict
Convert YAML .c2py files to Python dict format sidecar (.c2py.py).
The .c2py.py file is written alongside the original .c2py file and contains the equivalent interface as a Python dict literal. It is auto-detected by load_c2py() and can be loaded in place of the YAML.
Usage
python3 tools/convert_c2py_to_dict.py # tests/cases/ python3 tools/convert_c2py_to_dict.py --all # tests/cases/ + examples/ python3 tools/convert_c2py_to_dict.py path/file.c2py # single file python3 tools/convert_c2py_to_dict.py --check # validate symmetry only
convert_file(c2py_path, check_only=False)
Read YAML, write .c2py.py sidecar. Returns True on success.
Source code in tools/convert_c2py_to_dict.py
py_repr(obj, indent=0)
Render a Python object as a pretty-printed Python dict literal.
Source code in tools/convert_c2py_to_dict.py
Converts .c2py files from legacy YAML to Python dict format. YAML is no longer supported by c2py23 with default dependencies. This script is only needed for migration. Run with: