diff options
author | Pearu Peterson <pearu.peterson@gmail.com> | 2006-10-07 08:49:08 +0000 |
---|---|---|
committer | Pearu Peterson <pearu.peterson@gmail.com> | 2006-10-07 08:49:08 +0000 |
commit | 90d11ae25a5edabecc0b9e9c7a6e3de929d125f2 (patch) | |
tree | ebdf733a41b773c46af6bb00cba2a333d2a38661 | |
parent | 79f992d50ce28fa119455e0f12e428559b0ff0b8 (diff) | |
download | numpy-90d11ae25a5edabecc0b9e9c7a6e3de929d125f2.tar.gz |
F2PY G3: completed test site for int,float,complex scalar support. Fixed bugs.
-rw-r--r-- | numpy/f2py/lib/generate_pyobj_tofrom_funcs.py | 54 | ||||
-rw-r--r-- | numpy/f2py/lib/parser/base_classes.py | 18 | ||||
-rw-r--r-- | numpy/f2py/lib/parser/typedecl_statements.py | 8 | ||||
-rw-r--r-- | numpy/f2py/lib/py_wrap_type.py | 146 | ||||
-rw-r--r-- | numpy/f2py/lib/python_wrapper.py | 687 | ||||
-rw-r--r-- | numpy/f2py/lib/src/pyobj_to_Py_complex.c | 39 | ||||
-rw-r--r-- | numpy/f2py/lib/src/pyobj_to_double.c | 40 | ||||
-rw-r--r-- | numpy/f2py/lib/src/pyobj_to_long.c | 32 | ||||
-rw-r--r-- | numpy/f2py/lib/src/pyobj_to_npy_longlong.c | 35 | ||||
-rw-r--r-- | numpy/f2py/lib/test_scalar_in_out.py | 373 |
10 files changed, 640 insertions, 792 deletions
diff --git a/numpy/f2py/lib/generate_pyobj_tofrom_funcs.py b/numpy/f2py/lib/generate_pyobj_tofrom_funcs.py index 4b2c574ef..33385a439 100644 --- a/numpy/f2py/lib/generate_pyobj_tofrom_funcs.py +++ b/numpy/f2py/lib/generate_pyobj_tofrom_funcs.py @@ -12,7 +12,6 @@ def pyobj_from_npy_int(ctype): 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 @@ static PyObject* pyobj_from_%(ctype)s(%(ctype)s* value) { } ''' + + 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:]) diff --git a/numpy/f2py/lib/parser/base_classes.py b/numpy/f2py/lib/parser/base_classes.py index e79584ca5..4dce5ba8b 100644 --- a/numpy/f2py/lib/parser/base_classes.py +++ b/numpy/f2py/lib/parser/base_classes.py @@ -240,6 +240,7 @@ class Variable: 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 @@ class Variable: 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 diff --git a/numpy/f2py/lib/parser/typedecl_statements.py b/numpy/f2py/lib/parser/typedecl_statements.py index 7e5a23ba5..17b48c549 100644 --- a/numpy/f2py/lib/parser/typedecl_statements.py +++ b/numpy/f2py/lib/parser/typedecl_statements.py @@ -400,7 +400,7 @@ class Complex(TypeDeclarationStatement): 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 @@ class Complex(TypeDeclarationStatement): 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)' diff --git a/numpy/f2py/lib/py_wrap_type.py b/numpy/f2py/lib/py_wrap_type.py index 1eb152305..f9c426a3a 100644 --- a/numpy/f2py/lib/py_wrap_type.py +++ b/numpy/f2py/lib/py_wrap_type.py @@ -22,25 +22,147 @@ class PythonCAPIIntrinsicType(WrapperBase): """ 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)) - - ctype = typedecl.get_c_type() + self._defined.append(ctype) + self.info('Generating interface for %s: %s' % (typedecl.__class__, ctype)) 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 @@ static int %(oname)s_set_%(n)s(%(oname)sObject *self, self.use_stmt_list.append('use %s' % (typedecl.parent.name)) parent.apply_templates(self) - - return diff --git a/numpy/f2py/lib/python_wrapper.py b/numpy/f2py/lib/python_wrapper.py deleted file mode 100644 index 7f73d6fbb..000000000 --- a/numpy/f2py/lib/python_wrapper.py +++ /dev/null @@ -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 diff --git a/numpy/f2py/lib/src/pyobj_to_Py_complex.c b/numpy/f2py/lib/src/pyobj_to_Py_complex.c index 33eb2b6c4..254dd27d5 100644 --- a/numpy/f2py/lib/src/pyobj_to_Py_complex.c +++ b/numpy/f2py/lib/src/pyobj_to_Py_complex.c @@ -3,34 +3,52 @@ int pyobj_to_Py_complex(PyObject* obj, Py_complex* value) { #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 @@ int pyobj_to_Py_complex(PyObject* obj, Py_complex* value) { 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) diff --git a/numpy/f2py/lib/src/pyobj_to_double.c b/numpy/f2py/lib/src/pyobj_to_double.c index aad68f0c9..ca8721a62 100644 --- a/numpy/f2py/lib/src/pyobj_to_double.c +++ b/numpy/f2py/lib/src/pyobj_to_double.c @@ -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 @@ int pyobj_to_double(PyObject* obj, double* value) { #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; } diff --git a/numpy/f2py/lib/src/pyobj_to_long.c b/numpy/f2py/lib/src/pyobj_to_long.c index f93b34841..415a75855 100644 --- a/numpy/f2py/lib/src/pyobj_to_long.c +++ b/numpy/f2py/lib/src/pyobj_to_long.c @@ -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; } diff --git a/numpy/f2py/lib/src/pyobj_to_npy_longlong.c b/numpy/f2py/lib/src/pyobj_to_npy_longlong.c index 591392c8c..bb4f103f0 100644 --- a/numpy/f2py/lib/src/pyobj_to_npy_longlong.c +++ b/numpy/f2py/lib/src/pyobj_to_npy_longlong.c @@ -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; } diff --git a/numpy/f2py/lib/test_scalar_in_out.py b/numpy/f2py/lib/test_scalar_in_out.py new file mode 100644 index 000000000..37fd5ffb9 --- /dev/null +++ b/numpy/f2py/lib/test_scalar_in_out.py @@ -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() |