Question Details

No question body available.

Tags

python fortran meson-build f2py

Answers (2)

June 21, 2025 Score: 5 Rep: 32,449 Quality: Medium Completeness: 80%

This happens because distutils, the build system that f2py.compile() relied on, was officially deprecated in Python 3.10, and completely removed in Python 3.12 (PEP 632).

However, you can still make things work. The script below works as long as you have numpy installed and a version of gfortran on the path. (I installed it from conda-forge) I also needed to install meson and ninja for a complete build system stack.

conda create -n testenv -c conda-forge python=3.13 gfortran numpy meson ninja -y

The example code:

import os
import sys
import tempfile
import subprocess

def compilefortran(code: str, modulename: str): try: with tempfile.NamedTemporaryFile(mode="w", suffix=".f", delete=False) as tempsourcefile: tempsourcefile.write(code) tempsourcefile.flush() srcpath = tempsourcefile.name # compile using f2py subprocess.run( [sys.executable, "-m", "numpy.f2py", "-c", "-m", modulename, srcpath], check=True ) finally: os.remove(srcpath)

code = """ DOUBLE PRECISION FUNCTION ADDNUMBERS(A, B) DOUBLE PRECISION A, B ADDNUMBERS = A + B RETURN END """

compilefortran(code, 'minimal')

import minimal print(minimal.addnumbers(1.0, 2.0)) # will print 3.0

You did not share your Fortran code, so there may be some additional compilation issues based on the specific code, but this example shows that you can still use f2py and import the result.

The main thing is that you can't pass in-memory code directly to the system, so it writes a temporary file, calls f2py in a subprocess, and then cleans up the temp file at the end.

Once the function returns, there's a module in the working directory, which can be imported and used.

Note: your question states you are on Python 3.9, but the results you're getting suggests that's not the Python that's being used, or otherwise the wrong version of Numpy. Are you sure you're not running in some environment that has a newer version of Python?

If you are indeed on Python 3.9, the problem is likely that you upgraded your numpy beyond version 1.25.2. If I install python=3.9 and numpy=1.25.2, your code works, but it's a bit trickier to then get the module loaded, but you may have that working in your code already.

June 21, 2025 Score: 0 Rep: 609 Quality: Low Completeness: 80%

For all versions of NumPy, it was better to use

import subprocess
import sys

if 'google.colab' in str(getipython().config): backend = [ '--backend', 'meson' ] else: backend = [] mod = 'DmmexR14B4' ret = subprocess.checkcall([sys.executable, '-m', 'numpy.f2py', '-c', mod + '.f', '-m', mod] + backend)

instead of

from numpy import f2py

sourcefile = open('DmmexR14B4.f','rb') sourcecode = sourcefile.read() f2py.compile(sourcecode, modulename='DmmexR14B4')

Since, most likely, your task does not require creating a temporary copy of Fortran file and other things.

P.S.

On Python 3.12 or higher, the default backend is 'meson' (otherwise 'distutils'), but if 'setuptools>=76.1' installed, backed 'distutils' may failed. For example, when using Jupyter Notebook on colab.research.google.com, you need the key --backend meson.

Additional packages may also need to be installed.

  • Github Codespace (venv by default, but for install fortran compiler need use !conda..., for conda type environments is better to use %conda...):

!conda install -y -q -c conda-forge fortran-compiler %pip install -q -U 'setuptools>=76.1' meson \ ninja cmake pkgconfig
  • Google Colab:

%pip install -q -U meson ninja cmake pkgconfig