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

numpy-svn at scipy.org numpy-svn at scipy.org
Sat Oct 7 04:49:20 EDT 2006


Author: pearu
Date: 2006-10-07 03:49:08 -0500 (Sat, 07 Oct 2006)
New Revision: 3283

Added:
   trunk/numpy/f2py/lib/test_scalar_in_out.py
Removed:
   trunk/numpy/f2py/lib/python_wrapper.py
Modified:
   trunk/numpy/f2py/lib/generate_pyobj_tofrom_funcs.py
   trunk/numpy/f2py/lib/parser/base_classes.py
   trunk/numpy/f2py/lib/parser/typedecl_statements.py
   trunk/numpy/f2py/lib/py_wrap_type.py
   trunk/numpy/f2py/lib/src/pyobj_to_Py_complex.c
   trunk/numpy/f2py/lib/src/pyobj_to_double.c
   trunk/numpy/f2py/lib/src/pyobj_to_long.c
   trunk/numpy/f2py/lib/src/pyobj_to_npy_longlong.c
Log:
F2PY G3: completed test site for int,float,complex scalar support. Fixed bugs.

Modified: trunk/numpy/f2py/lib/generate_pyobj_tofrom_funcs.py
===================================================================
--- trunk/numpy/f2py/lib/generate_pyobj_tofrom_funcs.py	2006-10-07 08:00:20 UTC (rev 3282)
+++ trunk/numpy/f2py/lib/generate_pyobj_tofrom_funcs.py	2006-10-07 08:49:08 UTC (rev 3283)
@@ -12,7 +12,6 @@
     dtype = ctype.upper()
     cls = 'Int'+ctype[7:]
     return '''\
-/* depends: SCALARS_IN_BITS2.cpp */
 static PyObject* pyobj_from_%(ctype)s(%(ctype)s* value) {
   PyObject* obj = PyArrayScalar_New(%(cls)s);
   if (obj==NULL) /* TODO: set exception */ return NULL;
@@ -56,56 +55,19 @@
 }
 '''
 
+
+
 def pyobj_to_npy_int(ctype):
+    Cls = ctype[4].upper()+ctype[5:]
     ctype_bits = int(ctype[7:])
-    return '''
-/* depends: pyobj_to_long.c, pyobj_to_npy_longlong.c */
-#if NPY_BITSOF_LONG == %(ctype_bits)s
-#define pyobj_to_%(ctype)s pyobj_to_long
-#else
-#if NPY_BITSOF_LONG > %(ctype_bits)s
-static int pyobj_to_%(ctype)s(PyObject *obj, %(ctype)s* value) {
-  long tmp;
-  if (pyobj_to_long(obj,&tmp)) {
-    *value = (%(ctype)s)tmp;
-    return 1;
-  }
-  return 0;
-}
-#else
-static int pyobj_to_%(ctype)s(PyObject *obj, %(ctype)s* value) {
-  npy_longlong tmp;
-  if (pyobj_to_npy_longlong(obj,&tmp)) {
-    *value = (%(ctype)s)tmp;
-    return 1;
-  }
-  return 0;
-}
-#endif
-#endif
-''' % (locals())
+    CTYPE = ctype.upper()
+    return capi_code_template_scalar % (locals())
 
 def pyobj_to_npy_float(ctype):
+    Cls = ctype[4].upper()+ctype[5:]
     ctype_bits = int(ctype[9:])
-    return '''
-/* depends: pyobj_to_double.c */
-#if NPY_BITSOF_DOUBLE == %(ctype_bits)s
-#define pyobj_to_%(ctype)s pyobj_to_double
-#else
-#if NPY_BITSOF_DOUBLE > %(ctype_bits)s
-static int pyobj_to_%(ctype)s(PyObject *obj, %(ctype)s* value) {
-  double tmp;
-  if (pyobj_to_double(obj,&tmp)) {
-    *value = (%(ctype)s)tmp;
-    return 1;
-  }
-  return 0;
-}
-#else
-#error, "NOTIMPLEMENTED pyobj_to_%(ctype)s"
-#endif
-#endif
-''' % (locals())
+    CTYPE = ctype.upper()
+    return capi_code_template_scalar % (locals())
 
 def pyobj_to_npy_complex(ctype):
     ctype_bits = int(ctype[11:])

Modified: trunk/numpy/f2py/lib/parser/base_classes.py
===================================================================
--- trunk/numpy/f2py/lib/parser/base_classes.py	2006-10-07 08:00:20 UTC (rev 3282)
+++ trunk/numpy/f2py/lib/parser/base_classes.py	2006-10-07 08:49:08 UTC (rev 3283)
@@ -240,6 +240,7 @@
         return True
 
     def is_intent_inout(self):
+        if not self.intent: return False
         if 'INOUT' in self.intent:
             if 'IN' in self.intent or 'HIDE' in self.intent or 'INPLACE' in self.intent:
                 self.warning('INOUT ignored in INPUT(%s)' % (', '.join(self.intent)))
@@ -248,19 +249,20 @@
         return False
 
     def is_intent_hide(self):
+        if not self.intent: return False
         if 'HIDE' in self.intent: return True
         if 'OUT' in self.intent:
             return 'IN' not in self.intent and 'INPLACE' not in self.intent and 'INOUT' not in self.intent
         return False
 
-    def is_intent_inplace(self): return 'INPLACE' in self.intent
-    def is_intent_out(self): return 'OUT' in self.intent
-    def is_intent_c(self): return 'C' in self.intent
-    def is_intent_cache(self): return 'CACHE' in self.intent
-    def is_intent_copy(self): return 'COPY' in self.intent
-    def is_intent_overwrite(self): return 'OVERWRITE' in self.intent
-    def is_intent_callback(self): return 'CALLBACK' in self.intent
-    def is_intent_aux(self): return 'AUX' in self.intent
+    def is_intent_inplace(self): return self.intent and 'INPLACE' in self.intent
+    def is_intent_out(self): return  self.intent and 'OUT' in self.intent
+    def is_intent_c(self): return  self.intent and 'C' in self.intent
+    def is_intent_cache(self): return  self.intent and 'CACHE' in self.intent
+    def is_intent_copy(self): return  self.intent and 'COPY' in self.intent
+    def is_intent_overwrite(self): return  self.intent and 'OVERWRITE' in self.intent
+    def is_intent_callback(self): return  self.intent and 'CALLBACK' in self.intent
+    def is_intent_aux(self): return  self.intent and 'AUX' in self.intent
 
     def is_private(self):
         if 'PUBLIC' in self.attributes: return False

Modified: trunk/numpy/f2py/lib/parser/typedecl_statements.py
===================================================================
--- trunk/numpy/f2py/lib/parser/typedecl_statements.py	2006-10-07 08:00:20 UTC (rev 3282)
+++ trunk/numpy/f2py/lib/parser/typedecl_statements.py	2006-10-07 08:49:08 UTC (rev 3283)
@@ -400,7 +400,7 @@
 
     def get_byte_size(self):
         length, kind = self.selector
-        if length: return 2*int(length)
+        if length: return int(length)
         if kind: return 2*int(kind)
         return 2*self.default_kind
 
@@ -412,13 +412,17 @@
     def get_c_type(self):
         return 'npy_complex%s' % (self.get_bit_size())
 
+    def get_part_typedecl(self):
+        bz = self.get_byte_size()/2
+        return Real(self.parent, self.item.copy('REAL*%s' % (bz)))
+        
 class DoubleComplex(TypeDeclarationStatement):
     # not in standard
     match = re.compile(r'double\s*complex\b',re.I).match
     default_kind = 8
 
     def get_byte_size(self):
-        return 2 * self.default_kind
+        return 2*self.default_kind
 
     def get_zero_value(self):
         return '(0.0D0,0.0D0)'

Modified: trunk/numpy/f2py/lib/py_wrap_type.py
===================================================================
--- trunk/numpy/f2py/lib/py_wrap_type.py	2006-10-07 08:00:20 UTC (rev 3282)
+++ trunk/numpy/f2py/lib/py_wrap_type.py	2006-10-07 08:49:08 UTC (rev 3283)
@@ -22,25 +22,147 @@
     """
     Fortran intrinsic type hooks.
     """
+
+    capi_code_template_scalar = '''
+static PyObject* pyobj_from_%(ctype)s(%(ctype)s* value) {
+  PyObject* obj = PyArrayScalar_New(%(Cls)s);
+#if defined(F2PY_DEBUG_PYOBJ_TOFROM)
+  fprintf(stderr,"pyobj_from_%(ctype)s(value=%%"%(CTYPE)s_FMT")\\n",*value);
+#endif
+  if (obj==NULL) /* TODO: set exception */ return NULL;
+  PyArrayScalar_ASSIGN(obj,%(Cls)s,*value);
+  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 (obj==NULL) ;
+  else if (PyArray_IsScalar(obj,%(Cls)s)) {
+    *value = PyArrayScalar_VAL(obj,%(Cls)s);
+    return_value = 1;
+  }
+  else if (PySequence_Check(obj)) {
+    if (PySequence_Size(obj)==1)
+      return_value = pyobj_to_%(ctype)s(PySequence_GetItem(obj,0),value);
+  } else {
+    PyObject* sc = Py%(Cls)sArrType_Type.tp_new(
+      &Py%(Cls)sArrType_Type,Py_BuildValue("(O)",obj),NULL);
+    if (sc==NULL) ;
+    else if (PyArray_IsScalar(sc, Generic))
+      return_value = pyobj_to_%(ctype)s(sc,value);
+    else
+      return_value = pyobj_to_%(ctype)s(PyArray_ScalarFromObject(sc),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=%%"%(CTYPE)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_complex_scalar = '''
+static PyObject* pyobj_from_%(ctype)s(%(ctype)s* value) {
+  PyObject* obj = PyArrayScalar_New(%(Cls)s);
+#if defined(F2PY_DEBUG_PYOBJ_TOFROM)
+  fprintf(stderr,"pyobj_from_%(ctype)s(value=(%%"%(FCTYPE)s_FMT",%%"%(FCTYPE)s_FMT"))\\n",value->real, value->imag);
+#endif
+  if (obj==NULL) /* TODO: set exception */ return NULL;
+  PyArrayScalar_ASSIGN(obj,%(Cls)s,*value);
+  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 (obj==NULL) ;
+  else if (PyArray_IsScalar(obj,%(Cls)s)) {
+    value->real = PyArrayScalar_VAL(obj,%(Cls)s).real;
+    value->imag = PyArrayScalar_VAL(obj,%(Cls)s).imag;
+    return_value = 1;
+  }
+  else if (PySequence_Check(obj)) {
+    if (PySequence_Size(obj)==1)
+      return_value = pyobj_to_%(ctype)s(PySequence_GetItem(obj,0),value);
+    else if (PySequence_Size(obj)==2) {
+      return_value = pyobj_to_%(fctype)s(PySequence_GetItem(obj,0),&(value->real))
+                     && pyobj_to_%(fctype)s(PySequence_GetItem(obj,1),&(value->imag));
+    }
+  } else {
+    PyObject* sc = Py%(Cls)sArrType_Type.tp_new(
+      &Py%(Cls)sArrType_Type,Py_BuildValue("(O)",obj),NULL);
+    if (sc==NULL) ;
+    else if (PyArray_IsScalar(sc, Generic))
+      return_value = pyobj_to_%(ctype)s(sc,value);
+    else
+      return_value = pyobj_to_%(ctype)s(PyArray_ScalarFromObject(sc),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=(%%"%(FCTYPE)s_FMT",%%"%(FCTYPE)s_FMT")\\n",
+      value->real, value->imag);
+    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)
         self.name = name = typedecl.name
-        if name in self._defined:
+        self.ctype = ctype = typedecl.get_c_type()
+        if ctype in self._defined:
             return
-        self._defined.append(name)
-        self.info('Generating interface for %s: %s' % (typedecl.__class__, name))
+        self._defined.append(ctype)
+        self.info('Generating interface for %s: %s' % (typedecl.__class__, ctype))
 
-        ctype = typedecl.get_c_type()
-
         if ctype.startswith('npy_'):
-            WrapperCCode(parent, 'pyobj_from_%s' % (ctype))
-            WrapperCCode(parent, 'pyobj_to_%s' % (ctype))
+            self.Cls = ctype[4].upper() + ctype[5:] 
+            if ctype.startswith('npy_int') or ctype.startswith('npy_float'):
+                self.capi_code_template = self.capi_code_template_scalar
+            elif ctype.startswith('npy_complex'):
+                PythonCAPIIntrinsicType(parent, typedecl.get_part_typedecl())
+                bits = int(ctype[11:])
+                self.fctype = 'npy_float%s' % (bits/2)
+                self.capi_code_template = self.capi_code_template_complex_scalar
+            parent.apply_templates(self)
             return
-        
-        if not ctype.startswith('f2py_type_'):
-            raise NotImplementedError,`name,ctype`
-        return
+        raise NotImplementedError,`name,ctype`
 
 class PythonCAPIDerivedType(WrapperBase):
     """
@@ -314,6 +436,4 @@
             self.use_stmt_list.append('use %s' % (typedecl.parent.name))
 
         parent.apply_templates(self)
-
-
         return

Deleted: trunk/numpy/f2py/lib/python_wrapper.py
===================================================================
--- trunk/numpy/f2py/lib/python_wrapper.py	2006-10-07 08:00:20 UTC (rev 3282)
+++ trunk/numpy/f2py/lib/python_wrapper.py	2006-10-07 08:49:08 UTC (rev 3283)
@@ -1,687 +0,0 @@
-
-__all__ = ['TypeWrapper']
-
-import re
-import os
-import sys
-
-from parser.api import *
-
-from wrapper_base import *
-
-class PythonWrapperModule(WrapperBase):
-
-    main_template = '''\
-#ifdef __cplusplus
-extern \"C\" {
-#endif
-#include "Python.h"
-
-#define PY_ARRAY_UNIQUE_SYMBOL PyArray_API
-#include "numpy/arrayobject.h"
-#include "numpy/arrayscalars.h"
-
-%(header_list)s
-
-%(typedef_list)s
-
-%(extern_list)s
-
-%(c_code_list)s
-
-%(capi_code_list)s
-
-%(objdecl_list)s
-
-static PyObject *f2py_module;
-
-static PyMethodDef f2py_module_methods[] = {
-  %(module_method_list)s
-  {NULL,NULL,0,NULL}
-};
-
-PyMODINIT_FUNC init%(modulename)s(void) {
-  f2py_module = Py_InitModule("%(modulename)s", f2py_module_methods);
-  import_array();
-  %(module_init_list)s
-  if (PyErr_Occurred()) {
-    PyErr_SetString(PyExc_ImportError, "can\'t initialize module %(modulename)s");
-    return;
-  }
-}
-#ifdef __cplusplus
-}
-#endif
-'''
-
-    main_fortran_template = '''\
-! -*- f90 -*-
-%(fortran_code_list)s
-'''
-    def __init__(self, modulename):
-        WrapperBase.__init__(self)
-        self.modulename = modulename
-        
-        self.header_list = []
-        self.typedef_list = []
-        self.extern_list = []
-        self.objdecl_list = []
-        self.c_code_list = []
-        self.capi_code_list = []
-
-        self.module_method_list = []
-        self.module_init_list = []
-
-        self.fortran_code_list = []
-
-        self.list_names = ['header', 'typedef', 'extern', 'objdecl',
-                           'c_code','capi_code','module_method','module_init',
-                           'fortran_code']
-
-        return
-
-    def add(self, block):
-        if isinstance(block, BeginSource):
-            for name, moduleblock in block.a.module.items():
-                self.add(moduleblock)
-            #for name, subblock in block.a.external_subprogram.items():
-            #    self.add(subblock)
-        elif isinstance(block, (Subroutine, Function)):
-            self.info('Generating interface for %s' % (block.name))
-            f = PythonCAPIFunction(self, block)
-            f.fill()
-        elif isinstance(block, Module):
-            for name,declblock in block.a.type_decls.items():
-                self.add(declblock)
-        elif isinstance(block, TypeDecl):
-            PythonCAPIDerivedType(self, block)
-        elif isinstance(block, tuple(declaration_type_spec)):
-            PythonCAPIIntrinsicType(self, block)
-        else:
-            raise NotImplementedError,`block.__class__.__name__`
-        return
-    
-    def c_code(self):
-        return self.apply_attributes(self.main_template)
-    def fortran_code(self):
-        return self.apply_attributes(self.main_fortran_template)
-
-    def add_subroutine(self, block):
-        raise
-        f = PythonCAPIFunction(self, block)
-        f.fill()
-        return
-
-
-
-        
-class PythonCAPIIntrinsicType(WrapperBase):
-    """
-    Fortran intrinsic type hooks.
-    """
-    _defined_types = []
-    def __init__(self, parent, typedecl):
-        WrapperBase.__init__(self)
-        self.name = name = typedecl.name
-        if name in self._defined_types:
-            return
-        self._defined_types.append(name)
-
-        self.ctype = ctype = typedecl.get_c_type()
-
-        if ctype.startswith('npy_'):
-            WrapperCCode(parent, 'pyobj_from_%s' % (ctype))
-            return
-        
-        if not ctype.startswith('f2py_type_'):
-            raise NotImplementedError,`name,ctype`
-
-        for n in parent.list_names:
-            l = getattr(parent,n + '_list')
-            l.append(self.apply_attributes(getattr(self, n+'_template','')))
-
-        return
-
-class PythonCAPIDerivedType(WrapperBase):
-    """
-    Fortran 90 derived type hooks.
-    """
-
-    header_template = '''\
-#define %(oname)sObject_Check(obj) \\
-    PyObject_TypeCheck((PyObject*)obj, &%(oname)sType)
-#define %(init_func)s_f \\
-    F_FUNC(%(init_func)s,%(INIT_FUNC)s)
-'''
-
-    typedef_template = '''\
-typedef void * %(ctype)s;
-typedef struct {
-  PyObject_HEAD
-  %(ptrstruct_list)s
-  %(ctype)s data;
-} %(oname)sObject;
-'''
-
-    extern_template = '''\
-static PyTypeObject %(oname)sType;
-'''
-
-    objdecl_template = '''\
-static PyMethodDef %(oname)s_methods[] = {
-    %(type_method_list)s
-    {NULL}  /* Sentinel */
-};
-
-static PyGetSetDef %(oname)s_getseters[] = {
-    %(type_getseters_list)s
-    {NULL}  /* Sentinel */
-};
-
-static PyTypeObject %(oname)sType = {
-    PyObject_HEAD_INIT(NULL)
-    0,                         /*ob_size*/
-    "%(name)s",                /*tp_name*/
-    sizeof(%(oname)sObject),    /*tp_basicsize*/
-    0,                         /*tp_itemsize*/
-    (destructor)%(oname)s_dealloc, /*tp_dealloc*/
-    0,                         /*tp_print*/
-    0,                         /*tp_getattr*/
-    0,                         /*tp_setattr*/
-    0,                         /*tp_compare*/
-    %(oname)s_repr,            /*tp_repr*/
-    0,                         /*tp_as_number*/
-    0,                         /*tp_as_sequence*/
-    0,                         /*tp_as_mapping*/
-    0,                         /*tp_hash */
-    0,                         /*tp_call*/
-    0,                         /*tp_str*/
-    0,                         /*tp_getattro*/
-    0,                         /*tp_setattro*/
-    0,                         /*tp_as_buffer*/
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,        /*tp_flags*/
-    "Fortran derived type %(name)s objects",        /* tp_doc */
-    0,		               /* tp_traverse */
-    0,		               /* tp_clear */
-    0,		               /* tp_richcompare */
-    0,		               /* tp_weaklistoffset */
-    0,		               /* tp_iter */
-    0,		               /* tp_iternext */
-    %(oname)s_methods,          /* tp_methods */
-    0 /*%(oname)s_members*/,    /* tp_members */
-    %(oname)s_getseters,       /* tp_getset */
-    0,                         /* tp_base */
-    0,                         /* tp_dict */
-    0,                         /* tp_descr_get */
-    0,                         /* tp_descr_set */
-    0,                         /* tp_dictoffset */
-    (initproc)%(oname)s_init,      /* tp_init */
-    0,                         /* tp_alloc */
-    %(oname)s_new,                 /* tp_new */
-};
-'''
-
-    module_init_template = '''\
-if (PyType_Ready(&%(oname)sType) < 0)
-  return;
-PyModule_AddObject(f2py_module, "%(name)s",
-                                (PyObject *)&%(oname)sType);
-'''
-
-    c_code_template = '''\
-static void %(init_func)s_c(
-               %(init_func_c_arg_clist)s) {
-  %(init_func_c_body_list)s
-}
-'''
-
-    capi_code_template = '''\
-static void %(oname)s_dealloc(%(oname)sObject* self) {
-  if (self->data)
-    PyMem_Free(self->data);
-  self->ob_type->tp_free((PyObject*)self);
-}
-
-static int pyobj_to_%(ctype)s(PyObject *obj,
-                              %(ctype)s* value_ptr) {
-  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 (%(oname)sObject_Check(obj)) {
-    if (!memcpy(value_ptr,((%(oname)sObject *)obj)->data, %(byte_size)s)) {
-      PyErr_SetString(PyExc_MemoryError,
-         "failed to copy %(name)s instance memory to %(ctype)s object.");
-    } else {
-      return_value = 1;
-    }
-  }
-#if defined(F2PY_DEBUG_PYOBJ_TOFROM)
-  fprintf(stderr,"pyobj_to_%(ctype)s: return_value=%%d, PyErr_Occurred()=%%p\\n", return_value, PyErr_Occurred());
-#endif
-  return return_value;
-}
-
-static PyObject* pyobj_from_%(ctype)s(%(ctype)s* value_ptr) {
-  %(oname)sObject* obj = (%(oname)sObject*)(%(oname)sType.tp_alloc(&%(oname)sType, 0));
-  if (obj == NULL)
-    return NULL;
-  obj->data = PyMem_Malloc(%(byte_size)s);
-  if (obj->data == NULL) {
-    Py_DECREF(obj);
-    return PyErr_NoMemory();
-  }
-  if (value_ptr) {
-    if (!memcpy(obj->data, value_ptr, %(byte_size)s)) {
-      PyErr_SetString(PyExc_MemoryError,
-         "failed to copy %(ctype)s object memory to %(name)s instance.");
-    }
-  }
-  %(init_func)s_f(%(init_func)s_c, obj, obj->data);
-  return (PyObject*)obj;
-}
-
-static PyObject * %(oname)s_new(PyTypeObject *type,
-                                PyObject *args, PyObject *kwds)
-{
-  return pyobj_from_%(ctype)s(NULL);
-}
-
-static int %(oname)s_init(%(oname)sObject *self,
-                          PyObject *capi_args, PyObject *capi_kwds)
-{
-   int return_value = 0;
-#if defined(F2PY_DEBUG_PYOBJ_TOFROM)
-  fprintf(stderr,"%(oname)s_init()\\n");
-#endif
-   if (!PyArg_ParseTuple(capi_args,"%(attr_format_elist)s"
-                                   %(attr_init_clist)s))
-      return_value = -1;                             
-#if defined(F2PY_DEBUG_PYOBJ_TOFROM)
-  fprintf(stderr,"%(oname)s_init: return_value=%%d, PyErr_Occurred()=%%p\\n", return_value, PyErr_Occurred());
-#endif
-   return return_value;
-}
-
-static PyObject * %(oname)s_as_tuple(%(oname)sObject * self) {
-  return Py_BuildValue("%(as_tuple_format_elist)s"
-                        %(as_tuple_arg_clist)s);
-}
-
-static PyObject * %(oname)s_repr(PyObject * self) {
-  PyObject* r = PyString_FromString("%(name)s(");
-  PyString_ConcatAndDel(&r, PyObject_Repr(%(oname)s_as_tuple((%(oname)sObject*)self)));
-  PyString_ConcatAndDel(&r, PyString_FromString(")"));
-  return r;
-}
-
-%(getset_func_list)s
-'''
-
-    fortran_code_template = '''\
-      subroutine %(init_func)s(init_func_c, self, obj)
-      %(use_stmt_list)s
-      external init_func_c
-!     self is %(oname)sObject
-      external self
-      %(ftype)s obj
-      call init_func_c(%(init_func_f_arg_clist)s)
-      end
-'''
-
-    #module_method_template = ''''''
-
-    _defined_types = []
-    def __init__(self, parent, typedecl):
-        WrapperBase.__init__(self)
-        name = typedecl.name
-        if name in self._defined_types:
-            return
-        self._defined_types.append(name)
-
-        self.name = name
-        self.oname = oname = 'f2py_' + name
-        self.ctype = typedecl.get_c_type()
-        self.ctype_ptrs = self.ctype + '_ptrs'
-        self.ftype = typedecl.get_f_type()
-        self.byte_size = byte_size = typedecl.get_bit_size() / CHAR_BIT
-        WrapperCPPMacro(parent, 'F_FUNC')
-
-        self.init_func_f_arg_list = ['self']
-        self.init_func_c_arg_list = ['%sObject *self' % (self.oname)]
-        self.init_func_c_body_list = []
-        self.ptrstruct_list = []
-        self.attr_decl_list = []
-        self.attr_format_list = []
-        self.attr_init_list = []
-        self.as_tuple_format_list = []
-        self.as_tuple_arg_list = []
-        self.getset_func_list = []
-        self.type_getseters_list = []
-        for n in typedecl.a.component_names:
-            v = typedecl.a.components[n]
-            t = v.get_typedecl()
-            ct = t.get_c_type()
-            on = 'f2py_' + t.name
-            parent.add(t)
-            self.ptrstruct_list.append('%s* %s_ptr;' % (ct, n))
-            self.init_func_f_arg_list.append('obj %% %s' % (n))
-            self.init_func_c_arg_list.append('\n%s * %s_ptr' % (ct, n))
-            self.init_func_c_body_list.append('''\
-if (!((void*)%(n)s_ptr >= self->data
-      && (void*)%(n)s_ptr < self->data + %(byte_size)s ))
-  fprintf(stderr,"INCONSISTENCY IN %(name)s WRAPPER: "
-                 "self->data=%%p <= %(n)s_ptr=%%p < self->data+%(byte_size)s=%%p\\n",
-                 self->data, %(n)s_ptr, self->data + %(byte_size)s);
-self->%(n)s_ptr = %(n)s_ptr;
-''' % (locals()))
-            self.attr_format_list.append('O&')
-            WrapperCCode(parent, 'pyobj_to_%s' % (ct))
-            self.attr_init_list.append('\npyobj_to_%s, self->%s_ptr' % (ct,n))
-            WrapperCCode(parent, 'pyobj_from_%s' % (ct))
-            self.as_tuple_format_list.append('O&')
-            self.as_tuple_arg_list.append('\npyobj_from_%s, self->%s_ptr' % (ct, n))
-            self.getset_func_list.append('''\
-static PyObject * %(oname)s_get_%(n)s(%(oname)sObject *self,
-                                      void *closure) {
-  return pyobj_from_%(ct)s(self->%(n)s_ptr);
-}
-static int %(oname)s_set_%(n)s(%(oname)sObject *self,
-                               PyObject *value, void *closure)
-{
-  if (value == NULL) {
-    PyErr_SetString(PyExc_TypeError,
-                    "Cannot delete %(name)s attribute %(n)s");
-    return -1;
-  }
-  if (pyobj_to_%(ct)s(value, self->%(n)s_ptr))
-    return 0;
-  return -1;
-}
-''' % (locals()))
-            self.type_getseters_list.append('{"%(n)s",(getter)%(oname)s_get_%(n)s, (setter)%(oname)s_set_%(n)s,\n "component %(n)s",NULL},' % (locals()))
-        if self.attr_init_list: self.attr_init_list.insert(0,'')
-        if self.as_tuple_arg_list: self.as_tuple_arg_list.insert(0,'')
-        self.init_func = self.ctype + '_init'
-        self.INIT_FUNC = self.init_func.upper()
-
-        self.type_method_list = []
-        self.type_method_list.append('{"as_tuple",(PyCFunction)%(oname)s_as_tuple,METH_NOARGS,\n "Return %(name)s components as tuple."},' % (self.__dict__))
-        self.cname = typedecl.get_c_name()
-
-        self.use_stmt_list = []
-        if isinstance(typedecl.parent, Module):
-            self.use_stmt_list.append('use %s' % (typedecl.parent.name))
-
-        for n in parent.list_names:
-            l = getattr(parent,n + '_list')
-            l.append(self.apply_attributes(getattr(self, n+'_template','')))
-        return
-
-class PythonCAPIFunction(WrapperBase):
-    capi_function_template = '''
-static char f2py_doc_%(function_name)s[] = "%(function_doc)s";
-static PyObject* f2py_%(function_name)s(PyObject *capi_self, PyObject *capi_args, PyObject *capi_keywds) {
-  PyObject * volatile capi_buildvalue = NULL;
-  volatile int f2py_success = 1;
-  %(decl_list)s
-  static char *capi_kwlist[] = {%(keyword_clist+optkw_clist+extrakw_clist+["NULL"])s};
-  if (!PyArg_ParseTupleAndKeywords(capi_args,capi_keywds,
-                                   "%(pyarg_format_elist)s",
-                                   %(["capi_kwlist"]+pyarg_obj_clist)s))
-     return NULL;
-  %(frompyobj_list)s
-  %(call_list)s
-  f2py_success = !PyErr_Occurred();
-  if (f2py_success) {
-    %(pyobjfrom_list)s
-    capi_buildvalue = Py_BuildValue(%(buildvalue_clist)s);
-    %(clean_pyobjfrom_list)s
-  }
-  %(clean_frompyobj_list)s
-  return capi_buildvalue;
-}
-'''    
-
-    pymethoddef_template = '''\
-{"%(function_name)s", (PyCFunction)f2py_%(function_name)s, METH_VARARGS | METH_KEYWORDS, f2py_doc_%(function_name)s},\
-'''
-
-    cppmacro_template = '''\
-#define %(function_name)s_f F_FUNC(%(function_name)s,%(FUNCTION_NAME)s)
-'''
-
-    extdef_template = '''\
-extern void %(function_name)s_f();\
-'''
-
-    def __init__(self, parent, block):
-        WrapperBase.__init__(self)
-        self.parent = parent
-        self.block = block
-        self.function_name = block.name
-        self.FUNCTION_NAME = self.function_name.upper()
-        self.function_doc = ''
-        self.args_list = block.args
-        self.decl_list = []
-        self.keyword_list = []
-        self.optkw_list = []
-        self.extrakw_list = []
-        self.frompyobj_list = []
-        self.call_list = []
-        self.pyobjfrom_list = []
-        self.buildvalue_list = []
-        self.clean_pyobjfrom_list = []
-        self.clean_frompyobj_list = []
-        self.pyarg_format_list = []
-        self.pyarg_obj_list = []
-        return
-
-    def fill(self):
-        for argname in self.args_list:
-            var = self.block.a.variables[argname]
-            argwrap = ArgumentWrapper(self, var)
-            argwrap.fill()
-        self.call_list.append('%s_f(%s);' % (self.function_name, ', '.join(['&'+a for a in self.args_list])))
-        if not self.buildvalue_list:
-            self.buildvalue_list.append('""')
-        self.parent.capi_function_list.append(self.apply_attributes(self.capi_function_template))
-        self.parent.module_method_list.append(self.apply_attributes(self.pymethoddef_template))
-        self.parent.extern_list.append(self.apply_attributes(self.extdef_template))
-        self.parent.add_cppmacro('F_FUNC')
-        self.parent.cppmacro_list.append(self.apply_attributes(self.cppmacro_template))
-        return
-
-class ArgumentWrapper(WrapperBase):
-
-    objdecl_template = '%(ctype)s %(name)s;'
-    pyarg_obj_template = '\npyobj_to_%(ctype)s, &%(name)s'
-
-    def __init__(self, parent, variable):
-        WrapperBase.__init__(self)
-        self.parent = parent
-        self.grand_parent = parent.parent
-        self.variable = variable
-        self.typedecl = variable.typedecl
-        self.name = variable.name
-        self.ctype = self.typedecl.get_c_type()
-        
-    def fill(self):
-        typename = self.grand_parent.add_type(self.typedecl)
-        self.parent.decl_list.append(self.apply_attributes(self.objdecl_template))
-        
-        self.parent.pyarg_obj_list.append(self.apply_attributes(self.pyarg_obj_template))
-        self.parent.pyarg_format_list.append('O&')
-        self.parent.keyword_list.append('"%s"' % (self.name))
-
-        return
-
-
-class TypeDecl2(WrapperBase):
-    cppmacro_template = '''\
-#define initialize_%(typename)s_interface F_FUNC(initialize_%(typename)s_interface_f,INITIALIZE_%(TYPENAME)s_INTERFACE_F)\
-'''
-    typedef_template = '''\
-typedef struct { char data[%(byte_size)s]; } %(ctype)s;
-typedef %(ctype)s (*create_%(typename)s_functype)(void);
-typedef void (*initialize_%(typename)s_interface_functype)(create_%(typename)s_functype);\
-'''
-    objdecl_template = '''\
-static create_%(typename)s_functype create_%(typename)s_object;
-'''
-    funcdef_template = '''\
-static void initialize_%(typename)s_interface_c(create_%(typename)s_functype create_object_f) {
-  create_%(typename)s_object = create_object_f;
-}
-'''
-    extdef_template = '''\
-extern void initialize_%(typename)s_interface(initialize_%(typename)s_interface_functype);\
-'''
-    initcall_template = '''\
-initialize_%(typename)s_interface(initialize_%(typename)s_interface_c);\
-'''
-    fortran_code_template = '''\
-       function create_%(typename)s_object_f() result (obj)
-         %(typedecl_list)s
-         %(typedecl)s obj
-!        %(initexpr)s
-       end
-       subroutine initialize_%(typename)s_interface_f(init_c)
-         external create_%(typename)s_object_f
-         call init_c(create_%(typename)s_object_f)
-       end
-'''
-    pyobj_to_type_template = '''
-    static int pyobj_to_%(ctype)s(PyObject *obj, %(ctype)s* value) {
-      if (PyTuple_Check(obj)) {
-        return 0;
-      }
-    return 0;
-    }
-'''
-
-    def __init__(self, parent, typedecl):
-        WrapperBase.__init__(self)
-        self.parent = parent
-        self.typedecl = typedecl.astypedecl()
-        self.typedecl_list = []
-        self.ctype = self.typedecl.get_c_type()
-        self.byte_size = self.typedecl.get_byte_size()
-        self.typename = self.typedecl.name.lower()
-        self.TYPENAME = self.typedecl.name.upper()
-        self.initexpr = self.typedecl.assign_expression('obj',self.typedecl.get_zero_value())
-        return
-
-    def fill(self):
-        ctype =self.typedecl.get_c_type()
-        if ctype.startswith('npy_') or ctype.startswith('f2py_string'):
-            # wrappers are defined via pyobj_to_* functions
-            self.parent.add_c_function('pyobj_to_%s' % (self.ctype))
-            return
-        if ctype.startswith('f2py_type'):
-            return
-            self.parent.add_typedef(ctype,
-                                    self.apply_attributes('typedef struct { char data[%(byte_size)s]; } %(ctype)s;'))
-            self.parent.add_c_function(self.apply_attributes('pyobj_to_%(ctype)s'),
-                                       self.apply_attributes(self.pyobj_to_type_template)
-                                       )
-        else:
-            self.parent.typedef_list.append(self.apply_attributes(self.typedef_template))
-            self.parent.objdecl_list.append(self.apply_attributes(self.objdecl_template))
-            self.parent.c_function_list.append(self.apply_attributes(self.funcdef_template))
-            self.parent.extern_list.append(self.apply_attributes(self.extdef_template))
-            self.parent.initialize_interface_list.append(self.apply_attributes(self.initcall_template))
-            self.parent.fortran_code_list.append(self.apply_attributes(self.fortran_code_template))
-            self.parent.add_cppmacro('F_FUNC')
-            self.parent.cppmacro_list.append(self.apply_attributes(self.cppmacro_template))
-        return
-
-
-
-
-if __name__ == '__main__':
-
-    foo_code = """! -*- f90 -*-
-      module rat
-        type info
-          complex*8 flag
-        end type info
-        type rational
-          !integer n,d
-          type(info) i
-        end type rational
-      end module rat
-      subroutine foo(a,b)
-        use rat
-        integer a
-        !character*5 b
-        type(rational) b
-        print*,'a=',a,b
-      end
-"""
-
-    wm = PythonWrapperModule('foo')
-    wm.add(parse(foo_code))
-    #wm.add_fortran_code(foo_code)
-    #wm.add_subroutine(str2stmt(foo_code))
-    #print wm.c_code()
-
-    c_code = wm.c_code()
-    f_code = wm.fortran_code()
-
-    f = open('foomodule.c','w')
-    f.write(c_code)
-    f.close()
-    f = open('foo.f','w')
-    f.write(foo_code)
-    f.close()
-    f = open('foo_wrap.f','w')
-    f.write(f_code)
-    f.close()
-    f = open('foo_setup.py','w')
-    f.write('''\
-def configuration(parent_package='',top_path=None):
-    from numpy.distutils.misc_util import Configuration
-    config = Configuration('foopack',parent_package,top_path)
-    config.add_library('foolib',
-                       sources = ['foo.f','foo_wrap.f'])
-    config.add_extension('foo',
-                         sources=['foomodule.c'],
-                         libraries = ['foolib'],
-                         define_macros = [('F2PY_DEBUG_PYOBJ_TOFROM',None)]
-                         )
-    return config
-if __name__ == '__main__':
-    from numpy.distutils.core import setup
-    setup(configuration=configuration)
-''')
-    f.close()
-    #print get_char_bit()
-    os.system('python foo_setup.py config_fc --fcompiler=gnu95 build build_ext --inplace')
-    import foo
-    #print foo.__doc__
-    #print dir(foo)
-    #print foo.info.__doc__
-    #print foo.rational.__doc__
-    #print dir(foo.rational)
-    i = foo.info(2)
-    print 'i=',i
-    #print i #,i.as_tuple()
-    #print 'i.flag=',i.flag
-    r = foo.rational(2)
-    print r
-    j = r.i
-    print 'r.i.flag=',(r.i).flag
-    print 'j.flag=',type(j.flag)
-    #print 'r=',r
-    sys.exit()
-    n,d,ii = r.as_tuple()
-    n += 1
-    print n,d
-    print r
-    #foo.foo(2,r)
-    print r.n, r.d
-    r.n = 5
-    print r
-    r.n -= 1
-    print r

Modified: trunk/numpy/f2py/lib/src/pyobj_to_Py_complex.c
===================================================================
--- trunk/numpy/f2py/lib/src/pyobj_to_Py_complex.c	2006-10-07 08:00:20 UTC (rev 3282)
+++ trunk/numpy/f2py/lib/src/pyobj_to_Py_complex.c	2006-10-07 08:49:08 UTC (rev 3283)
@@ -3,34 +3,52 @@
 #if defined(F2PY_DEBUG_PYOBJ_TOFROM)
   fprintf(stderr,"pyobj_to_Py_complex(type=%s)\n",PyString_AS_STRING(PyObject_Repr(PyObject_Type(obj))));
 #endif
+  if (PyArray_CheckScalar(obj)) {
+    if (PyArray_IsScalar(obj, CDouble)) {
+      npy_cdouble obval = PyArrayScalar_VAL(obj, CDouble);
+      value->real = obval.real;
+      value->imag = obval.imag;
+      return_value = 1;
+      goto capi_done;
+    }
+    else if (PyArray_IsScalar(obj, CFloat)) {
+      npy_cfloat obval = PyArrayScalar_VAL(obj, CFloat);
+      value->real = obval.real;
+      value->imag = obval.imag;
+      return_value = 1;
+      goto capi_done;
+    }
+  }
   if (PyComplex_Check(obj)) {
-    *value =PyComplex_AsCComplex(obj);
+    *value = PyComplex_AsCComplex(obj);
     return_value = 1;
     goto capi_done;
   }
   /* Python does not provide PyNumber_Complex function :-( */
-  (*value).imag=0.0;
+  value->imag=0.0;
   if (PyFloat_Check(obj)) {
 #ifdef __sgi
-    (*value).real = PyFloat_AsDouble(obj);
+    value->real = PyFloat_AsDouble(obj);
     return_value = !PyErr_Occurred()
 #else
-    (*value).real = PyFloat_AS_DOUBLE(obj);
+    value->real = PyFloat_AS_DOUBLE(obj);
     return_value = 1;
 #endif
     goto capi_done;
   }
   if (PyInt_Check(obj)) {
-    (*value).real = (double)PyInt_AS_LONG(obj);
+    value->real = (double)PyInt_AS_LONG(obj);
     return_value = 1;
     goto capi_done;
   }
   if (PyLong_Check(obj)) {
-    (*value).real = PyLong_AsDouble(obj);
+    value->real = PyLong_AsDouble(obj);
     return_value = !PyErr_Occurred();;
     goto capi_done;
   }
-  if (PySequence_Check(obj) && (!PyString_Check(obj))) {
+  if (PyString_Check(obj))
+    /*pass*/;
+  else if (PySequence_Check(obj) && PySequence_Size(obj)==1) {
     PyObject *tmp = PySequence_GetItem(obj,0);
     if (tmp) {
       if (pyobj_to_Py_complex(tmp,value)) {
@@ -41,10 +59,11 @@
       Py_DECREF(tmp);
     }
   }
-
   if (!PyErr_Occurred()) {
-    PyErr_SetString(PyExc_TypeError,
-		    "Failed to convert python object to C Py_complex.");
+    PyObject* r = PyString_FromString("Failed to convert ");
+    PyString_ConcatAndDel(&r, PyObject_Repr(PyObject_Type(obj)));
+    PyString_ConcatAndDel(&r, PyString_FromString(" to C Py_complex"));
+    PyErr_SetObject(PyExc_TypeError,r);
   }
  capi_done:
 #if defined(F2PY_DEBUG_PYOBJ_TOFROM)

Modified: trunk/numpy/f2py/lib/src/pyobj_to_double.c
===================================================================
--- trunk/numpy/f2py/lib/src/pyobj_to_double.c	2006-10-07 08:00:20 UTC (rev 3282)
+++ trunk/numpy/f2py/lib/src/pyobj_to_double.c	2006-10-07 08:49:08 UTC (rev 3283)
@@ -1,12 +1,18 @@
 int pyobj_to_double(PyObject* obj, double* value) {
+  int return_value = 0;
+#if defined(F2PY_DEBUG_PYOBJ_TOFROM)
+  fprintf(stderr,"pyobj_to_double(type=%s)\n",PyString_AS_STRING(PyObject_Repr(PyObject_Type(obj))));
+#endif
   PyObject* tmp = NULL;
   if (PyFloat_Check(obj)) {
 #ifdef __sgi
     *value = PyFloat_AsDouble(obj);
-    return (!PyErr_Occurred());
+    return_value = !PyErr_Occurred();
+    goto capi_done;
 #else
     *value = PyFloat_AS_DOUBLE(obj);
-    return 1;
+    return_value = 1;
+    goto capi_done;
 #endif
   }
   tmp = PyNumber_Float(obj);
@@ -14,26 +20,42 @@
 #ifdef __sgi
     *value = PyFloat_AsDouble(tmp);
     Py_DECREF(tmp);
-    return (!PyErr_Occurred());
+    return_value = !PyErr_Occurred();
+    goto capi_done;
 #else
     *value = PyFloat_AS_DOUBLE(tmp);
     Py_DECREF(tmp);
-    return 1;
+    return_value = 1;
+    goto capi_done;
 #endif
   }
+  /*
   if (PyComplex_Check(obj))
     tmp = PyObject_GetAttrString(obj,"real");
-  else if (PyString_Check(obj))
+  else 
+  */
+  if (PyString_Check(obj))
     /*pass*/;
-  else if (PySequence_Check(obj))
+  else if (PySequence_Check(obj) && PySequence_Size(obj)==1)
     tmp = PySequence_GetItem(obj,0);
   if (tmp) {
     PyErr_Clear();
-    if (pyobj_to_double(tmp, value)) {Py_DECREF(tmp); return 1;}
+    if (pyobj_to_double(tmp, value)) {
+      Py_DECREF(tmp); 
+      return_value = 1;
+      goto capi_done;
+    }
     Py_DECREF(tmp);
   }
   if (!PyErr_Occurred()) {
-    PyErr_SetString(PyExc_TypeError, "Failed to convert python object to C double.");
+    PyObject* r = PyString_FromString("Failed to convert ");
+    PyString_ConcatAndDel(&r, PyObject_Repr(PyObject_Type(obj)));
+    PyString_ConcatAndDel(&r, PyString_FromString(" to C double"));
+    PyErr_SetObject(PyExc_TypeError,r);
   }
-  return 0;
+ capi_done:
+#if defined(F2PY_DEBUG_PYOBJ_TOFROM)
+  fprintf(stderr,"pyobj_to_double: return_value=%d, PyErr_Occurred()=%p\n", return_value, PyErr_Occurred());
+#endif
+  return return_value;
 }

Modified: trunk/numpy/f2py/lib/src/pyobj_to_long.c
===================================================================
--- trunk/numpy/f2py/lib/src/pyobj_to_long.c	2006-10-07 08:00:20 UTC (rev 3282)
+++ trunk/numpy/f2py/lib/src/pyobj_to_long.c	2006-10-07 08:49:08 UTC (rev 3283)
@@ -1,32 +1,48 @@
 int pyobj_to_long(PyObject *obj, long* value) {
+  int return_value = 0;
   PyObject* tmp = NULL;
+#if defined(F2PY_DEBUG_PYOBJ_TOFROM)
+  fprintf(stderr,"pyobj_to_long(type=%s)\n",PyString_AS_STRING(PyObject_Repr(PyObject_Type(obj))));
+#endif
   if (PyInt_Check(obj)) {
     *value = PyInt_AS_LONG(obj);
-    return 1;
+    return_value = 1;
+    goto capi_done;
   }
   tmp = PyNumber_Int(obj);
   if (tmp) {
     *value = PyInt_AS_LONG(tmp);
     Py_DECREF(tmp);
-    return 1;
+    return_value = 1;
+    goto capi_done;
   }
+  /*
   if (PyComplex_Check(obj))
     tmp = PyObject_GetAttrString(obj,"real");
-  else if (PyString_Check(obj))
+  else
+  */ 
+  if (PyString_Check(obj))
     /*pass*/;
-  else if (PySequence_Check(obj))
+  else if (PySequence_Check(obj) && PySequence_Size(obj)==1)
     tmp = PySequence_GetItem(obj,0);
   if (tmp) {
     PyErr_Clear();
     if (pyobj_to_long(tmp, value)) {
       Py_DECREF(tmp);
-      return 1;
+      return_value = 1;
+      goto capi_done;
     }
     Py_DECREF(tmp);
   }
   if (!PyErr_Occurred()) {
-    PyErr_SetString(PyExc_TypeError,
-                    "Failed to convert python object to C long.");
+    PyObject* r = PyString_FromString("Failed to convert ");
+    PyString_ConcatAndDel(&r, PyObject_Repr(PyObject_Type(obj)));
+    PyString_ConcatAndDel(&r, PyString_FromString(" to C long"));
+    PyErr_SetObject(PyExc_TypeError,r);
   }
-  return 0;
+ capi_done:
+#if defined(F2PY_DEBUG_PYOBJ_TOFROM)
+  fprintf(stderr,"pyobj_to_long: return_value=%d, PyErr_Occurred()=%p\n", return_value, PyErr_Occurred());
+#endif
+  return return_value;
 }

Modified: trunk/numpy/f2py/lib/src/pyobj_to_npy_longlong.c
===================================================================
--- trunk/numpy/f2py/lib/src/pyobj_to_npy_longlong.c	2006-10-07 08:00:20 UTC (rev 3282)
+++ trunk/numpy/f2py/lib/src/pyobj_to_npy_longlong.c	2006-10-07 08:49:08 UTC (rev 3283)
@@ -1,37 +1,54 @@
 int pyobj_to_npy_longlong(PyObject *obj, npy_longlong* value) {
+  int return_value = 0;
+#if defined(F2PY_DEBUG_PYOBJ_TOFROM)
+  fprintf(stderr,"pyobj_to_npy_longlong(type=%s)\n",PyString_AS_STRING(PyObject_Repr(PyObject_Type(obj))));
+#endif
   PyObject* tmp = NULL;
   if (PyLong_Check(obj)) {
     *value = PyLong_AsLongLong(obj);
-    return (!PyErr_Occurred());
+    return_value = !PyErr_Occurred();
+    goto capi_done;
   }
   if (PyInt_Check(obj)) {
     *value = (npy_longlong)PyInt_AS_LONG(obj);
-    return 1;
+    return_value = 1;
+    goto capi_done;
   }
   tmp = PyNumber_Long(obj);
   if (tmp) {
     *value = PyLong_AsLongLong(tmp);
     Py_DECREF(tmp);
-    return (!PyErr_Occurred());
+    return_value = !PyErr_Occurred();
+    goto capi_done;
   }
+  /*
   if (PyComplex_Check(obj))
     tmp = PyObject_GetAttrString(obj,"real");
-  else if (PyString_Check(obj))
+  else
+  */
+  if (PyString_Check(obj))
     /*pass*/;
-  else if (PySequence_Check(obj))
+  else if (PySequence_Check(obj) && PySequence_Size(obj)==1)
     tmp = PySequence_GetItem(obj,0);
   if (tmp) {
     PyErr_Clear();
     if (pyobj_to_npy_longlong(tmp, value)) {
       Py_DECREF(tmp);
-      return 1;
+      return_value = 1;
+      goto capi_done;
     }
     Py_DECREF(tmp);
   }
   if (!PyErr_Occurred()) {
-    PyErr_SetString(PyExc_TypeError,
-		    "Failed to convert python object to C npy_longlong.");
+    PyObject* r = PyString_FromString("Failed to convert ");
+    PyString_ConcatAndDel(&r, PyObject_Repr(PyObject_Type(obj)));
+    PyString_ConcatAndDel(&r, PyString_FromString(" to C npy_longlong"));
+    PyErr_SetObject(PyExc_TypeError,r);
   }
-  return 0;
+ capi_done:
+#if defined(F2PY_DEBUG_PYOBJ_TOFROM)
+  fprintf(stderr,"pyobj_to_npy_longlong: return_value=%d, PyErr_Occurred()=%p\n", return_value, PyErr_Occurred());
+#endif
+  return return_value;
 }
 

Added: trunk/numpy/f2py/lib/test_scalar_in_out.py
===================================================================
--- trunk/numpy/f2py/lib/test_scalar_in_out.py	2006-10-07 08:00:20 UTC (rev 3282)
+++ trunk/numpy/f2py/lib/test_scalar_in_out.py	2006-10-07 08:49:08 UTC (rev 3283)
@@ -0,0 +1,373 @@
+#!/usr/bin/env python
+
+import os
+import sys
+from numpy.testing import *
+
+def build(fortran_code, rebuild=True):
+    modulename = os.path.splitext(os.path.basename(__file__))[0]+'_ext'
+    try:
+        exec ('import %s as m' % (modulename))
+        if rebuild and os.stat(m.__file__)[8] < os.stat(__file__)[8]:
+            del sys.modules[m.__name__] # soft unload extension module
+            os.remove(m.__file__)
+            raise ImportError,'%s is newer than %s' % (__file__, m.__file__)
+    except ImportError,msg:
+        print msg, ', recompiling %s.' % (modulename)
+        import tempfile
+        fname = tempfile.mktemp() + '.f'
+        f = open(fname,'w')
+        f.write(fortran_code)
+        f.close()
+        sys_argv = ['--build-dir','foo']
+        #sys_argv.extend(['-DF2PY_DEBUG_PYOBJ_TOFROM'])
+        from main import build_extension
+        sys_argv.extend(['-m',modulename, fname])
+        build_extension(sys_argv)
+        os.remove(fname)
+        os.system(' '.join([sys.executable] + sys.argv))
+        sys.exit(0)
+    return m
+
+fortran_code = '''
+      subroutine fooint1(a)
+      integer*1 a
+!f2py intent(in,out) a
+      a = a + 1
+      end
+      subroutine fooint2(a)
+      integer*2 a
+!f2py intent(in,out) a
+      a = a + 1
+      end
+      subroutine fooint4(a)
+      integer*4 a
+!f2py intent(in,out) a
+      a = a + 1
+      end
+      subroutine fooint8(a)
+      integer*8 a
+!f2py intent(in,out) a
+      a = a + 1
+      end
+      subroutine foofloat4(a)
+      real*4 a
+!f2py intent(in,out) a
+      a = a + 1.0e0
+      end
+      subroutine foofloat8(a)
+      real*8 a
+!f2py intent(in,out) a
+      a = a + 1.0d0
+      end
+      subroutine foocomplex8(a)
+      complex*8 a
+!f2py intent(in,out) a
+      a = a + 1.0e0
+      end
+      subroutine foocomplex16(a)
+      complex*16 a
+!f2py intent(in,out) a
+      a = a + 1.0d0
+      end
+'''
+
+# tester note: set rebuild=True when changing fortan_code and for SVN
+m = build(fortran_code, rebuild=True)
+
+from numpy import *
+
+class test_m(NumpyTestCase):
+
+    def check_foo_integer1(self, level=1):
+        i = int8(2)
+        e = int8(3)
+        func = m.fooint1
+        assert isinstance(i,int8),`type(i)`
+        r = func(i)
+        assert isinstance(r,int8),`type(r)`
+        assert i is not r,`id(i),id(r)`
+        assert_equal(r,e)
+
+        r = func(2)
+        assert isinstance(r,int8),`type(r)`
+        assert_equal(r,e)
+
+        for intx in [int64,int16,int32]:
+            r = func(intx(2))
+            assert isinstance(r,int8),`type(r)`
+            assert_equal(r,e)
+
+        r = func(2.0)
+        assert isinstance(r,int8),`type(r)`
+        assert_equal(r,e)
+
+        r = func(2.2)
+        assert isinstance(r,int8),`type(r)`
+        assert_equal(r,e)
+
+        r = func([2])
+        assert isinstance(r,int8),`type(r)`
+        assert_equal(r,e)
+
+        self.assertRaises(TypeError,lambda :func(2.2j))
+        self.assertRaises(TypeError,lambda :func([2,1]))
+        self.assertRaises(TypeError,lambda :func({}))
+
+    def check_foo_integer2(self, level=1):
+        i = int16(2)
+        e = int16(3)
+        func = m.fooint2
+        assert isinstance(i,int16),`type(i)`
+        r = func(i)
+        assert isinstance(r,int16),`type(r)`
+        assert i is not r,`id(i),id(r)`
+        assert_equal(r,e)
+
+        r = func(2)
+        assert isinstance(r,int16),`type(r)`
+        assert_equal(r,e)
+
+        for intx in [int8,int64,int32]:
+            r = func(intx(2))
+            assert isinstance(r,int16),`type(r)`
+            assert_equal(r,e)
+
+        r = func(2.0)
+        assert isinstance(r,int16),`type(r)`
+        assert_equal(r,e)
+
+        r = func(2.2)
+        assert isinstance(r,int16),`type(r)`
+        assert_equal(r,e)
+
+        r = func([2])
+        assert isinstance(r,int16),`type(r)`
+        assert_equal(r,e)
+
+        self.assertRaises(TypeError,lambda :func(2.2j))
+        self.assertRaises(TypeError,lambda :func([2,1]))
+        self.assertRaises(TypeError,lambda :func({}))
+
+    def check_foo_integer4(self, level=1):
+        i = int32(2)
+        e = int32(3)
+        func = m.fooint4
+        assert isinstance(i,int32),`type(i)`
+        r = func(i)
+        assert isinstance(r,int32),`type(r)`
+        assert i is not r,`id(i),id(r)`
+        assert_equal(r,e)
+
+        r = func(2)
+        assert isinstance(r,int32),`type(r)`
+        assert_equal(r,e)
+
+        for intx in [int8,int16,int64]:
+            r = func(intx(2))
+            assert isinstance(r,int32),`type(r)`
+            assert_equal(r,e)
+
+        r = func(2.0)
+        assert isinstance(r,int32),`type(r)`
+        assert_equal(r,e)
+
+        r = func(2.2)
+        assert isinstance(r,int32),`type(r)`
+        assert_equal(r,e)
+
+        r = func([2])
+        assert isinstance(r,int32),`type(r)`
+        assert_equal(r,e)
+
+        self.assertRaises(TypeError,lambda :func(2.2j))
+        self.assertRaises(TypeError,lambda :func([2,1]))
+        self.assertRaises(TypeError,lambda :func({}))
+
+    def check_foo_integer8(self, level=1):
+        i = int64(2)
+        e = int64(3)
+        func = m.fooint8
+        assert isinstance(i,int64),`type(i)`
+        r = func(i)
+        assert isinstance(r,int64),`type(r)`
+        assert i is not r,`id(i),id(r)`
+        assert_equal(r,e)
+
+        r = func(2)
+        assert isinstance(r,int64),`type(r)`
+        assert_equal(r,e)
+
+        r = func(2.0)
+        assert isinstance(r,int64),`type(r)`
+        assert_equal(r,e)
+
+        r = func(2.2)
+        assert isinstance(r,int64),`type(r)`
+        assert_equal(r,e)
+
+        for intx in [int8,int16,int32]:
+            r = func(intx(2))
+            assert isinstance(r,int64),`type(r)`
+            assert_equal(r,e)
+
+        r = func([2])
+        assert isinstance(r,int64),`type(r)`
+        assert_equal(r,e)
+
+        self.assertRaises(TypeError,lambda :func(2.2j))
+        self.assertRaises(TypeError,lambda :func([2,1]))
+        self.assertRaises(TypeError,lambda :func({}))
+
+    def check_foo_real4(self, level=1):
+        i = float32(2)
+        e = float32(3)
+        func = m.foofloat4
+        assert isinstance(i,float32),`type(i)`
+        r = func(i)
+        assert isinstance(r,float32),`type(r)`
+        assert i is not r,`id(i),id(r)`
+        assert_equal(r,e)
+
+        r = func(2)
+        assert isinstance(r,float32),`type(r)`
+        assert_equal(r,e)
+
+        r = func(2.0)
+        assert isinstance(r,float32),`type(r)`
+        assert_equal(r,e)
+
+        r = func(2.2)
+        assert isinstance(r,float32),`type(r)`
+        assert_equal(r,e+float32(0.2))
+
+        r = func(float64(2.0))
+        assert isinstance(r,float32),`type(r)`
+        assert_equal(r,e)
+
+        r = func([2])
+        assert isinstance(r,float32),`type(r)`
+        assert_equal(r,e)
+
+        self.assertRaises(TypeError,lambda :func(2.2j))
+        self.assertRaises(TypeError,lambda :func([2,1]))
+        self.assertRaises(TypeError,lambda :func({}))
+
+    def check_foo_real8(self, level=1):
+        i = float64(2)
+        e = float64(3)
+        func = m.foofloat8
+        assert isinstance(i,float64),`type(i)`
+        r = func(i)
+        assert isinstance(r,float64),`type(r)`
+        assert i is not r,`id(i),id(r)`
+        assert_equal(r,e)
+
+        r = func(2)
+        assert isinstance(r,float64),`type(r)`
+        assert_equal(r,e)
+
+        r = func(2.0)
+        assert isinstance(r,float64),`type(r)`
+        assert_equal(r,e)
+
+        r = func(2.2)
+        assert isinstance(r,float64),`type(r)`
+        assert_equal(r,e+float64(0.2))
+
+        r = func(float32(2.0))
+        assert isinstance(r,float64),`type(r)`
+        assert_equal(r,e)
+
+        r = func([2])
+        assert isinstance(r,float64),`type(r)`
+        assert_equal(r,e)
+
+        self.assertRaises(TypeError,lambda :func(2.2j))
+        self.assertRaises(TypeError,lambda :func([2,1]))
+        self.assertRaises(TypeError,lambda :func({}))
+
+    def check_foo_complex8(self, level=1):
+        i = complex64(2)
+        e = complex64(3)
+        func = m.foocomplex8
+        assert isinstance(i,complex64),`type(i)`
+        r = func(i)
+        assert isinstance(r,complex64),`type(r)`
+        assert i is not r,`id(i),id(r)`
+        assert_equal(r,e)
+
+        r = func(2)
+        assert isinstance(r,complex64),`type(r)`
+        assert_equal(r,e)
+
+        r = func(2.0)
+        assert isinstance(r,complex64),`type(r)`
+        assert_equal(r,e)
+
+        r = func(2.2)
+        assert isinstance(r,complex64),`type(r)`
+        assert_equal(r,e+complex64(0.2))
+
+        r = func(2+1j)
+        assert isinstance(r,complex64),`type(r)`
+        assert_equal(r,e+complex64(1j))
+
+        r = func(complex128(2.0))
+        assert isinstance(r,complex64),`type(r)`
+        assert_equal(r,e)
+
+        r = func([2])
+        assert isinstance(r,complex64),`type(r)`
+        assert_equal(r,e)
+
+        r = func([2,3])
+        assert isinstance(r,complex64),`type(r)`
+        assert_equal(r,e+complex64(3j))
+
+        self.assertRaises(TypeError,lambda :func([2,1,3]))
+        self.assertRaises(TypeError,lambda :func({}))
+
+    def check_foo_complex16(self, level=1):
+        i = complex128(2)
+        e = complex128(3)
+        func = m.foocomplex16
+        assert isinstance(i,complex128),`type(i)`
+        r = func(i)
+        assert isinstance(r,complex128),`type(r)`
+        assert i is not r,`id(i),id(r)`
+        assert_equal(r,e)
+
+        r = func(2)
+        assert isinstance(r,complex128),`type(r)`
+        assert_equal(r,e)
+
+        r = func(2.0)
+        assert isinstance(r,complex128),`type(r)`
+        assert_equal(r,e)
+
+        r = func(2.2)
+        assert isinstance(r,complex128),`type(r)`
+        assert_equal(r,e+complex128(0.2))
+
+        r = func(2+1j)
+        assert isinstance(r,complex128),`type(r)`
+        assert_equal(r,e+complex128(1j))
+
+        r = func([2])
+        assert isinstance(r,complex128),`type(r)`
+        assert_equal(r,e)
+
+        r = func([2,3])
+        assert isinstance(r,complex128),`type(r)`
+        assert_equal(r,e+complex128(3j))
+
+        r = func(complex64(2.0))
+        assert isinstance(r,complex128),`type(r)`
+        assert_equal(r,e)
+
+        self.assertRaises(TypeError,lambda :func([2,1,3]))
+        self.assertRaises(TypeError,lambda :func({}))
+
+if __name__ == "__main__":
+    NumpyTest().run()




More information about the Numpy-svn mailing list