Skip to content

Commit

Permalink
Merge pull request #21807 from HaoZeke/useFortranValue
Browse files Browse the repository at this point in the history
  • Loading branch information
melissawm committed Jul 2, 2022
2 parents 3d9cacc + 93347a3 commit eea02b0
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 4 deletions.
7 changes: 7 additions & 0 deletions doc/release/upcoming_changes/21807.improvement.rst
@@ -0,0 +1,7 @@
F2PY supports the value attribute
=================================

The Fortran standard requires that variables declared with the ``value``
attribute must be passed by value instead of reference. F2PY now supports this
use pattern correctly. So ``integer, intent(in), value :: x`` in Fortran codes
will have correct wrappers generated.
8 changes: 6 additions & 2 deletions numpy/f2py/auxfuncs.py
Expand Up @@ -47,7 +47,7 @@
'isunsigned_chararray', 'isunsigned_long_long',
'isunsigned_long_longarray', 'isunsigned_short',
'isunsigned_shortarray', 'l_and', 'l_not', 'l_or', 'outmess',
'replace', 'show', 'stripcomma', 'throw_error',
'replace', 'show', 'stripcomma', 'throw_error', 'isattr_value'
]


Expand Down Expand Up @@ -298,6 +298,9 @@ def issubroutine_wrap(rout):
return 0
return issubroutine(rout) and hasassumedshape(rout)

def isattr_value(var):
return 'value' in var.get('attrspec', [])


def hasassumedshape(rout):
if rout.get('hasassumedshape'):
Expand Down Expand Up @@ -692,7 +695,8 @@ def getcallprotoargument(rout, cb_map={}):
elif isstring(var):
pass
else:
ctype = ctype + '*'
if not isattr_value(var):
ctype = ctype + '*'
if ((isstring(var)
or isarrayofstrings(var) # obsolete?
or isstringarray(var))):
Expand Down
4 changes: 2 additions & 2 deletions numpy/f2py/rules.py
Expand Up @@ -71,7 +71,7 @@
islong_double, islong_doublefunction, islong_long,
islong_longfunction, ismoduleroutine, isoptional, isrequired,
isscalar, issigned_long_longarray, isstring, isstringarray,
isstringfunction, issubroutine,
isstringfunction, issubroutine, isattr_value,
issubroutine_wrap, isthreadsafe, isunsigned, isunsigned_char,
isunsigned_chararray, isunsigned_long_long,
isunsigned_long_longarray, isunsigned_short, isunsigned_shortarray,
Expand Down Expand Up @@ -874,7 +874,7 @@
{ # Common
'decl': ' #ctype# #varname# = 0;',
'pyobjfrom': {debugcapi: ' fprintf(stderr,"#vardebugshowvalue#\\n",#varname#);'},
'callfortran': {isintent_c: '#varname#,', l_not(isintent_c): '&#varname#,'},
'callfortran': {l_or(isintent_c, isattr_value): '#varname#,', l_not(l_or(isintent_c, isattr_value)): '&#varname#,'},
'return': {isintent_out: ',#varname#'},
'_check': l_and(isscalar, l_not(iscomplex))
}, {
Expand Down
9 changes: 9 additions & 0 deletions numpy/f2py/tests/src/value_attrspec/gh21665.f90
@@ -0,0 +1,9 @@
module fortfuncs
implicit none
contains
subroutine square(x,y)
integer, intent(in), value :: x
integer, intent(out) :: y
y = x*x
end subroutine square
end module fortfuncs
14 changes: 14 additions & 0 deletions numpy/f2py/tests/test_value_attrspec.py
@@ -0,0 +1,14 @@
import os
import pytest

from . import util

class TestValueAttr(util.F2PyTest):
sources = [util.getpath("tests", "src", "value_attrspec", "gh21665.f90")]

# gh-21665
def test_long_long_map(self):
inp = 2
out = self.module.fortfuncs.square(inp)
exp_out = 4
assert out == exp_out

0 comments on commit eea02b0

Please sign in to comment.