summaryrefslogtreecommitdiff
path: root/numpy/f2py
diff options
context:
space:
mode:
Diffstat (limited to 'numpy/f2py')
-rw-r--r--numpy/f2py/__init__.py1
-rw-r--r--numpy/f2py/capi_maps.py28
-rw-r--r--numpy/f2py/cfuncs.py25
-rw-r--r--numpy/f2py/common_rules.py5
-rwxr-xr-xnumpy/f2py/f2py2e.py15
-rw-r--r--numpy/f2py/info.py6
-rwxr-xr-xnumpy/f2py/rules.py37
-rw-r--r--numpy/f2py/setup.py2
-rw-r--r--numpy/f2py/src/fortranobject.c37
-rw-r--r--numpy/f2py/src/test/foomodule.c18
-rw-r--r--numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c139
-rw-r--r--numpy/f2py/tests/test_assumed_shape.py22
-rw-r--r--numpy/f2py/tests/test_compile_function.py4
-rw-r--r--numpy/f2py/tests/util.py37
14 files changed, 251 insertions, 125 deletions
diff --git a/numpy/f2py/__init__.py b/numpy/f2py/__init__.py
index d146739bb..42e3632fd 100644
--- a/numpy/f2py/__init__.py
+++ b/numpy/f2py/__init__.py
@@ -109,6 +109,7 @@ def compile(source,
output = ''
else:
status = 0
+ output = output.decode()
if verbose:
print(output)
finally:
diff --git a/numpy/f2py/capi_maps.py b/numpy/f2py/capi_maps.py
index c41dd77c6..ce79f680f 100644
--- a/numpy/f2py/capi_maps.py
+++ b/numpy/f2py/capi_maps.py
@@ -179,17 +179,29 @@ f2cmap_all = {'real': {'': 'float', '4': 'float', '8': 'double',
'character': {'': 'string'}
}
-if os.path.isfile('.f2py_f2cmap'):
+f2cmap_default = copy.deepcopy(f2cmap_all)
+
+
+def load_f2cmap_file(f2cmap_file):
+ global f2cmap_all
+
+ f2cmap_all = copy.deepcopy(f2cmap_default)
+
+ if f2cmap_file is None:
+ # Default value
+ f2cmap_file = '.f2py_f2cmap'
+ if not os.path.isfile(f2cmap_file):
+ return
+
# User defined additions to f2cmap_all.
- # .f2py_f2cmap must contain a dictionary of dictionaries, only. For
+ # f2cmap_file must contain a dictionary of dictionaries, only. For
# example, {'real':{'low':'float'}} means that Fortran 'real(low)' is
# interpreted as C 'float'. This feature is useful for F90/95 users if
# they use PARAMETERSs in type specifications.
try:
- outmess('Reading .f2py_f2cmap ...\n')
- f = open('.f2py_f2cmap', 'r')
- d = eval(f.read(), {}, {})
- f.close()
+ outmess('Reading f2cmap from {!r} ...\n'.format(f2cmap_file))
+ with open(f2cmap_file, 'r') as f:
+ d = eval(f.read(), {}, {})
for k, d1 in list(d.items()):
for k1 in list(d1.keys()):
d1[k1.lower()] = d1[k1]
@@ -208,10 +220,10 @@ if os.path.isfile('.f2py_f2cmap'):
else:
errmess("\tIgnoring map {'%s':{'%s':'%s'}}: '%s' must be in %s\n" % (
k, k1, d[k][k1], d[k][k1], list(c2py_map.keys())))
- outmess('Successfully applied user defined changes from .f2py_f2cmap\n')
+ outmess('Successfully applied user defined f2cmap changes\n')
except Exception as msg:
errmess(
- 'Failed to apply user defined changes from .f2py_f2cmap: %s. Skipping.\n' % (msg))
+ 'Failed to apply user defined f2cmap changes: %s. Skipping.\n' % (msg))
cformat_map = {'double': '%g',
'float': '%g',
diff --git a/numpy/f2py/cfuncs.py b/numpy/f2py/cfuncs.py
index d59b6301c..ccb7b3a32 100644
--- a/numpy/f2py/cfuncs.py
+++ b/numpy/f2py/cfuncs.py
@@ -542,7 +542,7 @@ cppmacros[
'ARRSIZE'] = '#define ARRSIZE(dims,rank) (_PyArray_multiply_list(dims,rank))'
cppmacros['OLDPYNUM'] = """\
#ifdef OLDPYNUM
-#error You need to install Numeric Python version 13 or higher. Get it from http:/sourceforge.net/project/?group_id=1369
+#error You need to install NumPy version 13 or higher. See https://scipy.org/install.html
#endif
"""
################# C functions ###############
@@ -1049,8 +1049,10 @@ static int create_cb_arglist(PyObject* fun,PyTupleObject* xa,const int maxnofarg
CFUNCSMESS(\"create_cb_arglist\\n\");
tot=opt=ext=siz=0;
/* Get the total number of arguments */
- if (PyFunction_Check(fun))
+ if (PyFunction_Check(fun)) {
tmp_fun = fun;
+ Py_INCREF(tmp_fun);
+ }
else {
di = 1;
if (PyObject_HasAttrString(fun,\"im_func\")) {
@@ -1062,6 +1064,7 @@ static int create_cb_arglist(PyObject* fun,PyTupleObject* xa,const int maxnofarg
tmp_fun = PyObject_GetAttrString(tmp,\"im_func\");
else {
tmp_fun = fun; /* built-in function */
+ Py_INCREF(tmp_fun);
tot = maxnofargs;
if (xa != NULL)
tot += PyTuple_Size((PyObject *)xa);
@@ -1073,6 +1076,7 @@ static int create_cb_arglist(PyObject* fun,PyTupleObject* xa,const int maxnofarg
if (xa != NULL)
tot += PyTuple_Size((PyObject *)xa);
tmp_fun = fun;
+ Py_INCREF(tmp_fun);
}
else if (F2PyCapsule_Check(fun)) {
tot = maxnofargs;
@@ -1083,6 +1087,7 @@ static int create_cb_arglist(PyObject* fun,PyTupleObject* xa,const int maxnofarg
goto capi_fail;
}
tmp_fun = fun;
+ Py_INCREF(tmp_fun);
}
}
if (tmp_fun==NULL) {
@@ -1091,13 +1096,19 @@ goto capi_fail;
}
#if PY_VERSION_HEX >= 0x03000000
if (PyObject_HasAttrString(tmp_fun,\"__code__\")) {
- if (PyObject_HasAttrString(tmp = PyObject_GetAttrString(tmp_fun,\"__code__\"),\"co_argcount\"))
+ if (PyObject_HasAttrString(tmp = PyObject_GetAttrString(tmp_fun,\"__code__\"),\"co_argcount\")) {
#else
if (PyObject_HasAttrString(tmp_fun,\"func_code\")) {
- if (PyObject_HasAttrString(tmp = PyObject_GetAttrString(tmp_fun,\"func_code\"),\"co_argcount\"))
+ if (PyObject_HasAttrString(tmp = PyObject_GetAttrString(tmp_fun,\"func_code\"),\"co_argcount\")) {
#endif
- tot = PyInt_AsLong(PyObject_GetAttrString(tmp,\"co_argcount\")) - di;
- Py_XDECREF(tmp);
+ PyObject *tmp_argcount = PyObject_GetAttrString(tmp,\"co_argcount\");
+ Py_DECREF(tmp);
+ if (tmp_argcount == NULL) {
+ goto capi_fail;
+ }
+ tot = PyInt_AsLong(tmp_argcount) - di;
+ Py_DECREF(tmp_argcount);
+ }
}
/* Get the number of optional arguments */
#if PY_VERSION_HEX >= 0x03000000
@@ -1136,10 +1147,12 @@ goto capi_fail;
PyTuple_SET_ITEM(*args,i,tmp);
}
CFUNCSMESS(\"create_cb_arglist-end\\n\");
+ Py_DECREF(tmp_fun);
return 1;
capi_fail:
if ((PyErr_Occurred())==NULL)
PyErr_SetString(#modulename#_error,errmess);
+ Py_XDECREF(tmp_fun);
return 0;
}
"""
diff --git a/numpy/f2py/common_rules.py b/numpy/f2py/common_rules.py
index 62c1ba207..f61d8810a 100644
--- a/numpy/f2py/common_rules.py
+++ b/numpy/f2py/common_rules.py
@@ -124,8 +124,9 @@ def buildhooks(m):
cadd('\t%s(f2pyinit%s,F2PYINIT%s)(f2py_setup_%s);'
% (F_FUNC, lower_name, name.upper(), name))
cadd('}\n')
- iadd('\tF2PyDict_SetItemString(d, \"%s\", PyFortranObject_New(f2py_%s_def,f2py_init_%s));' % (
- name, name, name))
+ iadd('\ttmp = PyFortranObject_New(f2py_%s_def,f2py_init_%s);' % (name, name))
+ iadd('\tF2PyDict_SetItemString(d, \"%s\", tmp);' % name)
+ iadd('\tPy_DECREF(tmp);')
tname = name.replace('_', '\\_')
dadd('\\subsection{Common block \\texttt{%s}}\n' % (tname))
dadd('\\begin{description}')
diff --git a/numpy/f2py/f2py2e.py b/numpy/f2py/f2py2e.py
index 110337f92..d03eff9e3 100755
--- a/numpy/f2py/f2py2e.py
+++ b/numpy/f2py/f2py2e.py
@@ -28,6 +28,7 @@ from . import auxfuncs
from . import cfuncs
from . import f90mod_rules
from . import __version__
+from . import capi_maps
f2py_version = __version__.version
errmess = sys.stderr.write
@@ -118,6 +119,9 @@ Options:
--link-<resource> switch below. [..] is optional list
of resources names. E.g. try 'f2py --help-link lapack_opt'.
+ --f2cmap <filename> Load Fortran-to-Python KIND specification from the given
+ file. Default: .f2py_f2cmap in current directory.
+
--quiet Run quietly.
--verbose Run with extra verbosity.
-v Print f2py version ID and exit.
@@ -175,7 +179,7 @@ http://cens.ioc.ee/projects/f2py2e/""" % (f2py_version, numpy_version)
def scaninputline(inputline):
files, skipfuncs, onlyfuncs, debug = [], [], [], []
- f, f2, f3, f5, f6, f7, f8, f9 = 1, 0, 0, 0, 0, 0, 0, 0
+ f, f2, f3, f5, f6, f7, f8, f9, f10 = 1, 0, 0, 0, 0, 0, 0, 0, 0
verbose = 1
dolc = -1
dolatexdoc = 0
@@ -226,6 +230,8 @@ def scaninputline(inputline):
f8 = 1
elif l == '--f2py-wrapper-output':
f9 = 1
+ elif l == '--f2cmap':
+ f10 = 1
elif l == '--overwrite-signature':
options['h-overwrite'] = 1
elif l == '-h':
@@ -267,6 +273,9 @@ def scaninputline(inputline):
elif f9:
f9 = 0
options["f2py_wrapper_output"] = l
+ elif f10:
+ f10 = 0
+ options["f2cmap_file"] = l
elif f == 1:
try:
with open(l):
@@ -312,6 +321,7 @@ def scaninputline(inputline):
options['wrapfuncs'] = wrapfuncs
options['buildpath'] = buildpath
options['include_paths'] = include_paths
+ options.setdefault('f2cmap_file', None)
return files, options
@@ -422,6 +432,7 @@ def run_main(comline_list):
fobjcsrc = os.path.join(f2pydir, 'src', 'fortranobject.c')
files, options = scaninputline(comline_list)
auxfuncs.options = options
+ capi_maps.load_f2cmap_file(options['f2cmap_file'])
postlist = callcrackfortran(files, options)
isusedby = {}
for i in range(len(postlist)):
@@ -574,7 +585,7 @@ def run_compile():
modulename = 'untitled'
sources = sys.argv[1:]
- for optname in ['--include_paths', '--include-paths']:
+ for optname in ['--include_paths', '--include-paths', '--f2cmap']:
if optname in sys.argv:
i = sys.argv.index(optname)
f2py_flags.extend(sys.argv[i:i + 2])
diff --git a/numpy/f2py/info.py b/numpy/f2py/info.py
deleted file mode 100644
index c895c5de2..000000000
--- a/numpy/f2py/info.py
+++ /dev/null
@@ -1,6 +0,0 @@
-"""Fortran to Python Interface Generator.
-
-"""
-from __future__ import division, absolute_import, print_function
-
-postpone_import = True
diff --git a/numpy/f2py/rules.py b/numpy/f2py/rules.py
index 1b41498ea..f2f713bde 100755
--- a/numpy/f2py/rules.py
+++ b/numpy/f2py/rules.py
@@ -215,6 +215,7 @@ PyMODINIT_FUNC init#modulename#(void) {
\td = PyModule_GetDict(m);
\ts = PyString_FromString(\"$R""" + """evision: $\");
\tPyDict_SetItemString(d, \"__version__\", s);
+\tPy_DECREF(s);
#if PY_VERSION_HEX >= 0x03000000
\ts = PyUnicode_FromString(
#else
@@ -222,8 +223,14 @@ PyMODINIT_FUNC init#modulename#(void) {
#endif
\t\t\"This module '#modulename#' is auto-generated with f2py (version:#f2py_version#).\\nFunctions:\\n\"\n#docs#\".\");
\tPyDict_SetItemString(d, \"__doc__\", s);
-\t#modulename#_error = PyErr_NewException (\"#modulename#.error\", NULL, NULL);
\tPy_DECREF(s);
+\t#modulename#_error = PyErr_NewException (\"#modulename#.error\", NULL, NULL);
+\t/*
+\t * Store the error object inside the dict, so that it could get deallocated.
+\t * (in practice, this is a module, so it likely will not and cannot.)
+\t */
+\tPyDict_SetItemString(d, \"_#modulename#_error\", #modulename#_error);
+\tPy_DECREF(#modulename#_error);
\tfor(i=0;f2py_routine_defs[i].name!=NULL;i++) {
\t\ttmp = PyFortranObject_NewAsAttr(&f2py_routine_defs[i]);
\t\tPyDict_SetItemString(d, f2py_routine_defs[i].name, tmp);
@@ -238,7 +245,6 @@ PyMODINIT_FUNC init#modulename#(void) {
\tif (! PyErr_Occurred())
\t\ton_exit(f2py_report_on_exit,(void*)\"#modulename#\");
#endif
-
\treturn RETVAL;
}
#ifdef __cplusplus
@@ -439,12 +445,16 @@ rout_rules = [
{
extern #ctype# #F_FUNC#(#name_lower#,#NAME#)(void);
PyObject* o = PyDict_GetItemString(d,"#name#");
- PyObject_SetAttrString(o,"_cpointer", F2PyCapsule_FromVoidPtr((void*)#F_FUNC#(#name_lower#,#NAME#),NULL));
+ tmp = F2PyCapsule_FromVoidPtr((void*)#F_FUNC#(#name_lower#,#NAME#),NULL);
+ PyObject_SetAttrString(o,"_cpointer", tmp);
+ Py_DECREF(tmp);
#if PY_VERSION_HEX >= 0x03000000
- PyObject_SetAttrString(o,"__name__", PyUnicode_FromString("#name#"));
+ s = PyUnicode_FromString("#name#");
#else
- PyObject_SetAttrString(o,"__name__", PyString_FromString("#name#"));
+ s = PyString_FromString("#name#");
#endif
+ PyObject_SetAttrString(o,"__name__", s);
+ Py_DECREF(s);
}
'''},
'need': {l_not(l_or(ismoduleroutine, isdummyroutine)): ['F_WRAPPEDFUNC', 'F_FUNC']},
@@ -477,12 +487,16 @@ rout_rules = [
{
extern void #F_FUNC#(#name_lower#,#NAME#)(void);
PyObject* o = PyDict_GetItemString(d,"#name#");
- PyObject_SetAttrString(o,"_cpointer", F2PyCapsule_FromVoidPtr((void*)#F_FUNC#(#name_lower#,#NAME#),NULL));
+ tmp = F2PyCapsule_FromVoidPtr((void*)#F_FUNC#(#name_lower#,#NAME#),NULL);
+ PyObject_SetAttrString(o,"_cpointer", tmp);
+ Py_DECREF(tmp);
#if PY_VERSION_HEX >= 0x03000000
- PyObject_SetAttrString(o,"__name__", PyUnicode_FromString("#name#"));
+ s = PyUnicode_FromString("#name#");
#else
- PyObject_SetAttrString(o,"__name__", PyString_FromString("#name#"));
+ s = PyString_FromString("#name#");
#endif
+ PyObject_SetAttrString(o,"__name__", s);
+ Py_DECREF(s);
}
'''},
'need': {l_not(l_or(ismoduleroutine, isdummyroutine)): ['F_WRAPPEDFUNC', 'F_FUNC']},
@@ -794,10 +808,13 @@ if (#varname#_capi==Py_None) {
if (#varname#_xa_capi==NULL) {
if (PyObject_HasAttrString(#modulename#_module,\"#varname#_extra_args\")) {
PyObject* capi_tmp = PyObject_GetAttrString(#modulename#_module,\"#varname#_extra_args\");
- if (capi_tmp)
+ if (capi_tmp) {
#varname#_xa_capi = (PyTupleObject *)PySequence_Tuple(capi_tmp);
- else
+ Py_DECREF(capi_tmp);
+ }
+ else {
#varname#_xa_capi = (PyTupleObject *)Py_BuildValue(\"()\");
+ }
if (#varname#_xa_capi==NULL) {
PyErr_SetString(#modulename#_error,\"Failed to convert #modulename#.#varname#_extra_args to tuple.\\n\");
return NULL;
diff --git a/numpy/f2py/setup.py b/numpy/f2py/setup.py
index c0c50ce54..a8c1401aa 100644
--- a/numpy/f2py/setup.py
+++ b/numpy/f2py/setup.py
@@ -3,7 +3,7 @@
setup.py for installing F2PY
Usage:
- python setup.py install
+ pip install .
Copyright 2001-2005 Pearu Peterson all rights reserved,
Pearu Peterson <pearu@cens.ioc.ee>
diff --git a/numpy/f2py/src/fortranobject.c b/numpy/f2py/src/fortranobject.c
index b55385b50..8aa55555d 100644
--- a/numpy/f2py/src/fortranobject.c
+++ b/numpy/f2py/src/fortranobject.c
@@ -39,19 +39,33 @@ PyFortranObject_New(FortranDataDef* defs, f2py_void_func init) {
int i;
PyFortranObject *fp = NULL;
PyObject *v = NULL;
- if (init!=NULL) /* Initialize F90 module objects */
+ if (init!=NULL) { /* Initialize F90 module objects */
(*(init))();
- if ((fp = PyObject_New(PyFortranObject, &PyFortran_Type))==NULL) return NULL;
- if ((fp->dict = PyDict_New())==NULL) return NULL;
+ }
+ fp = PyObject_New(PyFortranObject, &PyFortran_Type);
+ if (fp == NULL) {
+ return NULL;
+ }
+ if ((fp->dict = PyDict_New()) == NULL) {
+ Py_DECREF(fp);
+ return NULL;
+ }
fp->len = 0;
- while (defs[fp->len].name != NULL) fp->len++;
- if (fp->len == 0) goto fail;
+ while (defs[fp->len].name != NULL) {
+ fp->len++;
+ }
+ if (fp->len == 0) {
+ goto fail;
+ }
fp->defs = defs;
- for (i=0;i<fp->len;i++)
+ for (i=0;i<fp->len;i++) {
if (fp->defs[i].rank == -1) { /* Is Fortran routine */
v = PyFortranObject_NewAsAttr(&(fp->defs[i]));
- if (v==NULL) return NULL;
+ if (v==NULL) {
+ goto fail;
+ }
PyDict_SetItemString(fp->dict,fp->defs[i].name,v);
+ Py_XDECREF(v);
} else
if ((fp->defs[i].data)!=NULL) { /* Is Fortran variable or array (not allocatable) */
if (fp->defs[i].type == NPY_STRING) {
@@ -65,13 +79,16 @@ PyFortranObject_New(FortranDataDef* defs, f2py_void_func init) {
fp->defs[i].type, NULL, fp->defs[i].data, 0, NPY_ARRAY_FARRAY,
NULL);
}
- if (v==NULL) return NULL;
+ if (v==NULL) {
+ goto fail;
+ }
PyDict_SetItemString(fp->dict,fp->defs[i].name,v);
+ Py_XDECREF(v);
}
- Py_XDECREF(v);
+ }
return (PyObject *)fp;
fail:
- Py_XDECREF(v);
+ Py_XDECREF(fp);
return NULL;
}
diff --git a/numpy/f2py/src/test/foomodule.c b/numpy/f2py/src/test/foomodule.c
index 733fab0be..caf3590d4 100644
--- a/numpy/f2py/src/test/foomodule.c
+++ b/numpy/f2py/src/test/foomodule.c
@@ -115,7 +115,7 @@ static PyMethodDef foo_module_methods[] = {
void initfoo() {
int i;
- PyObject *m, *d, *s;
+ PyObject *m, *d, *s, *tmp;
import_array();
m = Py_InitModule("foo", foo_module_methods);
@@ -125,11 +125,17 @@ void initfoo() {
PyDict_SetItemString(d, "__doc__", s);
/* Fortran objects: */
- PyDict_SetItemString(d, "mod", PyFortranObject_New(f2py_mod_def,f2py_init_mod));
- PyDict_SetItemString(d, "foodata", PyFortranObject_New(f2py_foodata_def,f2py_init_foodata));
- for(i=0;f2py_routines_def[i].name!=NULL;i++)
- PyDict_SetItemString(d, f2py_routines_def[i].name,
- PyFortranObject_NewAsAttr(&f2py_routines_def[i]));
+ tmp = PyFortranObject_New(f2py_mod_def,f2py_init_mod);
+ PyDict_SetItemString(d, "mod", tmp);
+ Py_DECREF(tmp);
+ tmp = PyFortranObject_New(f2py_foodata_def,f2py_init_foodata);
+ PyDict_SetItemString(d, "foodata", tmp);
+ Py_DECREF(tmp);
+ for(i=0;f2py_routines_def[i].name!=NULL;i++) {
+ tmp = PyFortranObject_NewAsAttr(&f2py_routines_def[i]);
+ PyDict_SetItemString(d, f2py_routines_def[i].name, tmp);
+ Py_DECREF(tmp);
+ }
Py_DECREF(s);
diff --git a/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c b/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c
index 7f46303b0..978db4e69 100644
--- a/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c
+++ b/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c
@@ -49,9 +49,18 @@ static PyObject *f2py_rout_wrap_call(PyObject *capi_self,
return NULL;
rank = PySequence_Length(dims_capi);
dims = malloc(rank*sizeof(npy_intp));
- for (i=0;i<rank;++i)
- dims[i] = (npy_intp)PyInt_AsLong(PySequence_GetItem(dims_capi,i));
-
+ for (i=0;i<rank;++i) {
+ PyObject *tmp;
+ tmp = PySequence_GetItem(dims_capi, i);
+ if (tmp == NULL) {
+ goto fail;
+ }
+ dims[i] = (npy_intp)PyInt_AsLong(tmp);
+ Py_DECREF(tmp);
+ if (dims[i] == -1 && PyErr_Occurred()) {
+ goto fail;
+ }
+ }
capi_arr_tmp = array_from_pyobj(type_num,dims,rank,intent|F2PY_INTENT_OUT,arr_capi);
if (capi_arr_tmp == NULL) {
free(dims);
@@ -60,6 +69,10 @@ static PyObject *f2py_rout_wrap_call(PyObject *capi_self,
capi_buildvalue = Py_BuildValue("N",capi_arr_tmp);
free(dims);
return capi_buildvalue;
+
+fail:
+ free(dims);
+ return NULL;
}
static char doc_f2py_rout_wrap_attrs[] = "\
@@ -97,7 +110,7 @@ static PyObject *f2py_rout_wrap_attrs(PyObject *capi_self,
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,PyArray_NDIM(arr),
+ return Py_BuildValue("siNNO(cciii)ii",s,PyArray_NDIM(arr),
dimensions,strides,
(PyArray_BASE(arr)==NULL?Py_None:PyArray_BASE(arr)),
PyArray_DESCR(arr)->kind,
@@ -154,61 +167,69 @@ PyMODINIT_FUNC inittest_array_from_pyobj_ext(void) {
PyDict_SetItemString(d, "__doc__", s);
wrap_error = PyErr_NewException ("wrap.error", NULL, NULL);
Py_DECREF(s);
- PyDict_SetItemString(d, "F2PY_INTENT_IN", PyInt_FromLong(F2PY_INTENT_IN));
- PyDict_SetItemString(d, "F2PY_INTENT_INOUT", PyInt_FromLong(F2PY_INTENT_INOUT));
- PyDict_SetItemString(d, "F2PY_INTENT_OUT", PyInt_FromLong(F2PY_INTENT_OUT));
- PyDict_SetItemString(d, "F2PY_INTENT_HIDE", PyInt_FromLong(F2PY_INTENT_HIDE));
- PyDict_SetItemString(d, "F2PY_INTENT_CACHE", PyInt_FromLong(F2PY_INTENT_CACHE));
- PyDict_SetItemString(d, "F2PY_INTENT_COPY", PyInt_FromLong(F2PY_INTENT_COPY));
- PyDict_SetItemString(d, "F2PY_INTENT_C", PyInt_FromLong(F2PY_INTENT_C));
- PyDict_SetItemString(d, "F2PY_OPTIONAL", PyInt_FromLong(F2PY_OPTIONAL));
- PyDict_SetItemString(d, "F2PY_INTENT_INPLACE", PyInt_FromLong(F2PY_INTENT_INPLACE));
- PyDict_SetItemString(d, "NPY_BOOL", PyInt_FromLong(NPY_BOOL));
- PyDict_SetItemString(d, "NPY_BYTE", PyInt_FromLong(NPY_BYTE));
- PyDict_SetItemString(d, "NPY_UBYTE", PyInt_FromLong(NPY_UBYTE));
- PyDict_SetItemString(d, "NPY_SHORT", PyInt_FromLong(NPY_SHORT));
- PyDict_SetItemString(d, "NPY_USHORT", PyInt_FromLong(NPY_USHORT));
- PyDict_SetItemString(d, "NPY_INT", PyInt_FromLong(NPY_INT));
- PyDict_SetItemString(d, "NPY_UINT", PyInt_FromLong(NPY_UINT));
- PyDict_SetItemString(d, "NPY_INTP", PyInt_FromLong(NPY_INTP));
- PyDict_SetItemString(d, "NPY_UINTP", PyInt_FromLong(NPY_UINTP));
- PyDict_SetItemString(d, "NPY_LONG", PyInt_FromLong(NPY_LONG));
- PyDict_SetItemString(d, "NPY_ULONG", PyInt_FromLong(NPY_ULONG));
- PyDict_SetItemString(d, "NPY_LONGLONG", PyInt_FromLong(NPY_LONGLONG));
- PyDict_SetItemString(d, "NPY_ULONGLONG", PyInt_FromLong(NPY_ULONGLONG));
- PyDict_SetItemString(d, "NPY_FLOAT", PyInt_FromLong(NPY_FLOAT));
- PyDict_SetItemString(d, "NPY_DOUBLE", PyInt_FromLong(NPY_DOUBLE));
- PyDict_SetItemString(d, "NPY_LONGDOUBLE", PyInt_FromLong(NPY_LONGDOUBLE));
- PyDict_SetItemString(d, "NPY_CFLOAT", PyInt_FromLong(NPY_CFLOAT));
- PyDict_SetItemString(d, "NPY_CDOUBLE", PyInt_FromLong(NPY_CDOUBLE));
- PyDict_SetItemString(d, "NPY_CLONGDOUBLE", PyInt_FromLong(NPY_CLONGDOUBLE));
- PyDict_SetItemString(d, "NPY_OBJECT", PyInt_FromLong(NPY_OBJECT));
- PyDict_SetItemString(d, "NPY_STRING", PyInt_FromLong(NPY_STRING));
- PyDict_SetItemString(d, "NPY_UNICODE", PyInt_FromLong(NPY_UNICODE));
- PyDict_SetItemString(d, "NPY_VOID", PyInt_FromLong(NPY_VOID));
- PyDict_SetItemString(d, "NPY_NTYPES", PyInt_FromLong(NPY_NTYPES));
- 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_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, "WRITEBACKIFCOPY", PyInt_FromLong(NPY_ARRAY_WRITEBACKIFCOPY));
-
- 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));
+
+#define ADDCONST(NAME, CONST) \
+ s = PyInt_FromLong(CONST); \
+ PyDict_SetItemString(d, NAME, s); \
+ Py_DECREF(s)
+
+ ADDCONST("F2PY_INTENT_IN", F2PY_INTENT_IN);
+ ADDCONST("F2PY_INTENT_INOUT", F2PY_INTENT_INOUT);
+ ADDCONST("F2PY_INTENT_OUT", F2PY_INTENT_OUT);
+ ADDCONST("F2PY_INTENT_HIDE", F2PY_INTENT_HIDE);
+ ADDCONST("F2PY_INTENT_CACHE", F2PY_INTENT_CACHE);
+ ADDCONST("F2PY_INTENT_COPY", F2PY_INTENT_COPY);
+ ADDCONST("F2PY_INTENT_C", F2PY_INTENT_C);
+ ADDCONST("F2PY_OPTIONAL", F2PY_OPTIONAL);
+ ADDCONST("F2PY_INTENT_INPLACE", F2PY_INTENT_INPLACE);
+ ADDCONST("NPY_BOOL", NPY_BOOL);
+ ADDCONST("NPY_BYTE", NPY_BYTE);
+ ADDCONST("NPY_UBYTE", NPY_UBYTE);
+ ADDCONST("NPY_SHORT", NPY_SHORT);
+ ADDCONST("NPY_USHORT", NPY_USHORT);
+ ADDCONST("NPY_INT", NPY_INT);
+ ADDCONST("NPY_UINT", NPY_UINT);
+ ADDCONST("NPY_INTP", NPY_INTP);
+ ADDCONST("NPY_UINTP", NPY_UINTP);
+ ADDCONST("NPY_LONG", NPY_LONG);
+ ADDCONST("NPY_ULONG", NPY_ULONG);
+ ADDCONST("NPY_LONGLONG", NPY_LONGLONG);
+ ADDCONST("NPY_ULONGLONG", NPY_ULONGLONG);
+ ADDCONST("NPY_FLOAT", NPY_FLOAT);
+ ADDCONST("NPY_DOUBLE", NPY_DOUBLE);
+ ADDCONST("NPY_LONGDOUBLE", NPY_LONGDOUBLE);
+ ADDCONST("NPY_CFLOAT", NPY_CFLOAT);
+ ADDCONST("NPY_CDOUBLE", NPY_CDOUBLE);
+ ADDCONST("NPY_CLONGDOUBLE", NPY_CLONGDOUBLE);
+ ADDCONST("NPY_OBJECT", NPY_OBJECT);
+ ADDCONST("NPY_STRING", NPY_STRING);
+ ADDCONST("NPY_UNICODE", NPY_UNICODE);
+ ADDCONST("NPY_VOID", NPY_VOID);
+ ADDCONST("NPY_NTYPES", NPY_NTYPES);
+ ADDCONST("NPY_NOTYPE", NPY_NOTYPE);
+ ADDCONST("NPY_USERDEF", NPY_USERDEF);
+
+ ADDCONST("CONTIGUOUS", NPY_ARRAY_C_CONTIGUOUS);
+ ADDCONST("FORTRAN", NPY_ARRAY_F_CONTIGUOUS);
+ ADDCONST("OWNDATA", NPY_ARRAY_OWNDATA);
+ ADDCONST("FORCECAST", NPY_ARRAY_FORCECAST);
+ ADDCONST("ENSURECOPY", NPY_ARRAY_ENSURECOPY);
+ ADDCONST("ENSUREARRAY", NPY_ARRAY_ENSUREARRAY);
+ ADDCONST("ALIGNED", NPY_ARRAY_ALIGNED);
+ ADDCONST("WRITEABLE", NPY_ARRAY_WRITEABLE);
+ ADDCONST("UPDATEIFCOPY", NPY_ARRAY_UPDATEIFCOPY);
+ ADDCONST("WRITEBACKIFCOPY", NPY_ARRAY_WRITEBACKIFCOPY);
+
+ ADDCONST("BEHAVED", NPY_ARRAY_BEHAVED);
+ ADDCONST("BEHAVED_NS", NPY_ARRAY_BEHAVED_NS);
+ ADDCONST("CARRAY", NPY_ARRAY_CARRAY);
+ ADDCONST("FARRAY", NPY_ARRAY_FARRAY);
+ ADDCONST("CARRAY_RO", NPY_ARRAY_CARRAY_RO);
+ ADDCONST("FARRAY_RO", NPY_ARRAY_FARRAY_RO);
+ ADDCONST("DEFAULT", NPY_ARRAY_DEFAULT);
+ ADDCONST("UPDATE_ALL", NPY_ARRAY_UPDATE_ALL);
+
+#undef ADDCONST(
if (PyErr_Occurred())
Py_FatalError("can't initialize module wrap");
diff --git a/numpy/f2py/tests/test_assumed_shape.py b/numpy/f2py/tests/test_assumed_shape.py
index 460afd68d..e5695a61c 100644
--- a/numpy/f2py/tests/test_assumed_shape.py
+++ b/numpy/f2py/tests/test_assumed_shape.py
@@ -2,6 +2,7 @@ from __future__ import division, absolute_import, print_function
import os
import pytest
+import tempfile
from numpy.testing import assert_
from . import util
@@ -16,6 +17,7 @@ class TestAssumedShapeSumExample(util.F2PyTest):
_path('src', 'assumed_shape', 'foo_use.f90'),
_path('src', 'assumed_shape', 'precision.f90'),
_path('src', 'assumed_shape', 'foo_mod.f90'),
+ _path('src', 'assumed_shape', '.f2py_f2cmap'),
]
@pytest.mark.slow
@@ -31,3 +33,23 @@ class TestAssumedShapeSumExample(util.F2PyTest):
assert_(r == 3, repr(r))
r = self.module.mod.fsum([1, 2])
assert_(r == 3, repr(r))
+
+
+class TestF2cmapOption(TestAssumedShapeSumExample):
+ def setup(self):
+ # Use a custom file name for .f2py_f2cmap
+ self.sources = list(self.sources)
+ f2cmap_src = self.sources.pop(-1)
+
+ self.f2cmap_file = tempfile.NamedTemporaryFile(delete=False)
+ with open(f2cmap_src, 'rb') as f:
+ self.f2cmap_file.write(f.read())
+ self.f2cmap_file.close()
+
+ self.sources.append(self.f2cmap_file.name)
+ self.options = ["--f2cmap", self.f2cmap_file.name]
+
+ super(TestF2cmapOption, self).setup()
+
+ def teardown(self):
+ os.unlink(self.f2cmap_file.name)
diff --git a/numpy/f2py/tests/test_compile_function.py b/numpy/f2py/tests/test_compile_function.py
index 36abf05f9..40ea7997f 100644
--- a/numpy/f2py/tests/test_compile_function.py
+++ b/numpy/f2py/tests/test_compile_function.py
@@ -29,6 +29,7 @@ def setup_module():
@pytest.mark.parametrize(
"extra_args", [['--noopt', '--debug'], '--noopt --debug', '']
)
+@pytest.mark.leaks_references(reason="Imported module seems never deleted.")
def test_f2py_init_compile(extra_args):
# flush through the f2py __init__ compile() function code path as a
# crude test for input handling following migration from
@@ -81,6 +82,9 @@ def test_f2py_init_compile(extra_args):
return_check = import_module(modname)
calc_result = return_check.foo()
assert_equal(calc_result, 15)
+ # Removal from sys.modules, is not as such necessary. Even with
+ # removal, the module (dict) stays alive.
+ del sys.modules[modname]
def test_f2py_init_compile_failure():
diff --git a/numpy/f2py/tests/util.py b/numpy/f2py/tests/util.py
index d20dc5908..bf005df88 100644
--- a/numpy/f2py/tests/util.py
+++ b/numpy/f2py/tests/util.py
@@ -31,6 +31,7 @@ except ImportError:
#
_module_dir = None
+_module_num = 5403
def _cleanup():
@@ -59,13 +60,14 @@ def get_module_dir():
def get_temp_module_name():
# Assume single-threaded, and the module dir usable only by this thread
+ global _module_num
d = get_module_dir()
- for j in range(5403, 9999999):
- name = "_test_ext_module_%d" % j
- fn = os.path.join(d, name)
- if name not in sys.modules and not os.path.isfile(fn + '.py'):
- return name
- raise RuntimeError("Failed to create a temporary module name")
+ name = "_test_ext_module_%d" % _module_num
+ _module_num += 1
+ if name in sys.modules:
+ # this should not be possible, but check anyway
+ raise RuntimeError("Temporary module name already in use.")
+ return name
def _memoize(func):
@@ -105,6 +107,7 @@ def build_module(source_files, options=[], skip=[], only=[], module_name=None):
# Copy files
dst_sources = []
+ f2py_sources = []
for fn in source_files:
if not os.path.isfile(fn):
raise RuntimeError("%s is not a file" % fn)
@@ -112,16 +115,14 @@ def build_module(source_files, options=[], skip=[], only=[], module_name=None):
shutil.copyfile(fn, dst)
dst_sources.append(dst)
- fn = os.path.join(os.path.dirname(fn), '.f2py_f2cmap')
- if os.path.isfile(fn):
- dst = os.path.join(d, os.path.basename(fn))
- if not os.path.isfile(dst):
- shutil.copyfile(fn, dst)
+ base, ext = os.path.splitext(dst)
+ if ext in ('.f90', '.f', '.c', '.pyf'):
+ f2py_sources.append(dst)
# Prepare options
if module_name is None:
module_name = get_temp_module_name()
- f2py_opts = ['-c', '-m', module_name] + options + dst_sources
+ f2py_opts = ['-c', '-m', module_name] + options + f2py_sources
if skip:
f2py_opts += ['skip:'] + skip
if only:
@@ -203,14 +204,20 @@ def _get_compiler_status():
""")
code = code % dict(syspath=repr(sys.path))
- with temppath(suffix='.py') as script:
+ tmpdir = tempfile.mkdtemp()
+ try:
+ script = os.path.join(tmpdir, 'setup.py')
+
with open(script, 'w') as f:
f.write(code)
- cmd = [sys.executable, script, 'config']
+ cmd = [sys.executable, 'setup.py', 'config']
p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
+ stderr=subprocess.STDOUT,
+ cwd=tmpdir)
out, err = p.communicate()
+ finally:
+ shutil.rmtree(tmpdir)
m = re.search(br'COMPILERS:(\d+),(\d+),(\d+)', out)
if m: