diff --git a/doc/source/f2py/code/ftype.f b/doc/source/f2py/code/ftype.f index cabbb9e2d5da..67d5a224b949 100644 --- a/doc/source/f2py/code/ftype.f +++ b/doc/source/f2py/code/ftype.f @@ -4,6 +4,6 @@ SUBROUTINE FOO(N) Cf2py integer optional,intent(in) :: n = 13 REAL A,X COMMON /DATA/ A,X(3) - PRINT*, "IN FOO: N=",N," A=",A," X=[",X(1),X(2),X(3),"]" +C PRINT*, "IN FOO: N=",N," A=",A," X=[",X(1),X(2),X(3),"]" END C END OF FTYPE.F diff --git a/numpy/f2py/crackfortran.py b/numpy/f2py/crackfortran.py index 61e83d555385..c0a79bcae941 100755 --- a/numpy/f2py/crackfortran.py +++ b/numpy/f2py/crackfortran.py @@ -2856,6 +2856,11 @@ def compute_deps(v, deps): kindselect, charselect, typename = cracktypespec( typespec, selector) vars[n]['typespec'] = typespec + try: + if block['result']: + vars[block['result']]['typespec'] = typespec + except Exception: + pass if kindselect: if 'kind' in kindselect: try: diff --git a/numpy/f2py/func2subr.py b/numpy/f2py/func2subr.py index 2a05f065b625..cc3cdc5b4f90 100644 --- a/numpy/f2py/func2subr.py +++ b/numpy/f2py/func2subr.py @@ -119,6 +119,12 @@ def add(line, ret=ret): sargs = ', '.join(args) if f90mode: + # gh-23598 fix warning + # Essentially, this gets called again with modules where the name of the + # function is added to the arguments, which is not required, and removed + sargs = sargs.replace(f"{name}, ", '') + args = [arg for arg in args if arg != name] + rout['args'] = args add('subroutine f2pywrap_%s_%s (%s)' % (rout['modulename'], name, sargs)) if not signature: diff --git a/numpy/f2py/tests/src/crackfortran/gh23598.f90 b/numpy/f2py/tests/src/crackfortran/gh23598.f90 new file mode 100644 index 000000000000..e0dffb5ef29e --- /dev/null +++ b/numpy/f2py/tests/src/crackfortran/gh23598.f90 @@ -0,0 +1,4 @@ +integer function intproduct(a, b) result(res) + integer, intent(in) :: a, b + res = a*b +end function diff --git a/numpy/f2py/tests/src/crackfortran/gh23598Warn.f90 b/numpy/f2py/tests/src/crackfortran/gh23598Warn.f90 new file mode 100644 index 000000000000..3b44efc5ef16 --- /dev/null +++ b/numpy/f2py/tests/src/crackfortran/gh23598Warn.f90 @@ -0,0 +1,11 @@ +module test_bug + implicit none + private + public :: intproduct + +contains + integer function intproduct(a, b) result(res) + integer, intent(in) :: a, b + res = a*b + end function +end module diff --git a/numpy/f2py/tests/test_crackfortran.py b/numpy/f2py/tests/test_crackfortran.py index 39555df05b9f..dc0f7e27a9cb 100644 --- a/numpy/f2py/tests/test_crackfortran.py +++ b/numpy/f2py/tests/test_crackfortran.py @@ -312,4 +312,12 @@ def test_nameargspattern_backtracking(self, adversary): # according to the old version of the regex. # that should still be true. good_version_of_adversary = repeated_adversary + '@)@' - assert nameargspattern.search(good_version_of_adversary) \ No newline at end of file + assert nameargspattern.search(good_version_of_adversary) + + +class TestFunctionReturn(util.F2PyTest): + sources = [util.getpath("tests", "src", "crackfortran", "gh23598.f90")] + + def test_function_rettype(self): + # gh-23598 + assert self.module.intproduct(3, 4) == 12 diff --git a/numpy/f2py/tests/test_f2py2e.py b/numpy/f2py/tests/test_f2py2e.py index 2c10f046f1d9..5f7b56a68a9d 100644 --- a/numpy/f2py/tests/test_f2py2e.py +++ b/numpy/f2py/tests/test_f2py2e.py @@ -62,6 +62,15 @@ def hello_world_f90(tmpdir_factory): return fn +@pytest.fixture(scope="session") +def gh23598_warn(tmpdir_factory): + """F90 file for testing warnings in gh23598""" + fdat = util.getpath("tests", "src", "crackfortran", "gh23598Warn.f90").read_text() + fn = tmpdir_factory.getbasetemp() / "gh23598Warn.f90" + fn.write_text(fdat, encoding="ascii") + return fn + + @pytest.fixture(scope="session") def hello_world_f77(tmpdir_factory): """Generates a single f77 file for testing""" @@ -91,6 +100,19 @@ def f2cmap_f90(tmpdir_factory): return fn +def test_gh23598_warn(capfd, gh23598_warn, monkeypatch): + foutl = get_io_paths(gh23598_warn, mname="test") + ipath = foutl.f90inp + monkeypatch.setattr( + sys, "argv", + f'f2py {ipath} -m test'.split()) + + with util.switchdir(ipath.parent): + f2pycli() # Generate files + wrapper = foutl.wrap90.read_text() + assert "intproductf2pywrap, intpr" not in wrapper + + def test_gen_pyf(capfd, hello_world_f90, monkeypatch): """Ensures that a signature file is generated via the CLI CLI :: -h