BUG: Certain fortran codes are not processed by f2py, this is for numpy 1.26.4
Open
Nobody has claimed this yet.
00 - Bug
component: numpy.f2py
- Dominant language
- Python
- Stars
- 32.8k
- Forks
- 12.8k
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 197
Description
Describe the issue:
Some Fortran codes are not successfully compiled. There is no clear pattern in the Fortran source code that does not work with f2py.
Reproduce the code example:
fortran 90 file ttt.f90 below
f2py -c -m ttt ttt.f90
=====================
Real*8 function tcb(p)
external p
real*8 p,a(6),c(6)
integer i
a=[ (i, i = 1, 6) ]
c=[ (i, i = 1, 6) ]
print *,a
print *,c
tcb=1.0
return
end function tcb
Error message:
routsign2map: Confused: function tcb has externals ['p', 'p'] but no "use" statement.
sign2map: Confused: external p is not in lcb_map[].
append_needs: unknown need 'p'
append_needs: unknown need 'p'
The Meson build system
Version: 1.3.2
Source dir: /tmp/tmpd65cg4ly
Build dir: /tmp/tmpd65cg4ly/bbdir
Build type: native build
Project name: ttt
Project version: 0.1
Fortran compiler for the host machine: gfortran (gcc 13.3.0 "GNU Fortran (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0")
Fortran linker for the host machine: gfortran ld.bfd 2.42
C compiler for the host machine: cc (gcc 13.3.0 "cc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0")
C linker for the host machine: cc ld.bfd 2.42
Host machine cpu family: x86_64
Host machine cpu: x86_64
Program /usr/bin/python3 found: YES (/usr/bin/python3)
Found pkg-config: YES (/usr/bin/pkg-config) 1.8.1
Run-time dependency python found: YES 3.12
Library quadmath found: YES
Build targets in project: 1
Found ninja-1.11.1 at /usr/bin/ninja
Generating targets: 0%| | 0/1 eta ?
Writing build.ninja: 0%| | 0/35 eta ?
ninja: Entering directory `/tmp/tmpd65cg4ly/bbdir'
[1/6] Compiling C object ttt.cpython-312-x86_64-linux-gnu.so.p/tttmodule.c.o
FAILED: ttt.cpython-312-x86_64-linux-gnu.so.p/tttmodule.c.o
cc -Ittt.cpython-312-x86_64-linux-gnu.so.p -I. -I.. -I/usr/lib/python3/dist-packages/numpy/core/include -I/usr/lib/python3/dist-packages/numpy/f2py/src -I/usr/include/python3.12 -I/usr/include/x86_64-linux-gnu/python3.12 -fvisibility=hidden -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -O3 -fPIC -MD -MQ ttt.cpython-312-x86_64-linux-gnu.so.p/tttmodule.c.o -MF ttt.cpython-312-x86_64-linux-gnu.so.p/tttmodule.c.o.d -o ttt.cpython-312-x86_64-linux-gnu.so.p/tttmodule.c.o -c ../tttmodule.c
../tttmodule.c: In function ‘f2py_rout_ttt_tcb’:
../tttmodule.c:317:5: error: unknown type name ‘p_t’
317 | p_t p_cb = { Py_None, NULL, 0 };
| ^~~
In file included from /usr/include/python3.12/Python.h:44,
from ../tttmodule.c:18:
/usr/include/python3.12/object.h:843:17: warning: initialization of ‘int’ from ‘PyObject *’ {aka ‘struct _object *’} makes integer from pointer without a cast [-Wint-conversion]
843 | #define Py_None (&_Py_NoneStruct)
| ^
../tttmodule.c:317:18: note: in expansion of macro ‘Py_None’
317 | p_t p_cb = { Py_None, NULL, 0 };
| ^~~~~~~
/usr/include/python3.12/object.h:843:17: note: (near initialization for ‘p_cb’)
843 | #define Py_None (&_Py_NoneStruct)
| ^
../tttmodule.c:317:18: note: in expansion of macro ‘Py_None’
317 | p_t p_cb = { Py_None, NULL, 0 };
| ^~~~~~~
../tttmodule.c:317:27: warning: excess elements in scalar initializer
317 | p_t p_cb = { Py_None, NULL, 0 };
| ^~~~
../tttmodule.c:317:27: note: (near initialization for ‘p_cb’)
../tttmodule.c:317:33: warning: excess elements in scalar initializer
317 | p_t p_cb = { Py_None, NULL, 0 };
| ^
../tttmodule.c:317:33: note: (near initialization for ‘p_cb’)
../tttmodule.c:318:5: error: unknown type name ‘p_t’
318 | p_t *p_cb_ptr = &p_cb;
| ^~~
../tttmodule.c:320:5: error: unknown type name ‘p_typedef’
320 | p_typedef p_cptr;
| ^~~~~~~~~
../tttmodule.c:329:26: error: request for member ‘capi’ in something not a structure or union
329 | capi_kwlist,&p_cb.capi,&PyTuple_Type,&p_xa_capi))
| ^
../tttmodule.c:334:26: error: request for member ‘capi’ in something not a structure or union
334 | if(F2PyCapsule_Check(p_cb.capi)) {
| ^
../tttmodule.c:335:38: error: request for member ‘capi’ in something not a structure or union
335 | p_cptr = F2PyCapsule_AsVoidPtr(p_cb.capi);
| ^
../tttmodule.c:337:12: error: ‘p’ undeclared (first use in this function)
337 | p_cptr = p;
| ^
../tttmodule.c:337:12: note: each undeclared identifier is reported only once for each function it appears in
../tttmodule.c:340:31: error: request for member ‘capi’ in something not a structure or union
340 | if (create_cb_arglist(p_cb.capi,p_xa_capi,#maxnofargs#,#nofoptargs#,&p_cb.nofargs,&p_cb.args_capi,"failed in processing argument list for call-back p.")) {
| ^
../tttmodule.c:340:47: error: stray ‘#’ in program
340 | if (create_cb_arglist(p_cb.capi,p_xa_capi,#maxnofargs#,#nofoptargs#,&p_cb.nofargs,&p_cb.args_capi,"failed in processing argument list for call-back p.")) {
| ^
../tttmodule.c:340:58: error: stray ‘#’ in program
340 | if (create_cb_arglist(p_cb.capi,p_xa_capi,#maxnofargs#,#nofoptargs#,&p_cb.nofargs,&p_cb.args_capi,"failed in processing argument list for call-back p.")) {
| ^
../tttmodule.c:340:48: error: ‘maxnofargs’ undeclared (first use in this function)
340 | if (create_cb_arglist(p_cb.capi,p_xa_capi,#maxnofargs#,#nofoptargs#,&p_cb.nofargs,&p_cb.args_capi,"failed in processing argument list for call-back p.")) {
| ^~~~~~~~~~
../tttmodule.c:340:60: error: stray ‘#’ in program
340 | if (create_cb_arglist(p_cb.capi,p_xa_capi,#maxnofargs#,#nofoptargs#,&p_cb.nofargs,&p_cb.args_capi,"failed in processing argument list for call-back p.")) {
| ^
../tttmodule.c:340:71: error: stray ‘#’ in program
340 | if (create_cb_arglist(p_cb.capi,p_xa_capi,#maxnofargs#,#nofoptargs#,&p_cb.nofargs,&p_cb.args_capi,"failed in processing argument list for call-back p.")) {
| ^
../tttmodule.c:340:61: error: ‘nofoptargs’ undeclared (first use in this function); did you mean ‘optarg’?
340 | if (create_cb_arglist(p_cb.capi,p_xa_capi,#maxnofargs#,#nofoptargs#,&p_cb.nofargs,&p_cb.args_capi,"failed in processing argument list for call-back p.")) {
| ^~~~~~~~~~
| optarg
../tttmodule.c:340:78: error: request for member ‘nofargs’ in something not a structure or union
340 | if (create_cb_arglist(p_cb.capi,p_xa_capi,#maxnofargs#,#nofoptargs#,&p_cb.nofargs,&p_cb.args_capi,"failed in processing argument list for call-back p.")) {
| ^
../tttmodule.c:340:92: error: request for member ‘args_capi’ in something not a structure or union
340 | if (create_cb_arglist(p_cb.capi,p_xa_capi,#maxnofargs#,#nofoptargs#,&p_cb.nofargs,&p_cb.args_capi,"failed in processing argument list for call-back p.")) {
| ^
../tttmodule.c:343:20: warning: implicit declaration of function ‘swap_active_p’ [-Wimplicit-function-declaration]
343 | p_cb_ptr = swap_active_p(p_cb_ptr);
| ^~~~~~~~~~~~~
../tttmodule.c:343:18: warning: assignment to ‘int *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
343 | p_cb_ptr = swap_active_p(p_cb_ptr);
| ^
In file included from /usr/lib/python3/dist-packages/numpy/core/include/numpy/npy_interrupt.h:22,
from /usr/lib/python3/dist-packages/numpy/core/include/numpy/arrayobject.h:6,
from /usr/lib/python3/dist-packages/numpy/f2py/src/fortranobject.h:16,
from ../tttmodule.c:22:
../tttmodule.c:349:21: error: request for member ‘jmpbuf’ in something not a structure or union
349 | if ((setjmp(p_cb.jmpbuf))) {
| ^
../tttmodule.c:352:23: warning: passing argument 2 of ‘f2py_func’ makes pointer from integer without a cast [-Wint-conversion]
352 | (*f2py_func)(&tcb,p_cptr);
| ^~~~~~
| |
| int
../tttmodule.c:352:23: note: expected ‘double *’ but argument is of type ‘int’
../tttmodule.c:370:18: warning: assignment to ‘int *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
370 | p_cb_ptr = swap_active_p(p_cb_ptr);
| ^
In file included from /usr/include/python3.12/Python.h:38:
../tttmodule.c:371:23: error: request for member ‘args_capi’ in something not a structure or union
371 | Py_DECREF(p_cb.args_capi);
| ^
/usr/include/python3.12/pyport.h:24:38: note: in definition of macro ‘_Py_CAST’
24 | #define _Py_CAST(type, expr) ((type)(expr))
| ^~~~
/usr/include/python3.12/object.h:708:33: note: in expansion of macro ‘_PyObject_CAST’
708 | #define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
| ^~~~~~~~~~~~~~
../tttmodule.c:371:9: note: in expansion of macro ‘Py_DECREF’
371 | Py_DECREF(p_cb.args_capi);
| ^~~~~~~~~
[2/6] Module scanner.
[3/6] Compiling C object ttt.cpython-312-x86_64-linux-gnu.so.p/a401c9f32d190a6af6440ba2de58d130ab56c9c1_.._.._f2py_src_fortranobject.c.o
ninja: build stopped: subcommand failed.
INFO: autodetecting backend as ninja
INFO: calculating backend command to run: /usr/bin/ninja -C /tmp/tmpd65cg4ly/bbdir
Cannot use distutils backend with Python>=3.12, using meson backend instead.
Using meson backend
Will pass --lower to f2py
See https://numpy.org/doc/stable/f2py/buildtools/meson.html
Reading fortran codes...
Reading file 'ttt.f90' (format:free)
Post-processing...
Block: ttt
Block: tcb
Applying post-processing hooks...
character_backward_compatibility_hook
Post-processing (stage 2)...
Building modules...
Building module "ttt"...
Generating possibly empty wrappers"
Maybe empty "ttt-f2pywrappers.f"
Creating wrapper for Fortran function "tcb"("tcb")...
Constructing wrapper function "tcb"...
tcb = tcb(p,[p_extra_args])
Wrote C/API module "ttt" to file "./tttmodule.c"
Fortran 77 wrappers are saved to "./ttt-f2pywrappers.f"
Traceback (most recent call last):
File "/usr/bin/f2py", line 8, in <module>
sys.exit(main())
^^^^^^
File "/usr/lib/python3/dist-packages/numpy/f2py/f2py2e.py", line 766, in main
run_compile()
File "/usr/lib/python3/dist-packages/numpy/f2py/f2py2e.py", line 738, in run_compile
builder.compile()
File "/usr/lib/python3/dist-packages/numpy/f2py/_backends/_meson.py", line 178, in compile
self.run_meson(self.build_dir)
File "/usr/lib/python3/dist-packages/numpy/f2py/_backends/_meson.py", line 173, in run_meson
self._run_subprocess_command(compile_command, build_dir)
File "/usr/lib/python3/dist-packages/numpy/f2py/_backends/_meson.py", line 167, in _run_subprocess_command
subprocess.run(command, cwd=cwd, check=True)
File "/usr/lib/python3.12/subprocess.py", line 571, in run
raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['meson', 'compile', '-C', 'bbdir']' returned non-zero exit status 1.
Python and NumPy Versions:
python:3.12.3
numpy:1.26.4
Runtime Environment:
No response
Context for the issue:
f2py being unreliable is a major showstopper for my computational physics.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the failure with the shown ttt.f90 file using f2py -c -m ttt ttt.f90, then inspect the generated tttmodule.c around the tcb callback wrapper and the reported external p handling. Done means this external-argument example builds successfully without unresolved callback types, placeholder tokens, or related C compilation errors.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- fortran, numpy, python
- Domain
- build-system, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100