diff options
-rw-r--r-- | numpy/f2py/lib/parser/typedecl_statements.py | 2 | ||||
-rw-r--r-- | numpy/f2py/lib/py_wrap_type.py | 120 | ||||
-rw-r--r-- | numpy/f2py/lib/test_scalar_in_out.py | 150 |
3 files changed, 270 insertions, 2 deletions
diff --git a/numpy/f2py/lib/parser/typedecl_statements.py b/numpy/f2py/lib/parser/typedecl_statements.py index 17b48c549..b038bbf2d 100644 --- a/numpy/f2py/lib/parser/typedecl_statements.py +++ b/numpy/f2py/lib/parser/typedecl_statements.py @@ -438,7 +438,7 @@ class Logical(TypeDeclarationStatement): return ".FALSE." def get_c_type(self): - return 'npy_int%s' % (self.get_bit_size()) + return 'f2py_bool%s' % (self.get_bit_size()) class Character(TypeDeclarationStatement): match = re.compile(r'character\b',re.I).match diff --git a/numpy/f2py/lib/py_wrap_type.py b/numpy/f2py/lib/py_wrap_type.py index f9c426a3a..605ea5fa9 100644 --- a/numpy/f2py/lib/py_wrap_type.py +++ b/numpy/f2py/lib/py_wrap_type.py @@ -140,7 +140,105 @@ static int pyobj_to_%(ctype)s(PyObject *obj, %(ctype)s* value) { return return_value; } ''' - + + capi_code_template_logical_scalar = ''' +static PyObject* pyobj_from_%(ctype)s(%(ctype)s* value) { +#if defined(F2PY_DEBUG_PYOBJ_TOFROM) + fprintf(stderr,"pyobj_from_%(ctype)s(value=%%"%(ICTYPE)s_FMT")\\n",*value); +#endif + if (*value) { + PyArrayScalar_RETURN_TRUE; + } else { + PyArrayScalar_RETURN_FALSE; + } +} +static int pyobj_to_%(ctype)s(PyObject *obj, %(ctype)s* value) { + int return_value = 0; +#if defined(F2PY_DEBUG_PYOBJ_TOFROM) + fprintf(stderr,"pyobj_to_%(ctype)s(type=%%s)\\n",PyString_AS_STRING(PyObject_Repr(PyObject_Type(obj)))); +#endif + if (obj==NULL) ; + else if (PyArray_IsScalar(obj,Bool)) { + *value = PyArrayScalar_VAL(obj,Bool); + return_value = 1; + } else { + switch (PyObject_IsTrue(obj)) { + case 0: *value = 0; return_value = 1; break; + case -1: break; + default: *value = 1; return_value = 1; + } + } + if (!return_value && !PyErr_Occurred()) { + PyObject* r = PyString_FromString("Failed to convert "); + PyString_ConcatAndDel(&r, PyObject_Repr(PyObject_Type(obj))); + PyString_ConcatAndDel(&r, PyString_FromString(" to C %(ctype)s")); + PyErr_SetObject(PyExc_TypeError,r); + } +#if defined(F2PY_DEBUG_PYOBJ_TOFROM) + if (PyErr_Occurred()) { + if (return_value) + fprintf(stderr,"pyobj_to_%(ctype)s:INCONSISTENCY with return_value=%%d and PyErr_Occurred()=%%p\\n",return_value, PyErr_Occurred()); + else + fprintf(stderr,"pyobj_to_%(ctype)s: PyErr_Occurred()=%%p\\n", PyErr_Occurred()); + } else { + if (return_value) + fprintf(stderr,"pyobj_to_%(ctype)s: value=%%"%(ICTYPE)s_FMT"\\n", *value); + else + fprintf(stderr,"pyobj_to_%(ctype)s:INCONSISTENCY with return_value=%%d and PyErr_Occurred()=%%p\\n",return_value, PyErr_Occurred()); + } +#endif + return return_value; +} +''' + capi_code_template_string_scalar = ''' +static PyObject* pyobj_from_%(ctype)s(%(ctype)s* value) { +#if defined(F2PY_DEBUG_PYOBJ_TOFROM) + fprintf(stderr,"pyobj_from_%(ctype)s(value->data=\'%%s\')\\n",value->data); +#endif + PyArray_Descr* descr = PyArray_DescrNewFromType(NPY_STRING); + descr->elsize = %(bytes)s; + PyObject* obj = PyArray_Scalar(value->data, descr, NULL); + if (obj==NULL) /* TODO: set exception */ return NULL; + return obj; +} + +static int pyobj_to_%(ctype)s(PyObject *obj, %(ctype)s* value) { + int return_value = 0; +#if defined(F2PY_DEBUG_PYOBJ_TOFROM) + fprintf(stderr,"pyobj_to_%(ctype)s(type=%%s)\\n",PyString_AS_STRING(PyObject_Repr(PyObject_Type(obj)))); +#endif + if (PyString_Check(obj)) { + int s = PyString_GET_SIZE(obj); + memset(value->data, (int)\' \',%(bytes)s); + return_value = !! strncpy(value->data,PyString_AS_STRING(obj),%(bytes)s); + if (return_value && s<%(bytes)s) { + memset(value->data + s, (int)\' \',%(bytes)s-s); + } + } else { + return_value = pyobj_to_%(ctype)s(PyObject_Str(obj), value); + } + if (!return_value && !PyErr_Occurred()) { + PyObject* r = PyString_FromString("Failed to convert "); + PyString_ConcatAndDel(&r, PyObject_Repr(PyObject_Type(obj))); + PyString_ConcatAndDel(&r, PyString_FromString(" to C %(ctype)s")); + PyErr_SetObject(PyExc_TypeError,r); + } +#if defined(F2PY_DEBUG_PYOBJ_TOFROM) + if (PyErr_Occurred()) { + if (return_value) + fprintf(stderr,"pyobj_to_%(ctype)s:INCONSISTENCY with return_value=%%d and PyErr_Occurred()=%%p\\n",return_value, PyErr_Occurred()); + else + fprintf(stderr,"pyobj_to_%(ctype)s: PyErr_Occurred()=%%p\\n", PyErr_Occurred()); + } else { + if (return_value) + fprintf(stderr,"pyobj_to_%(ctype)s: value->data=\'%%s\'\\n", value->data); + else + fprintf(stderr,"pyobj_to_%(ctype)s:INCONSISTENCY with return_value=%%d and PyErr_Occurred()=%%p\\n",return_value, PyErr_Occurred()); + } +#endif + return return_value; +} +''' _defined = [] def __init__(self, parent, typedecl): WrapperBase.__init__(self) @@ -160,8 +258,28 @@ static int pyobj_to_%(ctype)s(PyObject *obj, %(ctype)s* value) { bits = int(ctype[11:]) self.fctype = 'npy_float%s' % (bits/2) self.capi_code_template = self.capi_code_template_complex_scalar + else: + raise NotImplementedError,`name,ctype` parent.apply_templates(self) return + if ctype.startswith('f2py_'): + if ctype.startswith('f2py_bool'): + bits = int(ctype[9:]) + self.ictype = 'npy_int%s' % (bits) + self.header_template = '#define %(ctype)s %(ictype)s' + self.capi_code_template = self.capi_code_template_logical_scalar + parent.apply_templates(self) + return + if ctype.startswith('f2py_string'): + self.bits = bits = int(ctype[11:]) + self.bytes = bits/CHAR_BIT + self.header_template = ''' +#include <string.h> +typedef struct { char data[%(bytes)s] } %(ctype)s; +''' + self.capi_code_template = self.capi_code_template_string_scalar + parent.apply_templates(self) + return raise NotImplementedError,`name,ctype` class PythonCAPIDerivedType(WrapperBase): diff --git a/numpy/f2py/lib/test_scalar_in_out.py b/numpy/f2py/lib/test_scalar_in_out.py index 37fd5ffb9..954e3e90c 100644 --- a/numpy/f2py/lib/test_scalar_in_out.py +++ b/numpy/f2py/lib/test_scalar_in_out.py @@ -70,6 +70,36 @@ fortran_code = ''' !f2py intent(in,out) a a = a + 1.0d0 end + subroutine foobool1(a) + logical*1 a +!f2py intent(in,out) a + a = .not. a + end + subroutine foobool2(a) + logical*2 a +!f2py intent(in,out) a + a = .not. a + end + subroutine foobool4(a) + logical*4 a +!f2py intent(in,out) a + a = .not. a + end + subroutine foobool8(a) + logical*8 a +!f2py intent(in,out) a + a = .not. a + end + subroutine foostring1(a) + character*1 a +!f2py intent(in,out) a + a = "1" + end + subroutine foostring5(a) + character*5 a +!f2py intent(in,out) a + a(1:2) = "12" + end ''' # tester note: set rebuild=True when changing fortan_code and for SVN @@ -369,5 +399,125 @@ class test_m(NumpyTestCase): self.assertRaises(TypeError,lambda :func([2,1,3])) self.assertRaises(TypeError,lambda :func({})) + def check_foo_bool1(self, level=1): + i = bool8(True) + e = bool8(False) + func = m.foobool1 + assert isinstance(i,bool8),`type(i)` + r = func(i) + assert isinstance(r,bool8),`type(r)` + assert i is not r,`id(i),id(r)` + assert_equal(r,e) + + for tv in [1,2,2.1,-1j,[0],True]: + r = func(tv) + assert isinstance(r,bool8),`type(r)` + assert_equal(r,e) + + for fv in [0,0.0,0j,False,(),{},[]]: + r = func(fv) + assert isinstance(r,bool8),`type(r)` + assert_equal(r,not e) + + def check_foo_bool2(self, level=1): + i = bool8(True) + e = bool8(False) + func = m.foobool2 + assert isinstance(i,bool8),`type(i)` + r = func(i) + assert isinstance(r,bool8),`type(r)` + assert i is not r,`id(i),id(r)` + assert_equal(r,e) + + for tv in [1,2,2.1,-1j,[0],True]: + r = func(tv) + assert isinstance(r,bool8),`type(r)` + assert_equal(r,e) + + for fv in [0,0.0,0j,False,(),{},[]]: + r = func(fv) + assert isinstance(r,bool8),`type(r)` + assert_equal(r,not e) + + def check_foo_bool4(self, level=1): + i = bool8(True) + e = bool8(False) + func = m.foobool4 + assert isinstance(i,bool8),`type(i)` + r = func(i) + assert isinstance(r,bool8),`type(r)` + assert i is not r,`id(i),id(r)` + assert_equal(r,e) + + for tv in [1,2,2.1,-1j,[0],True]: + r = func(tv) + assert isinstance(r,bool8),`type(r)` + assert_equal(r,e) + + for fv in [0,0.0,0j,False,(),{},[]]: + r = func(fv) + assert isinstance(r,bool8),`type(r)` + assert_equal(r,not e) + + def check_foo_bool8(self, level=1): + i = bool8(True) + e = bool8(False) + func = m.foobool8 + assert isinstance(i,bool8),`type(i)` + r = func(i) + assert isinstance(r,bool8),`type(r)` + assert i is not r,`id(i),id(r)` + assert_equal(r,e) + + for tv in [1,2,2.1,-1j,[0],True]: + r = func(tv) + assert isinstance(r,bool8),`type(r)` + assert_equal(r,e) + + for fv in [0,0.0,0j,False,(),{},[]]: + r = func(fv) + assert isinstance(r,bool8),`type(r)` + assert_equal(r,not e) + + def check_foo_string1(self, level=1): + i = string0('a') + e = string0('1') + func = m.foostring1 + assert isinstance(i,string0),`type(i)` + r = func(i) + assert isinstance(r,string0),`type(r)` + assert i is not r,`id(i),id(r)` + assert_equal(r,e) + + r = func('ab') + assert isinstance(r,string0),`type(r)` + assert_equal(r,e) + + r = func('') + assert isinstance(r,string0),`type(r)` + assert_equal(r,e) + + def check_foo_string5(self, level=1): + i = string0('abcde') + e = string0('12cde') + func = m.foostring5 + assert isinstance(i,string0),`type(i)` + r = func(i) + assert isinstance(r,string0),`type(r)` + assert i is not r,`id(i),id(r)` + assert_equal(r,e) + + r = func('abc') + assert isinstance(r,string0),`type(r)` + assert_equal(r,'12c ') + + r = func('abcdefghi') + assert isinstance(r,string0),`type(r)` + assert_equal(r,'12cde') + + r = func([1]) + assert isinstance(r,string0),`type(r)` + assert_equal(r,'12] ') + if __name__ == "__main__": NumpyTest().run() |