[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