Describe the issue:
When using callstatement to overrride a subroutine with different code as per the docs , this works when said subroutine is directly invoked by Python. However, when invoking another subroutine that calls the first subroutine, this override is not in effect.
MWE:
test.f90
module utils
implicit none
contains
subroutine my_abort(message)
implicit none
character(len=*), intent(in) :: message
!f2py callstatement PyErr_SetString(PyExc_ValueError, message);f2py_success = 0;
!f2py callprotoargument char*
write(0,*) "THIS SHOULD NOT APPEAR"
stop 1
end subroutine my_abort
subroutine do_something()
call my_abort("aborting inside")
end subroutine do_something
end module utilsTo avoid #2547, you have to do the compilation in 2 steps:
python3 -m numpy.f2py -h test.pyf --no-lower -m test test.f90
python3 -m numpy.f2py -c --f90exec=gfortran --fcompiler=gnu95 test.pyf test.f90
Invoking my_abort directly works as expected, raising the ValueError I have defined:
$ python3 -c "import test; test.utils.my_abort('aborting directly')"
Traceback (most recent call last):
File "<string>", line 1, in <module>
ValueError: aborting directly
However, when calling do_something, which in turn calls my_abort, the override seems to do nothing, and we run into the stop:
$ python3 -c "import test; test.utils.do_something()"
THIS SHOULD NOT APPEAR
STOP 1
Expected result: Python raises ValueError: aborting inside
Reproduce the code example:
python3 -c "import test; test.utils.do_something()" THIS SHOULD NOT APPEAR STOP 1 # Expected result: Python raises `ValueError: aborting inside`
Error message:
No response
Python and NumPy Versions:
Numpy: 2.0.0rc2 via conda-forge
python: 3.11.9 | packaged by conda-forge | (main, Apr 19 2024, 18:36:13) [GCC 12.3.0]
gfortran: GNU Fortran (conda-forge gcc 11.2.0-16) 11.2.0
Using 2.0.0rc2 to avoid issue #26156
Runtime Environment:
[{'numpy_version': '2.0.0rc2',
'python': '3.11.9 | packaged by conda-forge | (main, Apr 19 2024, 18:36:13) '
'[GCC 12.3.0]',
'uname': uname_result(system='Linux', node='b5dc6932b437', release='5.15.146.1-microsoft-standard-WSL2', version='#1 SMP Thu Jan 11 04:09:03 UTC 2024', machine='x86_64')},
{'simd_extensions': {'baseline': ['SSE', 'SSE2', 'SSE3'],
'found': ['SSSE3',
'SSE41',
'POPCNT',
'SSE42',
'AVX',
'F16C',
'FMA3',
'AVX2',
'AVX512F',
'AVX512CD',
'AVX512_SKX',
'AVX512_CLX',
'AVX512_CNL',
'AVX512_ICL'],
'not_found': ['AVX512_KNL', 'AVX512_KNM', 'AVX512_SPR']}},
{'architecture': 'SkylakeX',
'filepath': '/opt/conda/envs/xplengine/lib/libopenblasp-r0.3.27.so',
'internal_api': 'openblas',
'num_threads': 4,
'prefix': 'libopenblas',
'threading_layer': 'pthreads',
'user_api': 'blas',
'version': '0.3.27'}]
Context for the issue:
What I'm intending here is to avoid executing the Fortran stop statement when running wrapped code in Python, because that also kills the Python interpreter and thus, in my case, the pytest run of a whole test suite that this code is part of.
This my_abort cleanup subroutine is potentially called from many places throughout the actual codebase.
A similar-feeling issue involving callbacks: #7855
Feels related: #26156
ping @HaoZeke