First, the honest framing: F2PY is not a competitor to beat, it's NumPy's own tool for connecting Fortran and Python, it's been maintained for over two decades, and nativegate uses f2py under the hood to emit its Fortran bindings. If you leave this page thinking "F2PY is bad," you misread it. The question is which scope of problem you have.
What each tool is for
F2PY's documented purpose is connecting Fortran and Python and
generating extension modules: f2py -c mymodule.f90 -m mymod,
and you have a Python-callable module. It does that well, including
a numpy.f2py module you can call programmatically, and despite
its age it keeps pace with NumPy releases.
nativegate's scope starts where the bindings stop. Bindings are one of eight artifacts it generates from a single configuration; the others are the build system, the Python package, tests, the numerical baseline, a FastAPI service, Docker, and Kubernetes manifests. Its premise is that a legacy codebase owner doesn't want bindings per se — they want the modernization outcome.
Side by side
| Capability | F2PY | nativegate |
|---|---|---|
| Fortran → Python bindings | ✓ | ✓ (via f2py) |
| Stable, maintained, huge track record | ✓ | |
| Free-form and fixed-form parsing | ✓ | ✓ |
| Derived types (with f90wrap, or natively in newer toolchains) | ✓ | narrow support |
| COMMON-block state handled in the API contract | your job | ✓ |
| Installable wheel + CMake build generated | your job | ✓ |
| Generated pytest suite | your job | ✓ |
| Numerical golden-record regression checks | — | ✓ |
| FastAPI service generation | — | ✓ |
| Docker image + Kubernetes manifests | — | ✓ |
| Works on C++ too (pybind11) | — | ✓ |
"Your job" is doing some work on that capability — not that it can't be done, just that it doesn't come from the tool. If your project is one well-understood module and a build system you already trust, those extra rows are irrelevant and F2PY is the right tool.
When F2PY is the better choice
- You need one or a few routines, and your build/packaging already exists.
- You need to hand-tune wrapper behavior argument by argument — f2py's directives give you that control.
- You want the outcome immediately, no opinionated pipeline in between. F2PY is an interface; nativegate is a workflow.
When the workflow earns its place
- The artifact that matters is a service, not a .so file: the model must be reachable over HTTP by other teams.
- The codebase is a legacy deck where intent is inferred, state is COMMON, and a
verifyanswer to "did the numbers move?" needs to exist. - Both exist in the same organization: C++ and Fortran, handled by one pipeline instead of two.
The combination answer
The most useful mental model isn't either/or. If you know how to run f2py but nothing else ever materializes around the module, you have satisfied F2PY's scope and stopped there. If the pipeline around it is the thing you never get to, nativegate exists to fill exactly that hole — and it delegates the f2py part to f2py, which knows it better than we do.