prik 0.1.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.
- prik-0.1.0/CHANGELOG.md +36 -0
- prik-0.1.0/LICENSE +21 -0
- prik-0.1.0/MANIFEST.in +1 -0
- prik-0.1.0/PKG-INFO +591 -0
- prik-0.1.0/README.md +542 -0
- prik-0.1.0/prik/__init__.py +157 -0
- prik-0.1.0/prik/__main__.py +3 -0
- prik-0.1.0/prik/binding_support/LICENSE +21 -0
- prik-0.1.0/prik/binding_support/__init__.py +1 -0
- prik-0.1.0/prik/binding_support/prik_binding.h +776 -0
- prik-0.1.0/prik/cli.py +2460 -0
- prik-0.1.0/prik/compiling/__init__.py +0 -0
- prik-0.1.0/prik/compiling/compiler_profiles.py +307 -0
- prik-0.1.0/prik/compiling/compilers.py +352 -0
- prik-0.1.0/prik/compiling/native_support.py +41 -0
- prik-0.1.0/prik/compiling/objects.py +37 -0
- prik-0.1.0/prik/contracts/__init__.py +352 -0
- prik-0.1.0/prik/extensions/__init__.py +1 -0
- prik-0.1.0/prik/naming/__init__.py +19 -0
- prik-0.1.0/prik/naming/policy.py +409 -0
- prik-0.1.0/prik/parsers/__init__.py +3 -0
- prik-0.1.0/prik/parsers/c/__init__.py +107 -0
- prik-0.1.0/prik/parsers/c/__main__.py +6 -0
- prik-0.1.0/prik/parsers/c/cli.py +232 -0
- prik-0.1.0/prik/parsers/c/lexer.py +802 -0
- prik-0.1.0/prik/parsers/c/models.py +563 -0
- prik-0.1.0/prik/parsers/c/parser.py +3155 -0
- prik-0.1.0/prik/parsers/c/preprocessor.py +117 -0
- prik-0.1.0/prik/parsers/c/type_resolver.py +149 -0
- prik-0.1.0/prik/parsers/fortran/__init__.py +1 -0
- prik-0.1.0/prik/parsers/fortran/__main__.py +3 -0
- prik-0.1.0/prik/parsers/fortran/cli.py +345 -0
- prik-0.1.0/prik/parsers/fortran/lexer.py +122 -0
- prik-0.1.0/prik/parsers/fortran/models.py +538 -0
- prik-0.1.0/prik/parsers/fortran/parser.py +4969 -0
- prik-0.1.0/prik/parsers/fortran/type_resolver.py +26 -0
- prik-0.1.0/prik/parsers/fortran/utils.py +60 -0
- prik-0.1.0/prik/parsers/pyi/__init__.py +5 -0
- prik-0.1.0/prik/parsers/pyi/parser.py +26 -0
- prik-0.1.0/prik/pipeline/__init__.py +1 -0
- prik-0.1.0/prik/pipeline/build.py +2297 -0
- prik-0.1.0/prik/pipeline/preprocessing.py +1306 -0
- prik-0.1.0/prik/pipeline/pyi.py +130 -0
- prik-0.1.0/prik/pipeline/wrapper_artifacts.py +58 -0
- prik-0.1.0/prik/probes/__init__.py +1 -0
- prik-0.1.0/prik/probes/c_types.py +545 -0
- prik-0.1.0/prik/probes/fortran_types.py +669 -0
- prik-0.1.0/prik/probes/report.py +321 -0
- prik-0.1.0/prik/runtime/__init__.py +1 -0
- prik-0.1.0/prik/runtime/handles.py +1588 -0
- prik-0.1.0/prik/semantics/__init__.py +39 -0
- prik-0.1.0/prik/semantics/c2ir.py +1567 -0
- prik-0.1.0/prik/semantics/fortran2ir.py +2639 -0
- prik-0.1.0/prik/semantics/metadata.py +17 -0
- prik-0.1.0/prik/semantics/models.py +642 -0
- prik-0.1.0/prik/semantics/native_array_handles.py +442 -0
- prik-0.1.0/prik/semantics/native_contract.py +272 -0
- prik-0.1.0/prik/semantics/ownership.py +1962 -0
- prik-0.1.0/prik/semantics/policy_completion.py +1681 -0
- prik-0.1.0/prik/semantics/pyi2ir.py +2955 -0
- prik-0.1.0/prik/semantics/pyi_metadata.py +5 -0
- prik-0.1.0/prik/semantics/wrapper_exports.py +103 -0
- prik-0.1.0/prik/semantics/wrapper_policy.py +6471 -0
- prik-0.1.0/prik/stage_values.py +50 -0
- prik-0.1.0/prik/types/__init__.py +1 -0
- prik-0.1.0/prik/types/numpy.py +84 -0
- prik-0.1.0/prik/utilities/__init__.py +1 -0
- prik-0.1.0/prik/utilities/strings.py +45 -0
- prik-0.1.0/prik/utilities/visitor.py +39 -0
- prik-0.1.0/prik/wrapper_codegen/__init__.py +167 -0
- prik-0.1.0/prik/wrapper_codegen/c/__init__.py +1 -0
- prik-0.1.0/prik/wrapper_codegen/c/binding.py +11846 -0
- prik-0.1.0/prik/wrapper_codegen/checks.py +275 -0
- prik-0.1.0/prik/wrapper_codegen/docstrings.py +646 -0
- prik-0.1.0/prik/wrapper_codegen/fortran/__init__.py +1 -0
- prik-0.1.0/prik/wrapper_codegen/fortran/bridge.py +7247 -0
- prik-0.1.0/prik/wrapper_codegen/generator.py +4476 -0
- prik-0.1.0/prik/wrapper_codegen/naming.py +18 -0
- prik-0.1.0/prik/wrapper_codegen/nodes.py +428 -0
- prik-0.1.0/prik/wrapper_codegen/plan.py +812 -0
- prik-0.1.0/prik/wrapper_codegen/planner.py +1990 -0
- prik-0.1.0/prik/wrapper_codegen/primitive_scalar_types.py +122 -0
- prik-0.1.0/prik/wrapper_codegen/printers/__init__.py +13 -0
- prik-0.1.0/prik/wrapper_codegen/printers/pyi_printer.py +2112 -0
- prik-0.1.0/prik/wrapper_codegen/printers/source_printers.py +772 -0
- prik-0.1.0/prik/wrapper_codegen/visitor.py +44 -0
- prik-0.1.0/prik.egg-info/PKG-INFO +591 -0
- prik-0.1.0/prik.egg-info/SOURCES.txt +92 -0
- prik-0.1.0/prik.egg-info/dependency_links.txt +1 -0
- prik-0.1.0/prik.egg-info/entry_points.txt +2 -0
- prik-0.1.0/prik.egg-info/requires.txt +26 -0
- prik-0.1.0/prik.egg-info/top_level.txt +1 -0
- prik-0.1.0/pyproject.toml +174 -0
- prik-0.1.0/setup.cfg +4 -0
prik-0.1.0/CHANGELOG.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
This file is the canonical record of user-visible PRIK changes. Add changes to
|
|
4
|
+
**Unreleased** as they land, then move them into a versioned section during
|
|
5
|
+
release preparation. Versions use [Semantic Versioning](https://semver.org/);
|
|
6
|
+
release tags add a leading `v` to the package version.
|
|
7
|
+
|
|
8
|
+
## Unreleased
|
|
9
|
+
|
|
10
|
+
_No unreleased changes._
|
|
11
|
+
|
|
12
|
+
## 0.1.0 — 2026-08-03
|
|
13
|
+
|
|
14
|
+
- First public release under the PRIK name.
|
|
15
|
+
- Build importable Python extensions from supported Fortran sources.
|
|
16
|
+
- Generate, inspect, edit, and rebuild from semantic `.pyi` contracts.
|
|
17
|
+
- Expose the `prik` console command and the equivalent `python -m prik`
|
|
18
|
+
module command.
|
|
19
|
+
- Report the installed release through `prik --version` and
|
|
20
|
+
`prik.__version__`.
|
|
21
|
+
- Added a complete runnable Reference BLAS correctness example covering all 155
|
|
22
|
+
discovered routines through PRIK, independent mathematical expectations, and
|
|
23
|
+
f2py differential comparisons.
|
|
24
|
+
- Moved the repository's authoritative Reference BLAS sources to
|
|
25
|
+
`examples/blas/native/` for shared use by the example, integration tests,
|
|
26
|
+
LAPACK CI build, and build comparison tooling.
|
|
27
|
+
- Added a complete Reference LAPACK build and correctness project. It wraps all
|
|
28
|
+
2,062 implementation sources once and explicitly validates the reviewed 127
|
|
29
|
+
SciPy 1.18.0 double-precision real routines against independent mathematical
|
|
30
|
+
invariants and f2py comparisons in the dedicated CI lane.
|
|
31
|
+
- Moved the repository's authoritative Reference LAPACK implementation sources
|
|
32
|
+
to `examples/lapack/native/` and updated full-library integration and CI to
|
|
33
|
+
consume that single source owner alongside `examples/blas/native/`.
|
|
34
|
+
- Fixed dependency-safe Python argument conversion ordering for wrappers whose
|
|
35
|
+
array extents depend on later native scalar arguments, including padded BLAS
|
|
36
|
+
leading dimensions.
|
prik-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Said Hadjout
|
|
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.
|
prik-0.1.0/MANIFEST.in
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
include CHANGELOG.md
|
prik-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,591 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: prik
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python Runtime Interop Kit for native-language Python wrappers
|
|
5
|
+
Author: Said Hadjout
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://pynumlab.github.io/prik/
|
|
8
|
+
Project-URL: Documentation, https://pynumlab.github.io/prik/
|
|
9
|
+
Project-URL: Repository, https://github.com/PyNumLab/prik
|
|
10
|
+
Project-URL: Issues, https://github.com/PyNumLab/prik/issues
|
|
11
|
+
Project-URL: Changelog, https://github.com/PyNumLab/prik/blob/main/CHANGELOG.md
|
|
12
|
+
Keywords: fortran,interop,native-extension,numpy,wrapper-generator
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Intended Audience :: Science/Research
|
|
16
|
+
Classifier: Operating System :: MacOS
|
|
17
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering
|
|
23
|
+
Classifier: Topic :: Software Development :: Code Generators
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: colorama>=0.4.6; platform_system == "Windows"
|
|
28
|
+
Requires-Dist: filelock>=3.12
|
|
29
|
+
Requires-Dist: numpy>=2.1
|
|
30
|
+
Requires-Dist: immutabledict>=4.0.0
|
|
31
|
+
Provides-Extra: pretty
|
|
32
|
+
Requires-Dist: rich>=13.7; extra == "pretty"
|
|
33
|
+
Requires-Dist: rich-argparse>=1.4; extra == "pretty"
|
|
34
|
+
Provides-Extra: docs
|
|
35
|
+
Requires-Dist: mkdocs==1.6.1; extra == "docs"
|
|
36
|
+
Requires-Dist: mkdocs-material==9.7.6; extra == "docs"
|
|
37
|
+
Requires-Dist: pyperf==2.10.0; extra == "docs"
|
|
38
|
+
Provides-Extra: qa
|
|
39
|
+
Requires-Dist: bandit[toml]==1.9.4; extra == "qa"
|
|
40
|
+
Requires-Dist: coverage[toml]>=7.10; extra == "qa"
|
|
41
|
+
Requires-Dist: hypothesis>=6.100; extra == "qa"
|
|
42
|
+
Requires-Dist: pytest>=8.0; extra == "qa"
|
|
43
|
+
Requires-Dist: pytest-randomly>=3.15; extra == "qa"
|
|
44
|
+
Requires-Dist: pyperf==2.10.0; extra == "qa"
|
|
45
|
+
Requires-Dist: radon[toml]==6.0.1; extra == "qa"
|
|
46
|
+
Requires-Dist: ruff==0.15.17; extra == "qa"
|
|
47
|
+
Requires-Dist: vulture==2.16; extra == "qa"
|
|
48
|
+
Dynamic: license-file
|
|
49
|
+
|
|
50
|
+
# PRIK
|
|
51
|
+
|
|
52
|
+
**Python Runtime Interop Kit.**
|
|
53
|
+
|
|
54
|
+
**Turn Fortran into natural Python APIs.**
|
|
55
|
+
|
|
56
|
+
Build clean, importable native extensions from supported Fortran without
|
|
57
|
+
writing low-level binding code. PRIK preserves modules, derived types, arrays,
|
|
58
|
+
and native behavior, and generates an editable `.pyi` contract so you can
|
|
59
|
+
shape the Python API.
|
|
60
|
+
|
|
61
|
+
**Project status: Alpha (`0.1.x`).** Core Fortran wrapper workflows are
|
|
62
|
+
implemented and tested across supported compilers, but public APIs may still
|
|
63
|
+
change before `1.0`.
|
|
64
|
+
|
|
65
|
+
<!-- PRIK_C_DOCS_START
|
|
66
|
+
Fortran-to-Python wrapper generation plus wrapper-oriented parser and semantic
|
|
67
|
+
interface tooling for Fortran and C. PRIK builds importable CPython extensions
|
|
68
|
+
from Fortran sources, extracts native declarations into language-neutral
|
|
69
|
+
semantic IR, emits editable `.pyi` interfaces, and reports unsupported or
|
|
70
|
+
incomplete contracts before code generation.
|
|
71
|
+
PRIK_C_DOCS_END -->
|
|
72
|
+
|
|
73
|
+
[](https://github.com/PyNumLab/prik/actions/workflows/tests.yml)
|
|
74
|
+
[](https://github.com/PyNumLab/prik/actions/workflows/static-analysis.yml)
|
|
75
|
+
[](https://codecov.io/gh/PyNumLab/prik)
|
|
76
|
+
|
|
77
|
+
[Read the documentation](https://pynumlab.github.io/prik/) for installation,
|
|
78
|
+
the user guide, examples, and reference material.
|
|
79
|
+
|
|
80
|
+
For a complete real-library example, see the
|
|
81
|
+
[155-routine BLAS correctness project](examples/blas/README.md), which builds
|
|
82
|
+
the same Reference BLAS sources with PRIK and f2py and checks both against
|
|
83
|
+
independent numerical expectations. The
|
|
84
|
+
[LAPACK correctness project](examples/lapack/README.md) wraps the complete
|
|
85
|
+
Reference LAPACK implementation corpus once and validates the reviewed 127
|
|
86
|
+
SciPy-backed double-precision routines in the dedicated CI lane.
|
|
87
|
+
|
|
88
|
+
The complete example below builds with one command:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
python3 -m prik points.f90 --out geometry
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## See it in action
|
|
95
|
+
|
|
96
|
+
Create `points.f90`:
|
|
97
|
+
|
|
98
|
+
<!-- prik-doc-source: tests/fortran/building_shared_library/end_to_end/fixtures/native/home_points.f90 -->
|
|
99
|
+
```fortran
|
|
100
|
+
module points
|
|
101
|
+
implicit none
|
|
102
|
+
|
|
103
|
+
type :: point
|
|
104
|
+
real(8) :: x = 0.0d0
|
|
105
|
+
real(8) :: y = 0.0d0
|
|
106
|
+
end type point
|
|
107
|
+
|
|
108
|
+
contains
|
|
109
|
+
|
|
110
|
+
subroutine move(item, dx, dy)
|
|
111
|
+
type(point), intent(inout) :: item
|
|
112
|
+
real(8), intent(in) :: dx, dy
|
|
113
|
+
item%x = item%x + dx
|
|
114
|
+
item%y = item%y + dy
|
|
115
|
+
end subroutine move
|
|
116
|
+
|
|
117
|
+
real(8) function norm_squared(item) result(value)
|
|
118
|
+
type(point), intent(in) :: item
|
|
119
|
+
value = item%x * item%x + item%y * item%y
|
|
120
|
+
end function norm_squared
|
|
121
|
+
|
|
122
|
+
end module points
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Generated Python API:**
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
import numpy as np
|
|
129
|
+
import geometry.points as points
|
|
130
|
+
|
|
131
|
+
item = points.point(x=np.float64(3.0), y=np.float64(4.0))
|
|
132
|
+
points.move(item, np.float64(1.0), np.float64(-2.0))
|
|
133
|
+
|
|
134
|
+
print(item.x, item.y) # 4.0 2.0
|
|
135
|
+
print(points.norm_squared(item)) # 20.0
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
No manual bindings are required. From this source, PRIK creates a Python
|
|
139
|
+
namespace, a class with accessible fields, a mutating procedure, and a
|
|
140
|
+
function.
|
|
141
|
+
|
|
142
|
+
Want a different Python API? Edit the generated `.pyi` contract to rename or
|
|
143
|
+
hide exports, flatten namespaces, define constructors and methods, or create
|
|
144
|
+
overloads. The
|
|
145
|
+
[contract guide](https://pynumlab.github.io/prik/user/reference/pyi-contracts/)
|
|
146
|
+
shows the available edits.
|
|
147
|
+
|
|
148
|
+
## Key Features
|
|
149
|
+
|
|
150
|
+
- Fortran modules exposed as Python namespaces and derived types as classes
|
|
151
|
+
- NumPy arrays with explicit dtype, shape, and layout checks
|
|
152
|
+
- Allocatable and pointer arrays with explicit lifetime operations
|
|
153
|
+
- Immediate Python callbacks and overloaded interfaces
|
|
154
|
+
- Editable `.pyi` contracts and readable generated docstrings
|
|
155
|
+
- Early, clear errors when a boundary cannot be wrapped
|
|
156
|
+
|
|
157
|
+
## Performance
|
|
158
|
+
|
|
159
|
+
**Low wrapper overhead, measured against NumPy's f2py.**
|
|
160
|
+
|
|
161
|
+
The included benchmark suite runs both tools against the same Fortran kernels
|
|
162
|
+
through their normal generated interfaces. Results are machine-dependent; the
|
|
163
|
+
charts below come from the latest successfully deployed benchmark snapshot.
|
|
164
|
+
|
|
165
|
+
**Runtime-call performance** — values above `1.0×` mean PRIK is faster.
|
|
166
|
+
|
|
167
|
+
[](https://pynumlab.github.io/prik/user/performance/)
|
|
168
|
+
|
|
169
|
+
**Clean end-to-end build time** — lower times are better.
|
|
170
|
+
|
|
171
|
+
[](https://pynumlab.github.io/prik/user/performance/#clean-build-time)
|
|
172
|
+
|
|
173
|
+
[See the complete results, test environment, and one-command reproduction instructions.](https://pynumlab.github.io/prik/user/performance/)
|
|
174
|
+
|
|
175
|
+
## Installation & Quick Start
|
|
176
|
+
|
|
177
|
+
PRIK requires **Python 3.10 or newer**, NumPy, Python development headers,
|
|
178
|
+
standard build tools, and Fortran and C compilers. GNU Fortran is the default
|
|
179
|
+
and is tested on Linux and macOS. LLVM Flang is tested on both platforms;
|
|
180
|
+
Intel IFX is tested on Linux.
|
|
181
|
+
|
|
182
|
+
Install the published PRIK package in a virtual environment:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
python3 -m venv .venv
|
|
186
|
+
source .venv/bin/activate
|
|
187
|
+
python3 -m pip install --upgrade pip
|
|
188
|
+
python3 -m pip install prik
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Check the installation:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
prik --version
|
|
195
|
+
python3 -m prik --help
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Contributors can instead clone
|
|
199
|
+
[`PyNumLab/prik`](https://github.com/PyNumLab/prik) and install an editable
|
|
200
|
+
checkout with `python3 -m pip install -e ".[qa]"`.
|
|
201
|
+
|
|
202
|
+
With the `points.f90` source from above in the current directory, build the
|
|
203
|
+
extension:
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
python3 -m prik points.f90 --out geometry
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
`--out geometry` selects the import name and the final shared-library name.
|
|
210
|
+
PRIK places the stable import file beside the source and keeps generated build
|
|
211
|
+
artifacts under `__prik__/`:
|
|
212
|
+
|
|
213
|
+
```text
|
|
214
|
+
.
|
|
215
|
+
points.f90
|
|
216
|
+
geometry.so
|
|
217
|
+
__prik__/
|
|
218
|
+
geometry.<extension-suffix>.so
|
|
219
|
+
generated-wrapper sources
|
|
220
|
+
binding_support/
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
The Python code shown at the top of this README can now import `geometry`
|
|
224
|
+
directly.
|
|
225
|
+
|
|
226
|
+
Use `--out-dir` to place the ABI-specific extension and generated files in a
|
|
227
|
+
chosen build directory:
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
python3 -m prik points.f90 \
|
|
231
|
+
--out geometry \
|
|
232
|
+
--out-dir build/geometry
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
```text
|
|
236
|
+
.
|
|
237
|
+
geometry.so
|
|
238
|
+
build/geometry/
|
|
239
|
+
geometry.<extension-suffix>.so
|
|
240
|
+
generated-wrapper sources
|
|
241
|
+
binding_support/
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Inspect the generated contract
|
|
245
|
+
|
|
246
|
+
Generate the editable `.pyi` contract for the same `points.f90`:
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
python3 -m prik generate --pyi points.f90 --out contracts
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
The command preserves the Fortran module as a contract module:
|
|
253
|
+
|
|
254
|
+
```text
|
|
255
|
+
contracts/
|
|
256
|
+
__init__.pyi
|
|
257
|
+
points.pyi
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
Generated `contracts/points.pyi`:
|
|
261
|
+
|
|
262
|
+
```python
|
|
263
|
+
from prik.contracts import Addr, Arg, Float64, native_call
|
|
264
|
+
|
|
265
|
+
class point:
|
|
266
|
+
def __init__(
|
|
267
|
+
self,
|
|
268
|
+
*,
|
|
269
|
+
x: Float64 = 0.0,
|
|
270
|
+
y: Float64 = 0.0
|
|
271
|
+
) -> None: ...
|
|
272
|
+
|
|
273
|
+
x: Float64 = 0.0
|
|
274
|
+
y: Float64 = 0.0
|
|
275
|
+
|
|
276
|
+
@native_call([Arg(0), Addr(Arg(1)), Addr(Arg(2))])
|
|
277
|
+
def move(
|
|
278
|
+
item: point,
|
|
279
|
+
dx: Float64,
|
|
280
|
+
dy: Float64
|
|
281
|
+
) -> None: ...
|
|
282
|
+
|
|
283
|
+
def norm_squared(
|
|
284
|
+
item: point
|
|
285
|
+
) -> Float64: ...
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
The contract describes the generated Python class, fields, functions, exact
|
|
289
|
+
NumPy scalar types, and native argument order. Editing it changes the wrapper
|
|
290
|
+
API; it does not change the Fortran implementation.
|
|
291
|
+
|
|
292
|
+
### Build from the contract
|
|
293
|
+
|
|
294
|
+
After editing the contract, rebuild the same Python API from the package entry
|
|
295
|
+
and the original Fortran implementation:
|
|
296
|
+
|
|
297
|
+
```bash
|
|
298
|
+
python3 -m prik contracts/__init__.pyi \
|
|
299
|
+
--native-fortran-sources points.f90 \
|
|
300
|
+
--out geometry \
|
|
301
|
+
--out-dir build/geometry_from_pyi
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
The contract build has the same import name and module layout:
|
|
305
|
+
|
|
306
|
+
```text
|
|
307
|
+
.
|
|
308
|
+
geometry.so
|
|
309
|
+
build/geometry_from_pyi/
|
|
310
|
+
geometry.<extension-suffix>.so
|
|
311
|
+
generated-wrapper sources
|
|
312
|
+
binding_support/
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
Import the extension from the explicit build directory when needed:
|
|
316
|
+
|
|
317
|
+
```python
|
|
318
|
+
import sys
|
|
319
|
+
|
|
320
|
+
import numpy as np
|
|
321
|
+
|
|
322
|
+
sys.path.insert(0, "build/geometry_from_pyi")
|
|
323
|
+
import geometry.points as points
|
|
324
|
+
|
|
325
|
+
item = points.point(x=np.float64(3.0), y=np.float64(4.0))
|
|
326
|
+
points.move(item, np.float64(1.0), np.float64(-2.0))
|
|
327
|
+
print(points.norm_squared(item)) # 20.0
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### Inspect the native build
|
|
331
|
+
|
|
332
|
+
Use `--verbose` when you want to see the compiler commands and confirm which
|
|
333
|
+
wrapper flags reached the build:
|
|
334
|
+
|
|
335
|
+
```bash
|
|
336
|
+
python3 -m prik points.f90 \
|
|
337
|
+
--out geometry_debug \
|
|
338
|
+
--out-dir build/geometry_debug \
|
|
339
|
+
--jobs 4 \
|
|
340
|
+
--verbose \
|
|
341
|
+
--compiler gfortran \
|
|
342
|
+
--wrapper-fortran-flags=-O2 \
|
|
343
|
+
--wrapper-c-flags=-O2
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
The verbose output includes native source compilation, generated bridge
|
|
347
|
+
compilation, generated Python binding compilation, and the final link command.
|
|
348
|
+
Dependency-ready source files and the generated binding may compile
|
|
349
|
+
concurrently; `--jobs 1` selects a serial diagnostic build.
|
|
350
|
+
The custom wrapper flags appear in the relevant command lines:
|
|
351
|
+
|
|
352
|
+
```text
|
|
353
|
+
<fortran compiler> ... -O2 ... generated bridge ...
|
|
354
|
+
<python-binding compiler> ... -O2 ... generated Python binding ...
|
|
355
|
+
<fortran compiler> -shared ... -O2 ... geometry_debug ...
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
## How it works
|
|
359
|
+
|
|
360
|
+
```text
|
|
361
|
+
Fortran sources
|
|
362
|
+
-> compiler preprocessing and target-type probing
|
|
363
|
+
-> Fortran parser
|
|
364
|
+
-> semantic IR construction
|
|
365
|
+
-> post-IR policy completion and ordered wrapper plan
|
|
366
|
+
-> direct native-bridge and Python-binding lowering
|
|
367
|
+
-> native compilation and shared-library link
|
|
368
|
+
-> importable Python extension
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
<!-- PRIK_C_DOCS_START
|
|
372
|
+
```text
|
|
373
|
+
Fortran sources
|
|
374
|
+
-> compiler preprocessing and target-type probing
|
|
375
|
+
-> Fortran parser
|
|
376
|
+
-> semantic IR construction
|
|
377
|
+
-> post-IR policy completion and ordered wrapper plan
|
|
378
|
+
-> direct Fortran bind(C) bridge lowering
|
|
379
|
+
-> direct C/CPython binding lowering and native binding support
|
|
380
|
+
-> native compilation and shared-library link
|
|
381
|
+
-> importable Python extension
|
|
382
|
+
```
|
|
383
|
+
PRIK_C_DOCS_END -->
|
|
384
|
+
|
|
385
|
+
For diagnostic and inspection commands beyond the main build path, start with
|
|
386
|
+
`python3 -m prik --help`, then continue to the
|
|
387
|
+
[CLI command reference](docs/user/reference/cli-commands.md).
|
|
388
|
+
|
|
389
|
+
<!-- PRIK_C_DOCS_START
|
|
390
|
+
The runtime build path accepts one or more ordered Fortran sources. C parsing,
|
|
391
|
+
semantic IR, and `.pyi` are implemented, but wrapping user-supplied
|
|
392
|
+
C libraries is a later backend. The generated C code used internally by the
|
|
393
|
+
Fortran wrapper is not that future C-input backend.
|
|
394
|
+
The [generated target datatype mapping example](docs/user/reference/semantic-ir.md#generated-linux-x86_64-mapping-example)
|
|
395
|
+
shows how the GitHub Actions C and Fortran scalar types map to NumPy dtypes.
|
|
396
|
+
PRIK_C_DOCS_END -->
|
|
397
|
+
|
|
398
|
+
<!-- PRIK_C_DOCS_START
|
|
399
|
+
### C
|
|
400
|
+
PRIK_C_DOCS_END -->
|
|
401
|
+
|
|
402
|
+
<!-- PRIK_C_DOCS_START
|
|
403
|
+
C inputs require explicit C mode. These commands parse the checked C API
|
|
404
|
+
fixture, inspect semantic IR, and generate its `.pyi`:
|
|
405
|
+
PRIK_C_DOCS_END -->
|
|
406
|
+
|
|
407
|
+
<!-- PRIK_C_DOCS_START
|
|
408
|
+
Input (`tests/c/fixtures/native/general/math_api.h`):
|
|
409
|
+
PRIK_C_DOCS_END -->
|
|
410
|
+
|
|
411
|
+
<!-- PRIK_C_DOCS_DISABLED: prik-doc-source: tests/c/fixtures/native/general/math_api.h -->
|
|
412
|
+
<!-- PRIK_C_DOCS_START
|
|
413
|
+
```c
|
|
414
|
+
#ifndef PRIK_GENERAL_MATH_API_H
|
|
415
|
+
#define PRIK_GENERAL_MATH_API_H
|
|
416
|
+
|
|
417
|
+
double norm2(int n, const double x[static 1]);
|
|
418
|
+
void scale(int n, double alpha, double x[static 1]);
|
|
419
|
+
double dot(int n, const double *restrict x, const double *restrict y);
|
|
420
|
+
void fill_identity3(double a[static 3][3]);
|
|
421
|
+
|
|
422
|
+
#endif
|
|
423
|
+
```
|
|
424
|
+
PRIK_C_DOCS_END -->
|
|
425
|
+
|
|
426
|
+
<!-- PRIK_C_DOCS_DISABLED: prik-doc-test: exact -->
|
|
427
|
+
<!-- PRIK_C_DOCS_START
|
|
428
|
+
```bash
|
|
429
|
+
python3 -m prik tests/c/fixtures/native/general/math_api.h --language c --parse
|
|
430
|
+
```
|
|
431
|
+
PRIK_C_DOCS_END -->
|
|
432
|
+
|
|
433
|
+
<!-- PRIK_C_DOCS_DISABLED: prik-doc-test-output -->
|
|
434
|
+
<!-- PRIK_C_DOCS_START
|
|
435
|
+
```text
|
|
436
|
+
File: tests/c/fixtures/native/general/math_api.h
|
|
437
|
+
Language: c
|
|
438
|
+
Functions: 4
|
|
439
|
+
Structs: 0
|
|
440
|
+
Unions: 0
|
|
441
|
+
Enums: 0
|
|
442
|
+
Typedefs: 0
|
|
443
|
+
Variables: 0
|
|
444
|
+
Macros: 0
|
|
445
|
+
Includes: 0
|
|
446
|
+
Diagnostics: 0
|
|
447
|
+
```
|
|
448
|
+
PRIK_C_DOCS_END -->
|
|
449
|
+
|
|
450
|
+
<!-- PRIK_C_DOCS_DISABLED: prik-doc-test: run -->
|
|
451
|
+
<!-- PRIK_C_DOCS_START
|
|
452
|
+
```bash
|
|
453
|
+
python3 -m prik tests/c/fixtures/native/general/math_api.h --language c --semantics
|
|
454
|
+
```
|
|
455
|
+
PRIK_C_DOCS_END -->
|
|
456
|
+
|
|
457
|
+
<!-- PRIK_C_DOCS_DISABLED: prik-doc-test: run -->
|
|
458
|
+
<!-- PRIK_C_DOCS_START
|
|
459
|
+
```bash
|
|
460
|
+
python3 -m prik tests/c/fixtures/native/general/math_api.h --language c --pyi
|
|
461
|
+
```
|
|
462
|
+
PRIK_C_DOCS_END -->
|
|
463
|
+
|
|
464
|
+
<!-- PRIK_C_DOCS_DISABLED: prik-doc-test: exact -->
|
|
465
|
+
<!-- PRIK_C_DOCS_START
|
|
466
|
+
```bash
|
|
467
|
+
```
|
|
468
|
+
PRIK_C_DOCS_END -->
|
|
469
|
+
|
|
470
|
+
<!-- PRIK_C_DOCS_DISABLED: prik-doc-test-output -->
|
|
471
|
+
<!-- PRIK_C_DOCS_START
|
|
472
|
+
```text
|
|
473
|
+
File: tests/c/fixtures/native/general/math_api.h
|
|
474
|
+
Source: c
|
|
475
|
+
Semantic modules: math_api
|
|
476
|
+
```
|
|
477
|
+
PRIK_C_DOCS_END -->
|
|
478
|
+
|
|
479
|
+
## Native Project Inputs
|
|
480
|
+
|
|
481
|
+
Fortran builds default to `gfortran`. For a real project, replace the checked
|
|
482
|
+
input path with your source path, use `--help` to choose the compiler and native
|
|
483
|
+
project options you need, and enable `--verbose` when you want to audit the
|
|
484
|
+
exact compiler and linker commands.
|
|
485
|
+
|
|
486
|
+
<!-- PRIK_C_DOCS_START
|
|
487
|
+
The CLI uses compiler preprocessing for native source. C defaults to `cc` and
|
|
488
|
+
Fortran defaults to `gfortran`. Pass the native project's important compiler
|
|
489
|
+
and target flags:
|
|
490
|
+
PRIK_C_DOCS_END -->
|
|
491
|
+
|
|
492
|
+
<!-- PRIK_C_DOCS_START
|
|
493
|
+
```bash
|
|
494
|
+
python3 -m prik include/api.h --language c --parse \
|
|
495
|
+
--compiler clang \
|
|
496
|
+
-I include \
|
|
497
|
+
-D API_EXPORT= \
|
|
498
|
+
--std c11 \
|
|
499
|
+
--compiler-arg=--sysroot=/opt/sdk
|
|
500
|
+
```
|
|
501
|
+
PRIK_C_DOCS_END -->
|
|
502
|
+
|
|
503
|
+
<!-- PRIK_C_DOCS_START
|
|
504
|
+
Compiler-backed semantic and `.pyi` stages also measure and cache
|
|
505
|
+
target datatype facts. C probing covers primitive ABI widths and signedness;
|
|
506
|
+
Fortran probing resolves kind expressions and measures intrinsic storage.
|
|
507
|
+
PRIK_C_DOCS_END -->
|
|
508
|
+
|
|
509
|
+
<!-- PRIK_C_DOCS_START
|
|
510
|
+
C projects can use a compilation database:
|
|
511
|
+
PRIK_C_DOCS_END -->
|
|
512
|
+
|
|
513
|
+
<!-- PRIK_C_DOCS_START
|
|
514
|
+
```bash
|
|
515
|
+
python3 -m prik src/api.c --language c --semantics \
|
|
516
|
+
--compile-commands build/compile_commands.json
|
|
517
|
+
```
|
|
518
|
+
PRIK_C_DOCS_END -->
|
|
519
|
+
|
|
520
|
+
Use `--out` to select generated contract locations, wrapper module names, or
|
|
521
|
+
explicit build directories, depending on the command mode.
|
|
522
|
+
|
|
523
|
+
## Python API
|
|
524
|
+
|
|
525
|
+
Public entrypoints cover Fortran extension builds, parsing, semantic
|
|
526
|
+
conversion and `.pyi` emission:
|
|
527
|
+
|
|
528
|
+
```python
|
|
529
|
+
from prik import build_fortran_extension
|
|
530
|
+
|
|
531
|
+
result = build_fortran_extension(
|
|
532
|
+
"points.f90",
|
|
533
|
+
output_name="geometry",
|
|
534
|
+
output_dir="build/geometry_api",
|
|
535
|
+
)
|
|
536
|
+
print(result.module_name)
|
|
537
|
+
print(result.shared_library)
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
Parser and semantic entrypoints remain available independently for controlled
|
|
541
|
+
strings, focused tests, and already-preprocessed inputs.
|
|
542
|
+
|
|
543
|
+
<!-- PRIK_C_DOCS_START
|
|
544
|
+
```python
|
|
545
|
+
from prik import (
|
|
546
|
+
c_file_to_semantic_modules,
|
|
547
|
+
emit_module_stubs,
|
|
548
|
+
parse_c_file,
|
|
549
|
+
)
|
|
550
|
+
|
|
551
|
+
parsed = parse_c_file("int add(int a, int b);", filename="api.h")
|
|
552
|
+
modules = c_file_to_semantic_modules(parsed)
|
|
553
|
+
stubs = emit_module_stubs(modules)
|
|
554
|
+
```
|
|
555
|
+
PRIK_C_DOCS_END -->
|
|
556
|
+
|
|
557
|
+
For native projects with macros, includes, or target flags, use the
|
|
558
|
+
compiler-preprocessed CLI path or an equivalent preprocessing configuration.
|
|
559
|
+
|
|
560
|
+
## Development
|
|
561
|
+
|
|
562
|
+
Run the full suite from the repository root:
|
|
563
|
+
|
|
564
|
+
```bash
|
|
565
|
+
PYTHONPATH=. python3 -m pytest -q
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
## License
|
|
569
|
+
|
|
570
|
+
PRIK is distributed under the [MIT License](LICENSE).
|
|
571
|
+
Copyright (c) 2026 Said Hadjout.
|
|
572
|
+
|
|
573
|
+
Using PRIK does not impose the MIT License on the user's native sources or on
|
|
574
|
+
wrapper code derived from those inputs. Users may distribute generated
|
|
575
|
+
wrappers under terms of their choice. Files copied from PRIK's
|
|
576
|
+
`binding_support/` package remain MIT-licensed and must retain the included
|
|
577
|
+
license notice when redistributed.
|
|
578
|
+
|
|
579
|
+
## Documentation
|
|
580
|
+
|
|
581
|
+
- **[Documentation](https://pynumlab.github.io/prik/)** — Learn how to install and use PRIK
|
|
582
|
+
- **[Getting Started](https://pynumlab.github.io/prik/user/getting-started/)** — Installation, verification, standalone procedures, modules, and rebuild workflow
|
|
583
|
+
- **[User Guide](https://pynumlab.github.io/prik/user/guide/)** — Data types, functions, modules, arrays, derived types, callbacks, ownership, and runtime behavior
|
|
584
|
+
- **[Changelog](CHANGELOG.md)** — User-visible changes by release
|
|
585
|
+
<!--
|
|
586
|
+
- **[Tutorials](docs/user/tutorials/index.md)** — Step-by-step walkthroughs
|
|
587
|
+
- **[CLI Reference](docs/user/reference/cli-commands.md)** — Complete command-line documentation
|
|
588
|
+
- **[Language Support](docs/user/language-support/index.md)** — What is supported, partially supported, or planned
|
|
589
|
+
- **[FAQ](docs/user/faq/index.md)** — Concise answers to common questions
|
|
590
|
+
- **[Troubleshooting](docs/user/troubleshooting/index.md)** — Solutions for installation, compiler, build, runtime, and platform issues
|
|
591
|
+
-->
|