Spaces:
Running
Running
import numpy as np | |
from numpy.testing import assert_array_equal | |
from . import util | |
from numpy.f2py import crackfortran | |
import tempfile | |
import textwrap | |
class TestNoSpace(util.F2PyTest): | |
# issue gh-15035: add handling for endsubroutine, endfunction with no space | |
# between "end" and the block name | |
code = """ | |
subroutine subb(k) | |
real(8), intent(inout) :: k(:) | |
k=k+1 | |
endsubroutine | |
subroutine subc(w,k) | |
real(8), intent(in) :: w(:) | |
real(8), intent(out) :: k(size(w)) | |
k=w+1 | |
endsubroutine | |
function t0(value) | |
character value | |
character t0 | |
t0 = value | |
endfunction | |
""" | |
def test_module(self): | |
k = np.array([1, 2, 3], dtype=np.float64) | |
w = np.array([1, 2, 3], dtype=np.float64) | |
self.module.subb(k) | |
assert_array_equal(k, w + 1) | |
self.module.subc([w, k]) | |
assert_array_equal(k, w + 1) | |
assert self.module.t0(23) == b'2' | |
class TestPublicPrivate(): | |
def test_defaultPrivate(self, tmp_path): | |
f_path = tmp_path / "mod.f90" | |
with f_path.open('w') as ff: | |
ff.write(textwrap.dedent("""\ | |
module foo | |
private | |
integer :: a | |
public :: setA | |
integer :: b | |
contains | |
subroutine setA(v) | |
integer, intent(in) :: v | |
a = v | |
end subroutine setA | |
end module foo | |
""")) | |
mod = crackfortran.crackfortran([str(f_path)]) | |
assert len(mod) == 1 | |
mod = mod[0] | |
assert 'private' in mod['vars']['a']['attrspec'] | |
assert 'public' not in mod['vars']['a']['attrspec'] | |
assert 'private' in mod['vars']['b']['attrspec'] | |
assert 'public' not in mod['vars']['b']['attrspec'] | |
assert 'private' not in mod['vars']['seta']['attrspec'] | |
assert 'public' in mod['vars']['seta']['attrspec'] | |
def test_defaultPublic(self, tmp_path): | |
f_path = tmp_path / "mod.f90" | |
with f_path.open('w') as ff: | |
ff.write(textwrap.dedent("""\ | |
module foo | |
public | |
integer, private :: a | |
public :: setA | |
contains | |
subroutine setA(v) | |
integer, intent(in) :: v | |
a = v | |
end subroutine setA | |
end module foo | |
""")) | |
mod = crackfortran.crackfortran([str(f_path)]) | |
assert len(mod) == 1 | |
mod = mod[0] | |
assert 'private' in mod['vars']['a']['attrspec'] | |
assert 'public' not in mod['vars']['a']['attrspec'] | |
assert 'private' not in mod['vars']['seta']['attrspec'] | |
assert 'public' in mod['vars']['seta']['attrspec'] | |
class TestExternal(util.F2PyTest): | |
# issue gh-17859: add external attribute support | |
code = """ | |
integer(8) function external_as_statement(fcn) | |
implicit none | |
external fcn | |
integer(8) :: fcn | |
external_as_statement = fcn(0) | |
end | |
integer(8) function external_as_attribute(fcn) | |
implicit none | |
integer(8), external :: fcn | |
external_as_attribute = fcn(0) | |
end | |
""" | |
def test_external_as_statement(self): | |
def incr(x): | |
return x + 123 | |
r = self.module.external_as_statement(incr) | |
assert r == 123 | |
def test_external_as_attribute(self): | |
def incr(x): | |
return x + 123 | |
r = self.module.external_as_attribute(incr) | |
assert r == 123 | |
class TestCrackFortran(util.F2PyTest): | |
suffix = '.f90' | |
code = textwrap.dedent(""" | |
subroutine gh2848( & | |
! first 2 parameters | |
par1, par2,& | |
! last 2 parameters | |
par3, par4) | |
integer, intent(in) :: par1, par2 | |
integer, intent(out) :: par3, par4 | |
par3 = par1 | |
par4 = par2 | |
end subroutine gh2848 | |
""") | |
def test_gh2848(self): | |
r = self.module.gh2848(1, 2) | |
assert r == (1, 2) | |