| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- from __future__ import division, absolute_import, print_function
- import math
- import textwrap
- import sys
- import pytest
- import numpy as np
- from numpy.testing import assert_, assert_equal
- from . import util
- class TestF77Callback(util.F2PyTest):
- code = """
- subroutine t(fun,a)
- integer a
- cf2py intent(out) a
- external fun
- call fun(a)
- end
- subroutine func(a)
- cf2py intent(in,out) a
- integer a
- a = a + 11
- end
- subroutine func0(a)
- cf2py intent(out) a
- integer a
- a = 11
- end
- subroutine t2(a)
- cf2py intent(callback) fun
- integer a
- cf2py intent(out) a
- external fun
- call fun(a)
- end
- subroutine string_callback(callback, a)
- external callback
- double precision callback
- double precision a
- character*1 r
- cf2py intent(out) a
- r = 'r'
- a = callback(r)
- end
- subroutine string_callback_array(callback, cu, lencu, a)
- external callback
- integer callback
- integer lencu
- character*8 cu(lencu)
- integer a
- cf2py intent(out) a
- a = callback(cu, lencu)
- end
- """
- @pytest.mark.slow
- @pytest.mark.parametrize('name', 't,t2'.split(','))
- def test_all(self, name):
- self.check_function(name)
- @pytest.mark.slow
- def test_docstring(self):
- expected = """
- a = t(fun,[fun_extra_args])
- Wrapper for ``t``.
- Parameters
- ----------
- fun : call-back function
- Other Parameters
- ----------------
- fun_extra_args : input tuple, optional
- Default: ()
- Returns
- -------
- a : int
- Notes
- -----
- Call-back functions::
- def fun(): return a
- Return objects:
- a : int
- """
- assert_equal(self.module.t.__doc__, textwrap.dedent(expected).lstrip())
- def check_function(self, name):
- t = getattr(self.module, name)
- r = t(lambda: 4)
- assert_(r == 4, repr(r))
- r = t(lambda a: 5, fun_extra_args=(6,))
- assert_(r == 5, repr(r))
- r = t(lambda a: a, fun_extra_args=(6,))
- assert_(r == 6, repr(r))
- r = t(lambda a: 5 + a, fun_extra_args=(7,))
- assert_(r == 12, repr(r))
- r = t(lambda a: math.degrees(a), fun_extra_args=(math.pi,))
- assert_(r == 180, repr(r))
- r = t(math.degrees, fun_extra_args=(math.pi,))
- assert_(r == 180, repr(r))
- r = t(self.module.func, fun_extra_args=(6,))
- assert_(r == 17, repr(r))
- r = t(self.module.func0)
- assert_(r == 11, repr(r))
- r = t(self.module.func0._cpointer)
- assert_(r == 11, repr(r))
- class A(object):
- def __call__(self):
- return 7
- def mth(self):
- return 9
- a = A()
- r = t(a)
- assert_(r == 7, repr(r))
- r = t(a.mth)
- assert_(r == 9, repr(r))
- @pytest.mark.skipif(sys.platform=='win32',
- reason='Fails with MinGW64 Gfortran (Issue #9673)')
- def test_string_callback(self):
- def callback(code):
- if code == 'r':
- return 0
- else:
- return 1
- f = getattr(self.module, 'string_callback')
- r = f(callback)
- assert_(r == 0, repr(r))
- @pytest.mark.skipif(sys.platform=='win32',
- reason='Fails with MinGW64 Gfortran (Issue #9673)')
- def test_string_callback_array(self):
- # See gh-10027
- cu = np.zeros((1, 8), 'S1')
- def callback(cu, lencu):
- if cu.shape != (lencu, 8):
- return 1
- if cu.dtype != 'S1':
- return 2
- if not np.all(cu == b''):
- return 3
- return 0
- f = getattr(self.module, 'string_callback_array')
- res = f(callback, cu, len(cu))
- assert_(res == 0, repr(res))
|