-
-
Notifications
You must be signed in to change notification settings - Fork 9.5k
/
test_crackfortran.py
178 lines (147 loc) · 5.24 KB
/
test_crackfortran.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
import numpy as np
from numpy.testing import assert_array_equal, assert_equal
from numpy.f2py.crackfortran import markinnerspaces
from . import util
from numpy.f2py import crackfortran
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)
class TestMarkinnerspaces():
# issue #14118: markinnerspaces does not handle multiple quotations
def test_do_not_touch_normal_spaces(self):
test_list = ["a ", " a", "a b c", "'abcdefghij'"]
for i in test_list:
assert_equal(markinnerspaces(i), i)
def test_one_relevant_space(self):
assert_equal(markinnerspaces("a 'b c' \\\' \\\'"), "a 'b@_@c' \\' \\'")
assert_equal(markinnerspaces(r'a "b c" \" \"'), r'a "b@_@c" \" \"')
def test_ignore_inner_quotes(self):
assert_equal(markinnerspaces('a \'b c" " d\' e'),
"a 'b@_@c\"@_@\"@_@d' e")
assert_equal(markinnerspaces('a "b c\' \' d" e'),
"a \"b@_@c'@_@'@_@d\" e")
def test_multiple_relevant_spaces(self):
assert_equal(markinnerspaces("a 'b c' 'd e'"), "a 'b@_@c' 'd@_@e'")
assert_equal(markinnerspaces(r'a "b c" "d e"'), r'a "b@_@c" "d@_@e"')
class TestEval(util.F2PyTest):
def test_eval_scalar(self):
eval_scalar = crackfortran._eval_scalar
assert eval_scalar('123', {}) == '123'
assert eval_scalar('12 + 3', {}) == '15'
assert eval_scalar('a + b', dict(a=1, b=2)) == '3'
assert eval_scalar('"123"', {}) == "'123'"