File size: 4,200 Bytes
dc2106c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
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)