diff options
Diffstat (limited to 'numpy/f2py')
-rw-r--r-- | numpy/f2py/cb_rules.py | 6 | ||||
-rw-r--r-- | numpy/f2py/cfuncs.py | 126 | ||||
-rwxr-xr-x | numpy/f2py/crackfortran.py | 10 | ||||
-rw-r--r-- | numpy/f2py/rules.py | 13 | ||||
-rw-r--r-- | numpy/f2py/setup.py | 34 | ||||
-rw-r--r-- | numpy/f2py/src/fortranobject.c | 293 | ||||
-rw-r--r-- | numpy/f2py/src/fortranobject.h | 2 | ||||
-rw-r--r-- | numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c | 62 | ||||
-rw-r--r-- | numpy/f2py/tests/src/regression/inout.f90 | 9 | ||||
-rw-r--r-- | numpy/f2py/tests/test_array_from_pyobj.py | 83 | ||||
-rw-r--r-- | numpy/f2py/tests/test_regression.py | 32 |
11 files changed, 396 insertions, 274 deletions
diff --git a/numpy/f2py/cb_rules.py b/numpy/f2py/cb_rules.py index f3bf848a7..5cf6b3010 100644 --- a/numpy/f2py/cb_rules.py +++ b/numpy/f2py/cb_rules.py @@ -357,11 +357,11 @@ cb_arg_rules=[ 'pyobjfrom': [{debugcapi:'\tfprintf(stderr,"debug-capi:cb:#varname#\\n");'}, {isintent_c: """\ \tif (#name#_nofargs>capi_i) { -\t\tPyArrayObject *tmp_arr = (PyArrayObject *)PyArray_New(&PyArray_Type,#rank#,#varname_i#_Dims,#atype#,NULL,(char*)#varname_i#,0,NPY_CARRAY,NULL); /*XXX: Hmm, what will destroy this array??? */ +\t\tPyArrayObject *tmp_arr = (PyArrayObject *)PyArray_New(&PyArray_Type,#rank#,#varname_i#_Dims,#atype#,NULL,(char*)#varname_i#,0,NPY_ARRAY_CARRAY,NULL); /*XXX: Hmm, what will destroy this array??? */ """, l_not(isintent_c): """\ \tif (#name#_nofargs>capi_i) { -\t\tPyArrayObject *tmp_arr = (PyArrayObject *)PyArray_New(&PyArray_Type,#rank#,#varname_i#_Dims,#atype#,NULL,(char*)#varname_i#,0,NPY_FARRAY,NULL); /*XXX: Hmm, what will destroy this array??? */ +\t\tPyArrayObject *tmp_arr = (PyArrayObject *)PyArray_New(&PyArray_Type,#rank#,#varname_i#_Dims,#atype#,NULL,(char*)#varname_i#,0,NPY_ARRAY_FARRAY,NULL); /*XXX: Hmm, what will destroy this array??? */ """, }, """ @@ -384,7 +384,7 @@ cb_arg_rules=[ \t\t\tfprintf(stderr,\"rv_cb_arr is NULL\\n\"); \t\t\tgoto capi_fail; \t\t} -\t\tMEMCOPY(#varname_i#,rv_cb_arr->data,PyArray_NBYTES(rv_cb_arr)); +\t\tMEMCOPY(#varname_i#,PyArray_DATA(rv_cb_arr),PyArray_NBYTES(rv_cb_arr)); \t\tif (capi_tmp != (PyObject *)rv_cb_arr) { \t\t\tPy_DECREF(rv_cb_arr); \t\t} diff --git a/numpy/f2py/cfuncs.py b/numpy/f2py/cfuncs.py index 7fb630697..01e189dc1 100644 --- a/numpy/f2py/cfuncs.py +++ b/numpy/f2py/cfuncs.py @@ -223,7 +223,7 @@ cppmacros['SWAP']="""\ \ta = b;\\ \tb = c;} """ -#cppmacros['ISCONTIGUOUS']='#define ISCONTIGUOUS(m) ((m)->flags & NPY_CONTIGUOUS)' +#cppmacros['ISCONTIGUOUS']='#define ISCONTIGUOUS(m) (PyArray_FLAGS(m) & NPY_ARRAY_C_CONTIGUOUS)' cppmacros['PRINTPYOBJERR']="""\ #define PRINTPYOBJERR(obj)\\ \tfprintf(stderr,\"#modulename#.error is related to \");\\ @@ -248,8 +248,8 @@ needs['len..']=['f2py_size'] cppmacros['len..']="""\ #define rank(var) var ## _Rank #define shape(var,dim) var ## _Dims[dim] -#define old_rank(var) (((PyArrayObject *)(capi_ ## var ## _tmp))->nd) -#define old_shape(var,dim) (((PyArrayObject *)(capi_ ## var ## _tmp))->dimensions[dim]) +#define old_rank(var) (PyArray_NDIM((PyArrayObject *)(capi_ ## var ## _tmp))) +#define old_shape(var,dim) PyArray_DIM(((PyArrayObject *)(capi_ ## var ## _tmp)),dim) #define fshape(var,dim) shape(var,rank(var)-dim-1) #define len(var) shape(var,0) #define flen(var) fshape(var,0) @@ -316,35 +316,35 @@ cppmacros['pyobj_from_string1size']='#define pyobj_from_string1size(v,len) (PyUS needs['TRYPYARRAYTEMPLATE']=['PRINTPYOBJERR'] cppmacros['TRYPYARRAYTEMPLATE']="""\ /* New SciPy */ -#define TRYPYARRAYTEMPLATECHAR case NPY_STRING: *(char *)(arr->data)=*v; break; -#define TRYPYARRAYTEMPLATELONG case NPY_LONG: *(long *)(arr->data)=*v; break; -#define TRYPYARRAYTEMPLATEOBJECT case NPY_OBJECT: (arr->descr->f->setitem)(pyobj_from_ ## ctype ## 1(*v),arr->data); break; +#define TRYPYARRAYTEMPLATECHAR case NPY_STRING: *(char *)(PyArray_DATA(arr))=*v; break; +#define TRYPYARRAYTEMPLATELONG case NPY_LONG: *(long *)(PyArray_DATA(arr))=*v; break; +#define TRYPYARRAYTEMPLATEOBJECT case NPY_OBJECT: (PyArray_DESCR(arr)->f->setitem)(pyobj_from_ ## ctype ## 1(*v),PyArray_DATA(arr)); break; #define TRYPYARRAYTEMPLATE(ctype,typecode) \\ PyArrayObject *arr = NULL;\\ if (!obj) return -2;\\ if (!PyArray_Check(obj)) return -1;\\ if (!(arr=(PyArrayObject *)obj)) {fprintf(stderr,\"TRYPYARRAYTEMPLATE:\");PRINTPYOBJERR(obj);return 0;}\\ - if (arr->descr->type==typecode) {*(ctype *)(arr->data)=*v; return 1;}\\ - switch (arr->descr->type_num) {\\ - case NPY_DOUBLE: *(double *)(arr->data)=*v; break;\\ - case NPY_INT: *(int *)(arr->data)=*v; break;\\ - case NPY_LONG: *(long *)(arr->data)=*v; break;\\ - case NPY_FLOAT: *(float *)(arr->data)=*v; break;\\ - case NPY_CDOUBLE: *(double *)(arr->data)=*v; break;\\ - case NPY_CFLOAT: *(float *)(arr->data)=*v; break;\\ - case NPY_BOOL: *(npy_bool *)(arr->data)=(*v!=0); break;\\ - case NPY_UBYTE: *(unsigned char *)(arr->data)=*v; break;\\ - case NPY_BYTE: *(signed char *)(arr->data)=*v; break;\\ - case NPY_SHORT: *(short *)(arr->data)=*v; break;\\ - case NPY_USHORT: *(npy_ushort *)(arr->data)=*v; break;\\ - case NPY_UINT: *(npy_uint *)(arr->data)=*v; break;\\ - case NPY_ULONG: *(npy_ulong *)(arr->data)=*v; break;\\ - case NPY_LONGLONG: *(npy_longlong *)(arr->data)=*v; break;\\ - case NPY_ULONGLONG: *(npy_ulonglong *)(arr->data)=*v; break;\\ - case NPY_LONGDOUBLE: *(npy_longdouble *)(arr->data)=*v; break;\\ - case NPY_CLONGDOUBLE: *(npy_longdouble *)(arr->data)=*v; break;\\ - case NPY_OBJECT: (arr->descr->f->setitem)(pyobj_from_ ## ctype ## 1(*v),arr->data, arr); break;\\ + if (PyArray_DESCR(arr)->type==typecode) {*(ctype *)(PyArray_DATA(arr))=*v; return 1;}\\ + switch (PyArray_TYPE(arr)) {\\ + case NPY_DOUBLE: *(double *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_INT: *(int *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_LONG: *(long *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_FLOAT: *(float *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_CDOUBLE: *(double *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_CFLOAT: *(float *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_BOOL: *(npy_bool *)(PyArray_DATA(arr))=(*v!=0); break;\\ + case NPY_UBYTE: *(unsigned char *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_BYTE: *(signed char *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_SHORT: *(short *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_USHORT: *(npy_ushort *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_UINT: *(npy_uint *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_ULONG: *(npy_ulong *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_LONGLONG: *(npy_longlong *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_ULONGLONG: *(npy_ulonglong *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_LONGDOUBLE: *(npy_longdouble *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_CLONGDOUBLE: *(npy_longdouble *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_OBJECT: (PyArray_DESCR(arr)->f->setitem)(pyobj_from_ ## ctype ## 1(*v),PyArray_DATA(arr), arr); break;\\ default: return -2;\\ };\\ return 1 @@ -352,36 +352,36 @@ cppmacros['TRYPYARRAYTEMPLATE']="""\ needs['TRYCOMPLEXPYARRAYTEMPLATE']=['PRINTPYOBJERR'] cppmacros['TRYCOMPLEXPYARRAYTEMPLATE']="""\ -#define TRYCOMPLEXPYARRAYTEMPLATEOBJECT case NPY_OBJECT: (arr->descr->f->setitem)(pyobj_from_complex_ ## ctype ## 1((*v)),arr->data, arr); break; +#define TRYCOMPLEXPYARRAYTEMPLATEOBJECT case NPY_OBJECT: (PyArray_DESCR(arr)->f->setitem)(pyobj_from_complex_ ## ctype ## 1((*v)),PyArray_DATA(arr), arr); break; #define TRYCOMPLEXPYARRAYTEMPLATE(ctype,typecode)\\ PyArrayObject *arr = NULL;\\ if (!obj) return -2;\\ if (!PyArray_Check(obj)) return -1;\\ if (!(arr=(PyArrayObject *)obj)) {fprintf(stderr,\"TRYCOMPLEXPYARRAYTEMPLATE:\");PRINTPYOBJERR(obj);return 0;}\\ - if (arr->descr->type==typecode) {\\ - *(ctype *)(arr->data)=(*v).r;\\ - *(ctype *)(arr->data+sizeof(ctype))=(*v).i;\\ + if (PyArray_DESCR(arr)->type==typecode) {\\ + *(ctype *)(PyArray_DATA(arr))=(*v).r;\\ + *(ctype *)(PyArray_DATA(arr)+sizeof(ctype))=(*v).i;\\ return 1;\\ }\\ - switch (arr->descr->type_num) {\\ - case NPY_CDOUBLE: *(double *)(arr->data)=(*v).r;*(double *)(arr->data+sizeof(double))=(*v).i;break;\\ - case NPY_CFLOAT: *(float *)(arr->data)=(*v).r;*(float *)(arr->data+sizeof(float))=(*v).i;break;\\ - case NPY_DOUBLE: *(double *)(arr->data)=(*v).r; break;\\ - case NPY_LONG: *(long *)(arr->data)=(*v).r; break;\\ - case NPY_FLOAT: *(float *)(arr->data)=(*v).r; break;\\ - case NPY_INT: *(int *)(arr->data)=(*v).r; break;\\ - case NPY_SHORT: *(short *)(arr->data)=(*v).r; break;\\ - case NPY_UBYTE: *(unsigned char *)(arr->data)=(*v).r; break;\\ - case NPY_BYTE: *(signed char *)(arr->data)=(*v).r; break;\\ - case NPY_BOOL: *(npy_bool *)(arr->data)=((*v).r!=0 && (*v).i!=0); break;\\ - case NPY_USHORT: *(npy_ushort *)(arr->data)=(*v).r; break;\\ - case NPY_UINT: *(npy_uint *)(arr->data)=(*v).r; break;\\ - case NPY_ULONG: *(npy_ulong *)(arr->data)=(*v).r; break;\\ - case NPY_LONGLONG: *(npy_longlong *)(arr->data)=(*v).r; break;\\ - case NPY_ULONGLONG: *(npy_ulonglong *)(arr->data)=(*v).r; break;\\ - case NPY_LONGDOUBLE: *(npy_longdouble *)(arr->data)=(*v).r; break;\\ - case NPY_CLONGDOUBLE: *(npy_longdouble *)(arr->data)=(*v).r;*(npy_longdouble *)(arr->data+sizeof(npy_longdouble))=(*v).i;break;\\ - case NPY_OBJECT: (arr->descr->f->setitem)(pyobj_from_complex_ ## ctype ## 1((*v)),arr->data, arr); break;\\ + switch (PyArray_TYPE(arr)) {\\ + case NPY_CDOUBLE: *(double *)(PyArray_DATA(arr))=(*v).r;*(double *)(PyArray_DATA(arr)+sizeof(double))=(*v).i;break;\\ + case NPY_CFLOAT: *(float *)(PyArray_DATA(arr))=(*v).r;*(float *)(PyArray_DATA(arr)+sizeof(float))=(*v).i;break;\\ + case NPY_DOUBLE: *(double *)(PyArray_DATA(arr))=(*v).r; break;\\ + case NPY_LONG: *(long *)(PyArray_DATA(arr))=(*v).r; break;\\ + case NPY_FLOAT: *(float *)(PyArray_DATA(arr))=(*v).r; break;\\ + case NPY_INT: *(int *)(PyArray_DATA(arr))=(*v).r; break;\\ + case NPY_SHORT: *(short *)(PyArray_DATA(arr))=(*v).r; break;\\ + case NPY_UBYTE: *(unsigned char *)(PyArray_DATA(arr))=(*v).r; break;\\ + case NPY_BYTE: *(signed char *)(PyArray_DATA(arr))=(*v).r; break;\\ + case NPY_BOOL: *(npy_bool *)(PyArray_DATA(arr))=((*v).r!=0 && (*v).i!=0); break;\\ + case NPY_USHORT: *(npy_ushort *)(PyArray_DATA(arr))=(*v).r; break;\\ + case NPY_UINT: *(npy_uint *)(PyArray_DATA(arr))=(*v).r; break;\\ + case NPY_ULONG: *(npy_ulong *)(PyArray_DATA(arr))=(*v).r; break;\\ + case NPY_LONGLONG: *(npy_longlong *)(PyArray_DATA(arr))=(*v).r; break;\\ + case NPY_ULONGLONG: *(npy_ulonglong *)(PyArray_DATA(arr))=(*v).r; break;\\ + case NPY_LONGDOUBLE: *(npy_longdouble *)(PyArray_DATA(arr))=(*v).r; break;\\ + case NPY_CLONGDOUBLE: *(npy_longdouble *)(PyArray_DATA(arr))=(*v).r;*(npy_longdouble *)(PyArray_DATA(arr)+sizeof(npy_longdouble))=(*v).i;break;\\ + case NPY_OBJECT: (PyArray_DESCR(arr)->f->setitem)(pyobj_from_complex_ ## ctype ## 1((*v)),PyArray_DATA(arr), arr); break;\\ default: return -2;\\ };\\ return -1; @@ -391,11 +391,11 @@ cppmacros['TRYCOMPLEXPYARRAYTEMPLATE']="""\ ## \tif (PyArray_Check(obj)) arr = (PyArrayObject *)obj;\\ ## \telse arr = (PyArrayObject *)PyArray_ContiguousFromObject(obj,typenum,0,0);\\ ## \tif (arr) {\\ -## \t\tif (arr->descr->type_num==NPY_OBJECT) {\\ -## \t\t\tif (!ctype ## _from_pyobj(v,(arr->descr->getitem)(arr->data),\"\"))\\ +## \t\tif (PyArray_TYPE(arr)==NPY_OBJECT) {\\ +## \t\t\tif (!ctype ## _from_pyobj(v,(PyArray_DESCR(arr)->getitem)(PyArray_DATA(arr)),\"\"))\\ ## \t\t\tgoto capi_fail;\\ ## \t\t} else {\\ -## \t\t\t(arr->descr->cast[typenum])(arr->data,1,(char*)v,1,1);\\ +## \t\t\t(PyArray_DESCR(arr)->cast[typenum])(PyArray_DATA(arr),1,(char*)v,1,1);\\ ## \t\t}\\ ## \t\tif ((PyObject *)arr != obj) { Py_DECREF(arr); }\\ ## \t\treturn 1;\\ @@ -407,11 +407,11 @@ cppmacros['TRYCOMPLEXPYARRAYTEMPLATE']="""\ ## \tif (PyArray_Check(obj)) arr = (PyArrayObject *)obj;\\ ## \telse arr = (PyArrayObject *)PyArray_ContiguousFromObject(obj,typenum,0,0);\\ ## \tif (arr) {\\ -## \t\tif (arr->descr->type_num==NPY_OBJECT) {\\ -## \t\t\tif (!ctype ## _from_pyobj(v,(arr->descr->getitem)(arr->data),\"\"))\\ +## \t\tif (PyArray_TYPE(arr)==NPY_OBJECT) {\\ +## \t\t\tif (!ctype ## _from_pyobj(v,(PyArray_DESCR(arr)->getitem)(PyArray_DATA(arr)),\"\"))\\ ## \t\t\tgoto capi_fail;\\ ## \t\t} else {\\ -## \t\t\t(arr->descr->cast[typenum])((void *)(arr->data),1,(void *)(v),1,1);\\ +## \t\t\t(PyArray_DESCR(arr)->cast[typenum])((void *)(PyArray_DATA(arr)),1,(void *)(v),1,1);\\ ## \t\t}\\ ## \t\tif ((PyObject *)arr != obj) { Py_DECREF(arr); }\\ ## \t\treturn 1;\\ @@ -536,15 +536,15 @@ cppmacros['OLDPYNUM']="""\ cfuncs['calcarrindex']="""\ static int calcarrindex(int *i,PyArrayObject *arr) { \tint k,ii = i[0]; -\tfor (k=1; k < arr->nd; k++) -\t\tii += (ii*(arr->dimensions[k] - 1)+i[k]); /* assuming contiguous arr */ +\tfor (k=1; k < PyArray_NDIM(arr); k++) +\t\tii += (ii*(PyArray_DIM(arr,k) - 1)+i[k]); /* assuming contiguous arr */ \treturn ii; }""" cfuncs['calcarrindextr']="""\ static int calcarrindextr(int *i,PyArrayObject *arr) { -\tint k,ii = i[arr->nd-1]; -\tfor (k=1; k < arr->nd; k++) -\t\tii += (ii*(arr->dimensions[arr->nd-k-1] - 1)+i[arr->nd-k-1]); /* assuming contiguous arr */ +\tint k,ii = i[PyArray_NDIM(arr)-1]; +\tfor (k=1; k < PyArray_NDIM(arr); k++) +\t\tii += (ii*(PyArray_DIM(arr,PyArray_NDIM(arr)-k-1) - 1)+i[PyArray_NDIM(arr)-k-1]); /* assuming contiguous arr */ \treturn ii; }""" cfuncs['forcomb']="""\ @@ -592,7 +592,7 @@ cfuncs['try_pyarr_from_string']="""\ static int try_pyarr_from_string(PyObject *obj,const string str) { \tPyArrayObject *arr = NULL; \tif (PyArray_Check(obj) && (!((arr = (PyArrayObject *)obj) == NULL))) -\t\t{ STRINGCOPYN(arr->data,str,PyArray_NBYTES(arr)); } +\t\t{ STRINGCOPYN(PyArray_DATA(arr),str,PyArray_NBYTES(arr)); } \treturn 1; capi_fail: \tPRINTPYOBJERR(obj); @@ -623,9 +623,9 @@ fprintf(stderr,\"string_from_pyobj(str='%s',len=%d,inistr='%s',obj=%p)\\n\",(cha \t\t\tgoto capi_fail; \t\t} \t\tif (*len == -1) -\t\t\t*len = (arr->descr->elsize)*PyArray_SIZE(arr); +\t\t\t*len = (PyArray_ITEMSIZE(arr))*PyArray_SIZE(arr); \t\tSTRINGMALLOC(*str,*len); -\t\tSTRINGCOPYN(*str,arr->data,*len+1); +\t\tSTRINGCOPYN(*str,PyArray_DATA(arr),*len+1); \t\treturn 1; \t} \tif (PyString_Check(obj)) { diff --git a/numpy/f2py/crackfortran.py b/numpy/f2py/crackfortran.py index 893081126..0fde37bcf 100755 --- a/numpy/f2py/crackfortran.py +++ b/numpy/f2py/crackfortran.py @@ -1274,7 +1274,7 @@ def markinnerspaces(line): cb='' for c in line: if cb=='\\' and c in ['\\', '\'', '"']: - l=l+c; + l=l+c cb=c continue if f==0 and c in ['\'', '"']: cc=c; cc1={'\'':'"','"':'\''}[c] @@ -2198,8 +2198,10 @@ def analyzevars(block): if 'intent' not in vars[n]: vars[n]['intent']=[] for c in [x.strip() for x in markoutercomma(intent).split('@,@')]: - if not c in vars[n]['intent']: - vars[n]['intent'].append(c) + # Remove spaces so that 'in out' becomes 'inout' + tmp = c.replace(' ', '') + if tmp not in vars[n]['intent']: + vars[n]['intent'].append(tmp) intent=None if note: note=note.replace('\\n\\n', '\n\n') @@ -2220,7 +2222,7 @@ def analyzevars(block): if 'check' not in vars[n]: vars[n]['check']=[] for c in [x.strip() for x in markoutercomma(check).split('@,@')]: - if not c in vars[n]['check']: + if c not in vars[n]['check']: vars[n]['check'].append(c) check=None if dim and 'dimension' not in vars[n]: diff --git a/numpy/f2py/rules.py b/numpy/f2py/rules.py index 4c186712c..b46776777 100644 --- a/numpy/f2py/rules.py +++ b/numpy/f2py/rules.py @@ -109,6 +109,8 @@ module_rules={ * $D"""+"""ate:$ * Do not edit this file directly unless you know what you are doing!!! */ + +#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION #ifdef __cplusplus extern \"C\" { #endif @@ -232,6 +234,7 @@ PyMODINIT_FUNC init#modulename#(void) { #ifdef __cplusplus } #endif +#undef NPY_NO_DEPRECATED_API """, 'separatorsfor':{'latexdoc':'\n\n', 'restdoc':'\n\n'}, @@ -1027,9 +1030,9 @@ if (#varname#_capi==Py_None) { # \tif ((#varname#_capi != Py_None) && PyArray_Check(#varname#_capi) \\ # \t\t&& (#varname#_capi != (PyObject *)capi_#varname#_tmp)) { -# \t\tif (((PyArrayObject *)#varname#_capi)->nd != capi_#varname#_tmp->nd) { -# \t\t\tif (#varname#_capi != capi_#varname#_tmp->base) -# \t\t\t\tcopy_ND_array((PyArrayObject *)capi_#varname#_tmp->base,(PyArrayObject *)#varname#_capi); +# \t\tif (PyArray_NDIM((PyArrayObject *)#varname#_capi) != PyArray_NDIM(capi_#varname#_tmp)) { +# \t\t\tif (#varname#_capi != PyArray_BASE(capi_#varname#_tmp)) +# \t\t\t\tcopy_ND_array(PyArray_BASE((PyArrayObject *)capi_#varname#_tmp),(PyArrayObject *)#varname#_capi); # \t\t} else # \t\t\tcopy_ND_array(capi_#varname#_tmp,(PyArrayObject *)#varname#_capi); # \t} @@ -1047,7 +1050,7 @@ if (#varname#_capi==Py_None) { \t\tif (!PyErr_Occurred()) \t\t\tPyErr_SetString(#modulename#_error,\"failed in converting #nth# `#varname#\' of #pyname# to C/Fortran array\" ); \t} else { -\t\t#varname# = (#ctype# *)(capi_#varname#_tmp->data); +\t\t#varname# = (#ctype# *)(PyArray_DATA(capi_#varname#_tmp)); """, {hasinitvalue:[ {isintent_nothide:'\tif (#varname#_capi == Py_None) {'}, @@ -1056,7 +1059,7 @@ if (#varname#_capi==Py_None) { """\ \t\tint *_i,capi_i=0; \t\tCFUNCSMESS(\"#name#: Initializing #varname#=#init#\\n\"); -\t\tif (initforcomb(capi_#varname#_tmp->dimensions,capi_#varname#_tmp->nd,1)) { +\t\tif (initforcomb(PyArray_DIMS(capi_#varname#_tmp),PyArray_NDIM(capi_#varname#_tmp),1)) { \t\t\twhile ((_i = nextforcomb())) \t\t\t\t#varname#[capi_i++] = #init#; /* fortran way */ \t\t} else { diff --git a/numpy/f2py/setup.py b/numpy/f2py/setup.py index 2f1fd6a01..a27a001a9 100644 --- a/numpy/f2py/setup.py +++ b/numpy/f2py/setup.py @@ -32,12 +32,10 @@ from __version__ import version def configuration(parent_package='',top_path=None): config = Configuration('f2py', parent_package, top_path) - config.add_data_dir('docs') config.add_data_dir('tests') config.add_data_files('src/fortranobject.c', 'src/fortranobject.h', - 'f2py.1' ) config.make_svn_version_py() @@ -90,26 +88,24 @@ main() if __name__ == "__main__": config = configuration(top_path='') - version = config.get_version() print('F2PY Version', version) config = config.todict() - if sys.version[:3]>='2.3': - config['download_url'] = "http://cens.ioc.ee/projects/f2py2e/2.x"\ - "/F2PY-2-latest.tar.gz" - config['classifiers'] = [ - 'Development Status :: 5 - Production/Stable', - 'Intended Audience :: Developers', - 'Intended Audience :: Science/Research', - 'License :: OSI Approved :: NumPy License', - 'Natural Language :: English', - 'Operating System :: OS Independent', - 'Programming Language :: C', - 'Programming Language :: Fortran', - 'Programming Language :: Python', - 'Topic :: Scientific/Engineering', - 'Topic :: Software Development :: Code Generators', - ] + config['download_url'] = "http://cens.ioc.ee/projects/f2py2e/2.x"\ + "/F2PY-2-latest.tar.gz" + config['classifiers'] = [ + 'Development Status :: 5 - Production/Stable', + 'Intended Audience :: Developers', + 'Intended Audience :: Science/Research', + 'License :: OSI Approved :: NumPy License', + 'Natural Language :: English', + 'Operating System :: OS Independent', + 'Programming Language :: C', + 'Programming Language :: Fortran', + 'Programming Language :: Python', + 'Topic :: Scientific/Engineering', + 'Topic :: Software Development :: Code Generators', + ] setup(version=version, description = "F2PY - Fortran to Python Interface Generaton", author = "Pearu Peterson", diff --git a/numpy/f2py/src/fortranobject.c b/numpy/f2py/src/fortranobject.c index 9c96c1f46..47a69640b 100644 --- a/numpy/f2py/src/fortranobject.c +++ b/numpy/f2py/src/fortranobject.c @@ -1,10 +1,14 @@ #define FORTRANOBJECT_C +#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION #include "fortranobject.h" #ifdef __cplusplus extern "C" { #endif +#include <stdlib.h> +#include <string.h> + /* This file implements: FortranObject, array_from_pyobj, copy_ND_array @@ -55,11 +59,11 @@ PyFortranObject_New(FortranDataDef* defs, f2py_void_func init) { int n = fp->defs[i].rank-1; v = PyArray_New(&PyArray_Type, n, fp->defs[i].dims.d, NPY_STRING, NULL, fp->defs[i].data, fp->defs[i].dims.d[n], - NPY_FARRAY, NULL); + NPY_ARRAY_FARRAY, NULL); } else { v = PyArray_New(&PyArray_Type, fp->defs[i].rank, fp->defs[i].dims.d, - fp->defs[i].type, NULL, fp->defs[i].data, 0, NPY_FARRAY, + fp->defs[i].type, NULL, fp->defs[i].data, 0, NPY_ARRAY_FARRAY, NULL); } if (v==NULL) return NULL; @@ -100,84 +104,141 @@ static PyMethodDef fortran_methods[] = { #endif -static PyObject * -fortran_doc (FortranDataDef def) { - char *p; - /* - p is used as a buffer to hold generated documentation strings. - A common operation in generating the documentation strings, is - appending a string to the buffer p. Earlier, the following - idiom was: +/* Returns number of bytes consumed from buf, or -1 on error. */ +static Py_ssize_t +format_def(char *buf, Py_ssize_t size, FortranDataDef def) +{ + char *p = buf; + int i, n; - sprintf(p, "%s<string to be appended>", p); + n = PyOS_snprintf(p, size, "array(%" NPY_INTP_FMT, def.dims.d[0]); + if (n < 0 || n >= size) { + return -1; + } + p += n; + size -= n; - but this does not work when _FORTIFY_SOURCE=2 is enabled: instead - of appending the string, the string is inserted. + for (i = 1; i < def.rank; i++) { + n = PyOS_snprintf(p, size, ",%" NPY_INTP_FMT, def.dims.d[i]); + if (n < 0 || n >= size) { + return -1; + } + p += n; + size -= n; + } + + if (size <= 0) { + return -1; + } - As a fix, the following idiom should be used for appending - strings to a buffer p: + p[size] = ')'; + p++; + size--; - sprintf(p + strlen(p), "<string to be appended>"); - */ + if (def.data == NULL) { + static const char notalloc[] = ", not allocated"; + if (size < sizeof(notalloc)) { + return -1; + } + memcpy(p, notalloc, sizeof(notalloc)); + } + + return p - buf; +} + +static PyObject * +fortran_doc(FortranDataDef def) +{ + char *buf, *p; PyObject *s = NULL; - int i; - unsigned size=100; - if (def.doc!=NULL) + Py_ssize_t n, origsize, size = 100; + + if (def.doc != NULL) { size += strlen(def.doc); - p = (char*)malloc (size); - p[0] = '\0'; /* make sure that the buffer has zero length */ - if (def.rank==-1) { - if (def.doc==NULL) { - if (sprintf(p,"%s - ",def.name)==0) goto fail; - if (sprintf(p+strlen(p),"no docs available")==0) + } + origsize = size; + buf = p = (char *)PyMem_Malloc(size); + if (buf == NULL) { + return PyErr_NoMemory(); + } + + if (def.rank == -1) { + if (def.doc) { + n = strlen(def.doc); + if (n > size) { goto fail; - } else { - if (sprintf(p+strlen(p),"%s",def.doc)==0) + } + memcpy(p, def.doc, n); + p += n; + size -= n; + } + else { + n = PyOS_snprintf(p, size, "%s - no docs available", def.name); + if (n < 0 || n >= size) { goto fail; + } + p += n; + size -= n; } - } else { + } + else { PyArray_Descr *d = PyArray_DescrFromType(def.type); - if (sprintf(p+strlen(p),"'%c'-",d->type)==0) { - Py_DECREF(d); - goto fail; - } + n = PyOS_snprintf(p, size, "'%c'-", d->type); Py_DECREF(d); - if (def.data==NULL) { - if (sprintf(p+strlen(p),"array(%" NPY_INTP_FMT,def.dims.d[0])==0) - goto fail; - for(i=1;i<def.rank;++i) - if (sprintf(p+strlen(p),",%" NPY_INTP_FMT,def.dims.d[i])==0) - goto fail; - if (sprintf(p+strlen(p),"), not allocated")==0) - goto fail; - } else { - if (def.rank>0) { - if (sprintf(p+strlen(p),"array(%"NPY_INTP_FMT,def.dims.d[0])==0) - goto fail; - for(i=1;i<def.rank;i++) - if (sprintf(p+strlen(p),",%" NPY_INTP_FMT,def.dims.d[i])==0) - goto fail; - if (sprintf(p+strlen(p),")")==0) goto fail; - } else { - if (sprintf(p+strlen(p),"scalar")==0) goto fail; + if (n < 0 || n >= size) { + goto fail; + } + p += n; + size -= n; + + if (def.data == NULL) { + n = format_def(p, size, def) == -1; + if (n < 0) { + goto fail; + } + p += n; + size -= n; + } + else if (def.rank > 0) { + n = format_def(p, size, def); + if (n < 0) { + goto fail; } + p += n; + size -= n; + } + else { + n = strlen("scalar"); + if (size < n) { + goto fail; + } + memcpy(p, "scalar", n); + p += n; + size -= n; } } - if (sprintf(p+strlen(p),"\n")==0) goto fail; - if (strlen(p)>size) { - fprintf(stderr,"fortranobject.c:fortran_doc:len(p)=%zd>%d(size):"\ - " too long doc string required, increase size\n",\ - strlen(p),size); + if (size <= 1) { goto fail; } + *p++ = '\n'; + size--; + + /* p now points one beyond the last character of the string in buf */ #if PY_VERSION_HEX >= 0x03000000 - s = PyUnicode_FromString(p); + s = PyUnicode_FromStringAndSize(buf, p - buf); #else - s = PyString_FromString(p); + s = PyString_FromStringAndSize(buf, p - buf); #endif - fail: - free(p); + + PyMem_Free(buf); return s; + + fail: + fprintf(stderr, "fortranobject.c: fortran_doc: len(p)=%zd>%zd=size:" + " too long docstring required, increase size\n", + p - buf, origsize); + PyMem_Free(buf); + return NULL; } static FortranDataDef *save_def; /* save pointer of an allocatable array */ @@ -213,7 +274,7 @@ fortran_getattr(PyFortranObject *fp, char *name) { k = fp->defs[i].rank; if (fp->defs[i].data !=NULL) { /* array is allocated */ PyObject *v = PyArray_New(&PyArray_Type, k, fp->defs[i].dims.d, - fp->defs[i].type, NULL, fp->defs[i].data, 0, NPY_FARRAY, + fp->defs[i].type, NULL, fp->defs[i].data, 0, NPY_ARRAY_FARRAY, NULL); if (v==NULL) return NULL; /* Py_INCREF(v); */ @@ -285,7 +346,7 @@ fortran_setattr(PyFortranObject *fp, char *name, PyObject *v) { for(k=0;k<fp->defs[i].rank;k++) dims[k]=-1; if ((arr = array_from_pyobj(fp->defs[i].type,dims,fp->defs[i].rank,F2PY_INTENT_IN,v))==NULL) return -1; - (*(fp->defs[i].func))(&fp->defs[i].rank,arr->dimensions,set_data,&flag); + (*(fp->defs[i].func))(&fp->defs[i].rank,PyArray_DIMS(arr),set_data,&flag); } else { /* deallocate */ for(k=0;k<fp->defs[i].rank;k++) dims[k]=0; (*(fp->defs[i].func))(&fp->defs[i].rank,dims,set_data,&flag); @@ -297,11 +358,11 @@ fortran_setattr(PyFortranObject *fp, char *name, PyObject *v) { return -1; } if (fp->defs[i].data!=NULL) { /* copy Python object to Fortran array */ - npy_intp s = PyArray_MultiplyList(fp->defs[i].dims.d,arr->nd); + npy_intp s = PyArray_MultiplyList(fp->defs[i].dims.d,PyArray_NDIM(arr)); if (s==-1) - s = PyArray_MultiplyList(arr->dimensions,arr->nd); + s = PyArray_MultiplyList(PyArray_DIMS(arr),PyArray_NDIM(arr)); if (s<0 || - (memcpy(fp->defs[i].data,arr->data,s*PyArray_ITEMSIZE(arr)))==NULL) { + (memcpy(fp->defs[i].data,PyArray_DATA(arr),s*PyArray_ITEMSIZE(arr)))==NULL) { if ((PyObject*)arr!=v) { Py_DECREF(arr); } @@ -493,10 +554,10 @@ void f2py_report_on_exit(int exit_flag,void *name) { #ifdef F2PY_REPORT_ON_ARRAY_COPY static void f2py_report_on_array_copy(PyArrayObject* arr) { - const long arr_size = PyArray_Size((PyObject *)arr); + const npy_intp arr_size = PyArray_Size((PyObject *)arr); if (arr_size>F2PY_REPORT_ON_ARRAY_COPY) { - fprintf(stderr,"copied an array: size=%ld, elsize=%d\n", - arr_size, PyArray_ITEMSIZE(arr)); + fprintf(stderr,"copied an array: size=%ld, elsize=%"NPY_INTP_FMT"\n", + arr_size, (npy_intp)PyArray_ITEMSIZE(arr)); } } static void f2py_report_on_array_copy_fromany(void) { @@ -556,8 +617,9 @@ void dump_dims(int rank, npy_intp* dims) { } printf("]\n"); } -void dump_attrs(const PyArrayObject* arr) { - int rank = arr->nd; +void dump_attrs(const PyArrayObject* obj) { + const PyArrayObject_fields *arr = (const PyArrayObject_fields*) obj; + int rank = PyArray_NDIM(arr); npy_intp size = PyArray_Size((PyObject *)arr); printf("\trank = %d, flags = %d, size = %" NPY_INTP_FMT "\n", rank,arr->flags,size); @@ -570,7 +632,9 @@ void dump_attrs(const PyArrayObject* arr) { #define SWAPTYPE(a,b,t) {t c; c = (a); (a) = (b); (b) = c; } -static int swap_arrays(PyArrayObject* arr1, PyArrayObject* arr2) { +static int swap_arrays(PyArrayObject* obj1, PyArrayObject* obj2) { + PyArrayObject_fields *arr1 = (PyArrayObject_fields*) obj1, + *arr2 = (PyArrayObject_fields*) obj2; SWAPTYPE(arr1->data,arr2->data,char*); SWAPTYPE(arr1->nd,arr2->nd,int); SWAPTYPE(arr1->dimensions,arr2->dimensions,npy_intp*); @@ -619,11 +683,11 @@ PyArrayObject* array_from_pyobj(const int type_num, /* intent(cache), optional, intent(hide) */ if (count_nonpos(rank,dims)) { int i; - sprintf(mess,"failed to create intent(cache|hide)|optional array" - "-- must have defined dimensions but got ("); + strcpy(mess, "failed to create intent(cache|hide)|optional array" + "-- must have defined dimensions but got ("); for(i=0;i<rank;++i) sprintf(mess+strlen(mess),"%" NPY_INTP_FMT ",",dims[i]); - sprintf(mess+strlen(mess),")"); + strcat(mess, ")"); PyErr_SetString(PyExc_ValueError,mess); return NULL; } @@ -647,21 +711,23 @@ PyArrayObject* array_from_pyobj(const int type_num, if (intent & F2PY_INTENT_CACHE) { /* intent(cache) */ - if (PyArray_ISONESEGMENT(obj) - && PyArray_ITEMSIZE((PyArrayObject *)obj)>=elsize) { - if (check_and_fix_dimensions((PyArrayObject *)obj,rank,dims)) { + if (PyArray_ISONESEGMENT(arr) + && PyArray_ITEMSIZE(arr)>=elsize) { + if (check_and_fix_dimensions(arr,rank,dims)) { return NULL; /*XXX: set exception */ } if (intent & F2PY_INTENT_OUT) - Py_INCREF(obj); - return (PyArrayObject *)obj; + Py_INCREF(arr); + return arr; } - sprintf(mess,"failed to initialize intent(cache) array"); - if (!PyArray_ISONESEGMENT(obj)) - sprintf(mess+strlen(mess)," -- input must be in one segment"); + strcpy(mess, "failed to initialize intent(cache) array"); + if (!PyArray_ISONESEGMENT(arr)) + strcat(mess, " -- input must be in one segment"); if (PyArray_ITEMSIZE(arr)<elsize) - sprintf(mess+strlen(mess)," -- expected at least elsize=%d but got %d", - elsize,PyArray_ITEMSIZE(arr) + sprintf(mess+strlen(mess), + " -- expected at least elsize=%d but got %" NPY_INTP_FMT, + elsize, + (npy_intp)PyArray_ITEMSIZE(arr) ); PyErr_SetString(PyExc_ValueError,mess); return NULL; @@ -694,19 +760,20 @@ PyArrayObject* array_from_pyobj(const int type_num, } if (intent & F2PY_INTENT_INOUT) { - sprintf(mess,"failed to initialize intent(inout) array"); + strcpy(mess, "failed to initialize intent(inout) array"); if ((intent & F2PY_INTENT_C) && !PyArray_ISCARRAY(arr)) - sprintf(mess+strlen(mess)," -- input not contiguous"); + strcat(mess, " -- input not contiguous"); if (!(intent & F2PY_INTENT_C) && !PyArray_ISFARRAY(arr)) - sprintf(mess+strlen(mess)," -- input not fortran contiguous"); + strcat(mess, " -- input not fortran contiguous"); if (PyArray_ITEMSIZE(arr)!=elsize) - sprintf(mess+strlen(mess)," -- expected elsize=%d but got %d", + sprintf(mess+strlen(mess), + " -- expected elsize=%d but got %" NPY_INTP_FMT, elsize, - PyArray_ITEMSIZE(arr) + (npy_intp)PyArray_ITEMSIZE(arr) ); if (!(ARRAY_ISCOMPATIBLE(arr,type_num))) sprintf(mess+strlen(mess)," -- input '%c' not compatible to '%c'", - arr->descr->type,typechar); + PyArray_DESCR(arr)->type,typechar); if (!(F2PY_CHECK_ALIGNMENT(arr, intent))) sprintf(mess+strlen(mess)," -- input not %d-aligned", F2PY_GET_ALIGNMENT(intent)); PyErr_SetString(PyExc_ValueError,mess); @@ -717,7 +784,7 @@ PyArrayObject* array_from_pyobj(const int type_num, { PyArrayObject *retarr = (PyArrayObject *) \ - PyArray_New(&PyArray_Type, arr->nd, arr->dimensions, type_num, + PyArray_New(&PyArray_Type, PyArray_NDIM(arr), PyArray_DIMS(arr), type_num, NULL,NULL,0, !(intent&F2PY_INTENT_C), NULL); @@ -754,8 +821,8 @@ PyArrayObject* array_from_pyobj(const int type_num, F2PY_REPORT_ON_ARRAY_COPY_FROMANY; arr = (PyArrayObject *) \ PyArray_FromAny(obj,PyArray_DescrFromType(type_num), 0,0, - ((intent & F2PY_INTENT_C)?NPY_CARRAY:NPY_FARRAY) \ - | NPY_FORCECAST, NULL); + ((intent & F2PY_INTENT_C)?NPY_ARRAY_CARRAY:NPY_ARRAY_FARRAY) \ + | NPY_ARRAY_FORCECAST, NULL); if (arr==NULL) return NULL; if (check_and_fix_dimensions(arr,rank,dims)) @@ -776,20 +843,20 @@ int check_and_fix_dimensions(const PyArrayObject* arr,const int rank,npy_intp *d the dimensions from arr. It also checks that non-blank dims will match with the corresponding values in arr dimensions. */ - const npy_intp arr_size = (arr->nd)?PyArray_Size((PyObject *)arr):1; + const npy_intp arr_size = (PyArray_NDIM(arr))?PyArray_Size((PyObject *)arr):1; #ifdef DEBUG_COPY_ND_ARRAY dump_attrs(arr); printf("check_and_fix_dimensions:init: dims="); dump_dims(rank,dims); #endif - if (rank > arr->nd) { /* [1,2] -> [[1],[2]]; 1 -> [[1]] */ + if (rank > PyArray_NDIM(arr)) { /* [1,2] -> [[1],[2]]; 1 -> [[1]] */ npy_intp new_size = 1; int free_axe = -1; int i; npy_intp d; /* Fill dims where -1 or 0; check dimensions; calc new_size; */ - for(i=0;i<arr->nd;++i) { - d = arr->dimensions[i]; + for(i=0;i<PyArray_NDIM(arr);++i) { + d = PyArray_DIM(arr,i); if (dims[i] >= 0) { if (d>1 && dims[i]!=d) { fprintf(stderr,"%d-th dimension must be fixed to %" NPY_INTP_FMT @@ -803,7 +870,7 @@ int check_and_fix_dimensions(const PyArrayObject* arr,const int rank,npy_intp *d } new_size *= dims[i]; } - for(i=arr->nd;i<rank;++i) + for(i=PyArray_NDIM(arr);i<rank;++i) if (dims[i]>1) { fprintf(stderr,"%d-th dimension must be %" NPY_INTP_FMT " but got 0 (not defined).\n", @@ -823,12 +890,12 @@ int check_and_fix_dimensions(const PyArrayObject* arr,const int rank,npy_intp *d " indices)\n", new_size,arr_size); return 1; } - } else if (rank==arr->nd) { + } else if (rank==PyArray_NDIM(arr)) { npy_intp new_size = 1; int i; npy_intp d; for (i=0; i<rank; ++i) { - d = arr->dimensions[i]; + d = PyArray_DIM(arr,i); if (dims[i]>=0) { if (d > 1 && d!=dims[i]) { fprintf(stderr,"%d-th dimension must be fixed to %" NPY_INTP_FMT @@ -850,19 +917,19 @@ int check_and_fix_dimensions(const PyArrayObject* arr,const int rank,npy_intp *d npy_intp d; int effrank; npy_intp size; - for (i=0,effrank=0;i<arr->nd;++i) - if (arr->dimensions[i]>1) ++effrank; + for (i=0,effrank=0;i<PyArray_NDIM(arr);++i) + if (PyArray_DIM(arr,i)>1) ++effrank; if (dims[rank-1]>=0) if (effrank>rank) { fprintf(stderr,"too many axes: %d (effrank=%d), expected rank=%d\n", - arr->nd,effrank,rank); + PyArray_NDIM(arr),effrank,rank); return 1; } for (i=0,j=0;i<rank;++i) { - while (j<arr->nd && arr->dimensions[j]<2) ++j; - if (j>=arr->nd) d = 1; - else d = arr->dimensions[j++]; + while (j<PyArray_NDIM(arr) && PyArray_DIM(arr,j)<2) ++j; + if (j>=PyArray_NDIM(arr)) d = 1; + else d = PyArray_DIM(arr,j++); if (dims[i]>=0) { if (d>1 && d!=dims[i]) { fprintf(stderr,"%d-th dimension must be fixed to %" NPY_INTP_FMT @@ -875,20 +942,20 @@ int check_and_fix_dimensions(const PyArrayObject* arr,const int rank,npy_intp *d dims[i] = d; } - for (i=rank;i<arr->nd;++i) { /* [[1,2],[3,4]] -> [1,2,3,4] */ - while (j<arr->nd && arr->dimensions[j]<2) ++j; - if (j>=arr->nd) d = 1; - else d = arr->dimensions[j++]; + for (i=rank;i<PyArray_NDIM(arr);++i) { /* [[1,2],[3,4]] -> [1,2,3,4] */ + while (j<PyArray_NDIM(arr) && PyArray_DIM(arr,j)<2) ++j; + if (j>=PyArray_NDIM(arr)) d = 1; + else d = PyArray_DIM(arr,j++); dims[rank-1] *= d; } for (i=0,size=1;i<rank;++i) size *= dims[i]; if (size != arr_size) { fprintf(stderr,"unexpected array size: size=%" NPY_INTP_FMT ", arr_size=%" NPY_INTP_FMT ", rank=%d, effrank=%d, arr.nd=%d, dims=[", - size,arr_size,rank,effrank,arr->nd); + size,arr_size,rank,effrank,PyArray_NDIM(arr)); for (i=0;i<rank;++i) fprintf(stderr," %" NPY_INTP_FMT,dims[i]); fprintf(stderr," ], arr.dims=["); - for (i=0;i<arr->nd;++i) fprintf(stderr," %" NPY_INTP_FMT,arr->dimensions[i]); + for (i=0;i<PyArray_NDIM(arr);++i) fprintf(stderr," %" NPY_INTP_FMT,PyArray_DIM(arr,i)); fprintf(stderr," ]\n"); return 1; } @@ -969,4 +1036,6 @@ F2PyCapsule_Check(PyObject *ptr) #ifdef __cplusplus } #endif + +#undef NPY_NO_DEPRECATED_API /************************* EOF fortranobject.c *******************************/ diff --git a/numpy/f2py/src/fortranobject.h b/numpy/f2py/src/fortranobject.h index 689f78c92..c9b54e259 100644 --- a/numpy/f2py/src/fortranobject.h +++ b/numpy/f2py/src/fortranobject.h @@ -119,7 +119,7 @@ int F2PyCapsule_Check(PyObject *ptr); #endif -#define ISCONTIGUOUS(m) ((m)->flags & NPY_CONTIGUOUS) +#define ISCONTIGUOUS(m) (PyArray_FLAGS(m) & NPY_ARRAY_C_CONTIGUOUS) #define F2PY_INTENT_IN 1 #define F2PY_INTENT_INOUT 2 #define F2PY_INTENT_OUT 4 diff --git a/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c b/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c index 9a21f2420..2da6a2c5d 100644 --- a/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c +++ b/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c @@ -90,22 +90,22 @@ static PyObject *f2py_rout_wrap_attrs(PyObject *capi_self, &PyArray_Type,&arr_capi)) return NULL; arr = (PyArrayObject *)arr_capi; - sprintf(s,"%p",arr->data); - dimensions = PyTuple_New(arr->nd); - strides = PyTuple_New(arr->nd); - for (i=0;i<arr->nd;++i) { - PyTuple_SetItem(dimensions,i,PyInt_FromLong(arr->dimensions[i])); - PyTuple_SetItem(strides,i,PyInt_FromLong(arr->strides[i])); + sprintf(s,"%p",PyArray_DATA(arr)); + dimensions = PyTuple_New(PyArray_NDIM(arr)); + strides = PyTuple_New(PyArray_NDIM(arr)); + for (i=0;i<PyArray_NDIM(arr);++i) { + PyTuple_SetItem(dimensions,i,PyInt_FromLong(PyArray_DIM(arr,i))); + PyTuple_SetItem(strides,i,PyInt_FromLong(PyArray_STRIDE(arr,i))); } - return Py_BuildValue("siOOO(cciii)ii",s,arr->nd, + return Py_BuildValue("siOOO(cciii)ii",s,PyArray_NDIM(arr), dimensions,strides, - (arr->base==NULL?Py_None:arr->base), - arr->descr->kind, - arr->descr->type, - arr->descr->type_num, - arr->descr->elsize, - arr->descr->alignment, - arr->flags, + (PyArray_BASE(arr)==NULL?Py_None:PyArray_BASE(arr)), + PyArray_DESCR(arr)->kind, + PyArray_DESCR(arr)->type, + PyArray_TYPE(arr), + PyArray_ITEMSIZE(arr), + PyArray_DESCR(arr)->alignment, + PyArray_FLAGS(arr), PyArray_ITEMSIZE(arr)); } @@ -190,24 +190,24 @@ PyMODINIT_FUNC inittest_array_from_pyobj_ext(void) { PyDict_SetItemString(d, "NPY_NOTYPE", PyInt_FromLong(NPY_NOTYPE)); PyDict_SetItemString(d, "NPY_USERDEF", PyInt_FromLong(NPY_USERDEF)); - PyDict_SetItemString(d, "CONTIGUOUS", PyInt_FromLong(NPY_CONTIGUOUS)); - PyDict_SetItemString(d, "FORTRAN", PyInt_FromLong(NPY_FORTRAN)); - PyDict_SetItemString(d, "OWNDATA", PyInt_FromLong(NPY_OWNDATA)); - PyDict_SetItemString(d, "FORCECAST", PyInt_FromLong(NPY_FORCECAST)); - PyDict_SetItemString(d, "ENSURECOPY", PyInt_FromLong(NPY_ENSURECOPY)); - PyDict_SetItemString(d, "ENSUREARRAY", PyInt_FromLong(NPY_ENSUREARRAY)); - PyDict_SetItemString(d, "ALIGNED", PyInt_FromLong(NPY_ALIGNED)); - PyDict_SetItemString(d, "WRITEABLE", PyInt_FromLong(NPY_WRITEABLE)); - PyDict_SetItemString(d, "UPDATEIFCOPY", PyInt_FromLong(NPY_UPDATEIFCOPY)); + PyDict_SetItemString(d, "CONTIGUOUS", PyInt_FromLong(NPY_ARRAY_C_CONTIGUOUS)); + PyDict_SetItemString(d, "FORTRAN", PyInt_FromLong(NPY_ARRAY_F_CONTIGUOUS)); + PyDict_SetItemString(d, "OWNDATA", PyInt_FromLong(NPY_ARRAY_OWNDATA)); + PyDict_SetItemString(d, "FORCECAST", PyInt_FromLong(NPY_ARRAY_FORCECAST)); + PyDict_SetItemString(d, "ENSURECOPY", PyInt_FromLong(NPY_ARRAY_ENSURECOPY)); + PyDict_SetItemString(d, "ENSUREARRAY", PyInt_FromLong(NPY_ARRAY_ENSUREARRAY)); + PyDict_SetItemString(d, "ALIGNED", PyInt_FromLong(NPY_ARRAY_ALIGNED)); + PyDict_SetItemString(d, "WRITEABLE", PyInt_FromLong(NPY_ARRAY_WRITEABLE)); + PyDict_SetItemString(d, "UPDATEIFCOPY", PyInt_FromLong(NPY_ARRAY_UPDATEIFCOPY)); - PyDict_SetItemString(d, "BEHAVED", PyInt_FromLong(NPY_BEHAVED)); - PyDict_SetItemString(d, "BEHAVED_NS", PyInt_FromLong(NPY_BEHAVED_NS)); - PyDict_SetItemString(d, "CARRAY", PyInt_FromLong(NPY_CARRAY)); - PyDict_SetItemString(d, "FARRAY", PyInt_FromLong(NPY_FARRAY)); - PyDict_SetItemString(d, "CARRAY_RO", PyInt_FromLong(NPY_CARRAY_RO)); - PyDict_SetItemString(d, "FARRAY_RO", PyInt_FromLong(NPY_FARRAY_RO)); - PyDict_SetItemString(d, "DEFAULT", PyInt_FromLong(NPY_DEFAULT)); - PyDict_SetItemString(d, "UPDATE_ALL", PyInt_FromLong(NPY_UPDATE_ALL)); + PyDict_SetItemString(d, "BEHAVED", PyInt_FromLong(NPY_ARRAY_BEHAVED)); + PyDict_SetItemString(d, "BEHAVED_NS", PyInt_FromLong(NPY_ARRAY_BEHAVED_NS)); + PyDict_SetItemString(d, "CARRAY", PyInt_FromLong(NPY_ARRAY_CARRAY)); + PyDict_SetItemString(d, "FARRAY", PyInt_FromLong(NPY_ARRAY_FARRAY)); + PyDict_SetItemString(d, "CARRAY_RO", PyInt_FromLong(NPY_ARRAY_CARRAY_RO)); + PyDict_SetItemString(d, "FARRAY_RO", PyInt_FromLong(NPY_ARRAY_FARRAY_RO)); + PyDict_SetItemString(d, "DEFAULT", PyInt_FromLong(NPY_ARRAY_DEFAULT)); + PyDict_SetItemString(d, "UPDATE_ALL", PyInt_FromLong(NPY_ARRAY_UPDATE_ALL)); if (PyErr_Occurred()) Py_FatalError("can't initialize module wrap"); diff --git a/numpy/f2py/tests/src/regression/inout.f90 b/numpy/f2py/tests/src/regression/inout.f90 new file mode 100644 index 000000000..80cdad90c --- /dev/null +++ b/numpy/f2py/tests/src/regression/inout.f90 @@ -0,0 +1,9 @@ +! Check that intent(in out) translates as intent(inout). +! The separation seems to be a common usage. + subroutine foo(x) + implicit none + real(4), intent(in out) :: x + dimension x(3) + x(1) = x(1) + x(2) + x(3) + return + end diff --git a/numpy/f2py/tests/test_array_from_pyobj.py b/numpy/f2py/tests/test_array_from_pyobj.py index 3a148e72c..c51fa3936 100644 --- a/numpy/f2py/tests/test_array_from_pyobj.py +++ b/numpy/f2py/tests/test_array_from_pyobj.py @@ -4,11 +4,13 @@ import unittest import os import sys import copy +import platform import nose from numpy.testing import * -from numpy import array, alltrue, ndarray, asarray, can_cast, zeros, dtype +from numpy import (array, alltrue, ndarray, asarray, can_cast, zeros, dtype, + intp, clongdouble) from numpy.core.multiarray import typeinfo import util @@ -81,37 +83,46 @@ class Intent(object): intent = Intent() -class Type(object): - _type_names = ['BOOL', 'BYTE', 'UBYTE', 'SHORT', 'USHORT', 'INT', 'UINT', - 'LONG', 'ULONG', 'LONGLONG', 'ULONGLONG', - 'FLOAT', 'DOUBLE', 'LONGDOUBLE', 'CFLOAT', 'CDOUBLE', - 'CLONGDOUBLE'] - _type_cache = {} - - _cast_dict = {'BOOL':['BOOL']} - _cast_dict['BYTE'] = _cast_dict['BOOL'] + ['BYTE'] - _cast_dict['UBYTE'] = _cast_dict['BOOL'] + ['UBYTE'] - _cast_dict['BYTE'] = ['BYTE'] - _cast_dict['UBYTE'] = ['UBYTE'] - _cast_dict['SHORT'] = _cast_dict['BYTE'] + ['UBYTE', 'SHORT'] - _cast_dict['USHORT'] = _cast_dict['UBYTE'] + ['BYTE', 'USHORT'] - _cast_dict['INT'] = _cast_dict['SHORT'] + ['USHORT', 'INT'] - _cast_dict['UINT'] = _cast_dict['USHORT'] + ['SHORT', 'UINT'] - - _cast_dict['LONG'] = _cast_dict['INT'] + ['LONG'] - _cast_dict['ULONG'] = _cast_dict['UINT'] + ['ULONG'] - - _cast_dict['LONGLONG'] = _cast_dict['LONG'] + ['LONGLONG'] - _cast_dict['ULONGLONG'] = _cast_dict['ULONG'] + ['ULONGLONG'] - - _cast_dict['FLOAT'] = _cast_dict['SHORT'] + ['USHORT', 'FLOAT'] - _cast_dict['DOUBLE'] = _cast_dict['INT'] + ['UINT', 'FLOAT', 'DOUBLE'] - _cast_dict['LONGDOUBLE'] = _cast_dict['LONG'] + ['ULONG', 'FLOAT', 'DOUBLE', 'LONGDOUBLE'] - - _cast_dict['CFLOAT'] = _cast_dict['FLOAT'] + ['CFLOAT'] +_type_names = ['BOOL', 'BYTE', 'UBYTE', 'SHORT', 'USHORT', 'INT', 'UINT', + 'LONG', 'ULONG', 'LONGLONG', 'ULONGLONG', + 'FLOAT', 'DOUBLE', 'CFLOAT'] + +_cast_dict = {'BOOL':['BOOL']} +_cast_dict['BYTE'] = _cast_dict['BOOL'] + ['BYTE'] +_cast_dict['UBYTE'] = _cast_dict['BOOL'] + ['UBYTE'] +_cast_dict['BYTE'] = ['BYTE'] +_cast_dict['UBYTE'] = ['UBYTE'] +_cast_dict['SHORT'] = _cast_dict['BYTE'] + ['UBYTE', 'SHORT'] +_cast_dict['USHORT'] = _cast_dict['UBYTE'] + ['BYTE', 'USHORT'] +_cast_dict['INT'] = _cast_dict['SHORT'] + ['USHORT', 'INT'] +_cast_dict['UINT'] = _cast_dict['USHORT'] + ['SHORT', 'UINT'] + +_cast_dict['LONG'] = _cast_dict['INT'] + ['LONG'] +_cast_dict['ULONG'] = _cast_dict['UINT'] + ['ULONG'] + +_cast_dict['LONGLONG'] = _cast_dict['LONG'] + ['LONGLONG'] +_cast_dict['ULONGLONG'] = _cast_dict['ULONG'] + ['ULONGLONG'] + +_cast_dict['FLOAT'] = _cast_dict['SHORT'] + ['USHORT', 'FLOAT'] +_cast_dict['DOUBLE'] = _cast_dict['INT'] + ['UINT', 'FLOAT', 'DOUBLE'] + +_cast_dict['CFLOAT'] = _cast_dict['FLOAT'] + ['CFLOAT'] + +# 32 bit system malloc typically does not provide the alignment required by +# 16 byte long double types this means the inout intent cannot be satisfied and +# several tests fail as the alignment flag can be randomly true or fals +# when numpy gains an aligned allocator the tests could be enabled again +if ((intp().dtype.itemsize != 4 or clongdouble().dtype.alignment <= 8) and + sys.platform != 'win32'): + _type_names.extend(['LONGDOUBLE', 'CDOUBLE', 'CLONGDOUBLE']) + _cast_dict['LONGDOUBLE'] = _cast_dict['LONG'] + \ + ['ULONG', 'FLOAT', 'DOUBLE', 'LONGDOUBLE'] + _cast_dict['CLONGDOUBLE'] = _cast_dict['LONGDOUBLE'] + \ + ['CFLOAT', 'CDOUBLE', 'CLONGDOUBLE'] _cast_dict['CDOUBLE'] = _cast_dict['DOUBLE'] + ['CFLOAT', 'CDOUBLE'] - _cast_dict['CLONGDOUBLE'] = _cast_dict['LONGDOUBLE'] + ['CFLOAT', 'CDOUBLE', 'CLONGDOUBLE'] +class Type(object): + _type_cache = {} def __new__(cls, name): if isinstance(name, dtype): @@ -138,15 +149,15 @@ class Type(object): self.dtypechar = typeinfo[self.NAME][0] def cast_types(self): - return [self.__class__(_m) for _m in self._cast_dict[self.NAME]] + return [self.__class__(_m) for _m in _cast_dict[self.NAME]] def all_types(self): - return [self.__class__(_m) for _m in self._type_names] + return [self.__class__(_m) for _m in _type_names] def smaller_types(self): bits = typeinfo[self.NAME][3] types = [] - for name in self._type_names: + for name in _type_names: if typeinfo[name][3]<bits: types.append(Type(name)) return types @@ -154,7 +165,7 @@ class Type(object): def equal_types(self): bits = typeinfo[self.NAME][3] types = [] - for name in self._type_names: + for name in _type_names: if name==self.NAME: continue if typeinfo[name][3]==bits: types.append(Type(name)) @@ -163,7 +174,7 @@ class Type(object): def larger_types(self): bits = typeinfo[self.NAME][3] types = [] - for name in self._type_names: + for name in _type_names: if typeinfo[name][3]>bits: types.append(Type(name)) return types @@ -532,7 +543,7 @@ class _test_shared_memory: assert_(obj.dtype.type is self.type.dtype) # obj type is changed inplace! -for t in Type._type_names: +for t in _type_names: exec('''\ class test_%s_gen(unittest.TestCase, _test_shared_memory diff --git a/numpy/f2py/tests/test_regression.py b/numpy/f2py/tests/test_regression.py new file mode 100644 index 000000000..9bd3f3fe3 --- /dev/null +++ b/numpy/f2py/tests/test_regression.py @@ -0,0 +1,32 @@ +from __future__ import division, absolute_import, print_function + +import os +import math + +import numpy as np +from numpy.testing import dec, assert_raises, assert_equal + +import util + +def _path(*a): + return os.path.join(*((os.path.dirname(__file__),) + a)) + +class TestIntentInOut(util.F2PyTest): + # Check that intent(in out) translates as intent(inout) + sources = [_path('src', 'regression', 'inout.f90')] + + @dec.slow + def test_inout(self): + # non-contiguous should raise error + x = np.arange(6, dtype=np.float32)[::2] + assert_raises(ValueError, self.module.foo, x) + + # check values with contiguous array + x = np.arange(3, dtype=np.float32) + self.module.foo(x) + assert_equal(x, [3, 1, 2]) + + +if __name__ == "__main__": + import nose + nose.runmodule() |