codekingpro/portable-devtools
114k
1import os
2import platform
3
4import pytest
5
6import numpy as np
7import numpy.testing as npt
8
9from . import util
10
11
12class TestIntentInOut(util.F2PyTest):
13 # Check that intent(in out) translates as intent(inout)
14 sources = [util.getpath("tests", "src", "regression", "inout.f90")]
15
16 @pytest.mark.slow
17 def test_inout(self):
18 # non-contiguous should raise error
19 x = np.arange(6, dtype=np.float32)[::2]
20 pytest.raises(ValueError, self.module.foo, x)
21
22 # check values with contiguous array
23 x = np.arange(3, dtype=np.float32)
24 self.module.foo(x)
25 assert np.allclose(x, [3, 1, 2])
26
27
28class TestDataOnlyMultiModule(util.F2PyTest):
29 # Check that modules without subroutines work
30 sources = [util.getpath("tests", "src", "regression", "datonly.f90")]
31
32 @pytest.mark.slow
33 def test_mdat(self):
34 assert self.module.datonly.max_value == 100
35 assert self.module.dat.max_ == 1009
36 int_in = 5
37 assert self.module.simple_subroutine(5) == 1014
38
39
40class TestModuleWithDerivedType(util.F2PyTest):
41 # Check that modules with derived types work
42 sources = [util.getpath("tests", "src", "regression", "mod_derived_types.f90")]
43
44 @pytest.mark.slow
45 def test_mtypes(self):
46 assert self.module.no_type_subroutine(10) == 110
47 assert self.module.type_subroutine(10) == 210
48
49
50class TestNegativeBounds(util.F2PyTest):
51 # Check that negative bounds work correctly
52 sources = [util.getpath("tests", "src", "negative_bounds", "issue_20853.f90")]
53
54 @pytest.mark.slow
55 def test_negbound(self):
56 xvec = np.arange(12)
57 xlow = -6
58 xhigh = 4
59
60 # Calculate the upper bound,
61 # Keeping the 1 index in mind
62
63 def ubound(xl, xh):
64 return xh - xl + 1
65 rval = self.module.foo(is_=xlow, ie_=xhigh,
66 arr=xvec[:ubound(xlow, xhigh)])
67 expval = np.arange(11, dtype=np.float32)
68 assert np.allclose(rval, expval)
69
70
71class TestNumpyVersionAttribute(util.F2PyTest):
72 # Check that th attribute __f2py_numpy_version__ is present
73 # in the compiled module and that has the value np.__version__.
74 sources = [util.getpath("tests", "src", "regression", "inout.f90")]
75
76 @pytest.mark.slow
77 def test_numpy_version_attribute(self):
78
79 # Check that self.module has an attribute named "__f2py_numpy_version__"
80 assert hasattr(self.module, "__f2py_numpy_version__")
81
82 # Check that the attribute __f2py_numpy_version__ is a string
83 assert isinstance(self.module.__f2py_numpy_version__, str)
84
85 # Check that __f2py_numpy_version__ has the value numpy.__version__
86 assert np.__version__ == self.module.__f2py_numpy_version__
87
88
89def test_include_path():
90 incdir = np.f2py.get_include()
91 fnames_in_dir = os.listdir(incdir)
92 for fname in ("fortranobject.c", "fortranobject.h"):
93 assert fname in fnames_in_dir
94
95
96class TestIncludeFiles(util.F2PyTest):
97 sources = [util.getpath("tests", "src", "regression", "incfile.f90")]
98 options = [f"-I{util.getpath('tests', 'src', 'regression')}",
99 f"--include-paths {util.getpath('tests', 'src', 'regression')}"]
100
101 @pytest.mark.slow
102 def test_gh25344(self):
103 exp = 7.0
104 res = self.module.add(3.0, 4.0)
105 assert exp == res
106
107class TestF77Comments(util.F2PyTest):
108 # Check that comments are stripped from F77 continuation lines
109 sources = [util.getpath("tests", "src", "regression", "f77comments.f")]
110
111 @pytest.mark.slow
112 def test_gh26148(self):
113 x1 = np.array(3, dtype=np.int32)
114 x2 = np.array(5, dtype=np.int32)
115 res = self.module.testsub(x1, x2)
116 assert res[0] == 8
117 assert res[1] == 15
118
119 @pytest.mark.slow
120 def test_gh26466(self):
121 # Check that comments after PARAMETER directions are stripped
122 expected = np.arange(1, 11, dtype=np.float32) * 2
123 res = self.module.testsub2()
124 npt.assert_allclose(expected, res)
125
126class TestF90Contiuation(util.F2PyTest):
127 # Check that comments are stripped from F90 continuation lines
128 sources = [util.getpath("tests", "src", "regression", "f90continuation.f90")]
129
130 @pytest.mark.slow
131 def test_gh26148b(self):
132 x1 = np.array(3, dtype=np.int32)
133 x2 = np.array(5, dtype=np.int32)
134 res = self.module.testsub(x1, x2)
135 assert res[0] == 8
136 assert res[1] == 15
137
138class TestLowerF2PYDirectives(util.F2PyTest):
139 # Check variables are cased correctly
140 sources = [util.getpath("tests", "src", "regression", "lower_f2py_fortran.f90")]
141
142 @pytest.mark.slow
143 def test_gh28014(self):
144 self.module.inquire_next(3)
145 assert True
146
147@pytest.mark.slow
148def test_gh26623():
149 # Including libraries with . should not generate an incorrect meson.build
150 try:
151 aa = util.build_module(
152 [util.getpath("tests", "src", "regression", "f90continuation.f90")],
153 ["-lfoo.bar"],
154 module_name="Blah",
155 )
156 except RuntimeError as rerr:
157 assert "lparen got assign" not in str(rerr)
158
159
160@pytest.mark.slow
161@pytest.mark.skipif(platform.system() == "Windows", reason='Unsupported on this platform for now')
162def test_gh25784():
163 # Compile dubious file using passed flags
164 try:
165 aa = util.build_module(
166 [util.getpath("tests", "src", "regression", "f77fixedform.f95")],
167 options=[
168 # Meson will collect and dedup these to pass to fortran_args:
169 "--f77flags='-ffixed-form -O2'",
170 "--f90flags=\"-ffixed-form -g\"",
171 ],
172 module_name="Blah",
173 )
174 except ImportError as rerr:
175 assert "unknown_subroutine_" in str(rerr)
176
177
178@pytest.mark.slow
179class TestAssignmentOnlyModules(util.F2PyTest):
180 # Ensure that variables are exposed without functions or subroutines in a module
181 sources = [util.getpath("tests", "src", "regression", "assignOnlyModule.f90")]
182
183 @pytest.mark.slow
184 def test_gh27167(self):
185 assert (self.module.f_globals.n_max == 16)
186 assert (self.module.f_globals.i_max == 18)
187 assert (self.module.f_globals.j_max == 72)
188 