[Numpy-svn] r3288 - in trunk/numpy/f2py/lib: . parser

numpy-svn at scipy.org numpy-svn at scipy.org
Sat Oct 7 13:05:24 CDT 2006


Author: pearu
Date: 2006-10-07 13:05:18 -0500 (Sat, 07 Oct 2006)
New Revision: 3288

Modified:
   trunk/numpy/f2py/lib/parser/typedecl_statements.py
   trunk/numpy/f2py/lib/py_wrap_type.py
   trunk/numpy/f2py/lib/test_scalar_in_out.py
Log:
F2PY G3: Impl. support and tests for scalar logical and character*<len> types.

Modified: trunk/numpy/f2py/lib/parser/typedecl_statements.py
===================================================================
--- trunk/numpy/f2py/lib/parser/typedecl_statements.py	2006-10-07 15:13:03 UTC (rev 3287)
+++ trunk/numpy/f2py/lib/parser/typedecl_statements.py	2006-10-07 18:05:18 UTC (rev 3288)
@@ -438,7 +438,7 @@
         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

Modified: trunk/numpy/f2py/lib/py_wrap_type.py
===================================================================
--- trunk/numpy/f2py/lib/py_wrap_type.py	2006-10-07 15:13:03 UTC (rev 3287)
+++ trunk/numpy/f2py/lib/py_wrap_type.py	2006-10-07 18:05:18 UTC (rev 3288)
@@ -140,7 +140,105 @@
   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 @@
                 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):

Modified: trunk/numpy/f2py/lib/test_scalar_in_out.py
===================================================================
--- trunk/numpy/f2py/lib/test_scalar_in_out.py	2006-10-07 15:13:03 UTC (rev 3287)
+++ trunk/numpy/f2py/lib/test_scalar_in_out.py	2006-10-07 18:05:18 UTC (rev 3288)
@@ -70,6 +70,36 @@
 !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 @@
         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()



More information about the Numpy-svn mailing list