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.
Files changed (94) hide show
  1. prik-0.1.0/CHANGELOG.md +36 -0
  2. prik-0.1.0/LICENSE +21 -0
  3. prik-0.1.0/MANIFEST.in +1 -0
  4. prik-0.1.0/PKG-INFO +591 -0
  5. prik-0.1.0/README.md +542 -0
  6. prik-0.1.0/prik/__init__.py +157 -0
  7. prik-0.1.0/prik/__main__.py +3 -0
  8. prik-0.1.0/prik/binding_support/LICENSE +21 -0
  9. prik-0.1.0/prik/binding_support/__init__.py +1 -0
  10. prik-0.1.0/prik/binding_support/prik_binding.h +776 -0
  11. prik-0.1.0/prik/cli.py +2460 -0
  12. prik-0.1.0/prik/compiling/__init__.py +0 -0
  13. prik-0.1.0/prik/compiling/compiler_profiles.py +307 -0
  14. prik-0.1.0/prik/compiling/compilers.py +352 -0
  15. prik-0.1.0/prik/compiling/native_support.py +41 -0
  16. prik-0.1.0/prik/compiling/objects.py +37 -0
  17. prik-0.1.0/prik/contracts/__init__.py +352 -0
  18. prik-0.1.0/prik/extensions/__init__.py +1 -0
  19. prik-0.1.0/prik/naming/__init__.py +19 -0
  20. prik-0.1.0/prik/naming/policy.py +409 -0
  21. prik-0.1.0/prik/parsers/__init__.py +3 -0
  22. prik-0.1.0/prik/parsers/c/__init__.py +107 -0
  23. prik-0.1.0/prik/parsers/c/__main__.py +6 -0
  24. prik-0.1.0/prik/parsers/c/cli.py +232 -0
  25. prik-0.1.0/prik/parsers/c/lexer.py +802 -0
  26. prik-0.1.0/prik/parsers/c/models.py +563 -0
  27. prik-0.1.0/prik/parsers/c/parser.py +3155 -0
  28. prik-0.1.0/prik/parsers/c/preprocessor.py +117 -0
  29. prik-0.1.0/prik/parsers/c/type_resolver.py +149 -0
  30. prik-0.1.0/prik/parsers/fortran/__init__.py +1 -0
  31. prik-0.1.0/prik/parsers/fortran/__main__.py +3 -0
  32. prik-0.1.0/prik/parsers/fortran/cli.py +345 -0
  33. prik-0.1.0/prik/parsers/fortran/lexer.py +122 -0
  34. prik-0.1.0/prik/parsers/fortran/models.py +538 -0
  35. prik-0.1.0/prik/parsers/fortran/parser.py +4969 -0
  36. prik-0.1.0/prik/parsers/fortran/type_resolver.py +26 -0
  37. prik-0.1.0/prik/parsers/fortran/utils.py +60 -0
  38. prik-0.1.0/prik/parsers/pyi/__init__.py +5 -0
  39. prik-0.1.0/prik/parsers/pyi/parser.py +26 -0
  40. prik-0.1.0/prik/pipeline/__init__.py +1 -0
  41. prik-0.1.0/prik/pipeline/build.py +2297 -0
  42. prik-0.1.0/prik/pipeline/preprocessing.py +1306 -0
  43. prik-0.1.0/prik/pipeline/pyi.py +130 -0
  44. prik-0.1.0/prik/pipeline/wrapper_artifacts.py +58 -0
  45. prik-0.1.0/prik/probes/__init__.py +1 -0
  46. prik-0.1.0/prik/probes/c_types.py +545 -0
  47. prik-0.1.0/prik/probes/fortran_types.py +669 -0
  48. prik-0.1.0/prik/probes/report.py +321 -0
  49. prik-0.1.0/prik/runtime/__init__.py +1 -0
  50. prik-0.1.0/prik/runtime/handles.py +1588 -0
  51. prik-0.1.0/prik/semantics/__init__.py +39 -0
  52. prik-0.1.0/prik/semantics/c2ir.py +1567 -0
  53. prik-0.1.0/prik/semantics/fortran2ir.py +2639 -0
  54. prik-0.1.0/prik/semantics/metadata.py +17 -0
  55. prik-0.1.0/prik/semantics/models.py +642 -0
  56. prik-0.1.0/prik/semantics/native_array_handles.py +442 -0
  57. prik-0.1.0/prik/semantics/native_contract.py +272 -0
  58. prik-0.1.0/prik/semantics/ownership.py +1962 -0
  59. prik-0.1.0/prik/semantics/policy_completion.py +1681 -0
  60. prik-0.1.0/prik/semantics/pyi2ir.py +2955 -0
  61. prik-0.1.0/prik/semantics/pyi_metadata.py +5 -0
  62. prik-0.1.0/prik/semantics/wrapper_exports.py +103 -0
  63. prik-0.1.0/prik/semantics/wrapper_policy.py +6471 -0
  64. prik-0.1.0/prik/stage_values.py +50 -0
  65. prik-0.1.0/prik/types/__init__.py +1 -0
  66. prik-0.1.0/prik/types/numpy.py +84 -0
  67. prik-0.1.0/prik/utilities/__init__.py +1 -0
  68. prik-0.1.0/prik/utilities/strings.py +45 -0
  69. prik-0.1.0/prik/utilities/visitor.py +39 -0
  70. prik-0.1.0/prik/wrapper_codegen/__init__.py +167 -0
  71. prik-0.1.0/prik/wrapper_codegen/c/__init__.py +1 -0
  72. prik-0.1.0/prik/wrapper_codegen/c/binding.py +11846 -0
  73. prik-0.1.0/prik/wrapper_codegen/checks.py +275 -0
  74. prik-0.1.0/prik/wrapper_codegen/docstrings.py +646 -0
  75. prik-0.1.0/prik/wrapper_codegen/fortran/__init__.py +1 -0
  76. prik-0.1.0/prik/wrapper_codegen/fortran/bridge.py +7247 -0
  77. prik-0.1.0/prik/wrapper_codegen/generator.py +4476 -0
  78. prik-0.1.0/prik/wrapper_codegen/naming.py +18 -0
  79. prik-0.1.0/prik/wrapper_codegen/nodes.py +428 -0
  80. prik-0.1.0/prik/wrapper_codegen/plan.py +812 -0
  81. prik-0.1.0/prik/wrapper_codegen/planner.py +1990 -0
  82. prik-0.1.0/prik/wrapper_codegen/primitive_scalar_types.py +122 -0
  83. prik-0.1.0/prik/wrapper_codegen/printers/__init__.py +13 -0
  84. prik-0.1.0/prik/wrapper_codegen/printers/pyi_printer.py +2112 -0
  85. prik-0.1.0/prik/wrapper_codegen/printers/source_printers.py +772 -0
  86. prik-0.1.0/prik/wrapper_codegen/visitor.py +44 -0
  87. prik-0.1.0/prik.egg-info/PKG-INFO +591 -0
  88. prik-0.1.0/prik.egg-info/SOURCES.txt +92 -0
  89. prik-0.1.0/prik.egg-info/dependency_links.txt +1 -0
  90. prik-0.1.0/prik.egg-info/entry_points.txt +2 -0
  91. prik-0.1.0/prik.egg-info/requires.txt +26 -0
  92. prik-0.1.0/prik.egg-info/top_level.txt +1 -0
  93. prik-0.1.0/pyproject.toml +174 -0
  94. prik-0.1.0/setup.cfg +4 -0
@@ -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
+ [![Tests](https://github.com/PyNumLab/prik/actions/workflows/tests.yml/badge.svg?branch=main)](https://github.com/PyNumLab/prik/actions/workflows/tests.yml)
74
+ [![Static Analysis](https://github.com/PyNumLab/prik/actions/workflows/static-analysis.yml/badge.svg?branch=main)](https://github.com/PyNumLab/prik/actions/workflows/static-analysis.yml)
75
+ [![codecov](https://codecov.io/gh/PyNumLab/prik/graph/badge.svg?token=QZRRCS5YO6)](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
+ [![Relative performance of PRIK and f2py across call, vector, and matrix workloads. Values above 1.0 mean PRIK is faster.](https://pynumlab.github.io/prik/user/assets/performance-comparison.svg)](https://pynumlab.github.io/prik/user/performance/)
168
+
169
+ **Clean end-to-end build time** — lower times are better.
170
+
171
+ [![Clean end-to-end build time for PRIK and f2py under development and optimized compiler profiles. Lower times are better.](https://pynumlab.github.io/prik/user/assets/build-time-comparison.svg)](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 &#45;&#45;language c &#45;&#45;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 &#45;&#45;language c &#45;&#45;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 &#45;&#45;language c &#45;&#45;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 &#45;&#45;language c &#45;&#45;parse \
495
+ &#45;&#45;compiler clang \
496
+ -I include \
497
+ -D API_EXPORT= \
498
+ &#45;&#45;std c11 \
499
+ &#45;&#45;compiler-arg=&#45;&#45;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 &#45;&#45;language c &#45;&#45;semantics \
516
+ &#45;&#45;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
+ -->