first commit

This commit is contained in:
2018-07-24 15:40:59 +02:00
commit d0d03faed9
1884 changed files with 366061 additions and 0 deletions

View File

@@ -0,0 +1,74 @@
#!/usr/bin/env python
"""Fortran to Python Interface Generator.
"""
from __future__ import division, absolute_import, print_function
__all__ = ['run_main', 'compile', 'f2py_testing']
import sys
from . import f2py2e
from . import f2py_testing
from . import diagnose
run_main = f2py2e.run_main
main = f2py2e.main
def compile(source,
modulename='untitled',
extra_args='',
verbose=True,
source_fn=None,
extension='.f'
):
"""
Build extension module from processing source with f2py.
Parameters
----------
source : str
Fortran source of module / subroutine to compile
modulename : str, optional
The name of the compiled python module
extra_args : str, optional
Additional parameters passed to f2py
verbose : bool, optional
Print f2py output to screen
source_fn : str, optional
Name of the file where the fortran source is written.
The default is to use a temporary file with the extension
provided by the `extension` parameter
extension : {'.f', '.f90'}, optional
Filename extension if `source_fn` is not provided.
The extension tells which fortran standard is used.
The default is `.f`, which implies F77 standard.
.. versionadded:: 1.11.0
"""
from numpy.distutils.exec_command import exec_command
import tempfile
if source_fn is None:
f = tempfile.NamedTemporaryFile(suffix=extension)
else:
f = open(source_fn, 'w')
try:
f.write(source)
f.flush()
args = ' -c -m {} {} {}'.format(modulename, f.name, extra_args)
c = '{} -c "import numpy.f2py as f2py2e;f2py2e.main()" {}'
c = c.format(sys.executable, args)
status, output = exec_command(c)
if verbose:
print(output)
finally:
f.close()
return status
from numpy.testing import _numpy_tester
test = _numpy_tester().test
bench = _numpy_tester().bench

View File

@@ -0,0 +1,27 @@
# See http://cens.ioc.ee/projects/f2py2e/
from __future__ import division, print_function
import os
import sys
for mode in ["g3-numpy", "2e-numeric", "2e-numarray", "2e-numpy"]:
try:
i = sys.argv.index("--" + mode)
del sys.argv[i]
break
except ValueError:
pass
os.environ["NO_SCIPY_IMPORT"] = "f2py"
if mode == "g3-numpy":
sys.stderr.write("G3 f2py support is not implemented, yet.\\n")
sys.exit(1)
elif mode == "2e-numeric":
from f2py2e import main
elif mode == "2e-numarray":
sys.argv.append("-DNUMARRAY")
from f2py2e import main
elif mode == "2e-numpy":
from numpy.f2py import main
else:
sys.stderr.write("Unknown mode: " + repr(mode) + "\\n")
sys.exit(1)
main()

View File

@@ -0,0 +1,10 @@
from __future__ import division, absolute_import, print_function
major = 2
try:
from __svn_version__ import version
version_info = (major, version)
version = '%s_%s' % version_info
except (ImportError, ValueError):
version = str(major)

View File

@@ -0,0 +1,854 @@
#!/usr/bin/env python
"""
Auxiliary functions for f2py2e.
Copyright 1999,2000 Pearu Peterson all rights reserved,
Pearu Peterson <pearu@ioc.ee>
Permission to use, modify, and distribute this software is given under the
terms of the NumPy (BSD style) LICENSE.
NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
$Date: 2005/07/24 19:01:55 $
Pearu Peterson
"""
from __future__ import division, absolute_import, print_function
import pprint
import sys
import types
from functools import reduce
from . import __version__
from . import cfuncs
__all__ = [
'applyrules', 'debugcapi', 'dictappend', 'errmess', 'gentitle',
'getargs2', 'getcallprotoargument', 'getcallstatement',
'getfortranname', 'getpymethoddef', 'getrestdoc', 'getusercode',
'getusercode1', 'hasbody', 'hascallstatement', 'hascommon',
'hasexternals', 'hasinitvalue', 'hasnote', 'hasresultnote',
'isallocatable', 'isarray', 'isarrayofstrings', 'iscomplex',
'iscomplexarray', 'iscomplexfunction', 'iscomplexfunction_warn',
'isdouble', 'isdummyroutine', 'isexternal', 'isfunction',
'isfunction_wrap', 'isint1array', 'isinteger', 'isintent_aux',
'isintent_c', 'isintent_callback', 'isintent_copy', 'isintent_dict',
'isintent_hide', 'isintent_in', 'isintent_inout', 'isintent_inplace',
'isintent_nothide', 'isintent_out', 'isintent_overwrite', 'islogical',
'islogicalfunction', 'islong_complex', 'islong_double',
'islong_doublefunction', 'islong_long', 'islong_longfunction',
'ismodule', 'ismoduleroutine', 'isoptional', 'isprivate', 'isrequired',
'isroutine', 'isscalar', 'issigned_long_longarray', 'isstring',
'isstringarray', 'isstringfunction', 'issubroutine',
'issubroutine_wrap', 'isthreadsafe', 'isunsigned', 'isunsigned_char',
'isunsigned_chararray', 'isunsigned_long_long',
'isunsigned_long_longarray', 'isunsigned_short',
'isunsigned_shortarray', 'l_and', 'l_not', 'l_or', 'outmess',
'replace', 'show', 'stripcomma', 'throw_error',
]
f2py_version = __version__.version
errmess = sys.stderr.write
show = pprint.pprint
options = {}
debugoptions = []
wrapfuncs = 1
def outmess(t):
if options.get('verbose', 1):
sys.stdout.write(t)
def debugcapi(var):
return 'capi' in debugoptions
def _isstring(var):
return 'typespec' in var and var['typespec'] == 'character' and \
not isexternal(var)
def isstring(var):
return _isstring(var) and not isarray(var)
def ischaracter(var):
return isstring(var) and 'charselector' not in var
def isstringarray(var):
return isarray(var) and _isstring(var)
def isarrayofstrings(var):
# leaving out '*' for now so that `character*(*) a(m)` and `character
# a(m,*)` are treated differently. Luckily `character**` is illegal.
return isstringarray(var) and var['dimension'][-1] == '(*)'
def isarray(var):
return 'dimension' in var and not isexternal(var)
def isscalar(var):
return not (isarray(var) or isstring(var) or isexternal(var))
def iscomplex(var):
return isscalar(var) and \
var.get('typespec') in ['complex', 'double complex']
def islogical(var):
return isscalar(var) and var.get('typespec') == 'logical'
def isinteger(var):
return isscalar(var) and var.get('typespec') == 'integer'
def isreal(var):
return isscalar(var) and var.get('typespec') == 'real'
def get_kind(var):
try:
return var['kindselector']['*']
except KeyError:
try:
return var['kindselector']['kind']
except KeyError:
pass
def islong_long(var):
if not isscalar(var):
return 0
if var.get('typespec') not in ['integer', 'logical']:
return 0
return get_kind(var) == '8'
def isunsigned_char(var):
if not isscalar(var):
return 0
if var.get('typespec') != 'integer':
return 0
return get_kind(var) == '-1'
def isunsigned_short(var):
if not isscalar(var):
return 0
if var.get('typespec') != 'integer':
return 0
return get_kind(var) == '-2'
def isunsigned(var):
if not isscalar(var):
return 0
if var.get('typespec') != 'integer':
return 0
return get_kind(var) == '-4'
def isunsigned_long_long(var):
if not isscalar(var):
return 0
if var.get('typespec') != 'integer':
return 0
return get_kind(var) == '-8'
def isdouble(var):
if not isscalar(var):
return 0
if not var.get('typespec') == 'real':
return 0
return get_kind(var) == '8'
def islong_double(var):
if not isscalar(var):
return 0
if not var.get('typespec') == 'real':
return 0
return get_kind(var) == '16'
def islong_complex(var):
if not iscomplex(var):
return 0
return get_kind(var) == '32'
def iscomplexarray(var):
return isarray(var) and \
var.get('typespec') in ['complex', 'double complex']
def isint1array(var):
return isarray(var) and var.get('typespec') == 'integer' \
and get_kind(var) == '1'
def isunsigned_chararray(var):
return isarray(var) and var.get('typespec') in ['integer', 'logical']\
and get_kind(var) == '-1'
def isunsigned_shortarray(var):
return isarray(var) and var.get('typespec') in ['integer', 'logical']\
and get_kind(var) == '-2'
def isunsignedarray(var):
return isarray(var) and var.get('typespec') in ['integer', 'logical']\
and get_kind(var) == '-4'
def isunsigned_long_longarray(var):
return isarray(var) and var.get('typespec') in ['integer', 'logical']\
and get_kind(var) == '-8'
def issigned_chararray(var):
return isarray(var) and var.get('typespec') in ['integer', 'logical']\
and get_kind(var) == '1'
def issigned_shortarray(var):
return isarray(var) and var.get('typespec') in ['integer', 'logical']\
and get_kind(var) == '2'
def issigned_array(var):
return isarray(var) and var.get('typespec') in ['integer', 'logical']\
and get_kind(var) == '4'
def issigned_long_longarray(var):
return isarray(var) and var.get('typespec') in ['integer', 'logical']\
and get_kind(var) == '8'
def isallocatable(var):
return 'attrspec' in var and 'allocatable' in var['attrspec']
def ismutable(var):
return not ('dimension' not in var or isstring(var))
def ismoduleroutine(rout):
return 'modulename' in rout
def ismodule(rout):
return 'block' in rout and 'module' == rout['block']
def isfunction(rout):
return 'block' in rout and 'function' == rout['block']
def isfunction_wrap(rout):
if isintent_c(rout):
return 0
return wrapfuncs and isfunction(rout) and (not isexternal(rout))
def issubroutine(rout):
return 'block' in rout and 'subroutine' == rout['block']
def issubroutine_wrap(rout):
if isintent_c(rout):
return 0
return issubroutine(rout) and hasassumedshape(rout)
def hasassumedshape(rout):
if rout.get('hasassumedshape'):
return True
for a in rout['args']:
for d in rout['vars'].get(a, {}).get('dimension', []):
if d == ':':
rout['hasassumedshape'] = True
return True
return False
def isroutine(rout):
return isfunction(rout) or issubroutine(rout)
def islogicalfunction(rout):
if not isfunction(rout):
return 0
if 'result' in rout:
a = rout['result']
else:
a = rout['name']
if a in rout['vars']:
return islogical(rout['vars'][a])
return 0
def islong_longfunction(rout):
if not isfunction(rout):
return 0
if 'result' in rout:
a = rout['result']
else:
a = rout['name']
if a in rout['vars']:
return islong_long(rout['vars'][a])
return 0
def islong_doublefunction(rout):
if not isfunction(rout):
return 0
if 'result' in rout:
a = rout['result']
else:
a = rout['name']
if a in rout['vars']:
return islong_double(rout['vars'][a])
return 0
def iscomplexfunction(rout):
if not isfunction(rout):
return 0
if 'result' in rout:
a = rout['result']
else:
a = rout['name']
if a in rout['vars']:
return iscomplex(rout['vars'][a])
return 0
def iscomplexfunction_warn(rout):
if iscomplexfunction(rout):
outmess("""\
**************************************************************
Warning: code with a function returning complex value
may not work correctly with your Fortran compiler.
Run the following test before using it in your applications:
$(f2py install dir)/test-site/{b/runme_scalar,e/runme}
When using GNU gcc/g77 compilers, codes should work correctly.
**************************************************************\n""")
return 1
return 0
def isstringfunction(rout):
if not isfunction(rout):
return 0
if 'result' in rout:
a = rout['result']
else:
a = rout['name']
if a in rout['vars']:
return isstring(rout['vars'][a])
return 0
def hasexternals(rout):
return 'externals' in rout and rout['externals']
def isthreadsafe(rout):
return 'f2pyenhancements' in rout and \
'threadsafe' in rout['f2pyenhancements']
def hasvariables(rout):
return 'vars' in rout and rout['vars']
def isoptional(var):
return ('attrspec' in var and 'optional' in var['attrspec'] and
'required' not in var['attrspec']) and isintent_nothide(var)
def isexternal(var):
return 'attrspec' in var and 'external' in var['attrspec']
def isrequired(var):
return not isoptional(var) and isintent_nothide(var)
def isintent_in(var):
if 'intent' not in var:
return 1
if 'hide' in var['intent']:
return 0
if 'inplace' in var['intent']:
return 0
if 'in' in var['intent']:
return 1
if 'out' in var['intent']:
return 0
if 'inout' in var['intent']:
return 0
if 'outin' in var['intent']:
return 0
return 1
def isintent_inout(var):
return ('intent' in var and ('inout' in var['intent'] or
'outin' in var['intent']) and 'in' not in var['intent'] and
'hide' not in var['intent'] and 'inplace' not in var['intent'])
def isintent_out(var):
return 'out' in var.get('intent', [])
def isintent_hide(var):
return ('intent' in var and ('hide' in var['intent'] or
('out' in var['intent'] and 'in' not in var['intent'] and
(not l_or(isintent_inout, isintent_inplace)(var)))))
def isintent_nothide(var):
return not isintent_hide(var)
def isintent_c(var):
return 'c' in var.get('intent', [])
def isintent_cache(var):
return 'cache' in var.get('intent', [])
def isintent_copy(var):
return 'copy' in var.get('intent', [])
def isintent_overwrite(var):
return 'overwrite' in var.get('intent', [])
def isintent_callback(var):
return 'callback' in var.get('intent', [])
def isintent_inplace(var):
return 'inplace' in var.get('intent', [])
def isintent_aux(var):
return 'aux' in var.get('intent', [])
def isintent_aligned4(var):
return 'aligned4' in var.get('intent', [])
def isintent_aligned8(var):
return 'aligned8' in var.get('intent', [])
def isintent_aligned16(var):
return 'aligned16' in var.get('intent', [])
isintent_dict = {isintent_in: 'INTENT_IN', isintent_inout: 'INTENT_INOUT',
isintent_out: 'INTENT_OUT', isintent_hide: 'INTENT_HIDE',
isintent_cache: 'INTENT_CACHE',
isintent_c: 'INTENT_C', isoptional: 'OPTIONAL',
isintent_inplace: 'INTENT_INPLACE',
isintent_aligned4: 'INTENT_ALIGNED4',
isintent_aligned8: 'INTENT_ALIGNED8',
isintent_aligned16: 'INTENT_ALIGNED16',
}
def isprivate(var):
return 'attrspec' in var and 'private' in var['attrspec']
def hasinitvalue(var):
return '=' in var
def hasinitvalueasstring(var):
if not hasinitvalue(var):
return 0
return var['='][0] in ['"', "'"]
def hasnote(var):
return 'note' in var
def hasresultnote(rout):
if not isfunction(rout):
return 0
if 'result' in rout:
a = rout['result']
else:
a = rout['name']
if a in rout['vars']:
return hasnote(rout['vars'][a])
return 0
def hascommon(rout):
return 'common' in rout
def containscommon(rout):
if hascommon(rout):
return 1
if hasbody(rout):
for b in rout['body']:
if containscommon(b):
return 1
return 0
def containsmodule(block):
if ismodule(block):
return 1
if not hasbody(block):
return 0
for b in block['body']:
if containsmodule(b):
return 1
return 0
def hasbody(rout):
return 'body' in rout
def hascallstatement(rout):
return getcallstatement(rout) is not None
def istrue(var):
return 1
def isfalse(var):
return 0
class F2PYError(Exception):
pass
class throw_error(object):
def __init__(self, mess):
self.mess = mess
def __call__(self, var):
mess = '\n\n var = %s\n Message: %s\n' % (var, self.mess)
raise F2PYError(mess)
def l_and(*f):
l, l2 = 'lambda v', []
for i in range(len(f)):
l = '%s,f%d=f[%d]' % (l, i, i)
l2.append('f%d(v)' % (i))
return eval('%s:%s' % (l, ' and '.join(l2)))
def l_or(*f):
l, l2 = 'lambda v', []
for i in range(len(f)):
l = '%s,f%d=f[%d]' % (l, i, i)
l2.append('f%d(v)' % (i))
return eval('%s:%s' % (l, ' or '.join(l2)))
def l_not(f):
return eval('lambda v,f=f:not f(v)')
def isdummyroutine(rout):
try:
return rout['f2pyenhancements']['fortranname'] == ''
except KeyError:
return 0
def getfortranname(rout):
try:
name = rout['f2pyenhancements']['fortranname']
if name == '':
raise KeyError
if not name:
errmess('Failed to use fortranname from %s\n' %
(rout['f2pyenhancements']))
raise KeyError
except KeyError:
name = rout['name']
return name
def getmultilineblock(rout, blockname, comment=1, counter=0):
try:
r = rout['f2pyenhancements'].get(blockname)
except KeyError:
return
if not r:
return
if counter > 0 and isinstance(r, str):
return
if isinstance(r, list):
if counter >= len(r):
return
r = r[counter]
if r[:3] == "'''":
if comment:
r = '\t/* start ' + blockname + \
' multiline (' + repr(counter) + ') */\n' + r[3:]
else:
r = r[3:]
if r[-3:] == "'''":
if comment:
r = r[:-3] + '\n\t/* end multiline (' + repr(counter) + ')*/'
else:
r = r[:-3]
else:
errmess("%s multiline block should end with `'''`: %s\n"
% (blockname, repr(r)))
return r
def getcallstatement(rout):
return getmultilineblock(rout, 'callstatement')
def getcallprotoargument(rout, cb_map={}):
r = getmultilineblock(rout, 'callprotoargument', comment=0)
if r:
return r
if hascallstatement(rout):
outmess(
'warning: callstatement is defined without callprotoargument\n')
return
from .capi_maps import getctype
arg_types, arg_types2 = [], []
if l_and(isstringfunction, l_not(isfunction_wrap))(rout):
arg_types.extend(['char*', 'size_t'])
for n in rout['args']:
var = rout['vars'][n]
if isintent_callback(var):
continue
if n in cb_map:
ctype = cb_map[n] + '_typedef'
else:
ctype = getctype(var)
if l_and(isintent_c, l_or(isscalar, iscomplex))(var):
pass
elif isstring(var):
pass
else:
ctype = ctype + '*'
if isstring(var) or isarrayofstrings(var):
arg_types2.append('size_t')
arg_types.append(ctype)
proto_args = ','.join(arg_types + arg_types2)
if not proto_args:
proto_args = 'void'
return proto_args
def getusercode(rout):
return getmultilineblock(rout, 'usercode')
def getusercode1(rout):
return getmultilineblock(rout, 'usercode', counter=1)
def getpymethoddef(rout):
return getmultilineblock(rout, 'pymethoddef')
def getargs(rout):
sortargs, args = [], []
if 'args' in rout:
args = rout['args']
if 'sortvars' in rout:
for a in rout['sortvars']:
if a in args:
sortargs.append(a)
for a in args:
if a not in sortargs:
sortargs.append(a)
else:
sortargs = rout['args']
return args, sortargs
def getargs2(rout):
sortargs, args = [], rout.get('args', [])
auxvars = [a for a in rout['vars'].keys() if isintent_aux(rout['vars'][a])
and a not in args]
args = auxvars + args
if 'sortvars' in rout:
for a in rout['sortvars']:
if a in args:
sortargs.append(a)
for a in args:
if a not in sortargs:
sortargs.append(a)
else:
sortargs = auxvars + rout['args']
return args, sortargs
def getrestdoc(rout):
if 'f2pymultilines' not in rout:
return None
k = None
if rout['block'] == 'python module':
k = rout['block'], rout['name']
return rout['f2pymultilines'].get(k, None)
def gentitle(name):
l = (80 - len(name) - 6) // 2
return '/*%s %s %s*/' % (l * '*', name, l * '*')
def flatlist(l):
if isinstance(l, list):
return reduce(lambda x, y, f=flatlist: x + f(y), l, [])
return [l]
def stripcomma(s):
if s and s[-1] == ',':
return s[:-1]
return s
def replace(str, d, defaultsep=''):
if isinstance(d, list):
return [replace(str, _m, defaultsep) for _m in d]
if isinstance(str, list):
return [replace(_m, d, defaultsep) for _m in str]
for k in 2 * list(d.keys()):
if k == 'separatorsfor':
continue
if 'separatorsfor' in d and k in d['separatorsfor']:
sep = d['separatorsfor'][k]
else:
sep = defaultsep
if isinstance(d[k], list):
str = str.replace('#%s#' % (k), sep.join(flatlist(d[k])))
else:
str = str.replace('#%s#' % (k), d[k])
return str
def dictappend(rd, ar):
if isinstance(ar, list):
for a in ar:
rd = dictappend(rd, a)
return rd
for k in ar.keys():
if k[0] == '_':
continue
if k in rd:
if isinstance(rd[k], str):
rd[k] = [rd[k]]
if isinstance(rd[k], list):
if isinstance(ar[k], list):
rd[k] = rd[k] + ar[k]
else:
rd[k].append(ar[k])
elif isinstance(rd[k], dict):
if isinstance(ar[k], dict):
if k == 'separatorsfor':
for k1 in ar[k].keys():
if k1 not in rd[k]:
rd[k][k1] = ar[k][k1]
else:
rd[k] = dictappend(rd[k], ar[k])
else:
rd[k] = ar[k]
return rd
def applyrules(rules, d, var={}):
ret = {}
if isinstance(rules, list):
for r in rules:
rr = applyrules(r, d, var)
ret = dictappend(ret, rr)
if '_break' in rr:
break
return ret
if '_check' in rules and (not rules['_check'](var)):
return ret
if 'need' in rules:
res = applyrules({'needs': rules['need']}, d, var)
if 'needs' in res:
cfuncs.append_needs(res['needs'])
for k in rules.keys():
if k == 'separatorsfor':
ret[k] = rules[k]
continue
if isinstance(rules[k], str):
ret[k] = replace(rules[k], d)
elif isinstance(rules[k], list):
ret[k] = []
for i in rules[k]:
ar = applyrules({k: i}, d, var)
if k in ar:
ret[k].append(ar[k])
elif k[0] == '_':
continue
elif isinstance(rules[k], dict):
ret[k] = []
for k1 in rules[k].keys():
if isinstance(k1, types.FunctionType) and k1(var):
if isinstance(rules[k][k1], list):
for i in rules[k][k1]:
if isinstance(i, dict):
res = applyrules({'supertext': i}, d, var)
if 'supertext' in res:
i = res['supertext']
else:
i = ''
ret[k].append(replace(i, d))
else:
i = rules[k][k1]
if isinstance(i, dict):
res = applyrules({'supertext': i}, d)
if 'supertext' in res:
i = res['supertext']
else:
i = ''
ret[k].append(replace(i, d))
else:
errmess('applyrules: ignoring rule %s.\n' % repr(rules[k]))
if isinstance(ret[k], list):
if len(ret[k]) == 1:
ret[k] = ret[k][0]
if ret[k] == []:
del ret[k]
return ret

View File

@@ -0,0 +1,840 @@
#!/usr/bin/env python
"""
Copyright 1999,2000 Pearu Peterson all rights reserved,
Pearu Peterson <pearu@ioc.ee>
Permission to use, modify, and distribute this software is given under the
terms of the NumPy License.
NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
$Date: 2005/05/06 10:57:33 $
Pearu Peterson
"""
from __future__ import division, absolute_import, print_function
__version__ = "$Revision: 1.60 $"[10:-1]
from . import __version__
f2py_version = __version__.version
import copy
import re
import os
import sys
from .crackfortran import markoutercomma
from . import cb_rules
# The eviroment provided by auxfuncs.py is needed for some calls to eval.
# As the needed functions cannot be determined by static inspection of the
# code, it is safest to use import * pending a major refactoring of f2py.
from .auxfuncs import *
__all__ = [
'getctype', 'getstrlength', 'getarrdims', 'getpydocsign',
'getarrdocsign', 'getinit', 'sign2map', 'routsign2map', 'modsign2map',
'cb_sign2map', 'cb_routsign2map', 'common_sign2map'
]
# Numarray and Numeric users should set this False
using_newcore = True
depargs = []
lcb_map = {}
lcb2_map = {}
# forced casting: mainly caused by the fact that Python or Numeric
# C/APIs do not support the corresponding C types.
c2py_map = {'double': 'float',
'float': 'float', # forced casting
'long_double': 'float', # forced casting
'char': 'int', # forced casting
'signed_char': 'int', # forced casting
'unsigned_char': 'int', # forced casting
'short': 'int', # forced casting
'unsigned_short': 'int', # forced casting
'int': 'int', # (forced casting)
'long': 'int',
'long_long': 'long',
'unsigned': 'int', # forced casting
'complex_float': 'complex', # forced casting
'complex_double': 'complex',
'complex_long_double': 'complex', # forced casting
'string': 'string',
}
c2capi_map = {'double': 'NPY_DOUBLE',
'float': 'NPY_FLOAT',
'long_double': 'NPY_DOUBLE', # forced casting
'char': 'NPY_STRING',
'unsigned_char': 'NPY_UBYTE',
'signed_char': 'NPY_BYTE',
'short': 'NPY_SHORT',
'unsigned_short': 'NPY_USHORT',
'int': 'NPY_INT',
'unsigned': 'NPY_UINT',
'long': 'NPY_LONG',
'long_long': 'NPY_LONG', # forced casting
'complex_float': 'NPY_CFLOAT',
'complex_double': 'NPY_CDOUBLE',
'complex_long_double': 'NPY_CDOUBLE', # forced casting
'string': 'NPY_STRING'}
# These new maps aren't used anyhere yet, but should be by default
# unless building numeric or numarray extensions.
if using_newcore:
c2capi_map = {'double': 'NPY_DOUBLE',
'float': 'NPY_FLOAT',
'long_double': 'NPY_LONGDOUBLE',
'char': 'NPY_BYTE',
'unsigned_char': 'NPY_UBYTE',
'signed_char': 'NPY_BYTE',
'short': 'NPY_SHORT',
'unsigned_short': 'NPY_USHORT',
'int': 'NPY_INT',
'unsigned': 'NPY_UINT',
'long': 'NPY_LONG',
'unsigned_long': 'NPY_ULONG',
'long_long': 'NPY_LONGLONG',
'unsigned_long_long': 'NPY_ULONGLONG',
'complex_float': 'NPY_CFLOAT',
'complex_double': 'NPY_CDOUBLE',
'complex_long_double': 'NPY_CDOUBLE',
'string':'NPY_STRING'
}
c2pycode_map = {'double': 'd',
'float': 'f',
'long_double': 'd', # forced casting
'char': '1',
'signed_char': '1',
'unsigned_char': 'b',
'short': 's',
'unsigned_short': 'w',
'int': 'i',
'unsigned': 'u',
'long': 'l',
'long_long': 'L',
'complex_float': 'F',
'complex_double': 'D',
'complex_long_double': 'D', # forced casting
'string': 'c'
}
if using_newcore:
c2pycode_map = {'double': 'd',
'float': 'f',
'long_double': 'g',
'char': 'b',
'unsigned_char': 'B',
'signed_char': 'b',
'short': 'h',
'unsigned_short': 'H',
'int': 'i',
'unsigned': 'I',
'long': 'l',
'unsigned_long': 'L',
'long_long': 'q',
'unsigned_long_long': 'Q',
'complex_float': 'F',
'complex_double': 'D',
'complex_long_double': 'G',
'string': 'S'}
c2buildvalue_map = {'double': 'd',
'float': 'f',
'char': 'b',
'signed_char': 'b',
'short': 'h',
'int': 'i',
'long': 'l',
'long_long': 'L',
'complex_float': 'N',
'complex_double': 'N',
'complex_long_double': 'N',
'string': 'z'}
if sys.version_info[0] >= 3:
# Bytes, not Unicode strings
c2buildvalue_map['string'] = 'y'
if using_newcore:
# c2buildvalue_map=???
pass
f2cmap_all = {'real': {'': 'float', '4': 'float', '8': 'double',
'12': 'long_double', '16': 'long_double'},
'integer': {'': 'int', '1': 'signed_char', '2': 'short',
'4': 'int', '8': 'long_long',
'-1': 'unsigned_char', '-2': 'unsigned_short',
'-4': 'unsigned', '-8': 'unsigned_long_long'},
'complex': {'': 'complex_float', '8': 'complex_float',
'16': 'complex_double', '24': 'complex_long_double',
'32': 'complex_long_double'},
'complexkind': {'': 'complex_float', '4': 'complex_float',
'8': 'complex_double', '12': 'complex_long_double',
'16': 'complex_long_double'},
'logical': {'': 'int', '1': 'char', '2': 'short', '4': 'int',
'8': 'long_long'},
'double complex': {'': 'complex_double'},
'double precision': {'': 'double'},
'byte': {'': 'char'},
'character': {'': 'string'}
}
if os.path.isfile('.f2py_f2cmap'):
# User defined additions to f2cmap_all.
# .f2py_f2cmap 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()
for k, d1 in list(d.items()):
for k1 in list(d1.keys()):
d1[k1.lower()] = d1[k1]
d[k.lower()] = d[k]
for k in list(d.keys()):
if k not in f2cmap_all:
f2cmap_all[k] = {}
for k1 in list(d[k].keys()):
if d[k][k1] in c2py_map:
if k1 in f2cmap_all[k]:
outmess(
"\tWarning: redefinition of {'%s':{'%s':'%s'->'%s'}}\n" % (k, k1, f2cmap_all[k][k1], d[k][k1]))
f2cmap_all[k][k1] = d[k][k1]
outmess('\tMapping "%s(kind=%s)" to "%s"\n' %
(k, k1, d[k][k1]))
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')
except Exception as msg:
errmess(
'Failed to apply user defined changes from .f2py_f2cmap: %s. Skipping.\n' % (msg))
cformat_map = {'double': '%g',
'float': '%g',
'long_double': '%Lg',
'char': '%d',
'signed_char': '%d',
'unsigned_char': '%hhu',
'short': '%hd',
'unsigned_short': '%hu',
'int': '%d',
'unsigned': '%u',
'long': '%ld',
'unsigned_long': '%lu',
'long_long': '%ld',
'complex_float': '(%g,%g)',
'complex_double': '(%g,%g)',
'complex_long_double': '(%Lg,%Lg)',
'string': '%s',
}
# Auxiliary functions
def getctype(var):
"""
Determines C type
"""
ctype = 'void'
if isfunction(var):
if 'result' in var:
a = var['result']
else:
a = var['name']
if a in var['vars']:
return getctype(var['vars'][a])
else:
errmess('getctype: function %s has no return value?!\n' % a)
elif issubroutine(var):
return ctype
elif 'typespec' in var and var['typespec'].lower() in f2cmap_all:
typespec = var['typespec'].lower()
f2cmap = f2cmap_all[typespec]
ctype = f2cmap[''] # default type
if 'kindselector' in var:
if '*' in var['kindselector']:
try:
ctype = f2cmap[var['kindselector']['*']]
except KeyError:
errmess('getctype: "%s %s %s" not supported.\n' %
(var['typespec'], '*', var['kindselector']['*']))
elif 'kind' in var['kindselector']:
if typespec + 'kind' in f2cmap_all:
f2cmap = f2cmap_all[typespec + 'kind']
try:
ctype = f2cmap[var['kindselector']['kind']]
except KeyError:
if typespec in f2cmap_all:
f2cmap = f2cmap_all[typespec]
try:
ctype = f2cmap[str(var['kindselector']['kind'])]
except KeyError:
errmess('getctype: "%s(kind=%s)" is mapped to C "%s" (to override define dict(%s = dict(%s="<C typespec>")) in %s/.f2py_f2cmap file).\n'
% (typespec, var['kindselector']['kind'], ctype,
typespec, var['kindselector']['kind'], os.getcwd()))
else:
if not isexternal(var):
errmess(
'getctype: No C-type found in "%s", assuming void.\n' % var)
return ctype
def getstrlength(var):
if isstringfunction(var):
if 'result' in var:
a = var['result']
else:
a = var['name']
if a in var['vars']:
return getstrlength(var['vars'][a])
else:
errmess('getstrlength: function %s has no return value?!\n' % a)
if not isstring(var):
errmess(
'getstrlength: expected a signature of a string but got: %s\n' % (repr(var)))
len = '1'
if 'charselector' in var:
a = var['charselector']
if '*' in a:
len = a['*']
elif 'len' in a:
len = a['len']
if re.match(r'\(\s*([*]|[:])\s*\)', len) or re.match(r'([*]|[:])', len):
if isintent_hide(var):
errmess('getstrlength:intent(hide): expected a string with defined length but got: %s\n' % (
repr(var)))
len = '-1'
return len
def getarrdims(a, var, verbose=0):
global depargs
ret = {}
if isstring(var) and not isarray(var):
ret['dims'] = getstrlength(var)
ret['size'] = ret['dims']
ret['rank'] = '1'
elif isscalar(var):
ret['size'] = '1'
ret['rank'] = '0'
ret['dims'] = ''
elif isarray(var):
dim = copy.copy(var['dimension'])
ret['size'] = '*'.join(dim)
try:
ret['size'] = repr(eval(ret['size']))
except Exception:
pass
ret['dims'] = ','.join(dim)
ret['rank'] = repr(len(dim))
ret['rank*[-1]'] = repr(len(dim) * [-1])[1:-1]
for i in range(len(dim)): # solve dim for dependecies
v = []
if dim[i] in depargs:
v = [dim[i]]
else:
for va in depargs:
if re.match(r'.*?\b%s\b.*' % va, dim[i]):
v.append(va)
for va in v:
if depargs.index(va) > depargs.index(a):
dim[i] = '*'
break
ret['setdims'], i = '', -1
for d in dim:
i = i + 1
if d not in ['*', ':', '(*)', '(:)']:
ret['setdims'] = '%s#varname#_Dims[%d]=%s,' % (
ret['setdims'], i, d)
if ret['setdims']:
ret['setdims'] = ret['setdims'][:-1]
ret['cbsetdims'], i = '', -1
for d in var['dimension']:
i = i + 1
if d not in ['*', ':', '(*)', '(:)']:
ret['cbsetdims'] = '%s#varname#_Dims[%d]=%s,' % (
ret['cbsetdims'], i, d)
elif isintent_in(var):
outmess('getarrdims:warning: assumed shape array, using 0 instead of %r\n'
% (d))
ret['cbsetdims'] = '%s#varname#_Dims[%d]=%s,' % (
ret['cbsetdims'], i, 0)
elif verbose:
errmess(
'getarrdims: If in call-back function: array argument %s must have bounded dimensions: got %s\n' % (repr(a), repr(d)))
if ret['cbsetdims']:
ret['cbsetdims'] = ret['cbsetdims'][:-1]
# if not isintent_c(var):
# var['dimension'].reverse()
return ret
def getpydocsign(a, var):
global lcb_map
if isfunction(var):
if 'result' in var:
af = var['result']
else:
af = var['name']
if af in var['vars']:
return getpydocsign(af, var['vars'][af])
else:
errmess('getctype: function %s has no return value?!\n' % af)
return '', ''
sig, sigout = a, a
opt = ''
if isintent_in(var):
opt = 'input'
elif isintent_inout(var):
opt = 'in/output'
out_a = a
if isintent_out(var):
for k in var['intent']:
if k[:4] == 'out=':
out_a = k[4:]
break
init = ''
ctype = getctype(var)
if hasinitvalue(var):
init, showinit = getinit(a, var)
init = ', optional\\n Default: %s' % showinit
if isscalar(var):
if isintent_inout(var):
sig = '%s : %s rank-0 array(%s,\'%s\')%s' % (a, opt, c2py_map[ctype],
c2pycode_map[ctype], init)
else:
sig = '%s : %s %s%s' % (a, opt, c2py_map[ctype], init)
sigout = '%s : %s' % (out_a, c2py_map[ctype])
elif isstring(var):
if isintent_inout(var):
sig = '%s : %s rank-0 array(string(len=%s),\'c\')%s' % (
a, opt, getstrlength(var), init)
else:
sig = '%s : %s string(len=%s)%s' % (
a, opt, getstrlength(var), init)
sigout = '%s : string(len=%s)' % (out_a, getstrlength(var))
elif isarray(var):
dim = var['dimension']
rank = repr(len(dim))
sig = '%s : %s rank-%s array(\'%s\') with bounds (%s)%s' % (a, opt, rank,
c2pycode_map[
ctype],
','.join(dim), init)
if a == out_a:
sigout = '%s : rank-%s array(\'%s\') with bounds (%s)'\
% (a, rank, c2pycode_map[ctype], ','.join(dim))
else:
sigout = '%s : rank-%s array(\'%s\') with bounds (%s) and %s storage'\
% (out_a, rank, c2pycode_map[ctype], ','.join(dim), a)
elif isexternal(var):
ua = ''
if a in lcb_map and lcb_map[a] in lcb2_map and 'argname' in lcb2_map[lcb_map[a]]:
ua = lcb2_map[lcb_map[a]]['argname']
if not ua == a:
ua = ' => %s' % ua
else:
ua = ''
sig = '%s : call-back function%s' % (a, ua)
sigout = sig
else:
errmess(
'getpydocsign: Could not resolve docsignature for "%s".\\n' % a)
return sig, sigout
def getarrdocsign(a, var):
ctype = getctype(var)
if isstring(var) and (not isarray(var)):
sig = '%s : rank-0 array(string(len=%s),\'c\')' % (a,
getstrlength(var))
elif isscalar(var):
sig = '%s : rank-0 array(%s,\'%s\')' % (a, c2py_map[ctype],
c2pycode_map[ctype],)
elif isarray(var):
dim = var['dimension']
rank = repr(len(dim))
sig = '%s : rank-%s array(\'%s\') with bounds (%s)' % (a, rank,
c2pycode_map[
ctype],
','.join(dim))
return sig
def getinit(a, var):
if isstring(var):
init, showinit = '""', "''"
else:
init, showinit = '', ''
if hasinitvalue(var):
init = var['=']
showinit = init
if iscomplex(var) or iscomplexarray(var):
ret = {}
try:
v = var["="]
if ',' in v:
ret['init.r'], ret['init.i'] = markoutercomma(
v[1:-1]).split('@,@')
else:
v = eval(v, {}, {})
ret['init.r'], ret['init.i'] = str(v.real), str(v.imag)
except Exception:
raise ValueError(
'getinit: expected complex number `(r,i)\' but got `%s\' as initial value of %r.' % (init, a))
if isarray(var):
init = '(capi_c.r=%s,capi_c.i=%s,capi_c)' % (
ret['init.r'], ret['init.i'])
elif isstring(var):
if not init:
init, showinit = '""', "''"
if init[0] == "'":
init = '"%s"' % (init[1:-1].replace('"', '\\"'))
if init[0] == '"':
showinit = "'%s'" % (init[1:-1])
return init, showinit
def sign2map(a, var):
"""
varname,ctype,atype
init,init.r,init.i,pytype
vardebuginfo,vardebugshowvalue,varshowvalue
varrfromat
intent
"""
global lcb_map, cb_map
out_a = a
if isintent_out(var):
for k in var['intent']:
if k[:4] == 'out=':
out_a = k[4:]
break
ret = {'varname': a, 'outvarname': out_a, 'ctype': getctype(var)}
intent_flags = []
for f, s in isintent_dict.items():
if f(var):
intent_flags.append('F2PY_%s' % s)
if intent_flags:
# XXX: Evaluate intent_flags here.
ret['intent'] = '|'.join(intent_flags)
else:
ret['intent'] = 'F2PY_INTENT_IN'
if isarray(var):
ret['varrformat'] = 'N'
elif ret['ctype'] in c2buildvalue_map:
ret['varrformat'] = c2buildvalue_map[ret['ctype']]
else:
ret['varrformat'] = 'O'
ret['init'], ret['showinit'] = getinit(a, var)
if hasinitvalue(var) and iscomplex(var) and not isarray(var):
ret['init.r'], ret['init.i'] = markoutercomma(
ret['init'][1:-1]).split('@,@')
if isexternal(var):
ret['cbnamekey'] = a
if a in lcb_map:
ret['cbname'] = lcb_map[a]
ret['maxnofargs'] = lcb2_map[lcb_map[a]]['maxnofargs']
ret['nofoptargs'] = lcb2_map[lcb_map[a]]['nofoptargs']
ret['cbdocstr'] = lcb2_map[lcb_map[a]]['docstr']
ret['cblatexdocstr'] = lcb2_map[lcb_map[a]]['latexdocstr']
else:
ret['cbname'] = a
errmess('sign2map: Confused: external %s is not in lcb_map%s.\n' % (
a, list(lcb_map.keys())))
if isstring(var):
ret['length'] = getstrlength(var)
if isarray(var):
ret = dictappend(ret, getarrdims(a, var))
dim = copy.copy(var['dimension'])
if ret['ctype'] in c2capi_map:
ret['atype'] = c2capi_map[ret['ctype']]
# Debug info
if debugcapi(var):
il = [isintent_in, 'input', isintent_out, 'output',
isintent_inout, 'inoutput', isrequired, 'required',
isoptional, 'optional', isintent_hide, 'hidden',
iscomplex, 'complex scalar',
l_and(isscalar, l_not(iscomplex)), 'scalar',
isstring, 'string', isarray, 'array',
iscomplexarray, 'complex array', isstringarray, 'string array',
iscomplexfunction, 'complex function',
l_and(isfunction, l_not(iscomplexfunction)), 'function',
isexternal, 'callback',
isintent_callback, 'callback',
isintent_aux, 'auxiliary',
]
rl = []
for i in range(0, len(il), 2):
if il[i](var):
rl.append(il[i + 1])
if isstring(var):
rl.append('slen(%s)=%s' % (a, ret['length']))
if isarray(var):
ddim = ','.join(
map(lambda x, y: '%s|%s' % (x, y), var['dimension'], dim))
rl.append('dims(%s)' % ddim)
if isexternal(var):
ret['vardebuginfo'] = 'debug-capi:%s=>%s:%s' % (
a, ret['cbname'], ','.join(rl))
else:
ret['vardebuginfo'] = 'debug-capi:%s %s=%s:%s' % (
ret['ctype'], a, ret['showinit'], ','.join(rl))
if isscalar(var):
if ret['ctype'] in cformat_map:
ret['vardebugshowvalue'] = 'debug-capi:%s=%s' % (
a, cformat_map[ret['ctype']])
if isstring(var):
ret['vardebugshowvalue'] = 'debug-capi:slen(%s)=%%d %s=\\"%%s\\"' % (
a, a)
if isexternal(var):
ret['vardebugshowvalue'] = 'debug-capi:%s=%%p' % (a)
if ret['ctype'] in cformat_map:
ret['varshowvalue'] = '#name#:%s=%s' % (a, cformat_map[ret['ctype']])
ret['showvalueformat'] = '%s' % (cformat_map[ret['ctype']])
if isstring(var):
ret['varshowvalue'] = '#name#:slen(%s)=%%d %s=\\"%%s\\"' % (a, a)
ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, var)
if hasnote(var):
ret['note'] = var['note']
return ret
def routsign2map(rout):
"""
name,NAME,begintitle,endtitle
rname,ctype,rformat
routdebugshowvalue
"""
global lcb_map
name = rout['name']
fname = getfortranname(rout)
ret = {'name': name,
'texname': name.replace('_', '\\_'),
'name_lower': name.lower(),
'NAME': name.upper(),
'begintitle': gentitle(name),
'endtitle': gentitle('end of %s' % name),
'fortranname': fname,
'FORTRANNAME': fname.upper(),
'callstatement': getcallstatement(rout) or '',
'usercode': getusercode(rout) or '',
'usercode1': getusercode1(rout) or '',
}
if '_' in fname:
ret['F_FUNC'] = 'F_FUNC_US'
else:
ret['F_FUNC'] = 'F_FUNC'
if '_' in name:
ret['F_WRAPPEDFUNC'] = 'F_WRAPPEDFUNC_US'
else:
ret['F_WRAPPEDFUNC'] = 'F_WRAPPEDFUNC'
lcb_map = {}
if 'use' in rout:
for u in rout['use'].keys():
if u in cb_rules.cb_map:
for un in cb_rules.cb_map[u]:
ln = un[0]
if 'map' in rout['use'][u]:
for k in rout['use'][u]['map'].keys():
if rout['use'][u]['map'][k] == un[0]:
ln = k
break
lcb_map[ln] = un[1]
elif 'externals' in rout and rout['externals']:
errmess('routsign2map: Confused: function %s has externals %s but no "use" statement.\n' % (
ret['name'], repr(rout['externals'])))
ret['callprotoargument'] = getcallprotoargument(rout, lcb_map) or ''
if isfunction(rout):
if 'result' in rout:
a = rout['result']
else:
a = rout['name']
ret['rname'] = a
ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, rout)
ret['ctype'] = getctype(rout['vars'][a])
if hasresultnote(rout):
ret['resultnote'] = rout['vars'][a]['note']
rout['vars'][a]['note'] = ['See elsewhere.']
if ret['ctype'] in c2buildvalue_map:
ret['rformat'] = c2buildvalue_map[ret['ctype']]
else:
ret['rformat'] = 'O'
errmess('routsign2map: no c2buildvalue key for type %s\n' %
(repr(ret['ctype'])))
if debugcapi(rout):
if ret['ctype'] in cformat_map:
ret['routdebugshowvalue'] = 'debug-capi:%s=%s' % (
a, cformat_map[ret['ctype']])
if isstringfunction(rout):
ret['routdebugshowvalue'] = 'debug-capi:slen(%s)=%%d %s=\\"%%s\\"' % (
a, a)
if isstringfunction(rout):
ret['rlength'] = getstrlength(rout['vars'][a])
if ret['rlength'] == '-1':
errmess('routsign2map: expected explicit specification of the length of the string returned by the fortran function %s; taking 10.\n' % (
repr(rout['name'])))
ret['rlength'] = '10'
if hasnote(rout):
ret['note'] = rout['note']
rout['note'] = ['See elsewhere.']
return ret
def modsign2map(m):
"""
modulename
"""
if ismodule(m):
ret = {'f90modulename': m['name'],
'F90MODULENAME': m['name'].upper(),
'texf90modulename': m['name'].replace('_', '\\_')}
else:
ret = {'modulename': m['name'],
'MODULENAME': m['name'].upper(),
'texmodulename': m['name'].replace('_', '\\_')}
ret['restdoc'] = getrestdoc(m) or []
if hasnote(m):
ret['note'] = m['note']
ret['usercode'] = getusercode(m) or ''
ret['usercode1'] = getusercode1(m) or ''
if m['body']:
ret['interface_usercode'] = getusercode(m['body'][0]) or ''
else:
ret['interface_usercode'] = ''
ret['pymethoddef'] = getpymethoddef(m) or ''
if 'coutput' in m:
ret['coutput'] = m['coutput']
if 'f2py_wrapper_output' in m:
ret['f2py_wrapper_output'] = m['f2py_wrapper_output']
return ret
def cb_sign2map(a, var, index=None):
ret = {'varname': a}
if index is None or 1: # disable 7712 patch
ret['varname_i'] = ret['varname']
else:
ret['varname_i'] = ret['varname'] + '_' + str(index)
ret['ctype'] = getctype(var)
if ret['ctype'] in c2capi_map:
ret['atype'] = c2capi_map[ret['ctype']]
if ret['ctype'] in cformat_map:
ret['showvalueformat'] = '%s' % (cformat_map[ret['ctype']])
if isarray(var):
ret = dictappend(ret, getarrdims(a, var))
ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, var)
if hasnote(var):
ret['note'] = var['note']
var['note'] = ['See elsewhere.']
return ret
def cb_routsign2map(rout, um):
"""
name,begintitle,endtitle,argname
ctype,rctype,maxnofargs,nofoptargs,returncptr
"""
ret = {'name': 'cb_%s_in_%s' % (rout['name'], um),
'returncptr': ''}
if isintent_callback(rout):
if '_' in rout['name']:
F_FUNC = 'F_FUNC_US'
else:
F_FUNC = 'F_FUNC'
ret['callbackname'] = '%s(%s,%s)' \
% (F_FUNC,
rout['name'].lower(),
rout['name'].upper(),
)
ret['static'] = 'extern'
else:
ret['callbackname'] = ret['name']
ret['static'] = 'static'
ret['argname'] = rout['name']
ret['begintitle'] = gentitle(ret['name'])
ret['endtitle'] = gentitle('end of %s' % ret['name'])
ret['ctype'] = getctype(rout)
ret['rctype'] = 'void'
if ret['ctype'] == 'string':
ret['rctype'] = 'void'
else:
ret['rctype'] = ret['ctype']
if ret['rctype'] != 'void':
if iscomplexfunction(rout):
ret['returncptr'] = """
#ifdef F2PY_CB_RETURNCOMPLEX
return_value=
#endif
"""
else:
ret['returncptr'] = 'return_value='
if ret['ctype'] in cformat_map:
ret['showvalueformat'] = '%s' % (cformat_map[ret['ctype']])
if isstringfunction(rout):
ret['strlength'] = getstrlength(rout)
if isfunction(rout):
if 'result' in rout:
a = rout['result']
else:
a = rout['name']
if hasnote(rout['vars'][a]):
ret['note'] = rout['vars'][a]['note']
rout['vars'][a]['note'] = ['See elsewhere.']
ret['rname'] = a
ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, rout)
if iscomplexfunction(rout):
ret['rctype'] = """
#ifdef F2PY_CB_RETURNCOMPLEX
#ctype#
#else
void
#endif
"""
else:
if hasnote(rout):
ret['note'] = rout['note']
rout['note'] = ['See elsewhere.']
nofargs = 0
nofoptargs = 0
if 'args' in rout and 'vars' in rout:
for a in rout['args']:
var = rout['vars'][a]
if l_or(isintent_in, isintent_inout)(var):
nofargs = nofargs + 1
if isoptional(var):
nofoptargs = nofoptargs + 1
ret['maxnofargs'] = repr(nofargs)
ret['nofoptargs'] = repr(nofoptargs)
if hasnote(rout) and isfunction(rout) and 'result' in rout:
ret['routnote'] = rout['note']
rout['note'] = ['See elsewhere.']
return ret
def common_sign2map(a, var): # obsolute
ret = {'varname': a, 'ctype': getctype(var)}
if isstringarray(var):
ret['ctype'] = 'char'
if ret['ctype'] in c2capi_map:
ret['atype'] = c2capi_map[ret['ctype']]
if ret['ctype'] in cformat_map:
ret['showvalueformat'] = '%s' % (cformat_map[ret['ctype']])
if isarray(var):
ret = dictappend(ret, getarrdims(a, var))
elif isstring(var):
ret['size'] = getstrlength(var)
ret['rank'] = '1'
ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, var)
if hasnote(var):
ret['note'] = var['note']
var['note'] = ['See elsewhere.']
# for strings this returns 0-rank but actually is 1-rank
ret['arrdocstr'] = getarrdocsign(a, var)
return ret

View File

@@ -0,0 +1,578 @@
#!/usr/bin/env python
"""
Build call-back mechanism for f2py2e.
Copyright 2000 Pearu Peterson all rights reserved,
Pearu Peterson <pearu@ioc.ee>
Permission to use, modify, and distribute this software is given under the
terms of the NumPy License.
NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
$Date: 2005/07/20 11:27:58 $
Pearu Peterson
"""
from __future__ import division, absolute_import, print_function
from . import __version__
from .auxfuncs import (
applyrules, debugcapi, dictappend, errmess, getargs, hasnote, isarray,
iscomplex, iscomplexarray, iscomplexfunction, isfunction, isintent_c,
isintent_hide, isintent_in, isintent_inout, isintent_nothide,
isintent_out, isoptional, isrequired, isscalar, isstring,
isstringfunction, issubroutine, l_and, l_not, l_or, outmess, replace,
stripcomma, throw_error
)
from . import cfuncs
f2py_version = __version__.version
################## Rules for callback function ##############
cb_routine_rules = {
'cbtypedefs': 'typedef #rctype#(*#name#_typedef)(#optargs_td##args_td##strarglens_td##noargs#);',
'body': """
#begintitle#
PyObject *#name#_capi = NULL;/*was Py_None*/
PyTupleObject *#name#_args_capi = NULL;
int #name#_nofargs = 0;
jmp_buf #name#_jmpbuf;
/*typedef #rctype#(*#name#_typedef)(#optargs_td##args_td##strarglens_td##noargs#);*/
#static# #rctype# #callbackname# (#optargs##args##strarglens##noargs#) {
\tPyTupleObject *capi_arglist = #name#_args_capi;
\tPyObject *capi_return = NULL;
\tPyObject *capi_tmp = NULL;
\tPyObject *capi_arglist_list = NULL;
\tint capi_j,capi_i = 0;
\tint capi_longjmp_ok = 1;
#decl#
#ifdef F2PY_REPORT_ATEXIT
f2py_cb_start_clock();
#endif
\tCFUNCSMESS(\"cb:Call-back function #name# (maxnofargs=#maxnofargs#(-#nofoptargs#))\\n\");
\tCFUNCSMESSPY(\"cb:#name#_capi=\",#name#_capi);
\tif (#name#_capi==NULL) {
\t\tcapi_longjmp_ok = 0;
\t\t#name#_capi = PyObject_GetAttrString(#modulename#_module,\"#argname#\");
\t}
\tif (#name#_capi==NULL) {
\t\tPyErr_SetString(#modulename#_error,\"cb: Callback #argname# not defined (as an argument or module #modulename# attribute).\\n\");
\t\tgoto capi_fail;
\t}
\tif (F2PyCapsule_Check(#name#_capi)) {
\t#name#_typedef #name#_cptr;
\t#name#_cptr = F2PyCapsule_AsVoidPtr(#name#_capi);
\t#returncptr#(*#name#_cptr)(#optargs_nm##args_nm##strarglens_nm#);
\t#return#
\t}
\tif (capi_arglist==NULL) {
\t\tcapi_longjmp_ok = 0;
\t\tcapi_tmp = PyObject_GetAttrString(#modulename#_module,\"#argname#_extra_args\");
\t\tif (capi_tmp) {
\t\t\tcapi_arglist = (PyTupleObject *)PySequence_Tuple(capi_tmp);
\t\t\tif (capi_arglist==NULL) {
\t\t\t\tPyErr_SetString(#modulename#_error,\"Failed to convert #modulename#.#argname#_extra_args to tuple.\\n\");
\t\t\t\tgoto capi_fail;
\t\t\t}
\t\t} else {
\t\t\tPyErr_Clear();
\t\t\tcapi_arglist = (PyTupleObject *)Py_BuildValue(\"()\");
\t\t}
\t}
\tif (capi_arglist == NULL) {
\t\tPyErr_SetString(#modulename#_error,\"Callback #argname# argument list is not set.\\n\");
\t\tgoto capi_fail;
\t}
#setdims#
#ifdef PYPY_VERSION
#define CAPI_ARGLIST_SETITEM(idx, value) PyList_SetItem((PyObject *)capi_arglist_list, idx, value)
\tcapi_arglist_list = PySequence_List(capi_arglist);
\tif (capi_arglist_list == NULL) goto capi_fail;
#else
#define CAPI_ARGLIST_SETITEM(idx, value) PyTuple_SetItem((PyObject *)capi_arglist, idx, value)
#endif
#pyobjfrom#
#undef CAPI_ARGLIST_SETITEM
#ifdef PYPY_VERSION
\tCFUNCSMESSPY(\"cb:capi_arglist=\",capi_arglist_list);
#else
\tCFUNCSMESSPY(\"cb:capi_arglist=\",capi_arglist);
#endif
\tCFUNCSMESS(\"cb:Call-back calling Python function #argname#.\\n\");
#ifdef F2PY_REPORT_ATEXIT
f2py_cb_start_call_clock();
#endif
#ifdef PYPY_VERSION
\tcapi_return = PyObject_CallObject(#name#_capi,(PyObject *)capi_arglist_list);
\tPy_DECREF(capi_arglist_list);
\tcapi_arglist_list = NULL;
#else
\tcapi_return = PyObject_CallObject(#name#_capi,(PyObject *)capi_arglist);
#endif
#ifdef F2PY_REPORT_ATEXIT
f2py_cb_stop_call_clock();
#endif
\tCFUNCSMESSPY(\"cb:capi_return=\",capi_return);
\tif (capi_return == NULL) {
\t\tfprintf(stderr,\"capi_return is NULL\\n\");
\t\tgoto capi_fail;
\t}
\tif (capi_return == Py_None) {
\t\tPy_DECREF(capi_return);
\t\tcapi_return = Py_BuildValue(\"()\");
\t}
\telse if (!PyTuple_Check(capi_return)) {
\t\tcapi_return = Py_BuildValue(\"(N)\",capi_return);
\t}
\tcapi_j = PyTuple_Size(capi_return);
\tcapi_i = 0;
#frompyobj#
\tCFUNCSMESS(\"cb:#name#:successful\\n\");
\tPy_DECREF(capi_return);
#ifdef F2PY_REPORT_ATEXIT
f2py_cb_stop_clock();
#endif
\tgoto capi_return_pt;
capi_fail:
\tfprintf(stderr,\"Call-back #name# failed.\\n\");
\tPy_XDECREF(capi_return);
\tPy_XDECREF(capi_arglist_list);
\tif (capi_longjmp_ok)
\t\tlongjmp(#name#_jmpbuf,-1);
capi_return_pt:
\t;
#return#
}
#endtitle#
""",
'need': ['setjmp.h', 'CFUNCSMESS'],
'maxnofargs': '#maxnofargs#',
'nofoptargs': '#nofoptargs#',
'docstr': """\
\tdef #argname#(#docsignature#): return #docreturn#\\n\\
#docstrsigns#""",
'latexdocstr': """
{{}\\verb@def #argname#(#latexdocsignature#): return #docreturn#@{}}
#routnote#
#latexdocstrsigns#""",
'docstrshort': 'def #argname#(#docsignature#): return #docreturn#'
}
cb_rout_rules = [
{ # Init
'separatorsfor': {'decl': '\n',
'args': ',', 'optargs': '', 'pyobjfrom': '\n', 'freemem': '\n',
'args_td': ',', 'optargs_td': '',
'args_nm': ',', 'optargs_nm': '',
'frompyobj': '\n', 'setdims': '\n',
'docstrsigns': '\\n"\n"',
'latexdocstrsigns': '\n',
'latexdocstrreq': '\n', 'latexdocstropt': '\n',
'latexdocstrout': '\n', 'latexdocstrcbs': '\n',
},
'decl': '/*decl*/', 'pyobjfrom': '/*pyobjfrom*/', 'frompyobj': '/*frompyobj*/',
'args': [], 'optargs': '', 'return': '', 'strarglens': '', 'freemem': '/*freemem*/',
'args_td': [], 'optargs_td': '', 'strarglens_td': '',
'args_nm': [], 'optargs_nm': '', 'strarglens_nm': '',
'noargs': '',
'setdims': '/*setdims*/',
'docstrsigns': '', 'latexdocstrsigns': '',
'docstrreq': '\tRequired arguments:',
'docstropt': '\tOptional arguments:',
'docstrout': '\tReturn objects:',
'docstrcbs': '\tCall-back functions:',
'docreturn': '', 'docsign': '', 'docsignopt': '',
'latexdocstrreq': '\\noindent Required arguments:',
'latexdocstropt': '\\noindent Optional arguments:',
'latexdocstrout': '\\noindent Return objects:',
'latexdocstrcbs': '\\noindent Call-back functions:',
'routnote': {hasnote: '--- #note#', l_not(hasnote): ''},
}, { # Function
'decl': '\t#ctype# return_value;',
'frompyobj': [{debugcapi: '\tCFUNCSMESS("cb:Getting return_value->");'},
'\tif (capi_j>capi_i)\n\t\tGETSCALARFROMPYTUPLE(capi_return,capi_i++,&return_value,#ctype#,"#ctype#_from_pyobj failed in converting return_value of call-back function #name# to C #ctype#\\n");',
{debugcapi:
'\tfprintf(stderr,"#showvalueformat#.\\n",return_value);'}
],
'need': ['#ctype#_from_pyobj', {debugcapi: 'CFUNCSMESS'}, 'GETSCALARFROMPYTUPLE'],
'return': '\treturn return_value;',
'_check': l_and(isfunction, l_not(isstringfunction), l_not(iscomplexfunction))
},
{ # String function
'pyobjfrom': {debugcapi: '\tfprintf(stderr,"debug-capi:cb:#name#:%d:\\n",return_value_len);'},
'args': '#ctype# return_value,int return_value_len',
'args_nm': 'return_value,&return_value_len',
'args_td': '#ctype# ,int',
'frompyobj': [{debugcapi: '\tCFUNCSMESS("cb:Getting return_value->\\"");'},
"""\tif (capi_j>capi_i)
\t\tGETSTRFROMPYTUPLE(capi_return,capi_i++,return_value,return_value_len);""",
{debugcapi:
'\tfprintf(stderr,"#showvalueformat#\\".\\n",return_value);'}
],
'need': ['#ctype#_from_pyobj', {debugcapi: 'CFUNCSMESS'},
'string.h', 'GETSTRFROMPYTUPLE'],
'return': 'return;',
'_check': isstringfunction
},
{ # Complex function
'optargs': """
#ifndef F2PY_CB_RETURNCOMPLEX
#ctype# *return_value
#endif
""",
'optargs_nm': """
#ifndef F2PY_CB_RETURNCOMPLEX
return_value
#endif
""",
'optargs_td': """
#ifndef F2PY_CB_RETURNCOMPLEX
#ctype# *
#endif
""",
'decl': """
#ifdef F2PY_CB_RETURNCOMPLEX
\t#ctype# return_value;
#endif
""",
'frompyobj': [{debugcapi: '\tCFUNCSMESS("cb:Getting return_value->");'},
"""\
\tif (capi_j>capi_i)
#ifdef F2PY_CB_RETURNCOMPLEX
\t\tGETSCALARFROMPYTUPLE(capi_return,capi_i++,&return_value,#ctype#,\"#ctype#_from_pyobj failed in converting return_value of call-back function #name# to C #ctype#\\n\");
#else
\t\tGETSCALARFROMPYTUPLE(capi_return,capi_i++,return_value,#ctype#,\"#ctype#_from_pyobj failed in converting return_value of call-back function #name# to C #ctype#\\n\");
#endif
""",
{debugcapi: """
#ifdef F2PY_CB_RETURNCOMPLEX
\tfprintf(stderr,\"#showvalueformat#.\\n\",(return_value).r,(return_value).i);
#else
\tfprintf(stderr,\"#showvalueformat#.\\n\",(*return_value).r,(*return_value).i);
#endif
"""}
],
'return': """
#ifdef F2PY_CB_RETURNCOMPLEX
\treturn return_value;
#else
\treturn;
#endif
""",
'need': ['#ctype#_from_pyobj', {debugcapi: 'CFUNCSMESS'},
'string.h', 'GETSCALARFROMPYTUPLE', '#ctype#'],
'_check': iscomplexfunction
},
{'docstrout': '\t\t#pydocsignout#',
'latexdocstrout': ['\\item[]{{}\\verb@#pydocsignout#@{}}',
{hasnote: '--- #note#'}],
'docreturn': '#rname#,',
'_check': isfunction},
{'_check': issubroutine, 'return': 'return;'}
]
cb_arg_rules = [
{ # Doc
'docstropt': {l_and(isoptional, isintent_nothide): '\t\t#pydocsign#'},
'docstrreq': {l_and(isrequired, isintent_nothide): '\t\t#pydocsign#'},
'docstrout': {isintent_out: '\t\t#pydocsignout#'},
'latexdocstropt': {l_and(isoptional, isintent_nothide): ['\\item[]{{}\\verb@#pydocsign#@{}}',
{hasnote: '--- #note#'}]},
'latexdocstrreq': {l_and(isrequired, isintent_nothide): ['\\item[]{{}\\verb@#pydocsign#@{}}',
{hasnote: '--- #note#'}]},
'latexdocstrout': {isintent_out: ['\\item[]{{}\\verb@#pydocsignout#@{}}',
{l_and(hasnote, isintent_hide): '--- #note#',
l_and(hasnote, isintent_nothide): '--- See above.'}]},
'docsign': {l_and(isrequired, isintent_nothide): '#varname#,'},
'docsignopt': {l_and(isoptional, isintent_nothide): '#varname#,'},
'depend': ''
},
{
'args': {
l_and(isscalar, isintent_c): '#ctype# #varname_i#',
l_and(isscalar, l_not(isintent_c)): '#ctype# *#varname_i#_cb_capi',
isarray: '#ctype# *#varname_i#',
isstring: '#ctype# #varname_i#'
},
'args_nm': {
l_and(isscalar, isintent_c): '#varname_i#',
l_and(isscalar, l_not(isintent_c)): '#varname_i#_cb_capi',
isarray: '#varname_i#',
isstring: '#varname_i#'
},
'args_td': {
l_and(isscalar, isintent_c): '#ctype#',
l_and(isscalar, l_not(isintent_c)): '#ctype# *',
isarray: '#ctype# *',
isstring: '#ctype#'
},
# untested with multiple args
'strarglens': {isstring: ',int #varname_i#_cb_len'},
'strarglens_td': {isstring: ',int'}, # untested with multiple args
# untested with multiple args
'strarglens_nm': {isstring: ',#varname_i#_cb_len'},
},
{ # Scalars
'decl': {l_not(isintent_c): '\t#ctype# #varname_i#=(*#varname_i#_cb_capi);'},
'error': {l_and(isintent_c, isintent_out,
throw_error('intent(c,out) is forbidden for callback scalar arguments')):
''},
'frompyobj': [{debugcapi: '\tCFUNCSMESS("cb:Getting #varname#->");'},
{isintent_out:
'\tif (capi_j>capi_i)\n\t\tGETSCALARFROMPYTUPLE(capi_return,capi_i++,#varname_i#_cb_capi,#ctype#,"#ctype#_from_pyobj failed in converting argument #varname# of call-back function #name# to C #ctype#\\n");'},
{l_and(debugcapi, l_and(l_not(iscomplex), isintent_c)):
'\tfprintf(stderr,"#showvalueformat#.\\n",#varname_i#);'},
{l_and(debugcapi, l_and(l_not(iscomplex), l_not( isintent_c))):
'\tfprintf(stderr,"#showvalueformat#.\\n",*#varname_i#_cb_capi);'},
{l_and(debugcapi, l_and(iscomplex, isintent_c)):
'\tfprintf(stderr,"#showvalueformat#.\\n",(#varname_i#).r,(#varname_i#).i);'},
{l_and(debugcapi, l_and(iscomplex, l_not( isintent_c))):
'\tfprintf(stderr,"#showvalueformat#.\\n",(*#varname_i#_cb_capi).r,(*#varname_i#_cb_capi).i);'},
],
'need': [{isintent_out: ['#ctype#_from_pyobj', 'GETSCALARFROMPYTUPLE']},
{debugcapi: 'CFUNCSMESS'}],
'_check': isscalar
}, {
'pyobjfrom': [{isintent_in: """\
\tif (#name#_nofargs>capi_i)
\t\tif (CAPI_ARGLIST_SETITEM(capi_i++,pyobj_from_#ctype#1(#varname_i#)))
\t\t\tgoto capi_fail;"""},
{isintent_inout: """\
\tif (#name#_nofargs>capi_i)
\t\tif (CAPI_ARGLIST_SETITEM(capi_i++,pyarr_from_p_#ctype#1(#varname_i#_cb_capi)))
\t\t\tgoto capi_fail;"""}],
'need': [{isintent_in: 'pyobj_from_#ctype#1'},
{isintent_inout: 'pyarr_from_p_#ctype#1'},
{iscomplex: '#ctype#'}],
'_check': l_and(isscalar, isintent_nothide),
'_optional': ''
}, { # String
'frompyobj': [{debugcapi: '\tCFUNCSMESS("cb:Getting #varname#->\\"");'},
"""\tif (capi_j>capi_i)
\t\tGETSTRFROMPYTUPLE(capi_return,capi_i++,#varname_i#,#varname_i#_cb_len);""",
{debugcapi:
'\tfprintf(stderr,"#showvalueformat#\\":%d:.\\n",#varname_i#,#varname_i#_cb_len);'},
],
'need': ['#ctype#', 'GETSTRFROMPYTUPLE',
{debugcapi: 'CFUNCSMESS'}, 'string.h'],
'_check': l_and(isstring, isintent_out)
}, {
'pyobjfrom': [{debugcapi: '\tfprintf(stderr,"debug-capi:cb:#varname#=\\"#showvalueformat#\\":%d:\\n",#varname_i#,#varname_i#_cb_len);'},
{isintent_in: """\
\tif (#name#_nofargs>capi_i)
\t\tif (CAPI_ARGLIST_SETITEM(capi_i++,pyobj_from_#ctype#1size(#varname_i#,#varname_i#_cb_len)))
\t\t\tgoto capi_fail;"""},
{isintent_inout: """\
\tif (#name#_nofargs>capi_i) {
\t\tint #varname_i#_cb_dims[] = {#varname_i#_cb_len};
\t\tif (CAPI_ARGLIST_SETITEM(capi_i++,pyarr_from_p_#ctype#1(#varname_i#,#varname_i#_cb_dims)))
\t\t\tgoto capi_fail;
\t}"""}],
'need': [{isintent_in: 'pyobj_from_#ctype#1size'},
{isintent_inout: 'pyarr_from_p_#ctype#1'}],
'_check': l_and(isstring, isintent_nothide),
'_optional': ''
},
# Array ...
{
'decl': '\tnpy_intp #varname_i#_Dims[#rank#] = {#rank*[-1]#};',
'setdims': '\t#cbsetdims#;',
'_check': isarray,
'_depend': ''
},
{
'pyobjfrom': [{debugcapi: '\tfprintf(stderr,"debug-capi:cb:#varname#\\n");'},
{isintent_c: """\
\tif (#name#_nofargs>capi_i) {
\t\tint itemsize_ = #atype# == NPY_STRING ? 1 : 0;
\t\t/*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#,itemsize_,NPY_ARRAY_CARRAY,NULL);
""",
l_not(isintent_c): """\
\tif (#name#_nofargs>capi_i) {
\t\tint itemsize_ = #atype# == NPY_STRING ? 1 : 0;
\t\t/*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#,itemsize_,NPY_ARRAY_FARRAY,NULL);
""",
},
"""
\t\tif (tmp_arr==NULL)
\t\t\tgoto capi_fail;
\t\tif (CAPI_ARGLIST_SETITEM(capi_i++,(PyObject *)tmp_arr))
\t\t\tgoto capi_fail;
}"""],
'_check': l_and(isarray, isintent_nothide, l_or(isintent_in, isintent_inout)),
'_optional': '',
}, {
'frompyobj': [{debugcapi: '\tCFUNCSMESS("cb:Getting #varname#->");'},
"""\tif (capi_j>capi_i) {
\t\tPyArrayObject *rv_cb_arr = NULL;
\t\tif ((capi_tmp = PyTuple_GetItem(capi_return,capi_i++))==NULL) goto capi_fail;
\t\trv_cb_arr = array_from_pyobj(#atype#,#varname_i#_Dims,#rank#,F2PY_INTENT_IN""",
{isintent_c: '|F2PY_INTENT_C'},
""",capi_tmp);
\t\tif (rv_cb_arr == NULL) {
\t\t\tfprintf(stderr,\"rv_cb_arr is NULL\\n\");
\t\t\tgoto capi_fail;
\t\t}
\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}
\t}""",
{debugcapi: '\tfprintf(stderr,"<-.\\n");'},
],
'need': ['MEMCOPY', {iscomplexarray: '#ctype#'}],
'_check': l_and(isarray, isintent_out)
}, {
'docreturn': '#varname#,',
'_check': isintent_out
}
]
################## Build call-back module #############
cb_map = {}
def buildcallbacks(m):
global cb_map
cb_map[m['name']] = []
for bi in m['body']:
if bi['block'] == 'interface':
for b in bi['body']:
if b:
buildcallback(b, m['name'])
else:
errmess('warning: empty body for %s\n' % (m['name']))
def buildcallback(rout, um):
global cb_map
from . import capi_maps
outmess('\tConstructing call-back function "cb_%s_in_%s"\n' %
(rout['name'], um))
args, depargs = getargs(rout)
capi_maps.depargs = depargs
var = rout['vars']
vrd = capi_maps.cb_routsign2map(rout, um)
rd = dictappend({}, vrd)
cb_map[um].append([rout['name'], rd['name']])
for r in cb_rout_rules:
if ('_check' in r and r['_check'](rout)) or ('_check' not in r):
ar = applyrules(r, vrd, rout)
rd = dictappend(rd, ar)
savevrd = {}
for i, a in enumerate(args):
vrd = capi_maps.cb_sign2map(a, var[a], index=i)
savevrd[a] = vrd
for r in cb_arg_rules:
if '_depend' in r:
continue
if '_optional' in r and isoptional(var[a]):
continue
if ('_check' in r and r['_check'](var[a])) or ('_check' not in r):
ar = applyrules(r, vrd, var[a])
rd = dictappend(rd, ar)
if '_break' in r:
break
for a in args:
vrd = savevrd[a]
for r in cb_arg_rules:
if '_depend' in r:
continue
if ('_optional' not in r) or ('_optional' in r and isrequired(var[a])):
continue
if ('_check' in r and r['_check'](var[a])) or ('_check' not in r):
ar = applyrules(r, vrd, var[a])
rd = dictappend(rd, ar)
if '_break' in r:
break
for a in depargs:
vrd = savevrd[a]
for r in cb_arg_rules:
if '_depend' not in r:
continue
if '_optional' in r:
continue
if ('_check' in r and r['_check'](var[a])) or ('_check' not in r):
ar = applyrules(r, vrd, var[a])
rd = dictappend(rd, ar)
if '_break' in r:
break
if 'args' in rd and 'optargs' in rd:
if isinstance(rd['optargs'], list):
rd['optargs'] = rd['optargs'] + ["""
#ifndef F2PY_CB_RETURNCOMPLEX
,
#endif
"""]
rd['optargs_nm'] = rd['optargs_nm'] + ["""
#ifndef F2PY_CB_RETURNCOMPLEX
,
#endif
"""]
rd['optargs_td'] = rd['optargs_td'] + ["""
#ifndef F2PY_CB_RETURNCOMPLEX
,
#endif
"""]
if isinstance(rd['docreturn'], list):
rd['docreturn'] = stripcomma(
replace('#docreturn#', {'docreturn': rd['docreturn']}))
optargs = stripcomma(replace('#docsignopt#',
{'docsignopt': rd['docsignopt']}
))
if optargs == '':
rd['docsignature'] = stripcomma(
replace('#docsign#', {'docsign': rd['docsign']}))
else:
rd['docsignature'] = replace('#docsign#[#docsignopt#]',
{'docsign': rd['docsign'],
'docsignopt': optargs,
})
rd['latexdocsignature'] = rd['docsignature'].replace('_', '\\_')
rd['latexdocsignature'] = rd['latexdocsignature'].replace(',', ', ')
rd['docstrsigns'] = []
rd['latexdocstrsigns'] = []
for k in ['docstrreq', 'docstropt', 'docstrout', 'docstrcbs']:
if k in rd and isinstance(rd[k], list):
rd['docstrsigns'] = rd['docstrsigns'] + rd[k]
k = 'latex' + k
if k in rd and isinstance(rd[k], list):
rd['latexdocstrsigns'] = rd['latexdocstrsigns'] + rd[k][0:1] +\
['\\begin{description}'] + rd[k][1:] +\
['\\end{description}']
if 'args' not in rd:
rd['args'] = ''
rd['args_td'] = ''
rd['args_nm'] = ''
if not (rd.get('args') or rd.get('optargs') or rd.get('strarglens')):
rd['noargs'] = 'void'
ar = applyrules(cb_routine_rules, rd)
cfuncs.callbacks[rd['name']] = ar['body']
if isinstance(ar['need'], str):
ar['need'] = [ar['need']]
if 'need' in rd:
for t in cfuncs.typedefs.keys():
if t in rd['need']:
ar['need'].append(t)
cfuncs.typedefs_generated[rd['name'] + '_typedef'] = ar['cbtypedefs']
ar['need'].append(rd['name'] + '_typedef')
cfuncs.needs[rd['name']] = ar['need']
capi_maps.lcb2_map[rd['name']] = {'maxnofargs': ar['maxnofargs'],
'nofoptargs': ar['nofoptargs'],
'docstr': ar['docstr'],
'latexdocstr': ar['latexdocstr'],
'argname': rd['argname']
}
outmess('\t %s\n' % (ar['docstrshort']))
return
################## Build call-back function #############

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,150 @@
#!/usr/bin/env python
"""
Build common block mechanism for f2py2e.
Copyright 2000 Pearu Peterson all rights reserved,
Pearu Peterson <pearu@ioc.ee>
Permission to use, modify, and distribute this software is given under the
terms of the NumPy License
NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
$Date: 2005/05/06 10:57:33 $
Pearu Peterson
"""
from __future__ import division, absolute_import, print_function
__version__ = "$Revision: 1.19 $"[10:-1]
from . import __version__
f2py_version = __version__.version
from .auxfuncs import (
hasbody, hascommon, hasnote, isintent_hide, outmess
)
from . import capi_maps
from . import func2subr
from .crackfortran import rmbadname
def findcommonblocks(block, top=1):
ret = []
if hascommon(block):
for n in block['common'].keys():
vars = {}
for v in block['common'][n]:
vars[v] = block['vars'][v]
ret.append((n, block['common'][n], vars))
elif hasbody(block):
for b in block['body']:
ret = ret + findcommonblocks(b, 0)
if top:
tret = []
names = []
for t in ret:
if t[0] not in names:
names.append(t[0])
tret.append(t)
return tret
return ret
def buildhooks(m):
ret = {'commonhooks': [], 'initcommonhooks': [],
'docs': ['"COMMON blocks:\\n"']}
fwrap = ['']
def fadd(line, s=fwrap):
s[0] = '%s\n %s' % (s[0], line)
chooks = ['']
def cadd(line, s=chooks):
s[0] = '%s\n%s' % (s[0], line)
ihooks = ['']
def iadd(line, s=ihooks):
s[0] = '%s\n%s' % (s[0], line)
doc = ['']
def dadd(line, s=doc):
s[0] = '%s\n%s' % (s[0], line)
for (name, vnames, vars) in findcommonblocks(m):
lower_name = name.lower()
hnames, inames = [], []
for n in vnames:
if isintent_hide(vars[n]):
hnames.append(n)
else:
inames.append(n)
if hnames:
outmess('\t\tConstructing COMMON block support for "%s"...\n\t\t %s\n\t\t Hidden: %s\n' % (
name, ','.join(inames), ','.join(hnames)))
else:
outmess('\t\tConstructing COMMON block support for "%s"...\n\t\t %s\n' % (
name, ','.join(inames)))
fadd('subroutine f2pyinit%s(setupfunc)' % name)
fadd('external setupfunc')
for n in vnames:
fadd(func2subr.var2fixfortran(vars, n))
if name == '_BLNK_':
fadd('common %s' % (','.join(vnames)))
else:
fadd('common /%s/ %s' % (name, ','.join(vnames)))
fadd('call setupfunc(%s)' % (','.join(inames)))
fadd('end\n')
cadd('static FortranDataDef f2py_%s_def[] = {' % (name))
idims = []
for n in inames:
ct = capi_maps.getctype(vars[n])
at = capi_maps.c2capi_map[ct]
dm = capi_maps.getarrdims(n, vars[n])
if dm['dims']:
idims.append('(%s)' % (dm['dims']))
else:
idims.append('')
dms = dm['dims'].strip()
if not dms:
dms = '-1'
cadd('\t{\"%s\",%s,{{%s}},%s},' % (n, dm['rank'], dms, at))
cadd('\t{NULL}\n};')
inames1 = rmbadname(inames)
inames1_tps = ','.join(['char *' + s for s in inames1])
cadd('static void f2py_setup_%s(%s) {' % (name, inames1_tps))
cadd('\tint i_f2py=0;')
for n in inames1:
cadd('\tf2py_%s_def[i_f2py++].data = %s;' % (name, n))
cadd('}')
if '_' in lower_name:
F_FUNC = 'F_FUNC_US'
else:
F_FUNC = 'F_FUNC'
cadd('extern void %s(f2pyinit%s,F2PYINIT%s)(void(*)(%s));'
% (F_FUNC, lower_name, name.upper(),
','.join(['char*'] * len(inames1))))
cadd('static void f2py_init_%s(void) {' % name)
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))
tname = name.replace('_', '\\_')
dadd('\\subsection{Common block \\texttt{%s}}\n' % (tname))
dadd('\\begin{description}')
for n in inames:
dadd('\\item[]{{}\\verb@%s@{}}' %
(capi_maps.getarrdocsign(n, vars[n])))
if hasnote(vars[n]):
note = vars[n]['note']
if isinstance(note, list):
note = '\n'.join(note)
dadd('--- %s' % (note))
dadd('\\end{description}')
ret['docs'].append(
'"\t/%s/ %s\\n"' % (name, ','.join(map(lambda v, d: v + d, inames, idims))))
ret['commonhooks'] = chooks
ret['initcommonhooks'] = ihooks
ret['latexdoc'] = doc[0]
if len(ret['docs']) <= 1:
ret['docs'] = ''
return ret, fwrap[0]

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,156 @@
#!/usr/bin/env python
from __future__ import division, absolute_import, print_function
import os
import sys
import tempfile
def run_command(cmd):
print('Running %r:' % (cmd))
os.system(cmd)
print('------')
def run():
_path = os.getcwd()
os.chdir(tempfile.gettempdir())
print('------')
print('os.name=%r' % (os.name))
print('------')
print('sys.platform=%r' % (sys.platform))
print('------')
print('sys.version:')
print(sys.version)
print('------')
print('sys.prefix:')
print(sys.prefix)
print('------')
print('sys.path=%r' % (':'.join(sys.path)))
print('------')
try:
import numpy
has_newnumpy = 1
except ImportError:
print('Failed to import new numpy:', sys.exc_info()[1])
has_newnumpy = 0
try:
from numpy.f2py import f2py2e
has_f2py2e = 1
except ImportError:
print('Failed to import f2py2e:', sys.exc_info()[1])
has_f2py2e = 0
try:
import numpy.distutils
has_numpy_distutils = 2
except ImportError:
try:
import numpy_distutils
has_numpy_distutils = 1
except ImportError:
print('Failed to import numpy_distutils:', sys.exc_info()[1])
has_numpy_distutils = 0
if has_newnumpy:
try:
print('Found new numpy version %r in %s' %
(numpy.__version__, numpy.__file__))
except Exception as msg:
print('error:', msg)
print('------')
if has_f2py2e:
try:
print('Found f2py2e version %r in %s' %
(f2py2e.__version__.version, f2py2e.__file__))
except Exception as msg:
print('error:', msg)
print('------')
if has_numpy_distutils:
try:
if has_numpy_distutils == 2:
print('Found numpy.distutils version %r in %r' % (
numpy.distutils.__version__,
numpy.distutils.__file__))
else:
print('Found numpy_distutils version %r in %r' % (
numpy_distutils.numpy_distutils_version.numpy_distutils_version,
numpy_distutils.__file__))
print('------')
except Exception as msg:
print('error:', msg)
print('------')
try:
if has_numpy_distutils == 1:
print(
'Importing numpy_distutils.command.build_flib ...', end=' ')
import numpy_distutils.command.build_flib as build_flib
print('ok')
print('------')
try:
print(
'Checking availability of supported Fortran compilers:')
for compiler_class in build_flib.all_compilers:
compiler_class(verbose=1).is_available()
print('------')
except Exception as msg:
print('error:', msg)
print('------')
except Exception as msg:
print(
'error:', msg, '(ignore it, build_flib is obsolute for numpy.distutils 0.2.2 and up)')
print('------')
try:
if has_numpy_distutils == 2:
print('Importing numpy.distutils.fcompiler ...', end=' ')
import numpy.distutils.fcompiler as fcompiler
else:
print('Importing numpy_distutils.fcompiler ...', end=' ')
import numpy_distutils.fcompiler as fcompiler
print('ok')
print('------')
try:
print('Checking availability of supported Fortran compilers:')
fcompiler.show_fcompilers()
print('------')
except Exception as msg:
print('error:', msg)
print('------')
except Exception as msg:
print('error:', msg)
print('------')
try:
if has_numpy_distutils == 2:
print('Importing numpy.distutils.cpuinfo ...', end=' ')
from numpy.distutils.cpuinfo import cpuinfo
print('ok')
print('------')
else:
try:
print(
'Importing numpy_distutils.command.cpuinfo ...', end=' ')
from numpy_distutils.command.cpuinfo import cpuinfo
print('ok')
print('------')
except Exception as msg:
print('error:', msg, '(ignore it)')
print('Importing numpy_distutils.cpuinfo ...', end=' ')
from numpy_distutils.cpuinfo import cpuinfo
print('ok')
print('------')
cpu = cpuinfo()
print('CPU information:', end=' ')
for name in dir(cpuinfo):
if name[0] == '_' and name[1] != '_' and getattr(cpu, name[1:])():
print(name[1:], end=' ')
print('------')
except Exception as msg:
print('error:', msg)
print('------')
os.chdir(_path)
if __name__ == "__main__":
run()

View File

@@ -0,0 +1,656 @@
#!/usr/bin/env python
"""
f2py2e - Fortran to Python C/API generator. 2nd Edition.
See __usage__ below.
Copyright 1999--2011 Pearu Peterson all rights reserved,
Pearu Peterson <pearu@cens.ioc.ee>
Permission to use, modify, and distribute this software is given under the
terms of the NumPy License.
NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
$Date: 2005/05/06 08:31:19 $
Pearu Peterson
"""
from __future__ import division, absolute_import, print_function
import sys
import os
import pprint
import re
from . import crackfortran
from . import rules
from . import cb_rules
from . import auxfuncs
from . import cfuncs
from . import f90mod_rules
from . import __version__
f2py_version = __version__.version
errmess = sys.stderr.write
# outmess=sys.stdout.write
show = pprint.pprint
outmess = auxfuncs.outmess
try:
from numpy import __version__ as numpy_version
except ImportError:
numpy_version = 'N/A'
__usage__ = """\
Usage:
1) To construct extension module sources:
f2py [<options>] <fortran files> [[[only:]||[skip:]] \\
<fortran functions> ] \\
[: <fortran files> ...]
2) To compile fortran files and build extension modules:
f2py -c [<options>, <build_flib options>, <extra options>] <fortran files>
3) To generate signature files:
f2py -h <filename.pyf> ...< same options as in (1) >
Description: This program generates a Python C/API file (<modulename>module.c)
that contains wrappers for given fortran functions so that they
can be called from Python. With the -c option the corresponding
extension modules are built.
Options:
--2d-numpy Use numpy.f2py tool with NumPy support. [DEFAULT]
--2d-numeric Use f2py2e tool with Numeric support.
--2d-numarray Use f2py2e tool with Numarray support.
--g3-numpy Use 3rd generation f2py from the separate f2py package.
[NOT AVAILABLE YET]
-h <filename> Write signatures of the fortran routines to file <filename>
and exit. You can then edit <filename> and use it instead
of <fortran files>. If <filename>==stdout then the
signatures are printed to stdout.
<fortran functions> Names of fortran routines for which Python C/API
functions will be generated. Default is all that are found
in <fortran files>.
<fortran files> Paths to fortran/signature files that will be scanned for
<fortran functions> in order to determine their signatures.
skip: Ignore fortran functions that follow until `:'.
only: Use only fortran functions that follow until `:'.
: Get back to <fortran files> mode.
-m <modulename> Name of the module; f2py generates a Python/C API
file <modulename>module.c or extension module <modulename>.
Default is 'untitled'.
--[no-]lower Do [not] lower the cases in <fortran files>. By default,
--lower is assumed with -h key, and --no-lower without -h key.
--build-dir <dirname> All f2py generated files are created in <dirname>.
Default is tempfile.mkdtemp().
--overwrite-signature Overwrite existing signature file.
--[no-]latex-doc Create (or not) <modulename>module.tex.
Default is --no-latex-doc.
--short-latex Create 'incomplete' LaTeX document (without commands
\\documentclass, \\tableofcontents, and \\begin{document},
\\end{document}).
--[no-]rest-doc Create (or not) <modulename>module.rst.
Default is --no-rest-doc.
--debug-capi Create C/API code that reports the state of the wrappers
during runtime. Useful for debugging.
--[no-]wrap-functions Create Fortran subroutine wrappers to Fortran 77
functions. --wrap-functions is default because it ensures
maximum portability/compiler independence.
--include-paths <path1>:<path2>:... Search include files from the given
directories.
--help-link [..] List system resources found by system_info.py. See also
--link-<resource> switch below. [..] is optional list
of resources names. E.g. try 'f2py --help-link lapack_opt'.
--quiet Run quietly.
--verbose Run with extra verbosity.
-v Print f2py version ID and exit.
numpy.distutils options (only effective with -c):
--fcompiler= Specify Fortran compiler type by vendor
--compiler= Specify C compiler type (as defined by distutils)
--help-fcompiler List available Fortran compilers and exit
--f77exec= Specify the path to F77 compiler
--f90exec= Specify the path to F90 compiler
--f77flags= Specify F77 compiler flags
--f90flags= Specify F90 compiler flags
--opt= Specify optimization flags
--arch= Specify architecture specific optimization flags
--noopt Compile without optimization
--noarch Compile without arch-dependent optimization
--debug Compile with debugging information
Extra options (only effective with -c):
--link-<resource> Link extension module with <resource> as defined
by numpy.distutils/system_info.py. E.g. to link
with optimized LAPACK libraries (vecLib on MacOSX,
ATLAS elsewhere), use --link-lapack_opt.
See also --help-link switch.
-L/path/to/lib/ -l<libname>
-D<define> -U<name>
-I/path/to/include/
<filename>.o <filename>.so <filename>.a
Using the following macros may be required with non-gcc Fortran
compilers:
-DPREPEND_FORTRAN -DNO_APPEND_FORTRAN -DUPPERCASE_FORTRAN
-DUNDERSCORE_G77
When using -DF2PY_REPORT_ATEXIT, a performance report of F2PY
interface is printed out at exit (platforms: Linux).
When using -DF2PY_REPORT_ON_ARRAY_COPY=<int>, a message is
sent to stderr whenever F2PY interface makes a copy of an
array. Integer <int> sets the threshold for array sizes when
a message should be shown.
Version: %s
numpy Version: %s
Requires: Python 2.3 or higher.
License: NumPy license (see LICENSE.txt in the NumPy source code)
Copyright 1999 - 2011 Pearu Peterson all rights reserved.
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
verbose = 1
dolc = -1
dolatexdoc = 0
dorestdoc = 0
wrapfuncs = 1
buildpath = '.'
include_paths = []
signsfile, modulename = None, None
options = {'buildpath': buildpath,
'coutput': None,
'f2py_wrapper_output': None}
for l in inputline:
if l == '':
pass
elif l == 'only:':
f = 0
elif l == 'skip:':
f = -1
elif l == ':':
f = 1
elif l[:8] == '--debug-':
debug.append(l[8:])
elif l == '--lower':
dolc = 1
elif l == '--build-dir':
f6 = 1
elif l == '--no-lower':
dolc = 0
elif l == '--quiet':
verbose = 0
elif l == '--verbose':
verbose += 1
elif l == '--latex-doc':
dolatexdoc = 1
elif l == '--no-latex-doc':
dolatexdoc = 0
elif l == '--rest-doc':
dorestdoc = 1
elif l == '--no-rest-doc':
dorestdoc = 0
elif l == '--wrap-functions':
wrapfuncs = 1
elif l == '--no-wrap-functions':
wrapfuncs = 0
elif l == '--short-latex':
options['shortlatex'] = 1
elif l == '--coutput':
f8 = 1
elif l == '--f2py-wrapper-output':
f9 = 1
elif l == '--overwrite-signature':
options['h-overwrite'] = 1
elif l == '-h':
f2 = 1
elif l == '-m':
f3 = 1
elif l[:2] == '-v':
print(f2py_version)
sys.exit()
elif l == '--show-compilers':
f5 = 1
elif l[:8] == '-include':
cfuncs.outneeds['userincludes'].append(l[9:-1])
cfuncs.userincludes[l[9:-1]] = '#include ' + l[8:]
elif l[:15] in '--include_paths':
outmess(
'f2py option --include_paths is deprecated, use --include-paths instead.\n')
f7 = 1
elif l[:15] in '--include-paths':
f7 = 1
elif l[0] == '-':
errmess('Unknown option %s\n' % repr(l))
sys.exit()
elif f2:
f2 = 0
signsfile = l
elif f3:
f3 = 0
modulename = l
elif f6:
f6 = 0
buildpath = l
elif f7:
f7 = 0
include_paths.extend(l.split(os.pathsep))
elif f8:
f8 = 0
options["coutput"] = l
elif f9:
f9 = 0
options["f2py_wrapper_output"] = l
elif f == 1:
try:
open(l).close()
files.append(l)
except IOError as detail:
errmess('IOError: %s. Skipping file "%s".\n' %
(str(detail), l))
elif f == -1:
skipfuncs.append(l)
elif f == 0:
onlyfuncs.append(l)
if not f5 and not files and not modulename:
print(__usage__)
sys.exit()
if not os.path.isdir(buildpath):
if not verbose:
outmess('Creating build directory %s' % (buildpath))
os.mkdir(buildpath)
if signsfile:
signsfile = os.path.join(buildpath, signsfile)
if signsfile and os.path.isfile(signsfile) and 'h-overwrite' not in options:
errmess(
'Signature file "%s" exists!!! Use --overwrite-signature to overwrite.\n' % (signsfile))
sys.exit()
options['debug'] = debug
options['verbose'] = verbose
if dolc == -1 and not signsfile:
options['do-lower'] = 0
else:
options['do-lower'] = dolc
if modulename:
options['module'] = modulename
if signsfile:
options['signsfile'] = signsfile
if onlyfuncs:
options['onlyfuncs'] = onlyfuncs
if skipfuncs:
options['skipfuncs'] = skipfuncs
options['dolatexdoc'] = dolatexdoc
options['dorestdoc'] = dorestdoc
options['wrapfuncs'] = wrapfuncs
options['buildpath'] = buildpath
options['include_paths'] = include_paths
return files, options
def callcrackfortran(files, options):
rules.options = options
crackfortran.debug = options['debug']
crackfortran.verbose = options['verbose']
if 'module' in options:
crackfortran.f77modulename = options['module']
if 'skipfuncs' in options:
crackfortran.skipfuncs = options['skipfuncs']
if 'onlyfuncs' in options:
crackfortran.onlyfuncs = options['onlyfuncs']
crackfortran.include_paths[:] = options['include_paths']
crackfortran.dolowercase = options['do-lower']
postlist = crackfortran.crackfortran(files)
if 'signsfile' in options:
outmess('Saving signatures to file "%s"\n' % (options['signsfile']))
pyf = crackfortran.crack2fortran(postlist)
if options['signsfile'][-6:] == 'stdout':
sys.stdout.write(pyf)
else:
f = open(options['signsfile'], 'w')
f.write(pyf)
f.close()
if options["coutput"] is None:
for mod in postlist:
mod["coutput"] = "%smodule.c" % mod["name"]
else:
for mod in postlist:
mod["coutput"] = options["coutput"]
if options["f2py_wrapper_output"] is None:
for mod in postlist:
mod["f2py_wrapper_output"] = "%s-f2pywrappers.f" % mod["name"]
else:
for mod in postlist:
mod["f2py_wrapper_output"] = options["f2py_wrapper_output"]
return postlist
def buildmodules(lst):
cfuncs.buildcfuncs()
outmess('Building modules...\n')
modules, mnames, isusedby = [], [], {}
for i in range(len(lst)):
if '__user__' in lst[i]['name']:
cb_rules.buildcallbacks(lst[i])
else:
if 'use' in lst[i]:
for u in lst[i]['use'].keys():
if u not in isusedby:
isusedby[u] = []
isusedby[u].append(lst[i]['name'])
modules.append(lst[i])
mnames.append(lst[i]['name'])
ret = {}
for i in range(len(mnames)):
if mnames[i] in isusedby:
outmess('\tSkipping module "%s" which is used by %s.\n' % (
mnames[i], ','.join(['"%s"' % s for s in isusedby[mnames[i]]])))
else:
um = []
if 'use' in modules[i]:
for u in modules[i]['use'].keys():
if u in isusedby and u in mnames:
um.append(modules[mnames.index(u)])
else:
outmess(
'\tModule "%s" uses nonexisting "%s" which will be ignored.\n' % (mnames[i], u))
ret[mnames[i]] = {}
dict_append(ret[mnames[i]], rules.buildmodule(modules[i], um))
return ret
def dict_append(d_out, d_in):
for (k, v) in d_in.items():
if k not in d_out:
d_out[k] = []
if isinstance(v, list):
d_out[k] = d_out[k] + v
else:
d_out[k].append(v)
def run_main(comline_list):
"""Run f2py as if string.join(comline_list,' ') is used as a command line.
In case of using -h flag, return None.
"""
crackfortran.reset_global_f2py_vars()
f2pydir = os.path.dirname(os.path.abspath(cfuncs.__file__))
fobjhsrc = os.path.join(f2pydir, 'src', 'fortranobject.h')
fobjcsrc = os.path.join(f2pydir, 'src', 'fortranobject.c')
files, options = scaninputline(comline_list)
auxfuncs.options = options
postlist = callcrackfortran(files, options)
isusedby = {}
for i in range(len(postlist)):
if 'use' in postlist[i]:
for u in postlist[i]['use'].keys():
if u not in isusedby:
isusedby[u] = []
isusedby[u].append(postlist[i]['name'])
for i in range(len(postlist)):
if postlist[i]['block'] == 'python module' and '__user__' in postlist[i]['name']:
if postlist[i]['name'] in isusedby:
# if not quiet:
outmess('Skipping Makefile build for module "%s" which is used by %s\n' % (
postlist[i]['name'], ','.join(['"%s"' % s for s in isusedby[postlist[i]['name']]])))
if 'signsfile' in options:
if options['verbose'] > 1:
outmess(
'Stopping. Edit the signature file and then run f2py on the signature file: ')
outmess('%s %s\n' %
(os.path.basename(sys.argv[0]), options['signsfile']))
return
for i in range(len(postlist)):
if postlist[i]['block'] != 'python module':
if 'python module' not in options:
errmess(
'Tip: If your original code is Fortran source then you must use -m option.\n')
raise TypeError('All blocks must be python module blocks but got %s' % (
repr(postlist[i]['block'])))
auxfuncs.debugoptions = options['debug']
f90mod_rules.options = options
auxfuncs.wrapfuncs = options['wrapfuncs']
ret = buildmodules(postlist)
for mn in ret.keys():
dict_append(ret[mn], {'csrc': fobjcsrc, 'h': fobjhsrc})
return ret
def filter_files(prefix, suffix, files, remove_prefix=None):
"""
Filter files by prefix and suffix.
"""
filtered, rest = [], []
match = re.compile(prefix + r'.*' + suffix + r'\Z').match
if remove_prefix:
ind = len(prefix)
else:
ind = 0
for file in [x.strip() for x in files]:
if match(file):
filtered.append(file[ind:])
else:
rest.append(file)
return filtered, rest
def get_prefix(module):
p = os.path.dirname(os.path.dirname(module.__file__))
return p
def run_compile():
"""
Do it all in one call!
"""
import tempfile
i = sys.argv.index('-c')
del sys.argv[i]
remove_build_dir = 0
try:
i = sys.argv.index('--build-dir')
except ValueError:
i = None
if i is not None:
build_dir = sys.argv[i + 1]
del sys.argv[i + 1]
del sys.argv[i]
else:
remove_build_dir = 1
build_dir = tempfile.mkdtemp()
_reg1 = re.compile(r'[-][-]link[-]')
sysinfo_flags = [_m for _m in sys.argv[1:] if _reg1.match(_m)]
sys.argv = [_m for _m in sys.argv if _m not in sysinfo_flags]
if sysinfo_flags:
sysinfo_flags = [f[7:] for f in sysinfo_flags]
_reg2 = re.compile(
r'[-][-]((no[-]|)(wrap[-]functions|lower)|debug[-]capi|quiet)|[-]include')
f2py_flags = [_m for _m in sys.argv[1:] if _reg2.match(_m)]
sys.argv = [_m for _m in sys.argv if _m not in f2py_flags]
f2py_flags2 = []
fl = 0
for a in sys.argv[1:]:
if a in ['only:', 'skip:']:
fl = 1
elif a == ':':
fl = 0
if fl or a == ':':
f2py_flags2.append(a)
if f2py_flags2 and f2py_flags2[-1] != ':':
f2py_flags2.append(':')
f2py_flags.extend(f2py_flags2)
sys.argv = [_m for _m in sys.argv if _m not in f2py_flags2]
_reg3 = re.compile(
r'[-][-]((f(90)?compiler([-]exec|)|compiler)=|help[-]compiler)')
flib_flags = [_m for _m in sys.argv[1:] if _reg3.match(_m)]
sys.argv = [_m for _m in sys.argv if _m not in flib_flags]
_reg4 = re.compile(
r'[-][-]((f(77|90)(flags|exec)|opt|arch)=|(debug|noopt|noarch|help[-]fcompiler))')
fc_flags = [_m for _m in sys.argv[1:] if _reg4.match(_m)]
sys.argv = [_m for _m in sys.argv if _m not in fc_flags]
if 1:
del_list = []
for s in flib_flags:
v = '--fcompiler='
if s[:len(v)] == v:
from numpy.distutils import fcompiler
fcompiler.load_all_fcompiler_classes()
allowed_keys = list(fcompiler.fcompiler_class.keys())
nv = ov = s[len(v):].lower()
if ov not in allowed_keys:
vmap = {} # XXX
try:
nv = vmap[ov]
except KeyError:
if ov not in vmap.values():
print('Unknown vendor: "%s"' % (s[len(v):]))
nv = ov
i = flib_flags.index(s)
flib_flags[i] = '--fcompiler=' + nv
continue
for s in del_list:
i = flib_flags.index(s)
del flib_flags[i]
assert len(flib_flags) <= 2, repr(flib_flags)
_reg5 = re.compile(r'[-][-](verbose)')
setup_flags = [_m for _m in sys.argv[1:] if _reg5.match(_m)]
sys.argv = [_m for _m in sys.argv if _m not in setup_flags]
if '--quiet' in f2py_flags:
setup_flags.append('--quiet')
modulename = 'untitled'
sources = sys.argv[1:]
for optname in ['--include_paths', '--include-paths']:
if optname in sys.argv:
i = sys.argv.index(optname)
f2py_flags.extend(sys.argv[i:i + 2])
del sys.argv[i + 1], sys.argv[i]
sources = sys.argv[1:]
if '-m' in sys.argv:
i = sys.argv.index('-m')
modulename = sys.argv[i + 1]
del sys.argv[i + 1], sys.argv[i]
sources = sys.argv[1:]
else:
from numpy.distutils.command.build_src import get_f2py_modulename
pyf_files, sources = filter_files('', '[.]pyf([.]src|)', sources)
sources = pyf_files + sources
for f in pyf_files:
modulename = get_f2py_modulename(f)
if modulename:
break
extra_objects, sources = filter_files('', '[.](o|a|so)', sources)
include_dirs, sources = filter_files('-I', '', sources, remove_prefix=1)
library_dirs, sources = filter_files('-L', '', sources, remove_prefix=1)
libraries, sources = filter_files('-l', '', sources, remove_prefix=1)
undef_macros, sources = filter_files('-U', '', sources, remove_prefix=1)
define_macros, sources = filter_files('-D', '', sources, remove_prefix=1)
for i in range(len(define_macros)):
name_value = define_macros[i].split('=', 1)
if len(name_value) == 1:
name_value.append(None)
if len(name_value) == 2:
define_macros[i] = tuple(name_value)
else:
print('Invalid use of -D:', name_value)
from numpy.distutils.system_info import get_info
num_info = {}
if num_info:
include_dirs.extend(num_info.get('include_dirs', []))
from numpy.distutils.core import setup, Extension
ext_args = {'name': modulename, 'sources': sources,
'include_dirs': include_dirs,
'library_dirs': library_dirs,
'libraries': libraries,
'define_macros': define_macros,
'undef_macros': undef_macros,
'extra_objects': extra_objects,
'f2py_options': f2py_flags,
}
if sysinfo_flags:
from numpy.distutils.misc_util import dict_append
for n in sysinfo_flags:
i = get_info(n)
if not i:
outmess('No %s resources found in system'
' (try `f2py --help-link`)\n' % (repr(n)))
dict_append(ext_args, **i)
ext = Extension(**ext_args)
sys.argv = [sys.argv[0]] + setup_flags
sys.argv.extend(['build',
'--build-temp', build_dir,
'--build-base', build_dir,
'--build-platlib', '.'])
if fc_flags:
sys.argv.extend(['config_fc'] + fc_flags)
if flib_flags:
sys.argv.extend(['build_ext'] + flib_flags)
setup(ext_modules=[ext])
if remove_build_dir and os.path.exists(build_dir):
import shutil
outmess('Removing build directory %s\n' % (build_dir))
shutil.rmtree(build_dir)
def main():
if '--help-link' in sys.argv[1:]:
sys.argv.remove('--help-link')
from numpy.distutils.system_info import show_all
show_all()
return
if '-c' in sys.argv[1:]:
run_compile()
else:
run_main(sys.argv[1:])
# if __name__ == "__main__":
# main()
# EOF

View File

@@ -0,0 +1,48 @@
from __future__ import division, absolute_import, print_function
import sys
import re
from numpy.testing import jiffies, memusage
def cmdline():
m = re.compile(r'\A\d+\Z')
args = []
repeat = 1
for a in sys.argv[1:]:
if m.match(a):
repeat = eval(a)
else:
args.append(a)
f2py_opts = ' '.join(args)
return repeat, f2py_opts
def run(runtest, test_functions, repeat=1):
l = [(t, repr(t.__doc__.split('\n')[1].strip())) for t in test_functions]
start_memusage = memusage()
diff_memusage = None
start_jiffies = jiffies()
i = 0
while i < repeat:
i += 1
for t, fname in l:
runtest(t)
if start_memusage is None:
continue
if diff_memusage is None:
diff_memusage = memusage() - start_memusage
else:
diff_memusage2 = memusage() - start_memusage
if diff_memusage2 != diff_memusage:
print('memory usage change at step %i:' % i,
diff_memusage2 - diff_memusage,
fname)
diff_memusage = diff_memusage2
current_memusage = memusage()
print('run', repeat * len(test_functions), 'tests',
'in %.2f seconds' % ((jiffies() - start_jiffies) / 100.0))
if start_memusage:
print('initial virtual memory size:', start_memusage, 'bytes')
print('current virtual memory size:', current_memusage, 'bytes')

View File

@@ -0,0 +1,272 @@
#!/usr/bin/env python
"""
Build F90 module support for f2py2e.
Copyright 2000 Pearu Peterson all rights reserved,
Pearu Peterson <pearu@ioc.ee>
Permission to use, modify, and distribute this software is given under the
terms of the NumPy License.
NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
$Date: 2005/02/03 19:30:23 $
Pearu Peterson
"""
from __future__ import division, absolute_import, print_function
__version__ = "$Revision: 1.27 $"[10:-1]
f2py_version = 'See `f2py -v`'
import numpy as np
from . import capi_maps
from . import func2subr
from .crackfortran import undo_rmbadname, undo_rmbadname1
# The eviroment provided by auxfuncs.py is needed for some calls to eval.
# As the needed functions cannot be determined by static inspection of the
# code, it is safest to use import * pending a major refactoring of f2py.
from .auxfuncs import *
options = {}
def findf90modules(m):
if ismodule(m):
return [m]
if not hasbody(m):
return []
ret = []
for b in m['body']:
if ismodule(b):
ret.append(b)
else:
ret = ret + findf90modules(b)
return ret
fgetdims1 = """\
external f2pysetdata
logical ns
integer r,i
integer(%d) s(*)
ns = .FALSE.
if (allocated(d)) then
do i=1,r
if ((size(d,i).ne.s(i)).and.(s(i).ge.0)) then
ns = .TRUE.
end if
end do
if (ns) then
deallocate(d)
end if
end if
if ((.not.allocated(d)).and.(s(1).ge.1)) then""" % np.intp().itemsize
fgetdims2 = """\
end if
if (allocated(d)) then
do i=1,r
s(i) = size(d,i)
end do
end if
flag = 1
call f2pysetdata(d,allocated(d))"""
fgetdims2_sa = """\
end if
if (allocated(d)) then
do i=1,r
s(i) = size(d,i)
end do
!s(r) must be equal to len(d(1))
end if
flag = 2
call f2pysetdata(d,allocated(d))"""
def buildhooks(pymod):
global fgetdims1, fgetdims2
from . import rules
ret = {'f90modhooks': [], 'initf90modhooks': [], 'body': [],
'need': ['F_FUNC', 'arrayobject.h'],
'separatorsfor': {'includes0': '\n', 'includes': '\n'},
'docs': ['"Fortran 90/95 modules:\\n"'],
'latexdoc': []}
fhooks = ['']
def fadd(line, s=fhooks):
s[0] = '%s\n %s' % (s[0], line)
doc = ['']
def dadd(line, s=doc):
s[0] = '%s\n%s' % (s[0], line)
for m in findf90modules(pymod):
sargs, fargs, efargs, modobjs, notvars, onlyvars = [], [], [], [], [
m['name']], []
sargsp = []
ifargs = []
mfargs = []
if hasbody(m):
for b in m['body']:
notvars.append(b['name'])
for n in m['vars'].keys():
var = m['vars'][n]
if (n not in notvars) and (not l_or(isintent_hide, isprivate)(var)):
onlyvars.append(n)
mfargs.append(n)
outmess('\t\tConstructing F90 module support for "%s"...\n' %
(m['name']))
if onlyvars:
outmess('\t\t Variables: %s\n' % (' '.join(onlyvars)))
chooks = ['']
def cadd(line, s=chooks):
s[0] = '%s\n%s' % (s[0], line)
ihooks = ['']
def iadd(line, s=ihooks):
s[0] = '%s\n%s' % (s[0], line)
vrd = capi_maps.modsign2map(m)
cadd('static FortranDataDef f2py_%s_def[] = {' % (m['name']))
dadd('\\subsection{Fortran 90/95 module \\texttt{%s}}\n' % (m['name']))
if hasnote(m):
note = m['note']
if isinstance(note, list):
note = '\n'.join(note)
dadd(note)
if onlyvars:
dadd('\\begin{description}')
for n in onlyvars:
var = m['vars'][n]
modobjs.append(n)
ct = capi_maps.getctype(var)
at = capi_maps.c2capi_map[ct]
dm = capi_maps.getarrdims(n, var)
dms = dm['dims'].replace('*', '-1').strip()
dms = dms.replace(':', '-1').strip()
if not dms:
dms = '-1'
use_fgetdims2 = fgetdims2
if isstringarray(var):
if 'charselector' in var and 'len' in var['charselector']:
cadd('\t{"%s",%s,{{%s,%s}},%s},'
% (undo_rmbadname1(n), dm['rank'], dms, var['charselector']['len'], at))
use_fgetdims2 = fgetdims2_sa
else:
cadd('\t{"%s",%s,{{%s}},%s},' %
(undo_rmbadname1(n), dm['rank'], dms, at))
else:
cadd('\t{"%s",%s,{{%s}},%s},' %
(undo_rmbadname1(n), dm['rank'], dms, at))
dadd('\\item[]{{}\\verb@%s@{}}' %
(capi_maps.getarrdocsign(n, var)))
if hasnote(var):
note = var['note']
if isinstance(note, list):
note = '\n'.join(note)
dadd('--- %s' % (note))
if isallocatable(var):
fargs.append('f2py_%s_getdims_%s' % (m['name'], n))
efargs.append(fargs[-1])
sargs.append(
'void (*%s)(int*,int*,void(*)(char*,int*),int*)' % (n))
sargsp.append('void (*)(int*,int*,void(*)(char*,int*),int*)')
iadd('\tf2py_%s_def[i_f2py++].func = %s;' % (m['name'], n))
fadd('subroutine %s(r,s,f2pysetdata,flag)' % (fargs[-1]))
fadd('use %s, only: d => %s\n' %
(m['name'], undo_rmbadname1(n)))
fadd('integer flag\n')
fhooks[0] = fhooks[0] + fgetdims1
dms = eval('range(1,%s+1)' % (dm['rank']))
fadd(' allocate(d(%s))\n' %
(','.join(['s(%s)' % i for i in dms])))
fhooks[0] = fhooks[0] + use_fgetdims2
fadd('end subroutine %s' % (fargs[-1]))
else:
fargs.append(n)
sargs.append('char *%s' % (n))
sargsp.append('char*')
iadd('\tf2py_%s_def[i_f2py++].data = %s;' % (m['name'], n))
if onlyvars:
dadd('\\end{description}')
if hasbody(m):
for b in m['body']:
if not isroutine(b):
print('Skipping', b['block'], b['name'])
continue
modobjs.append('%s()' % (b['name']))
b['modulename'] = m['name']
api, wrap = rules.buildapi(b)
if isfunction(b):
fhooks[0] = fhooks[0] + wrap
fargs.append('f2pywrap_%s_%s' % (m['name'], b['name']))
ifargs.append(func2subr.createfuncwrapper(b, signature=1))
else:
if wrap:
fhooks[0] = fhooks[0] + wrap
fargs.append('f2pywrap_%s_%s' % (m['name'], b['name']))
ifargs.append(
func2subr.createsubrwrapper(b, signature=1))
else:
fargs.append(b['name'])
mfargs.append(fargs[-1])
api['externroutines'] = []
ar = applyrules(api, vrd)
ar['docs'] = []
ar['docshort'] = []
ret = dictappend(ret, ar)
cadd('\t{"%s",-1,{{-1}},0,NULL,(void *)f2py_rout_#modulename#_%s_%s,doc_f2py_rout_#modulename#_%s_%s},' %
(b['name'], m['name'], b['name'], m['name'], b['name']))
sargs.append('char *%s' % (b['name']))
sargsp.append('char *')
iadd('\tf2py_%s_def[i_f2py++].data = %s;' %
(m['name'], b['name']))
cadd('\t{NULL}\n};\n')
iadd('}')
ihooks[0] = 'static void f2py_setup_%s(%s) {\n\tint i_f2py=0;%s' % (
m['name'], ','.join(sargs), ihooks[0])
if '_' in m['name']:
F_FUNC = 'F_FUNC_US'
else:
F_FUNC = 'F_FUNC'
iadd('extern void %s(f2pyinit%s,F2PYINIT%s)(void (*)(%s));'
% (F_FUNC, m['name'], m['name'].upper(), ','.join(sargsp)))
iadd('static void f2py_init_%s(void) {' % (m['name']))
iadd('\t%s(f2pyinit%s,F2PYINIT%s)(f2py_setup_%s);'
% (F_FUNC, m['name'], m['name'].upper(), m['name']))
iadd('}\n')
ret['f90modhooks'] = ret['f90modhooks'] + chooks + ihooks
ret['initf90modhooks'] = ['\tPyDict_SetItemString(d, "%s", PyFortranObject_New(f2py_%s_def,f2py_init_%s));' % (
m['name'], m['name'], m['name'])] + ret['initf90modhooks']
fadd('')
fadd('subroutine f2pyinit%s(f2pysetupfunc)' % (m['name']))
if mfargs:
for a in undo_rmbadname(mfargs):
fadd('use %s, only : %s' % (m['name'], a))
if ifargs:
fadd(' '.join(['interface'] + ifargs))
fadd('end interface')
fadd('external f2pysetupfunc')
if efargs:
for a in undo_rmbadname(efargs):
fadd('external %s' % (a))
fadd('call f2pysetupfunc(%s)' % (','.join(undo_rmbadname(fargs))))
fadd('end subroutine f2pyinit%s\n' % (m['name']))
dadd('\n'.join(ret['latexdoc']).replace(
r'\subsection{', r'\subsubsection{'))
ret['latexdoc'] = []
ret['docs'].append('"\t%s --- %s"' % (m['name'],
','.join(undo_rmbadname(modobjs))))
ret['routine_defs'] = ''
ret['doc'] = []
ret['docshort'] = []
ret['latexdoc'] = doc[0]
if len(ret['docs']) <= 1:
ret['docs'] = ''
return ret, fhooks[0]

View File

@@ -0,0 +1,299 @@
#!/usr/bin/env python
"""
Rules for building C/API module with f2py2e.
Copyright 1999,2000 Pearu Peterson all rights reserved,
Pearu Peterson <pearu@ioc.ee>
Permission to use, modify, and distribute this software is given under the
terms of the NumPy License.
NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
$Date: 2004/11/26 11:13:06 $
Pearu Peterson
"""
from __future__ import division, absolute_import, print_function
__version__ = "$Revision: 1.16 $"[10:-1]
f2py_version = 'See `f2py -v`'
import copy
from .auxfuncs import (
getfortranname, isexternal, isfunction, isfunction_wrap, isintent_in,
isintent_out, islogicalfunction, ismoduleroutine, isscalar,
issubroutine, issubroutine_wrap, outmess, show
)
def var2fixfortran(vars, a, fa=None, f90mode=None):
if fa is None:
fa = a
if a not in vars:
show(vars)
outmess('var2fixfortran: No definition for argument "%s".\n' % a)
return ''
if 'typespec' not in vars[a]:
show(vars[a])
outmess('var2fixfortran: No typespec for argument "%s".\n' % a)
return ''
vardef = vars[a]['typespec']
if vardef == 'type' and 'typename' in vars[a]:
vardef = '%s(%s)' % (vardef, vars[a]['typename'])
selector = {}
lk = ''
if 'kindselector' in vars[a]:
selector = vars[a]['kindselector']
lk = 'kind'
elif 'charselector' in vars[a]:
selector = vars[a]['charselector']
lk = 'len'
if '*' in selector:
if f90mode:
if selector['*'] in ['*', ':', '(*)']:
vardef = '%s(len=*)' % (vardef)
else:
vardef = '%s(%s=%s)' % (vardef, lk, selector['*'])
else:
if selector['*'] in ['*', ':']:
vardef = '%s*(%s)' % (vardef, selector['*'])
else:
vardef = '%s*%s' % (vardef, selector['*'])
else:
if 'len' in selector:
vardef = '%s(len=%s' % (vardef, selector['len'])
if 'kind' in selector:
vardef = '%s,kind=%s)' % (vardef, selector['kind'])
else:
vardef = '%s)' % (vardef)
elif 'kind' in selector:
vardef = '%s(kind=%s)' % (vardef, selector['kind'])
vardef = '%s %s' % (vardef, fa)
if 'dimension' in vars[a]:
vardef = '%s(%s)' % (vardef, ','.join(vars[a]['dimension']))
return vardef
def createfuncwrapper(rout, signature=0):
assert isfunction(rout)
extra_args = []
vars = rout['vars']
for a in rout['args']:
v = rout['vars'][a]
for i, d in enumerate(v.get('dimension', [])):
if d == ':':
dn = 'f2py_%s_d%s' % (a, i)
dv = dict(typespec='integer', intent=['hide'])
dv['='] = 'shape(%s, %s)' % (a, i)
extra_args.append(dn)
vars[dn] = dv
v['dimension'][i] = dn
rout['args'].extend(extra_args)
need_interface = bool(extra_args)
ret = ['']
def add(line, ret=ret):
ret[0] = '%s\n %s' % (ret[0], line)
name = rout['name']
fortranname = getfortranname(rout)
f90mode = ismoduleroutine(rout)
newname = '%sf2pywrap' % (name)
if newname not in vars:
vars[newname] = vars[name]
args = [newname] + rout['args'][1:]
else:
args = [newname] + rout['args']
l = var2fixfortran(vars, name, newname, f90mode)
if l[:13] == 'character*(*)':
if f90mode:
l = 'character(len=10)' + l[13:]
else:
l = 'character*10' + l[13:]
charselect = vars[name]['charselector']
if charselect.get('*', '') == '(*)':
charselect['*'] = '10'
sargs = ', '.join(args)
if f90mode:
add('subroutine f2pywrap_%s_%s (%s)' %
(rout['modulename'], name, sargs))
if not signature:
add('use %s, only : %s' % (rout['modulename'], fortranname))
else:
add('subroutine f2pywrap%s (%s)' % (name, sargs))
if not need_interface:
add('external %s' % (fortranname))
l = l + ', ' + fortranname
if need_interface:
for line in rout['saved_interface'].split('\n'):
if line.lstrip().startswith('use '):
add(line)
args = args[1:]
dumped_args = []
for a in args:
if isexternal(vars[a]):
add('external %s' % (a))
dumped_args.append(a)
for a in args:
if a in dumped_args:
continue
if isscalar(vars[a]):
add(var2fixfortran(vars, a, f90mode=f90mode))
dumped_args.append(a)
for a in args:
if a in dumped_args:
continue
if isintent_in(vars[a]):
add(var2fixfortran(vars, a, f90mode=f90mode))
dumped_args.append(a)
for a in args:
if a in dumped_args:
continue
add(var2fixfortran(vars, a, f90mode=f90mode))
add(l)
if need_interface:
if f90mode:
# f90 module already defines needed interface
pass
else:
add('interface')
add(rout['saved_interface'].lstrip())
add('end interface')
sargs = ', '.join([a for a in args if a not in extra_args])
if not signature:
if islogicalfunction(rout):
add('%s = .not.(.not.%s(%s))' % (newname, fortranname, sargs))
else:
add('%s = %s(%s)' % (newname, fortranname, sargs))
if f90mode:
add('end subroutine f2pywrap_%s_%s' % (rout['modulename'], name))
else:
add('end')
return ret[0]
def createsubrwrapper(rout, signature=0):
assert issubroutine(rout)
extra_args = []
vars = rout['vars']
for a in rout['args']:
v = rout['vars'][a]
for i, d in enumerate(v.get('dimension', [])):
if d == ':':
dn = 'f2py_%s_d%s' % (a, i)
dv = dict(typespec='integer', intent=['hide'])
dv['='] = 'shape(%s, %s)' % (a, i)
extra_args.append(dn)
vars[dn] = dv
v['dimension'][i] = dn
rout['args'].extend(extra_args)
need_interface = bool(extra_args)
ret = ['']
def add(line, ret=ret):
ret[0] = '%s\n %s' % (ret[0], line)
name = rout['name']
fortranname = getfortranname(rout)
f90mode = ismoduleroutine(rout)
args = rout['args']
sargs = ', '.join(args)
if f90mode:
add('subroutine f2pywrap_%s_%s (%s)' %
(rout['modulename'], name, sargs))
if not signature:
add('use %s, only : %s' % (rout['modulename'], fortranname))
else:
add('subroutine f2pywrap%s (%s)' % (name, sargs))
if not need_interface:
add('external %s' % (fortranname))
if need_interface:
for line in rout['saved_interface'].split('\n'):
if line.lstrip().startswith('use '):
add(line)
dumped_args = []
for a in args:
if isexternal(vars[a]):
add('external %s' % (a))
dumped_args.append(a)
for a in args:
if a in dumped_args:
continue
if isscalar(vars[a]):
add(var2fixfortran(vars, a, f90mode=f90mode))
dumped_args.append(a)
for a in args:
if a in dumped_args:
continue
add(var2fixfortran(vars, a, f90mode=f90mode))
if need_interface:
if f90mode:
# f90 module already defines needed interface
pass
else:
add('interface')
add(rout['saved_interface'].lstrip())
add('end interface')
sargs = ', '.join([a for a in args if a not in extra_args])
if not signature:
add('call %s(%s)' % (fortranname, sargs))
if f90mode:
add('end subroutine f2pywrap_%s_%s' % (rout['modulename'], name))
else:
add('end')
return ret[0]
def assubr(rout):
if isfunction_wrap(rout):
fortranname = getfortranname(rout)
name = rout['name']
outmess('\t\tCreating wrapper for Fortran function "%s"("%s")...\n' % (
name, fortranname))
rout = copy.copy(rout)
fname = name
rname = fname
if 'result' in rout:
rname = rout['result']
rout['vars'][fname] = rout['vars'][rname]
fvar = rout['vars'][fname]
if not isintent_out(fvar):
if 'intent' not in fvar:
fvar['intent'] = []
fvar['intent'].append('out')
flag = 1
for i in fvar['intent']:
if i.startswith('out='):
flag = 0
break
if flag:
fvar['intent'].append('out=%s' % (rname))
rout['args'][:] = [fname] + rout['args']
return rout, createfuncwrapper(rout)
if issubroutine_wrap(rout):
fortranname = getfortranname(rout)
name = rout['name']
outmess('\t\tCreating wrapper for Fortran subroutine "%s"("%s")...\n' % (
name, fortranname))
rout = copy.copy(rout)
return rout, createsubrwrapper(rout)
return rout, ''

View File

@@ -0,0 +1,6 @@
"""Fortran to Python Interface Generator.
"""
from __future__ import division, absolute_import, print_function
postpone_import = True

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,117 @@
#!/usr/bin/env python
"""
setup.py for installing F2PY
Usage:
python setup.py install
Copyright 2001-2005 Pearu Peterson all rights reserved,
Pearu Peterson <pearu@cens.ioc.ee>
Permission to use, modify, and distribute this software is given under the
terms of the NumPy License.
NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
$Revision: 1.32 $
$Date: 2005/01/30 17:22:14 $
Pearu Peterson
"""
from __future__ import division, print_function
__version__ = "$Id: setup.py,v 1.32 2005/01/30 17:22:14 pearu Exp $"
import os
import sys
from distutils.dep_util import newer
from numpy.distutils import log
from numpy.distutils.core import setup
from numpy.distutils.misc_util import Configuration
from __version__ import version
def _get_f2py_shebang():
""" Return shebang line for f2py script
If we are building a binary distribution format, then the shebang line
should be ``#!python`` rather than ``#!`` followed by the contents of
``sys.executable``.
"""
if set(('bdist_wheel', 'bdist_egg', 'bdist_wininst',
'bdist_rpm')).intersection(sys.argv):
return '#!python'
return '#!' + sys.executable
def configuration(parent_package='', top_path=None):
config = Configuration('f2py', parent_package, top_path)
config.add_data_dir('tests')
config.add_data_files('src/fortranobject.c',
'src/fortranobject.h',
)
config.make_svn_version_py()
def generate_f2py_py(build_dir):
f2py_exe = 'f2py' + os.path.basename(sys.executable)[6:]
if f2py_exe[-4:] == '.exe':
f2py_exe = f2py_exe[:-4] + '.py'
if 'bdist_wininst' in sys.argv and f2py_exe[-3:] != '.py':
f2py_exe = f2py_exe + '.py'
target = os.path.join(build_dir, f2py_exe)
if newer(__file__, target):
log.info('Creating %s', target)
f = open(target, 'w')
f.write(_get_f2py_shebang() + '\n')
mainloc = os.path.join(os.path.dirname(__file__), "__main__.py")
with open(mainloc) as mf:
f.write(mf.read())
f.close()
return target
config.add_scripts(generate_f2py_py)
log.info('F2PY Version %s', config.get_version())
return config
if __name__ == "__main__":
config = configuration(top_path='')
print('F2PY Version', version)
config = config.todict()
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",
author_email="pearu@cens.ioc.ee",
maintainer="Pearu Peterson",
maintainer_email="pearu@cens.ioc.ee",
license="BSD",
platforms="Unix, Windows (mingw|cygwin), Mac OSX",
long_description="""\
The Fortran to Python Interface Generator, or F2PY for short, is a
command line tool (f2py) for generating Python C/API modules for
wrapping Fortran 77/90/95 subroutines, accessing common blocks from
Python, and calling Python functions from Fortran (call-backs).
Interfacing subroutines/data from Fortran 90/95 modules is supported.""",
url="http://cens.ioc.ee/projects/f2py2e/",
keywords=['Fortran', 'f2py'],
**config)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,162 @@
#ifndef Py_FORTRANOBJECT_H
#define Py_FORTRANOBJECT_H
#ifdef __cplusplus
extern "C" {
#endif
#include "Python.h"
#ifdef FORTRANOBJECT_C
#define NO_IMPORT_ARRAY
#endif
#define PY_ARRAY_UNIQUE_SYMBOL _npy_f2py_ARRAY_API
#include "numpy/arrayobject.h"
/*
* Python 3 support macros
*/
#if PY_VERSION_HEX >= 0x03000000
#define PyString_Check PyBytes_Check
#define PyString_GET_SIZE PyBytes_GET_SIZE
#define PyString_AS_STRING PyBytes_AS_STRING
#define PyString_FromString PyBytes_FromString
#define PyUString_FromStringAndSize PyUnicode_FromStringAndSize
#define PyString_ConcatAndDel PyBytes_ConcatAndDel
#define PyString_AsString PyBytes_AsString
#define PyInt_Check PyLong_Check
#define PyInt_FromLong PyLong_FromLong
#define PyInt_AS_LONG PyLong_AsLong
#define PyInt_AsLong PyLong_AsLong
#define PyNumber_Int PyNumber_Long
#else
#define PyUString_FromStringAndSize PyString_FromStringAndSize
#endif
#ifdef F2PY_REPORT_ATEXIT
#include <sys/timeb.h>
extern void f2py_start_clock(void);
extern void f2py_stop_clock(void);
extern void f2py_start_call_clock(void);
extern void f2py_stop_call_clock(void);
extern void f2py_cb_start_clock(void);
extern void f2py_cb_stop_clock(void);
extern void f2py_cb_start_call_clock(void);
extern void f2py_cb_stop_call_clock(void);
extern void f2py_report_on_exit(int,void*);
#endif
#ifdef DMALLOC
#include "dmalloc.h"
#endif
/* Fortran object interface */
/*
123456789-123456789-123456789-123456789-123456789-123456789-123456789-12
PyFortranObject represents various Fortran objects:
Fortran (module) routines, COMMON blocks, module data.
Author: Pearu Peterson <pearu@cens.ioc.ee>
*/
#define F2PY_MAX_DIMS 40
typedef void (*f2py_set_data_func)(char*,npy_intp*);
typedef void (*f2py_void_func)(void);
typedef void (*f2py_init_func)(int*,npy_intp*,f2py_set_data_func,int*);
/*typedef void* (*f2py_c_func)(void*,...);*/
typedef void *(*f2pycfunc)(void);
typedef struct {
char *name; /* attribute (array||routine) name */
int rank; /* array rank, 0 for scalar, max is F2PY_MAX_DIMS,
|| rank=-1 for Fortran routine */
struct {npy_intp d[F2PY_MAX_DIMS];} dims; /* dimensions of the array, || not used */
int type; /* PyArray_<type> || not used */
char *data; /* pointer to array || Fortran routine */
f2py_init_func func; /* initialization function for
allocatable arrays:
func(&rank,dims,set_ptr_func,name,len(name))
|| C/API wrapper for Fortran routine */
char *doc; /* documentation string; only recommended
for routines. */
} FortranDataDef;
typedef struct {
PyObject_HEAD
int len; /* Number of attributes */
FortranDataDef *defs; /* An array of FortranDataDef's */
PyObject *dict; /* Fortran object attribute dictionary */
} PyFortranObject;
#define PyFortran_Check(op) (Py_TYPE(op) == &PyFortran_Type)
#define PyFortran_Check1(op) (0==strcmp(Py_TYPE(op)->tp_name,"fortran"))
extern PyTypeObject PyFortran_Type;
extern int F2PyDict_SetItemString(PyObject* dict, char *name, PyObject *obj);
extern PyObject * PyFortranObject_New(FortranDataDef* defs, f2py_void_func init);
extern PyObject * PyFortranObject_NewAsAttr(FortranDataDef* defs);
#if PY_VERSION_HEX >= 0x03000000
PyObject * F2PyCapsule_FromVoidPtr(void *ptr, void (*dtor)(PyObject *));
void * F2PyCapsule_AsVoidPtr(PyObject *obj);
int F2PyCapsule_Check(PyObject *ptr);
#else
PyObject * F2PyCapsule_FromVoidPtr(void *ptr, void (*dtor)(void *));
void * F2PyCapsule_AsVoidPtr(PyObject *ptr);
int F2PyCapsule_Check(PyObject *ptr);
#endif
#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
#define F2PY_INTENT_HIDE 8
#define F2PY_INTENT_CACHE 16
#define F2PY_INTENT_COPY 32
#define F2PY_INTENT_C 64
#define F2PY_OPTIONAL 128
#define F2PY_INTENT_INPLACE 256
#define F2PY_INTENT_ALIGNED4 512
#define F2PY_INTENT_ALIGNED8 1024
#define F2PY_INTENT_ALIGNED16 2048
#define ARRAY_ISALIGNED(ARR, SIZE) ((size_t)(PyArray_DATA(ARR)) % (SIZE) == 0)
#define F2PY_ALIGN4(intent) (intent & F2PY_INTENT_ALIGNED4)
#define F2PY_ALIGN8(intent) (intent & F2PY_INTENT_ALIGNED8)
#define F2PY_ALIGN16(intent) (intent & F2PY_INTENT_ALIGNED16)
#define F2PY_GET_ALIGNMENT(intent) \
(F2PY_ALIGN4(intent) ? 4 : \
(F2PY_ALIGN8(intent) ? 8 : \
(F2PY_ALIGN16(intent) ? 16 : 1) ))
#define F2PY_CHECK_ALIGNMENT(arr, intent) ARRAY_ISALIGNED(arr, F2PY_GET_ALIGNMENT(intent))
extern PyArrayObject* array_from_pyobj(const int type_num,
npy_intp *dims,
const int rank,
const int intent,
PyObject *obj);
extern int copy_ND_array(const PyArrayObject *in, PyArrayObject *out);
#ifdef DEBUG_COPY_ND_ARRAY
extern void dump_attrs(const PyArrayObject* arr);
#endif
#ifdef __cplusplus
}
#endif
#endif /* !Py_FORTRANOBJECT_H */

View File

@@ -0,0 +1,224 @@
/* File: wrapmodule.c
* This file is auto-generated with f2py (version:2_1330).
* Hand edited by Pearu.
* f2py is a Fortran to Python Interface Generator (FPIG), Second Edition,
* written by Pearu Peterson <pearu@cens.ioc.ee>.
* See http://cens.ioc.ee/projects/f2py2e/
* Generation date: Fri Oct 21 22:41:12 2005
* $Revision:$
* $Date:$
* Do not edit this file directly unless you know what you are doing!!!
*/
#ifdef __cplusplus
extern "C" {
#endif
/*********************** See f2py2e/cfuncs.py: includes ***********************/
#include "Python.h"
#include "fortranobject.h"
#include <math.h>
static PyObject *wrap_error;
static PyObject *wrap_module;
/************************************ call ************************************/
static char doc_f2py_rout_wrap_call[] = "\
Function signature:\n\
arr = call(type_num,dims,intent,obj)\n\
Required arguments:\n"
" type_num : input int\n"
" dims : input int-sequence\n"
" intent : input int\n"
" obj : input python object\n"
"Return objects:\n"
" arr : array";
static PyObject *f2py_rout_wrap_call(PyObject *capi_self,
PyObject *capi_args) {
PyObject * volatile capi_buildvalue = NULL;
int type_num = 0;
npy_intp *dims = NULL;
PyObject *dims_capi = Py_None;
int rank = 0;
int intent = 0;
PyArrayObject *capi_arr_tmp = NULL;
PyObject *arr_capi = Py_None;
int i;
if (!PyArg_ParseTuple(capi_args,"iOiO|:wrap.call",\
&type_num,&dims_capi,&intent,&arr_capi))
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));
capi_arr_tmp = array_from_pyobj(type_num,dims,rank,intent|F2PY_INTENT_OUT,arr_capi);
if (capi_arr_tmp == NULL) {
free(dims);
return NULL;
}
capi_buildvalue = Py_BuildValue("N",capi_arr_tmp);
free(dims);
return capi_buildvalue;
}
static char doc_f2py_rout_wrap_attrs[] = "\
Function signature:\n\
arr = array_attrs(arr)\n\
Required arguments:\n"
" arr : input array object\n"
"Return objects:\n"
" data : data address in hex\n"
" nd : int\n"
" dimensions : tuple\n"
" strides : tuple\n"
" base : python object\n"
" (kind,type,type_num,elsize,alignment) : 4-tuple\n"
" flags : int\n"
" itemsize : int\n"
;
static PyObject *f2py_rout_wrap_attrs(PyObject *capi_self,
PyObject *capi_args) {
PyObject *arr_capi = Py_None;
PyArrayObject *arr = NULL;
PyObject *dimensions = NULL;
PyObject *strides = NULL;
char s[100];
int i;
memset(s,0,100*sizeof(char));
if (!PyArg_ParseTuple(capi_args,"O!|:wrap.attrs",
&PyArray_Type,&arr_capi))
return NULL;
arr = (PyArrayObject *)arr_capi;
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,PyArray_NDIM(arr),
dimensions,strides,
(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));
}
static PyMethodDef f2py_module_methods[] = {
{"call",f2py_rout_wrap_call,METH_VARARGS,doc_f2py_rout_wrap_call},
{"array_attrs",f2py_rout_wrap_attrs,METH_VARARGS,doc_f2py_rout_wrap_attrs},
{NULL,NULL}
};
#if PY_VERSION_HEX >= 0x03000000
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT,
"test_array_from_pyobj_ext",
NULL,
-1,
f2py_module_methods,
NULL,
NULL,
NULL,
NULL
};
#endif
#if PY_VERSION_HEX >= 0x03000000
#define RETVAL m
PyMODINIT_FUNC PyInit_test_array_from_pyobj_ext(void) {
#else
#define RETVAL
PyMODINIT_FUNC inittest_array_from_pyobj_ext(void) {
#endif
PyObject *m,*d, *s;
#if PY_VERSION_HEX >= 0x03000000
m = wrap_module = PyModule_Create(&moduledef);
#else
m = wrap_module = Py_InitModule("test_array_from_pyobj_ext", f2py_module_methods);
#endif
Py_TYPE(&PyFortran_Type) = &PyType_Type;
import_array();
if (PyErr_Occurred())
Py_FatalError("can't initialize module wrap (failed to import numpy)");
d = PyModule_GetDict(m);
s = PyString_FromString("This module 'wrap' is auto-generated with f2py (version:2_1330).\nFunctions:\n"
" arr = call(type_num,dims,intent,obj)\n"
".");
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));
if (PyErr_Occurred())
Py_FatalError("can't initialize module wrap");
#ifdef F2PY_REPORT_ATEXIT
on_exit(f2py_report_on_exit,(void*)"array_from_pyobj.wrap.call");
#endif
return RETVAL;
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1 @@
dict(real=dict(rk="double"))

View File

@@ -0,0 +1,34 @@
subroutine sum(x, res)
implicit none
real, intent(in) :: x(:)
real, intent(out) :: res
integer :: i
!print *, "sum: size(x) = ", size(x)
res = 0.0
do i = 1, size(x)
res = res + x(i)
enddo
end subroutine sum
function fsum(x) result (res)
implicit none
real, intent(in) :: x(:)
real :: res
integer :: i
!print *, "fsum: size(x) = ", size(x)
res = 0.0
do i = 1, size(x)
res = res + x(i)
enddo
end function fsum

View File

@@ -0,0 +1,41 @@
module mod
contains
subroutine sum(x, res)
implicit none
real, intent(in) :: x(:)
real, intent(out) :: res
integer :: i
!print *, "sum: size(x) = ", size(x)
res = 0.0
do i = 1, size(x)
res = res + x(i)
enddo
end subroutine sum
function fsum(x) result (res)
implicit none
real, intent(in) :: x(:)
real :: res
integer :: i
!print *, "fsum: size(x) = ", size(x)
res = 0.0
do i = 1, size(x)
res = res + x(i)
enddo
end function fsum
end module mod

View File

@@ -0,0 +1,19 @@
subroutine sum_with_use(x, res)
use precision
implicit none
real(kind=rk), intent(in) :: x(:)
real(kind=rk), intent(out) :: res
integer :: i
!print *, "size(x) = ", size(x)
res = 0.0
do i = 1, size(x)
res = res + x(i)
enddo
end subroutine

View File

@@ -0,0 +1,4 @@
module precision
integer, parameter :: rk = selected_real_kind(8)
integer, parameter :: ik = selected_real_kind(4)
end module

View File

@@ -0,0 +1,11 @@
SUBROUTINE INITCB
DOUBLE PRECISION LONG
CHARACTER STRING
INTEGER OK
COMMON /BLOCK/ LONG, STRING, OK
LONG = 1.0
STRING = '2'
OK = 3
RETURN
END

View File

@@ -0,0 +1,20 @@
subroutine selectedrealkind(p, r, res)
implicit none
integer, intent(in) :: p, r
!f2py integer :: r=0
integer, intent(out) :: res
res = selected_real_kind(p, r)
end subroutine
subroutine selectedintkind(p, res)
implicit none
integer, intent(in) :: p
integer, intent(out) :: res
res = selected_int_kind(p)
end subroutine

View File

@@ -0,0 +1,5 @@
subroutine bar11(a)
cf2py intent(out) a
integer a
a = 11
end

View File

@@ -0,0 +1,8 @@
module foo_fixed
contains
subroutine bar12(a)
!f2py intent(out) a
integer a
a = 12
end subroutine bar12
end module foo_fixed

View File

@@ -0,0 +1,8 @@
module foo_free
contains
subroutine bar13(a)
!f2py intent(out) a
integer a
a = 13
end subroutine bar13
end module foo_free

View File

@@ -0,0 +1,57 @@
! Check that parameters are correct intercepted.
! Constants with comma separations are commonly
! used, for instance Pi = 3._dp
subroutine foo(x)
implicit none
integer, parameter :: sp = selected_real_kind(6)
integer, parameter :: dp = selected_real_kind(15)
integer, parameter :: ii = selected_int_kind(9)
integer, parameter :: il = selected_int_kind(18)
real(dp), intent(inout) :: x
dimension x(3)
real(sp), parameter :: three_s = 3._sp
real(dp), parameter :: three_d = 3._dp
integer(ii), parameter :: three_i = 3_ii
integer(il), parameter :: three_l = 3_il
x(1) = x(1) + x(2) * three_s * three_i + x(3) * three_d * three_l
x(2) = x(2) * three_s
x(3) = x(3) * three_l
return
end subroutine
subroutine foo_no(x)
implicit none
integer, parameter :: sp = selected_real_kind(6)
integer, parameter :: dp = selected_real_kind(15)
integer, parameter :: ii = selected_int_kind(9)
integer, parameter :: il = selected_int_kind(18)
real(dp), intent(inout) :: x
dimension x(3)
real(sp), parameter :: three_s = 3.
real(dp), parameter :: three_d = 3.
integer(ii), parameter :: three_i = 3
integer(il), parameter :: three_l = 3
x(1) = x(1) + x(2) * three_s * three_i + x(3) * three_d * three_l
x(2) = x(2) * three_s
x(3) = x(3) * three_l
return
end subroutine
subroutine foo_sum(x)
implicit none
integer, parameter :: sp = selected_real_kind(6)
integer, parameter :: dp = selected_real_kind(15)
integer, parameter :: ii = selected_int_kind(9)
integer, parameter :: il = selected_int_kind(18)
real(dp), intent(inout) :: x
dimension x(3)
real(sp), parameter :: three_s = 2._sp + 1._sp
real(dp), parameter :: three_d = 1._dp + 2._dp
integer(ii), parameter :: three_i = 2_ii + 1_ii
integer(il), parameter :: three_l = 1_il + 2_il
x(1) = x(1) + x(2) * three_s * three_i + x(3) * three_d * three_l
x(2) = x(2) * three_s
x(3) = x(3) * three_l
return
end subroutine

View File

@@ -0,0 +1,15 @@
! Check that parameters are correct intercepted.
! Constants with comma separations are commonly
! used, for instance Pi = 3._dp
subroutine foo_compound_int(x)
implicit none
integer, parameter :: ii = selected_int_kind(9)
integer(ii), intent(inout) :: x
dimension x(3)
integer(ii), parameter :: three = 3_ii
integer(ii), parameter :: two = 2_ii
integer(ii), parameter :: six = three * 1_ii * two
x(1) = x(1) + x(2) + x(3) * six
return
end subroutine

View File

@@ -0,0 +1,22 @@
! Check that parameters are correct intercepted.
! Constants with comma separations are commonly
! used, for instance Pi = 3._dp
subroutine foo_int(x)
implicit none
integer, parameter :: ii = selected_int_kind(9)
integer(ii), intent(inout) :: x
dimension x(3)
integer(ii), parameter :: three = 3_ii
x(1) = x(1) + x(2) + x(3) * three
return
end subroutine
subroutine foo_long(x)
implicit none
integer, parameter :: ii = selected_int_kind(18)
integer(ii), intent(inout) :: x
dimension x(3)
integer(ii), parameter :: three = 3_ii
x(1) = x(1) + x(2) + x(3) * three
return
end subroutine

View File

@@ -0,0 +1,23 @@
! Check that parameters are correct intercepted.
! Specifically that types of constants without
! compound kind specs are correctly inferred
! adapted Gibbs iteration code from pymc
! for this test case
subroutine foo_non_compound_int(x)
implicit none
integer, parameter :: ii = selected_int_kind(9)
integer(ii) maxiterates
parameter (maxiterates=2)
integer(ii) maxseries
parameter (maxseries=2)
integer(ii) wasize
parameter (wasize=maxiterates*maxseries)
integer(ii), intent(inout) :: x
dimension x(wasize)
x(1) = x(1) + x(2) + x(3) + x(4) * wasize
return
end subroutine

View File

@@ -0,0 +1,23 @@
! Check that parameters are correct intercepted.
! Constants with comma separations are commonly
! used, for instance Pi = 3._dp
subroutine foo_single(x)
implicit none
integer, parameter :: rp = selected_real_kind(6)
real(rp), intent(inout) :: x
dimension x(3)
real(rp), parameter :: three = 3._rp
x(1) = x(1) + x(2) + x(3) * three
return
end subroutine
subroutine foo_double(x)
implicit none
integer, parameter :: rp = selected_real_kind(15)
real(rp), intent(inout) :: x
dimension x(3)
real(rp), parameter :: three = 3._rp
x(1) = x(1) + x(2) + x(3) * three
return
end subroutine

View File

@@ -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

View File

@@ -0,0 +1,44 @@
subroutine foo(a, n, m, b)
implicit none
real, intent(in) :: a(n, m)
integer, intent(in) :: n, m
real, intent(out) :: b(size(a, 1))
integer :: i
do i = 1, size(b)
b(i) = sum(a(i,:))
enddo
end subroutine
subroutine trans(x,y)
implicit none
real, intent(in), dimension(:,:) :: x
real, intent(out), dimension( size(x,2), size(x,1) ) :: y
integer :: N, M, i, j
N = size(x,1)
M = size(x,2)
DO i=1,N
do j=1,M
y(j,i) = x(i,j)
END DO
END DO
end subroutine trans
subroutine flatten(x,y)
implicit none
real, intent(in), dimension(:,:) :: x
real, intent(out), dimension( size(x) ) :: y
integer :: N, M, i, j, k
N = size(x,1)
M = size(x,2)
k = 1
DO i=1,N
do j=1,M
y(k) = x(i,j)
k = k + 1
END DO
END DO
end subroutine flatten

View File

@@ -0,0 +1,29 @@
MODULE char_test
CONTAINS
SUBROUTINE change_strings(strings, n_strs, out_strings)
IMPLICIT NONE
! Inputs
INTEGER, INTENT(IN) :: n_strs
CHARACTER, INTENT(IN), DIMENSION(2,n_strs) :: strings
CHARACTER, INTENT(OUT), DIMENSION(2,n_strs) :: out_strings
!f2py INTEGER, INTENT(IN) :: n_strs
!f2py CHARACTER, INTENT(IN), DIMENSION(2,n_strs) :: strings
!f2py CHARACTER, INTENT(OUT), DIMENSION(2,n_strs) :: strings
! Misc.
INTEGER*4 :: j
DO j=1, n_strs
out_strings(1,j) = strings(1,j)
out_strings(2,j) = 'A'
END DO
END SUBROUTINE change_strings
END MODULE char_test

View File

@@ -0,0 +1,589 @@
from __future__ import division, absolute_import, print_function
import unittest
import os
import sys
import copy
from numpy import (
array, alltrue, ndarray, zeros, dtype, intp, clongdouble
)
from numpy.testing import (
run_module_suite, assert_, assert_equal, SkipTest
)
from numpy.core.multiarray import typeinfo
from . import util
wrap = None
def setup_module():
"""
Build the required testing extension module
"""
global wrap
# Check compiler availability first
if not util.has_c_compiler():
raise SkipTest("No C compiler available")
if wrap is None:
config_code = """
config.add_extension('test_array_from_pyobj_ext',
sources=['wrapmodule.c', 'fortranobject.c'],
define_macros=[])
"""
d = os.path.dirname(__file__)
src = [os.path.join(d, 'src', 'array_from_pyobj', 'wrapmodule.c'),
os.path.join(d, '..', 'src', 'fortranobject.c'),
os.path.join(d, '..', 'src', 'fortranobject.h')]
wrap = util.build_module_distutils(src, config_code,
'test_array_from_pyobj_ext')
def flags_info(arr):
flags = wrap.array_attrs(arr)[6]
return flags2names(flags)
def flags2names(flags):
info = []
for flagname in ['CONTIGUOUS', 'FORTRAN', 'OWNDATA', 'ENSURECOPY',
'ENSUREARRAY', 'ALIGNED', 'NOTSWAPPED', 'WRITEABLE',
'WRITEBACKIFCOPY', 'UPDATEIFCOPY', 'BEHAVED', 'BEHAVED_RO',
'CARRAY', 'FARRAY'
]:
if abs(flags) & getattr(wrap, flagname, 0):
info.append(flagname)
return info
class Intent(object):
def __init__(self, intent_list=[]):
self.intent_list = intent_list[:]
flags = 0
for i in intent_list:
if i == 'optional':
flags |= wrap.F2PY_OPTIONAL
else:
flags |= getattr(wrap, 'F2PY_INTENT_' + i.upper())
self.flags = flags
def __getattr__(self, name):
name = name.lower()
if name == 'in_':
name = 'in'
return self.__class__(self.intent_list + [name])
def __str__(self):
return 'intent(%s)' % (','.join(self.intent_list))
def __repr__(self):
return 'Intent(%r)' % (self.intent_list)
def is_intent(self, *names):
for name in names:
if name not in self.intent_list:
return False
return True
def is_intent_exact(self, *names):
return len(self.intent_list) == len(names) and self.is_intent(*names)
intent = Intent()
_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']
class Type(object):
_type_cache = {}
def __new__(cls, name):
if isinstance(name, dtype):
dtype0 = name
name = None
for n, i in typeinfo.items():
if isinstance(i, tuple) and dtype0.type is i[-1]:
name = n
break
obj = cls._type_cache.get(name.upper(), None)
if obj is not None:
return obj
obj = object.__new__(cls)
obj._init(name)
cls._type_cache[name.upper()] = obj
return obj
def _init(self, name):
self.NAME = name.upper()
self.type_num = getattr(wrap, 'NPY_' + self.NAME)
assert_equal(self.type_num, typeinfo[self.NAME][1])
self.dtype = typeinfo[self.NAME][-1]
self.elsize = typeinfo[self.NAME][2] / 8
self.dtypechar = typeinfo[self.NAME][0]
def cast_types(self):
return [self.__class__(_m) for _m in _cast_dict[self.NAME]]
def all_types(self):
return [self.__class__(_m) for _m in _type_names]
def smaller_types(self):
bits = typeinfo[self.NAME][3]
types = []
for name in _type_names:
if typeinfo[name][3] < bits:
types.append(Type(name))
return types
def equal_types(self):
bits = typeinfo[self.NAME][3]
types = []
for name in _type_names:
if name == self.NAME:
continue
if typeinfo[name][3] == bits:
types.append(Type(name))
return types
def larger_types(self):
bits = typeinfo[self.NAME][3]
types = []
for name in _type_names:
if typeinfo[name][3] > bits:
types.append(Type(name))
return types
class Array(object):
def __init__(self, typ, dims, intent, obj):
self.type = typ
self.dims = dims
self.intent = intent
self.obj_copy = copy.deepcopy(obj)
self.obj = obj
# arr.dtypechar may be different from typ.dtypechar
self.arr = wrap.call(typ.type_num, dims, intent.flags, obj)
assert_(isinstance(self.arr, ndarray), repr(type(self.arr)))
self.arr_attr = wrap.array_attrs(self.arr)
if len(dims) > 1:
if self.intent.is_intent('c'):
assert_(intent.flags & wrap.F2PY_INTENT_C)
assert_(not self.arr.flags['FORTRAN'],
repr((self.arr.flags, getattr(obj, 'flags', None))))
assert_(self.arr.flags['CONTIGUOUS'])
assert_(not self.arr_attr[6] & wrap.FORTRAN)
else:
assert_(not intent.flags & wrap.F2PY_INTENT_C)
assert_(self.arr.flags['FORTRAN'])
assert_(not self.arr.flags['CONTIGUOUS'])
assert_(self.arr_attr[6] & wrap.FORTRAN)
if obj is None:
self.pyarr = None
self.pyarr_attr = None
return
if intent.is_intent('cache'):
assert_(isinstance(obj, ndarray), repr(type(obj)))
self.pyarr = array(obj).reshape(*dims).copy()
else:
self.pyarr = array(array(obj, dtype=typ.dtypechar).reshape(*dims),
order=self.intent.is_intent('c') and 'C' or 'F')
assert_(self.pyarr.dtype == typ,
repr((self.pyarr.dtype, typ)))
assert_(self.pyarr.flags['OWNDATA'], (obj, intent))
self.pyarr_attr = wrap.array_attrs(self.pyarr)
if len(dims) > 1:
if self.intent.is_intent('c'):
assert_(not self.pyarr.flags['FORTRAN'])
assert_(self.pyarr.flags['CONTIGUOUS'])
assert_(not self.pyarr_attr[6] & wrap.FORTRAN)
else:
assert_(self.pyarr.flags['FORTRAN'])
assert_(not self.pyarr.flags['CONTIGUOUS'])
assert_(self.pyarr_attr[6] & wrap.FORTRAN)
assert_(self.arr_attr[1] == self.pyarr_attr[1]) # nd
assert_(self.arr_attr[2] == self.pyarr_attr[2]) # dimensions
if self.arr_attr[1] <= 1:
assert_(self.arr_attr[3] == self.pyarr_attr[3],
repr((self.arr_attr[3], self.pyarr_attr[3],
self.arr.tobytes(), self.pyarr.tobytes()))) # strides
assert_(self.arr_attr[5][-2:] == self.pyarr_attr[5][-2:],
repr((self.arr_attr[5], self.pyarr_attr[5]))) # descr
assert_(self.arr_attr[6] == self.pyarr_attr[6],
repr((self.arr_attr[6], self.pyarr_attr[6],
flags2names(0 * self.arr_attr[6] - self.pyarr_attr[6]),
flags2names(self.arr_attr[6]), intent))) # flags
if intent.is_intent('cache'):
assert_(self.arr_attr[5][3] >= self.type.elsize,
repr((self.arr_attr[5][3], self.type.elsize)))
else:
assert_(self.arr_attr[5][3] == self.type.elsize,
repr((self.arr_attr[5][3], self.type.elsize)))
assert_(self.arr_equal(self.pyarr, self.arr))
if isinstance(self.obj, ndarray):
if typ.elsize == Type(obj.dtype).elsize:
if not intent.is_intent('copy') and self.arr_attr[1] <= 1:
assert_(self.has_shared_memory())
def arr_equal(self, arr1, arr2):
if arr1.shape != arr2.shape:
return False
s = arr1 == arr2
return alltrue(s.flatten())
def __str__(self):
return str(self.arr)
def has_shared_memory(self):
"""Check that created array shares data with input array.
"""
if self.obj is self.arr:
return True
if not isinstance(self.obj, ndarray):
return False
obj_attr = wrap.array_attrs(self.obj)
return obj_attr[0] == self.arr_attr[0]
class TestIntent(object):
def test_in_out(self):
assert_equal(str(intent.in_.out), 'intent(in,out)')
assert_(intent.in_.c.is_intent('c'))
assert_(not intent.in_.c.is_intent_exact('c'))
assert_(intent.in_.c.is_intent_exact('c', 'in'))
assert_(intent.in_.c.is_intent_exact('in', 'c'))
assert_(not intent.in_.is_intent('c'))
class _test_shared_memory(object):
num2seq = [1, 2]
num23seq = [[1, 2, 3], [4, 5, 6]]
def test_in_from_2seq(self):
a = self.array([2], intent.in_, self.num2seq)
assert_(not a.has_shared_memory())
def test_in_from_2casttype(self):
for t in self.type.cast_types():
obj = array(self.num2seq, dtype=t.dtype)
a = self.array([len(self.num2seq)], intent.in_, obj)
if t.elsize == self.type.elsize:
assert_(
a.has_shared_memory(), repr((self.type.dtype, t.dtype)))
else:
assert_(not a.has_shared_memory(), repr(t.dtype))
def test_inout_2seq(self):
obj = array(self.num2seq, dtype=self.type.dtype)
a = self.array([len(self.num2seq)], intent.inout, obj)
assert_(a.has_shared_memory())
try:
a = self.array([2], intent.in_.inout, self.num2seq)
except TypeError as msg:
if not str(msg).startswith('failed to initialize intent'
'(inout|inplace|cache) array'):
raise
else:
raise SystemError('intent(inout) should have failed on sequence')
def test_f_inout_23seq(self):
obj = array(self.num23seq, dtype=self.type.dtype, order='F')
shape = (len(self.num23seq), len(self.num23seq[0]))
a = self.array(shape, intent.in_.inout, obj)
assert_(a.has_shared_memory())
obj = array(self.num23seq, dtype=self.type.dtype, order='C')
shape = (len(self.num23seq), len(self.num23seq[0]))
try:
a = self.array(shape, intent.in_.inout, obj)
except ValueError as msg:
if not str(msg).startswith('failed to initialize intent'
'(inout) array'):
raise
else:
raise SystemError(
'intent(inout) should have failed on improper array')
def test_c_inout_23seq(self):
obj = array(self.num23seq, dtype=self.type.dtype)
shape = (len(self.num23seq), len(self.num23seq[0]))
a = self.array(shape, intent.in_.c.inout, obj)
assert_(a.has_shared_memory())
def test_in_copy_from_2casttype(self):
for t in self.type.cast_types():
obj = array(self.num2seq, dtype=t.dtype)
a = self.array([len(self.num2seq)], intent.in_.copy, obj)
assert_(not a.has_shared_memory(), repr(t.dtype))
def test_c_in_from_23seq(self):
a = self.array([len(self.num23seq), len(self.num23seq[0])],
intent.in_, self.num23seq)
assert_(not a.has_shared_memory())
def test_in_from_23casttype(self):
for t in self.type.cast_types():
obj = array(self.num23seq, dtype=t.dtype)
a = self.array([len(self.num23seq), len(self.num23seq[0])],
intent.in_, obj)
assert_(not a.has_shared_memory(), repr(t.dtype))
def test_f_in_from_23casttype(self):
for t in self.type.cast_types():
obj = array(self.num23seq, dtype=t.dtype, order='F')
a = self.array([len(self.num23seq), len(self.num23seq[0])],
intent.in_, obj)
if t.elsize == self.type.elsize:
assert_(a.has_shared_memory(), repr(t.dtype))
else:
assert_(not a.has_shared_memory(), repr(t.dtype))
def test_c_in_from_23casttype(self):
for t in self.type.cast_types():
obj = array(self.num23seq, dtype=t.dtype)
a = self.array([len(self.num23seq), len(self.num23seq[0])],
intent.in_.c, obj)
if t.elsize == self.type.elsize:
assert_(a.has_shared_memory(), repr(t.dtype))
else:
assert_(not a.has_shared_memory(), repr(t.dtype))
def test_f_copy_in_from_23casttype(self):
for t in self.type.cast_types():
obj = array(self.num23seq, dtype=t.dtype, order='F')
a = self.array([len(self.num23seq), len(self.num23seq[0])],
intent.in_.copy, obj)
assert_(not a.has_shared_memory(), repr(t.dtype))
def test_c_copy_in_from_23casttype(self):
for t in self.type.cast_types():
obj = array(self.num23seq, dtype=t.dtype)
a = self.array([len(self.num23seq), len(self.num23seq[0])],
intent.in_.c.copy, obj)
assert_(not a.has_shared_memory(), repr(t.dtype))
def test_in_cache_from_2casttype(self):
for t in self.type.all_types():
if t.elsize != self.type.elsize:
continue
obj = array(self.num2seq, dtype=t.dtype)
shape = (len(self.num2seq),)
a = self.array(shape, intent.in_.c.cache, obj)
assert_(a.has_shared_memory(), repr(t.dtype))
a = self.array(shape, intent.in_.cache, obj)
assert_(a.has_shared_memory(), repr(t.dtype))
obj = array(self.num2seq, dtype=t.dtype, order='F')
a = self.array(shape, intent.in_.c.cache, obj)
assert_(a.has_shared_memory(), repr(t.dtype))
a = self.array(shape, intent.in_.cache, obj)
assert_(a.has_shared_memory(), repr(t.dtype))
try:
a = self.array(shape, intent.in_.cache, obj[::-1])
except ValueError as msg:
if not str(msg).startswith('failed to initialize'
' intent(cache) array'):
raise
else:
raise SystemError(
'intent(cache) should have failed on multisegmented array')
def test_in_cache_from_2casttype_failure(self):
for t in self.type.all_types():
if t.elsize >= self.type.elsize:
continue
obj = array(self.num2seq, dtype=t.dtype)
shape = (len(self.num2seq),)
try:
self.array(shape, intent.in_.cache, obj) # Should succeed
except ValueError as msg:
if not str(msg).startswith('failed to initialize'
' intent(cache) array'):
raise
else:
raise SystemError(
'intent(cache) should have failed on smaller array')
def test_cache_hidden(self):
shape = (2,)
a = self.array(shape, intent.cache.hide, None)
assert_(a.arr.shape == shape)
shape = (2, 3)
a = self.array(shape, intent.cache.hide, None)
assert_(a.arr.shape == shape)
shape = (-1, 3)
try:
a = self.array(shape, intent.cache.hide, None)
except ValueError as msg:
if not str(msg).startswith('failed to create intent'
'(cache|hide)|optional array'):
raise
else:
raise SystemError(
'intent(cache) should have failed on undefined dimensions')
def test_hidden(self):
shape = (2,)
a = self.array(shape, intent.hide, None)
assert_(a.arr.shape == shape)
assert_(a.arr_equal(a.arr, zeros(shape, dtype=self.type.dtype)))
shape = (2, 3)
a = self.array(shape, intent.hide, None)
assert_(a.arr.shape == shape)
assert_(a.arr_equal(a.arr, zeros(shape, dtype=self.type.dtype)))
assert_(a.arr.flags['FORTRAN'] and not a.arr.flags['CONTIGUOUS'])
shape = (2, 3)
a = self.array(shape, intent.c.hide, None)
assert_(a.arr.shape == shape)
assert_(a.arr_equal(a.arr, zeros(shape, dtype=self.type.dtype)))
assert_(not a.arr.flags['FORTRAN'] and a.arr.flags['CONTIGUOUS'])
shape = (-1, 3)
try:
a = self.array(shape, intent.hide, None)
except ValueError as msg:
if not str(msg).startswith('failed to create intent'
'(cache|hide)|optional array'):
raise
else:
raise SystemError('intent(hide) should have failed'
' on undefined dimensions')
def test_optional_none(self):
shape = (2,)
a = self.array(shape, intent.optional, None)
assert_(a.arr.shape == shape)
assert_(a.arr_equal(a.arr, zeros(shape, dtype=self.type.dtype)))
shape = (2, 3)
a = self.array(shape, intent.optional, None)
assert_(a.arr.shape == shape)
assert_(a.arr_equal(a.arr, zeros(shape, dtype=self.type.dtype)))
assert_(a.arr.flags['FORTRAN'] and not a.arr.flags['CONTIGUOUS'])
shape = (2, 3)
a = self.array(shape, intent.c.optional, None)
assert_(a.arr.shape == shape)
assert_(a.arr_equal(a.arr, zeros(shape, dtype=self.type.dtype)))
assert_(not a.arr.flags['FORTRAN'] and a.arr.flags['CONTIGUOUS'])
def test_optional_from_2seq(self):
obj = self.num2seq
shape = (len(obj),)
a = self.array(shape, intent.optional, obj)
assert_(a.arr.shape == shape)
assert_(not a.has_shared_memory())
def test_optional_from_23seq(self):
obj = self.num23seq
shape = (len(obj), len(obj[0]))
a = self.array(shape, intent.optional, obj)
assert_(a.arr.shape == shape)
assert_(not a.has_shared_memory())
a = self.array(shape, intent.optional.c, obj)
assert_(a.arr.shape == shape)
assert_(not a.has_shared_memory())
def test_inplace(self):
obj = array(self.num23seq, dtype=self.type.dtype)
assert_(not obj.flags['FORTRAN'] and obj.flags['CONTIGUOUS'])
shape = obj.shape
a = self.array(shape, intent.inplace, obj)
assert_(obj[1][2] == a.arr[1][2], repr((obj, a.arr)))
a.arr[1][2] = 54
assert_(obj[1][2] == a.arr[1][2] ==
array(54, dtype=self.type.dtype), repr((obj, a.arr)))
assert_(a.arr is obj)
assert_(obj.flags['FORTRAN']) # obj attributes are changed inplace!
assert_(not obj.flags['CONTIGUOUS'])
def test_inplace_from_casttype(self):
for t in self.type.cast_types():
if t is self.type:
continue
obj = array(self.num23seq, dtype=t.dtype)
assert_(obj.dtype.type == t.dtype)
assert_(obj.dtype.type is not self.type.dtype)
assert_(not obj.flags['FORTRAN'] and obj.flags['CONTIGUOUS'])
shape = obj.shape
a = self.array(shape, intent.inplace, obj)
assert_(obj[1][2] == a.arr[1][2], repr((obj, a.arr)))
a.arr[1][2] = 54
assert_(obj[1][2] == a.arr[1][2] ==
array(54, dtype=self.type.dtype), repr((obj, a.arr)))
assert_(a.arr is obj)
assert_(obj.flags['FORTRAN']) # obj attributes changed inplace!
assert_(not obj.flags['CONTIGUOUS'])
assert_(obj.dtype.type is self.type.dtype) # obj changed inplace!
for t in _type_names:
exec('''\
class TestGen_%s(_test_shared_memory):
def setup(self):
self.type = Type(%r)
array = lambda self,dims,intent,obj: Array(Type(%r),dims,intent,obj)
''' % (t, t, t))
if __name__ == "__main__":
setup_module()
run_module_suite()

View File

@@ -0,0 +1,35 @@
from __future__ import division, absolute_import, print_function
import os
from numpy.testing import run_module_suite, assert_, dec
from . import util
def _path(*a):
return os.path.join(*((os.path.dirname(__file__),) + a))
class TestAssumedShapeSumExample(util.F2PyTest):
sources = [_path('src', 'assumed_shape', 'foo_free.f90'),
_path('src', 'assumed_shape', 'foo_use.f90'),
_path('src', 'assumed_shape', 'precision.f90'),
_path('src', 'assumed_shape', 'foo_mod.f90'),
]
@dec.slow
def test_all(self):
r = self.module.fsum([1, 2])
assert_(r == 3, repr(r))
r = self.module.sum([1, 2])
assert_(r == 3, repr(r))
r = self.module.sum_with_use([1, 2])
assert_(r == 3, repr(r))
r = self.module.mod.sum([1, 2])
assert_(r == 3, repr(r))
r = self.module.mod.fsum([1, 2])
assert_(r == 3, repr(r))
if __name__ == "__main__":
run_module_suite()

View File

@@ -0,0 +1,25 @@
from __future__ import division, absolute_import, print_function
import textwrap
import sys
from . import util
from numpy.testing import run_module_suite, assert_equal, dec
class TestBlockDocString(util.F2PyTest):
code = """
SUBROUTINE FOO()
INTEGER BAR(2, 3)
COMMON /BLOCK/ BAR
RETURN
END
"""
@dec.knownfailureif(sys.platform=='win32', msg='Fails with MinGW64 Gfortran (Issue #9673)')
def test_block_docstring(self):
expected = "'i'-array(2,3)\n"
assert_equal(self.module.block.__doc__, expected)
if __name__ == "__main__":
run_module_suite()

View File

@@ -0,0 +1,168 @@
from __future__ import division, absolute_import, print_function
import math
import textwrap
import sys
import numpy as np
from numpy.testing import run_module_suite, assert_, assert_equal, dec
from . import util
class TestF77Callback(util.F2PyTest):
code = """
subroutine t(fun,a)
integer a
cf2py intent(out) a
external fun
call fun(a)
end
subroutine func(a)
cf2py intent(in,out) a
integer a
a = a + 11
end
subroutine func0(a)
cf2py intent(out) a
integer a
a = 11
end
subroutine t2(a)
cf2py intent(callback) fun
integer a
cf2py intent(out) a
external fun
call fun(a)
end
subroutine string_callback(callback, a)
external callback
double precision callback
double precision a
character*1 r
cf2py intent(out) a
r = 'r'
a = callback(r)
end
subroutine string_callback_array(callback, cu, lencu, a)
external callback
integer callback
integer lencu
character*8 cu(lencu)
integer a
cf2py intent(out) a
a = callback(cu, lencu)
end
"""
@dec.slow
def test_all(self):
for name in "t,t2".split(","):
self.check_function(name)
@dec.slow
def test_docstring(self):
expected = """
a = t(fun,[fun_extra_args])
Wrapper for ``t``.
Parameters
----------
fun : call-back function
Other Parameters
----------------
fun_extra_args : input tuple, optional
Default: ()
Returns
-------
a : int
Notes
-----
Call-back functions::
def fun(): return a
Return objects:
a : int
"""
assert_equal(self.module.t.__doc__, textwrap.dedent(expected).lstrip())
def check_function(self, name):
t = getattr(self.module, name)
r = t(lambda: 4)
assert_(r == 4, repr(r))
r = t(lambda a: 5, fun_extra_args=(6,))
assert_(r == 5, repr(r))
r = t(lambda a: a, fun_extra_args=(6,))
assert_(r == 6, repr(r))
r = t(lambda a: 5 + a, fun_extra_args=(7,))
assert_(r == 12, repr(r))
r = t(lambda a: math.degrees(a), fun_extra_args=(math.pi,))
assert_(r == 180, repr(r))
r = t(math.degrees, fun_extra_args=(math.pi,))
assert_(r == 180, repr(r))
r = t(self.module.func, fun_extra_args=(6,))
assert_(r == 17, repr(r))
r = t(self.module.func0)
assert_(r == 11, repr(r))
r = t(self.module.func0._cpointer)
assert_(r == 11, repr(r))
class A(object):
def __call__(self):
return 7
def mth(self):
return 9
a = A()
r = t(a)
assert_(r == 7, repr(r))
r = t(a.mth)
assert_(r == 9, repr(r))
@dec.knownfailureif(sys.platform=='win32',
msg='Fails with MinGW64 Gfortran (Issue #9673)')
def test_string_callback(self):
def callback(code):
if code == 'r':
return 0
else:
return 1
f = getattr(self.module, 'string_callback')
r = f(callback)
assert_(r == 0, repr(r))
@dec.knownfailureif(sys.platform=='win32',
msg='Fails with MinGW64 Gfortran (Issue #9673)')
def test_string_callback_array(self):
# See gh-10027
cu = np.zeros((1, 8), 'S1')
def callback(cu, lencu):
if cu.shape != (lencu, 8):
return 1
if cu.dtype != 'S1':
return 2
if not np.all(cu == b''):
return 3
return 0
f = getattr(self.module, 'string_callback_array')
res = f(callback, cu, len(cu))
assert_(res == 0, repr(res))
if __name__ == "__main__":
run_module_suite()

View File

@@ -0,0 +1,27 @@
from __future__ import division, absolute_import, print_function
import os
import sys
import numpy as np
from . import util
from numpy.testing import run_module_suite, assert_array_equal, dec
def _path(*a):
return os.path.join(*((os.path.dirname(__file__),) + a))
class TestCommonBlock(util.F2PyTest):
sources = [_path('src', 'common', 'block.f')]
@dec.knownfailureif(sys.platform=='win32', msg='Fails with MinGW64 Gfortran (Issue #9673)')
def test_common_block(self):
self.module.initcb()
assert_array_equal(self.module.block.long_bn,
np.array(1.0, dtype=np.float64))
assert_array_equal(self.module.block.string_bn,
np.array('2', dtype='|S1'))
assert_array_equal(self.module.block.ok,
np.array(3, dtype=np.int32))
if __name__ == "__main__":
run_module_suite()

View File

@@ -0,0 +1,36 @@
from __future__ import division, absolute_import, print_function
import os
from numpy.testing import run_module_suite, assert_, dec
from numpy.f2py.crackfortran import (
_selected_int_kind_func as selected_int_kind,
_selected_real_kind_func as selected_real_kind
)
from . import util
def _path(*a):
return os.path.join(*((os.path.dirname(__file__),) + a))
class TestKind(util.F2PyTest):
sources = [_path('src', 'kind', 'foo.f90')]
@dec.slow
def test_all(self):
selectedrealkind = self.module.selectedrealkind
selectedintkind = self.module.selectedintkind
for i in range(40):
assert_(selectedintkind(i) in [selected_int_kind(i), -1],
'selectedintkind(%s): expected %r but got %r' %
(i, selected_int_kind(i), selectedintkind(i)))
for i in range(20):
assert_(selectedrealkind(i) in [selected_real_kind(i), -1],
'selectedrealkind(%s): expected %r but got %r' %
(i, selected_real_kind(i), selectedrealkind(i)))
if __name__ == "__main__":
run_module_suite()

View File

@@ -0,0 +1,40 @@
from __future__ import division, absolute_import, print_function
import os
import textwrap
from numpy.testing import run_module_suite, assert_, assert_equal, dec
from . import util
def _path(*a):
return os.path.join(*((os.path.dirname(__file__),) + a))
class TestMixed(util.F2PyTest):
sources = [_path('src', 'mixed', 'foo.f'),
_path('src', 'mixed', 'foo_fixed.f90'),
_path('src', 'mixed', 'foo_free.f90')]
@dec.slow
def test_all(self):
assert_(self.module.bar11() == 11)
assert_(self.module.foo_fixed.bar12() == 12)
assert_(self.module.foo_free.bar13() == 13)
@dec.slow
def test_docstring(self):
expected = """
a = bar11()
Wrapper for ``bar11``.
Returns
-------
a : int
"""
assert_equal(self.module.bar11.__doc__,
textwrap.dedent(expected).lstrip())
if __name__ == "__main__":
run_module_suite()

View File

@@ -0,0 +1,122 @@
from __future__ import division, absolute_import, print_function
import os
import math
import numpy as np
from numpy.testing import run_module_suite, dec, assert_raises, assert_equal
from . import util
def _path(*a):
return os.path.join(*((os.path.dirname(__file__),) + a))
class TestParameters(util.F2PyTest):
# Check that intent(in out) translates as intent(inout)
sources = [_path('src', 'parameter', 'constant_real.f90'),
_path('src', 'parameter', 'constant_integer.f90'),
_path('src', 'parameter', 'constant_both.f90'),
_path('src', 'parameter', 'constant_compound.f90'),
_path('src', 'parameter', 'constant_non_compound.f90'),
]
@dec.slow
def test_constant_real_single(self):
# non-contiguous should raise error
x = np.arange(6, dtype=np.float32)[::2]
assert_raises(ValueError, self.module.foo_single, x)
# check values with contiguous array
x = np.arange(3, dtype=np.float32)
self.module.foo_single(x)
assert_equal(x, [0 + 1 + 2*3, 1, 2])
@dec.slow
def test_constant_real_double(self):
# non-contiguous should raise error
x = np.arange(6, dtype=np.float64)[::2]
assert_raises(ValueError, self.module.foo_double, x)
# check values with contiguous array
x = np.arange(3, dtype=np.float64)
self.module.foo_double(x)
assert_equal(x, [0 + 1 + 2*3, 1, 2])
@dec.slow
def test_constant_compound_int(self):
# non-contiguous should raise error
x = np.arange(6, dtype=np.int32)[::2]
assert_raises(ValueError, self.module.foo_compound_int, x)
# check values with contiguous array
x = np.arange(3, dtype=np.int32)
self.module.foo_compound_int(x)
assert_equal(x, [0 + 1 + 2*6, 1, 2])
@dec.slow
def test_constant_non_compound_int(self):
# check values
x = np.arange(4, dtype=np.int32)
self.module.foo_non_compound_int(x)
assert_equal(x, [0 + 1 + 2 + 3*4, 1, 2, 3])
@dec.slow
def test_constant_integer_int(self):
# non-contiguous should raise error
x = np.arange(6, dtype=np.int32)[::2]
assert_raises(ValueError, self.module.foo_int, x)
# check values with contiguous array
x = np.arange(3, dtype=np.int32)
self.module.foo_int(x)
assert_equal(x, [0 + 1 + 2*3, 1, 2])
@dec.slow
def test_constant_integer_long(self):
# non-contiguous should raise error
x = np.arange(6, dtype=np.int64)[::2]
assert_raises(ValueError, self.module.foo_long, x)
# check values with contiguous array
x = np.arange(3, dtype=np.int64)
self.module.foo_long(x)
assert_equal(x, [0 + 1 + 2*3, 1, 2])
@dec.slow
def test_constant_both(self):
# non-contiguous should raise error
x = np.arange(6, dtype=np.float64)[::2]
assert_raises(ValueError, self.module.foo, x)
# check values with contiguous array
x = np.arange(3, dtype=np.float64)
self.module.foo(x)
assert_equal(x, [0 + 1*3*3 + 2*3*3, 1*3, 2*3])
@dec.slow
def test_constant_no(self):
# non-contiguous should raise error
x = np.arange(6, dtype=np.float64)[::2]
assert_raises(ValueError, self.module.foo_no, x)
# check values with contiguous array
x = np.arange(3, dtype=np.float64)
self.module.foo_no(x)
assert_equal(x, [0 + 1*3*3 + 2*3*3, 1*3, 2*3])
@dec.slow
def test_constant_sum(self):
# non-contiguous should raise error
x = np.arange(6, dtype=np.float64)[::2]
assert_raises(ValueError, self.module.foo_sum, x)
# check values with contiguous array
x = np.arange(3, dtype=np.float64)
self.module.foo_sum(x)
assert_equal(x, [0 + 1*3*3 + 2*3*3, 1*3, 2*3])
if __name__ == "__main__":
run_module_suite()

View File

@@ -0,0 +1,33 @@
from __future__ import division, absolute_import, print_function
import os
import math
import numpy as np
from numpy.testing import run_module_suite, dec, assert_raises, assert_equal
from . 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__":
run_module_suite()

View File

@@ -0,0 +1,147 @@
from __future__ import division, absolute_import, print_function
from numpy import array
from numpy.testing import run_module_suite, assert_, dec
from . import util
class TestReturnCharacter(util.F2PyTest):
def check_function(self, t):
tname = t.__doc__.split()[0]
if tname in ['t0', 't1', 's0', 's1']:
assert_(t(23) == b'2')
r = t('ab')
assert_(r == b'a', repr(r))
r = t(array('ab'))
assert_(r == b'a', repr(r))
r = t(array(77, 'u1'))
assert_(r == b'M', repr(r))
#assert_(_raises(ValueError, t, array([77,87])))
#assert_(_raises(ValueError, t, array(77)))
elif tname in ['ts', 'ss']:
assert_(t(23) == b'23 ', repr(t(23)))
assert_(t('123456789abcdef') == b'123456789a')
elif tname in ['t5', 's5']:
assert_(t(23) == b'23 ', repr(t(23)))
assert_(t('ab') == b'ab ', repr(t('ab')))
assert_(t('123456789abcdef') == b'12345')
else:
raise NotImplementedError
class TestF77ReturnCharacter(TestReturnCharacter):
code = """
function t0(value)
character value
character t0
t0 = value
end
function t1(value)
character*1 value
character*1 t1
t1 = value
end
function t5(value)
character*5 value
character*5 t5
t5 = value
end
function ts(value)
character*(*) value
character*(*) ts
ts = value
end
subroutine s0(t0,value)
character value
character t0
cf2py intent(out) t0
t0 = value
end
subroutine s1(t1,value)
character*1 value
character*1 t1
cf2py intent(out) t1
t1 = value
end
subroutine s5(t5,value)
character*5 value
character*5 t5
cf2py intent(out) t5
t5 = value
end
subroutine ss(ts,value)
character*(*) value
character*10 ts
cf2py intent(out) ts
ts = value
end
"""
@dec.slow
def test_all(self):
for name in "t0,t1,t5,s0,s1,s5,ss".split(","):
self.check_function(getattr(self.module, name))
class TestF90ReturnCharacter(TestReturnCharacter):
suffix = ".f90"
code = """
module f90_return_char
contains
function t0(value)
character :: value
character :: t0
t0 = value
end function t0
function t1(value)
character(len=1) :: value
character(len=1) :: t1
t1 = value
end function t1
function t5(value)
character(len=5) :: value
character(len=5) :: t5
t5 = value
end function t5
function ts(value)
character(len=*) :: value
character(len=10) :: ts
ts = value
end function ts
subroutine s0(t0,value)
character :: value
character :: t0
!f2py intent(out) t0
t0 = value
end subroutine s0
subroutine s1(t1,value)
character(len=1) :: value
character(len=1) :: t1
!f2py intent(out) t1
t1 = value
end subroutine s1
subroutine s5(t5,value)
character(len=5) :: value
character(len=5) :: t5
!f2py intent(out) t5
t5 = value
end subroutine s5
subroutine ss(ts,value)
character(len=*) :: value
character(len=10) :: ts
!f2py intent(out) ts
ts = value
end subroutine ss
end module f90_return_char
"""
@dec.slow
def test_all(self):
for name in "t0,t1,t5,ts,s0,s1,s5,ss".split(","):
self.check_function(getattr(self.module.f90_return_char, name))
if __name__ == "__main__":
run_module_suite()

View File

@@ -0,0 +1,170 @@
from __future__ import division, absolute_import, print_function
from numpy import array
from numpy.compat import long
from numpy.testing import run_module_suite, assert_, assert_raises, dec
from . import util
class TestReturnComplex(util.F2PyTest):
def check_function(self, t):
tname = t.__doc__.split()[0]
if tname in ['t0', 't8', 's0', 's8']:
err = 1e-5
else:
err = 0.0
assert_(abs(t(234j) - 234.0j) <= err)
assert_(abs(t(234.6) - 234.6) <= err)
assert_(abs(t(long(234)) - 234.0) <= err)
assert_(abs(t(234.6 + 3j) - (234.6 + 3j)) <= err)
#assert_( abs(t('234')-234.)<=err)
#assert_( abs(t('234.6')-234.6)<=err)
assert_(abs(t(-234) + 234.) <= err)
assert_(abs(t([234]) - 234.) <= err)
assert_(abs(t((234,)) - 234.) <= err)
assert_(abs(t(array(234)) - 234.) <= err)
assert_(abs(t(array(23 + 4j, 'F')) - (23 + 4j)) <= err)
assert_(abs(t(array([234])) - 234.) <= err)
assert_(abs(t(array([[234]])) - 234.) <= err)
assert_(abs(t(array([234], 'b')) + 22.) <= err)
assert_(abs(t(array([234], 'h')) - 234.) <= err)
assert_(abs(t(array([234], 'i')) - 234.) <= err)
assert_(abs(t(array([234], 'l')) - 234.) <= err)
assert_(abs(t(array([234], 'q')) - 234.) <= err)
assert_(abs(t(array([234], 'f')) - 234.) <= err)
assert_(abs(t(array([234], 'd')) - 234.) <= err)
assert_(abs(t(array([234 + 3j], 'F')) - (234 + 3j)) <= err)
assert_(abs(t(array([234], 'D')) - 234.) <= err)
#assert_raises(TypeError, t, array([234], 'a1'))
assert_raises(TypeError, t, 'abc')
assert_raises(IndexError, t, [])
assert_raises(IndexError, t, ())
assert_raises(TypeError, t, t)
assert_raises(TypeError, t, {})
try:
r = t(10 ** 400)
assert_(repr(r) in ['(inf+0j)', '(Infinity+0j)'], repr(r))
except OverflowError:
pass
class TestF77ReturnComplex(TestReturnComplex):
code = """
function t0(value)
complex value
complex t0
t0 = value
end
function t8(value)
complex*8 value
complex*8 t8
t8 = value
end
function t16(value)
complex*16 value
complex*16 t16
t16 = value
end
function td(value)
double complex value
double complex td
td = value
end
subroutine s0(t0,value)
complex value
complex t0
cf2py intent(out) t0
t0 = value
end
subroutine s8(t8,value)
complex*8 value
complex*8 t8
cf2py intent(out) t8
t8 = value
end
subroutine s16(t16,value)
complex*16 value
complex*16 t16
cf2py intent(out) t16
t16 = value
end
subroutine sd(td,value)
double complex value
double complex td
cf2py intent(out) td
td = value
end
"""
@dec.slow
def test_all(self):
for name in "t0,t8,t16,td,s0,s8,s16,sd".split(","):
self.check_function(getattr(self.module, name))
class TestF90ReturnComplex(TestReturnComplex):
suffix = ".f90"
code = """
module f90_return_complex
contains
function t0(value)
complex :: value
complex :: t0
t0 = value
end function t0
function t8(value)
complex(kind=4) :: value
complex(kind=4) :: t8
t8 = value
end function t8
function t16(value)
complex(kind=8) :: value
complex(kind=8) :: t16
t16 = value
end function t16
function td(value)
double complex :: value
double complex :: td
td = value
end function td
subroutine s0(t0,value)
complex :: value
complex :: t0
!f2py intent(out) t0
t0 = value
end subroutine s0
subroutine s8(t8,value)
complex(kind=4) :: value
complex(kind=4) :: t8
!f2py intent(out) t8
t8 = value
end subroutine s8
subroutine s16(t16,value)
complex(kind=8) :: value
complex(kind=8) :: t16
!f2py intent(out) t16
t16 = value
end subroutine s16
subroutine sd(td,value)
double complex :: value
double complex :: td
!f2py intent(out) td
td = value
end subroutine sd
end module f90_return_complex
"""
@dec.slow
def test_all(self):
for name in "t0,t8,t16,td,s0,s8,s16,sd".split(","):
self.check_function(getattr(self.module.f90_return_complex, name))
if __name__ == "__main__":
run_module_suite()

View File

@@ -0,0 +1,180 @@
from __future__ import division, absolute_import, print_function
from numpy import array
from numpy.compat import long
from numpy.testing import run_module_suite, assert_, assert_raises, dec
from . import util
class TestReturnInteger(util.F2PyTest):
def check_function(self, t):
assert_(t(123) == 123, repr(t(123)))
assert_(t(123.6) == 123)
assert_(t(long(123)) == 123)
assert_(t('123') == 123)
assert_(t(-123) == -123)
assert_(t([123]) == 123)
assert_(t((123,)) == 123)
assert_(t(array(123)) == 123)
assert_(t(array([123])) == 123)
assert_(t(array([[123]])) == 123)
assert_(t(array([123], 'b')) == 123)
assert_(t(array([123], 'h')) == 123)
assert_(t(array([123], 'i')) == 123)
assert_(t(array([123], 'l')) == 123)
assert_(t(array([123], 'B')) == 123)
assert_(t(array([123], 'f')) == 123)
assert_(t(array([123], 'd')) == 123)
#assert_raises(ValueError, t, array([123],'S3'))
assert_raises(ValueError, t, 'abc')
assert_raises(IndexError, t, [])
assert_raises(IndexError, t, ())
assert_raises(Exception, t, t)
assert_raises(Exception, t, {})
if t.__doc__.split()[0] in ['t8', 's8']:
assert_raises(OverflowError, t, 100000000000000000000000)
assert_raises(OverflowError, t, 10000000011111111111111.23)
class TestF77ReturnInteger(TestReturnInteger):
code = """
function t0(value)
integer value
integer t0
t0 = value
end
function t1(value)
integer*1 value
integer*1 t1
t1 = value
end
function t2(value)
integer*2 value
integer*2 t2
t2 = value
end
function t4(value)
integer*4 value
integer*4 t4
t4 = value
end
function t8(value)
integer*8 value
integer*8 t8
t8 = value
end
subroutine s0(t0,value)
integer value
integer t0
cf2py intent(out) t0
t0 = value
end
subroutine s1(t1,value)
integer*1 value
integer*1 t1
cf2py intent(out) t1
t1 = value
end
subroutine s2(t2,value)
integer*2 value
integer*2 t2
cf2py intent(out) t2
t2 = value
end
subroutine s4(t4,value)
integer*4 value
integer*4 t4
cf2py intent(out) t4
t4 = value
end
subroutine s8(t8,value)
integer*8 value
integer*8 t8
cf2py intent(out) t8
t8 = value
end
"""
@dec.slow
def test_all(self):
for name in "t0,t1,t2,t4,t8,s0,s1,s2,s4,s8".split(","):
self.check_function(getattr(self.module, name))
class TestF90ReturnInteger(TestReturnInteger):
suffix = ".f90"
code = """
module f90_return_integer
contains
function t0(value)
integer :: value
integer :: t0
t0 = value
end function t0
function t1(value)
integer(kind=1) :: value
integer(kind=1) :: t1
t1 = value
end function t1
function t2(value)
integer(kind=2) :: value
integer(kind=2) :: t2
t2 = value
end function t2
function t4(value)
integer(kind=4) :: value
integer(kind=4) :: t4
t4 = value
end function t4
function t8(value)
integer(kind=8) :: value
integer(kind=8) :: t8
t8 = value
end function t8
subroutine s0(t0,value)
integer :: value
integer :: t0
!f2py intent(out) t0
t0 = value
end subroutine s0
subroutine s1(t1,value)
integer(kind=1) :: value
integer(kind=1) :: t1
!f2py intent(out) t1
t1 = value
end subroutine s1
subroutine s2(t2,value)
integer(kind=2) :: value
integer(kind=2) :: t2
!f2py intent(out) t2
t2 = value
end subroutine s2
subroutine s4(t4,value)
integer(kind=4) :: value
integer(kind=4) :: t4
!f2py intent(out) t4
t4 = value
end subroutine s4
subroutine s8(t8,value)
integer(kind=8) :: value
integer(kind=8) :: t8
!f2py intent(out) t8
t8 = value
end subroutine s8
end module f90_return_integer
"""
@dec.slow
def test_all(self):
for name in "t0,t1,t2,t4,t8,s0,s1,s2,s4,s8".split(","):
self.check_function(getattr(self.module.f90_return_integer, name))
if __name__ == "__main__":
run_module_suite()

View File

@@ -0,0 +1,189 @@
from __future__ import division, absolute_import, print_function
from numpy import array
from numpy.compat import long
from numpy.testing import run_module_suite, assert_, assert_raises, dec
from . import util
class TestReturnLogical(util.F2PyTest):
def check_function(self, t):
assert_(t(True) == 1, repr(t(True)))
assert_(t(False) == 0, repr(t(False)))
assert_(t(0) == 0)
assert_(t(None) == 0)
assert_(t(0.0) == 0)
assert_(t(0j) == 0)
assert_(t(1j) == 1)
assert_(t(234) == 1)
assert_(t(234.6) == 1)
assert_(t(long(234)) == 1)
assert_(t(234.6 + 3j) == 1)
assert_(t('234') == 1)
assert_(t('aaa') == 1)
assert_(t('') == 0)
assert_(t([]) == 0)
assert_(t(()) == 0)
assert_(t({}) == 0)
assert_(t(t) == 1)
assert_(t(-234) == 1)
assert_(t(10 ** 100) == 1)
assert_(t([234]) == 1)
assert_(t((234,)) == 1)
assert_(t(array(234)) == 1)
assert_(t(array([234])) == 1)
assert_(t(array([[234]])) == 1)
assert_(t(array([234], 'b')) == 1)
assert_(t(array([234], 'h')) == 1)
assert_(t(array([234], 'i')) == 1)
assert_(t(array([234], 'l')) == 1)
assert_(t(array([234], 'f')) == 1)
assert_(t(array([234], 'd')) == 1)
assert_(t(array([234 + 3j], 'F')) == 1)
assert_(t(array([234], 'D')) == 1)
assert_(t(array(0)) == 0)
assert_(t(array([0])) == 0)
assert_(t(array([[0]])) == 0)
assert_(t(array([0j])) == 0)
assert_(t(array([1])) == 1)
assert_raises(ValueError, t, array([0, 0]))
class TestF77ReturnLogical(TestReturnLogical):
code = """
function t0(value)
logical value
logical t0
t0 = value
end
function t1(value)
logical*1 value
logical*1 t1
t1 = value
end
function t2(value)
logical*2 value
logical*2 t2
t2 = value
end
function t4(value)
logical*4 value
logical*4 t4
t4 = value
end
c function t8(value)
c logical*8 value
c logical*8 t8
c t8 = value
c end
subroutine s0(t0,value)
logical value
logical t0
cf2py intent(out) t0
t0 = value
end
subroutine s1(t1,value)
logical*1 value
logical*1 t1
cf2py intent(out) t1
t1 = value
end
subroutine s2(t2,value)
logical*2 value
logical*2 t2
cf2py intent(out) t2
t2 = value
end
subroutine s4(t4,value)
logical*4 value
logical*4 t4
cf2py intent(out) t4
t4 = value
end
c subroutine s8(t8,value)
c logical*8 value
c logical*8 t8
cf2py intent(out) t8
c t8 = value
c end
"""
@dec.slow
def test_all(self):
for name in "t0,t1,t2,t4,s0,s1,s2,s4".split(","):
self.check_function(getattr(self.module, name))
class TestF90ReturnLogical(TestReturnLogical):
suffix = ".f90"
code = """
module f90_return_logical
contains
function t0(value)
logical :: value
logical :: t0
t0 = value
end function t0
function t1(value)
logical(kind=1) :: value
logical(kind=1) :: t1
t1 = value
end function t1
function t2(value)
logical(kind=2) :: value
logical(kind=2) :: t2
t2 = value
end function t2
function t4(value)
logical(kind=4) :: value
logical(kind=4) :: t4
t4 = value
end function t4
function t8(value)
logical(kind=8) :: value
logical(kind=8) :: t8
t8 = value
end function t8
subroutine s0(t0,value)
logical :: value
logical :: t0
!f2py intent(out) t0
t0 = value
end subroutine s0
subroutine s1(t1,value)
logical(kind=1) :: value
logical(kind=1) :: t1
!f2py intent(out) t1
t1 = value
end subroutine s1
subroutine s2(t2,value)
logical(kind=2) :: value
logical(kind=2) :: t2
!f2py intent(out) t2
t2 = value
end subroutine s2
subroutine s4(t4,value)
logical(kind=4) :: value
logical(kind=4) :: t4
!f2py intent(out) t4
t4 = value
end subroutine s4
subroutine s8(t8,value)
logical(kind=8) :: value
logical(kind=8) :: t8
!f2py intent(out) t8
t8 = value
end subroutine s8
end module f90_return_logical
"""
@dec.slow
def test_all(self):
for name in "t0,t1,t2,t4,t8,s0,s1,s2,s4,s8".split(","):
self.check_function(getattr(self.module.f90_return_logical, name))
if __name__ == "__main__":
run_module_suite()

View File

@@ -0,0 +1,206 @@
from __future__ import division, absolute_import, print_function
from numpy import array
from numpy.compat import long
from numpy.testing import run_module_suite, assert_, assert_raises, dec
from . import util
class TestReturnReal(util.F2PyTest):
def check_function(self, t):
if t.__doc__.split()[0] in ['t0', 't4', 's0', 's4']:
err = 1e-5
else:
err = 0.0
assert_(abs(t(234) - 234.0) <= err)
assert_(abs(t(234.6) - 234.6) <= err)
assert_(abs(t(long(234)) - 234.0) <= err)
assert_(abs(t('234') - 234) <= err)
assert_(abs(t('234.6') - 234.6) <= err)
assert_(abs(t(-234) + 234) <= err)
assert_(abs(t([234]) - 234) <= err)
assert_(abs(t((234,)) - 234.) <= err)
assert_(abs(t(array(234)) - 234.) <= err)
assert_(abs(t(array([234])) - 234.) <= err)
assert_(abs(t(array([[234]])) - 234.) <= err)
assert_(abs(t(array([234], 'b')) + 22) <= err)
assert_(abs(t(array([234], 'h')) - 234.) <= err)
assert_(abs(t(array([234], 'i')) - 234.) <= err)
assert_(abs(t(array([234], 'l')) - 234.) <= err)
assert_(abs(t(array([234], 'B')) - 234.) <= err)
assert_(abs(t(array([234], 'f')) - 234.) <= err)
assert_(abs(t(array([234], 'd')) - 234.) <= err)
if t.__doc__.split()[0] in ['t0', 't4', 's0', 's4']:
assert_(t(1e200) == t(1e300)) # inf
#assert_raises(ValueError, t, array([234], 'S1'))
assert_raises(ValueError, t, 'abc')
assert_raises(IndexError, t, [])
assert_raises(IndexError, t, ())
assert_raises(Exception, t, t)
assert_raises(Exception, t, {})
try:
r = t(10 ** 400)
assert_(repr(r) in ['inf', 'Infinity'], repr(r))
except OverflowError:
pass
class TestCReturnReal(TestReturnReal):
suffix = ".pyf"
module_name = "c_ext_return_real"
code = """
python module c_ext_return_real
usercode \'\'\'
float t4(float value) { return value; }
void s4(float *t4, float value) { *t4 = value; }
double t8(double value) { return value; }
void s8(double *t8, double value) { *t8 = value; }
\'\'\'
interface
function t4(value)
real*4 intent(c) :: t4,value
end
function t8(value)
real*8 intent(c) :: t8,value
end
subroutine s4(t4,value)
intent(c) s4
real*4 intent(out) :: t4
real*4 intent(c) :: value
end
subroutine s8(t8,value)
intent(c) s8
real*8 intent(out) :: t8
real*8 intent(c) :: value
end
end interface
end python module c_ext_return_real
"""
@dec.slow
def test_all(self):
for name in "t4,t8,s4,s8".split(","):
self.check_function(getattr(self.module, name))
class TestF77ReturnReal(TestReturnReal):
code = """
function t0(value)
real value
real t0
t0 = value
end
function t4(value)
real*4 value
real*4 t4
t4 = value
end
function t8(value)
real*8 value
real*8 t8
t8 = value
end
function td(value)
double precision value
double precision td
td = value
end
subroutine s0(t0,value)
real value
real t0
cf2py intent(out) t0
t0 = value
end
subroutine s4(t4,value)
real*4 value
real*4 t4
cf2py intent(out) t4
t4 = value
end
subroutine s8(t8,value)
real*8 value
real*8 t8
cf2py intent(out) t8
t8 = value
end
subroutine sd(td,value)
double precision value
double precision td
cf2py intent(out) td
td = value
end
"""
@dec.slow
def test_all(self):
for name in "t0,t4,t8,td,s0,s4,s8,sd".split(","):
self.check_function(getattr(self.module, name))
class TestF90ReturnReal(TestReturnReal):
suffix = ".f90"
code = """
module f90_return_real
contains
function t0(value)
real :: value
real :: t0
t0 = value
end function t0
function t4(value)
real(kind=4) :: value
real(kind=4) :: t4
t4 = value
end function t4
function t8(value)
real(kind=8) :: value
real(kind=8) :: t8
t8 = value
end function t8
function td(value)
double precision :: value
double precision :: td
td = value
end function td
subroutine s0(t0,value)
real :: value
real :: t0
!f2py intent(out) t0
t0 = value
end subroutine s0
subroutine s4(t4,value)
real(kind=4) :: value
real(kind=4) :: t4
!f2py intent(out) t4
t4 = value
end subroutine s4
subroutine s8(t8,value)
real(kind=8) :: value
real(kind=8) :: t8
!f2py intent(out) t8
t8 = value
end subroutine s8
subroutine sd(td,value)
double precision :: value
double precision :: td
!f2py intent(out) td
td = value
end subroutine sd
end module f90_return_real
"""
@dec.slow
def test_all(self):
for name in "t0,t4,t8,td,s0,s4,s8,sd".split(","):
self.check_function(getattr(self.module.f90_return_real, name))
if __name__ == "__main__":
run_module_suite()

View File

@@ -0,0 +1,53 @@
from __future__ import division, absolute_import, print_function
import os
from numpy.testing import run_module_suite, assert_equal, dec
from . import util
def _path(*a):
return os.path.join(*((os.path.dirname(__file__),) + a))
class TestSizeSumExample(util.F2PyTest):
sources = [_path('src', 'size', 'foo.f90')]
@dec.slow
def test_all(self):
r = self.module.foo([[]])
assert_equal(r, [0], repr(r))
r = self.module.foo([[1, 2]])
assert_equal(r, [3], repr(r))
r = self.module.foo([[1, 2], [3, 4]])
assert_equal(r, [3, 7], repr(r))
r = self.module.foo([[1, 2], [3, 4], [5, 6]])
assert_equal(r, [3, 7, 11], repr(r))
@dec.slow
def test_transpose(self):
r = self.module.trans([[]])
assert_equal(r.T, [[]], repr(r))
r = self.module.trans([[1, 2]])
assert_equal(r, [[1], [2]], repr(r))
r = self.module.trans([[1, 2, 3], [4, 5, 6]])
assert_equal(r, [[1, 4], [2, 5], [3, 6]], repr(r))
@dec.slow
def test_flatten(self):
r = self.module.flatten([[]])
assert_equal(r, [], repr(r))
r = self.module.flatten([[1, 2]])
assert_equal(r, [1, 2], repr(r))
r = self.module.flatten([[1, 2, 3], [4, 5, 6]])
assert_equal(r, [1, 2, 3, 4, 5, 6], repr(r))
if __name__ == "__main__":
run_module_suite()

View File

@@ -0,0 +1,26 @@
from __future__ import division, absolute_import, print_function
import os
from numpy.testing import run_module_suite, assert_array_equal, dec
import numpy as np
from . import util
def _path(*a):
return os.path.join(*((os.path.dirname(__file__),) + a))
class TestString(util.F2PyTest):
sources = [_path('src', 'string', 'char.f90')]
@dec.slow
def test_char(self):
strings = np.array(['ab', 'cd', 'ef'], dtype='c').T
inp, out = self.module.char_test.change_strings(strings, strings.shape[1])
assert_array_equal(inp, strings)
expected = strings.copy()
expected[1, :] = 'AAA'
assert_array_equal(out, expected)
if __name__ == "__main__":
run_module_suite()

View File

@@ -0,0 +1,359 @@
"""
Utility functions for
- building and importing modules on test time, using a temporary location
- detecting if compilers are present
"""
from __future__ import division, absolute_import, print_function
import os
import sys
import subprocess
import tempfile
import shutil
import atexit
import textwrap
import re
import random
import numpy.f2py
from numpy.compat import asbytes, asstr
from numpy.testing import SkipTest, temppath, dec
from importlib import import_module
try:
from hashlib import md5
except ImportError:
from md5 import new as md5
#
# Maintaining a temporary module directory
#
_module_dir = None
def _cleanup():
global _module_dir
if _module_dir is not None:
try:
sys.path.remove(_module_dir)
except ValueError:
pass
try:
shutil.rmtree(_module_dir)
except (IOError, OSError):
pass
_module_dir = None
def get_module_dir():
global _module_dir
if _module_dir is None:
_module_dir = tempfile.mkdtemp()
atexit.register(_cleanup)
if _module_dir not in sys.path:
sys.path.insert(0, _module_dir)
return _module_dir
def get_temp_module_name():
# Assume single-threaded, and the module dir usable only by this thread
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")
def _memoize(func):
memo = {}
def wrapper(*a, **kw):
key = repr((a, kw))
if key not in memo:
try:
memo[key] = func(*a, **kw)
except Exception as e:
memo[key] = e
raise
ret = memo[key]
if isinstance(ret, Exception):
raise ret
return ret
wrapper.__name__ = func.__name__
return wrapper
#
# Building modules
#
@_memoize
def build_module(source_files, options=[], skip=[], only=[], module_name=None):
"""
Compile and import a f2py module, built from the given files.
"""
code = ("import sys; sys.path = %s; import numpy.f2py as f2py2e; "
"f2py2e.main()" % repr(sys.path))
d = get_module_dir()
# Copy files
dst_sources = []
for fn in source_files:
if not os.path.isfile(fn):
raise RuntimeError("%s is not a file" % fn)
dst = os.path.join(d, os.path.basename(fn))
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)
# Prepare options
if module_name is None:
module_name = get_temp_module_name()
f2py_opts = ['-c', '-m', module_name] + options + dst_sources
if skip:
f2py_opts += ['skip:'] + skip
if only:
f2py_opts += ['only:'] + only
# Build
cwd = os.getcwd()
try:
os.chdir(d)
cmd = [sys.executable, '-c', code] + f2py_opts
p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
out, err = p.communicate()
if p.returncode != 0:
raise RuntimeError("Running f2py failed: %s\n%s"
% (cmd[4:], asstr(out)))
finally:
os.chdir(cwd)
# Partial cleanup
for fn in dst_sources:
os.unlink(fn)
# Import
return import_module(module_name)
@_memoize
def build_code(source_code, options=[], skip=[], only=[], suffix=None,
module_name=None):
"""
Compile and import Fortran code using f2py.
"""
if suffix is None:
suffix = '.f'
with temppath(suffix=suffix) as path:
with open(path, 'w') as f:
f.write(source_code)
return build_module([path], options=options, skip=skip, only=only,
module_name=module_name)
#
# Check if compilers are available at all...
#
_compiler_status = None
def _get_compiler_status():
global _compiler_status
if _compiler_status is not None:
return _compiler_status
_compiler_status = (False, False, False)
# XXX: this is really ugly. But I don't know how to invoke Distutils
# in a safer way...
code = """
import os
import sys
sys.path = %(syspath)s
def configuration(parent_name='',top_path=None):
global config
from numpy.distutils.misc_util import Configuration
config = Configuration('', parent_name, top_path)
return config
from numpy.distutils.core import setup
setup(configuration=configuration)
config_cmd = config.get_config_cmd()
have_c = config_cmd.try_compile('void foo() {}')
print('COMPILERS:%%d,%%d,%%d' %% (have_c,
config.have_f77c(),
config.have_f90c()))
sys.exit(99)
"""
code = code % dict(syspath=repr(sys.path))
with temppath(suffix='.py') as script:
with open(script, 'w') as f:
f.write(code)
cmd = [sys.executable, script, 'config']
p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
out, err = p.communicate()
m = re.search(br'COMPILERS:(\d+),(\d+),(\d+)', out)
if m:
_compiler_status = (bool(int(m.group(1))), bool(int(m.group(2))),
bool(int(m.group(3))))
# Finished
return _compiler_status
def has_c_compiler():
return _get_compiler_status()[0]
def has_f77_compiler():
return _get_compiler_status()[1]
def has_f90_compiler():
return _get_compiler_status()[2]
#
# Building with distutils
#
@_memoize
def build_module_distutils(source_files, config_code, module_name, **kw):
"""
Build a module via distutils and import it.
"""
from numpy.distutils.misc_util import Configuration
from numpy.distutils.core import setup
d = get_module_dir()
# Copy files
dst_sources = []
for fn in source_files:
if not os.path.isfile(fn):
raise RuntimeError("%s is not a file" % fn)
dst = os.path.join(d, os.path.basename(fn))
shutil.copyfile(fn, dst)
dst_sources.append(dst)
# Build script
config_code = textwrap.dedent(config_code).replace("\n", "\n ")
code = """\
import os
import sys
sys.path = %(syspath)s
def configuration(parent_name='',top_path=None):
from numpy.distutils.misc_util import Configuration
config = Configuration('', parent_name, top_path)
%(config_code)s
return config
if __name__ == "__main__":
from numpy.distutils.core import setup
setup(configuration=configuration)
""" % dict(config_code=config_code, syspath=repr(sys.path))
script = os.path.join(d, get_temp_module_name() + '.py')
dst_sources.append(script)
f = open(script, 'wb')
f.write(asbytes(code))
f.close()
# Build
cwd = os.getcwd()
try:
os.chdir(d)
cmd = [sys.executable, script, 'build_ext', '-i']
p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
out, err = p.communicate()
if p.returncode != 0:
raise RuntimeError("Running distutils build failed: %s\n%s"
% (cmd[4:], asstr(out)))
finally:
os.chdir(cwd)
# Partial cleanup
for fn in dst_sources:
os.unlink(fn)
# Import
__import__(module_name)
return sys.modules[module_name]
#
# Unittest convenience
#
class F2PyTest(object):
code = None
sources = None
options = []
skip = []
only = []
suffix = '.f'
module = None
module_name = None
@dec.knownfailureif(sys.platform=='win32', msg='Fails with MinGW64 Gfortran (Issue #9673)')
def setup(self):
if self.module is not None:
return
# Check compiler availability first
if not has_c_compiler():
raise SkipTest("No C compiler available")
codes = []
if self.sources:
codes.extend(self.sources)
if self.code is not None:
codes.append(self.suffix)
needs_f77 = False
needs_f90 = False
for fn in codes:
if fn.endswith('.f'):
needs_f77 = True
elif fn.endswith('.f90'):
needs_f90 = True
if needs_f77 and not has_f77_compiler():
raise SkipTest("No Fortran 77 compiler available")
if needs_f90 and not has_f90_compiler():
raise SkipTest("No Fortran 90 compiler available")
# Build the module
if self.code is not None:
self.module = build_code(self.code, options=self.options,
skip=self.skip, only=self.only,
suffix=self.suffix,
module_name=self.module_name)
if self.sources is not None:
self.module = build_module(self.sources, options=self.options,
skip=self.skip, only=self.only,
module_name=self.module_name)

View File

@@ -0,0 +1,115 @@
#!/usr/bin/env python
"""
Build 'use others module data' mechanism for f2py2e.
Unfinished.
Copyright 2000 Pearu Peterson all rights reserved,
Pearu Peterson <pearu@ioc.ee>
Permission to use, modify, and distribute this software is given under the
terms of the NumPy License.
NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
$Date: 2000/09/10 12:35:43 $
Pearu Peterson
"""
from __future__ import division, absolute_import, print_function
__version__ = "$Revision: 1.3 $"[10:-1]
f2py_version = 'See `f2py -v`'
from .auxfuncs import (
applyrules, dictappend, gentitle, hasnote, outmess
)
usemodule_rules = {
'body': """
#begintitle#
static char doc_#apiname#[] = \"\\\nVariable wrapper signature:\\n\\
\t #name# = get_#name#()\\n\\
Arguments:\\n\\
#docstr#\";
extern F_MODFUNC(#usemodulename#,#USEMODULENAME#,#realname#,#REALNAME#);
static PyObject *#apiname#(PyObject *capi_self, PyObject *capi_args) {
/*#decl#*/
\tif (!PyArg_ParseTuple(capi_args, \"\")) goto capi_fail;
printf(\"c: %d\\n\",F_MODFUNC(#usemodulename#,#USEMODULENAME#,#realname#,#REALNAME#));
\treturn Py_BuildValue(\"\");
capi_fail:
\treturn NULL;
}
""",
'method': '\t{\"get_#name#\",#apiname#,METH_VARARGS|METH_KEYWORDS,doc_#apiname#},',
'need': ['F_MODFUNC']
}
################
def buildusevars(m, r):
ret = {}
outmess(
'\t\tBuilding use variable hooks for module "%s" (feature only for F90/F95)...\n' % (m['name']))
varsmap = {}
revmap = {}
if 'map' in r:
for k in r['map'].keys():
if r['map'][k] in revmap:
outmess('\t\t\tVariable "%s<=%s" is already mapped by "%s". Skipping.\n' % (
r['map'][k], k, revmap[r['map'][k]]))
else:
revmap[r['map'][k]] = k
if 'only' in r and r['only']:
for v in r['map'].keys():
if r['map'][v] in m['vars']:
if revmap[r['map'][v]] == v:
varsmap[v] = r['map'][v]
else:
outmess('\t\t\tIgnoring map "%s=>%s". See above.\n' %
(v, r['map'][v]))
else:
outmess(
'\t\t\tNo definition for variable "%s=>%s". Skipping.\n' % (v, r['map'][v]))
else:
for v in m['vars'].keys():
if v in revmap:
varsmap[v] = revmap[v]
else:
varsmap[v] = v
for v in varsmap.keys():
ret = dictappend(ret, buildusevar(v, varsmap[v], m['vars'], m['name']))
return ret
def buildusevar(name, realname, vars, usemodulename):
outmess('\t\t\tConstructing wrapper function for variable "%s=>%s"...\n' % (
name, realname))
ret = {}
vrd = {'name': name,
'realname': realname,
'REALNAME': realname.upper(),
'usemodulename': usemodulename,
'USEMODULENAME': usemodulename.upper(),
'texname': name.replace('_', '\\_'),
'begintitle': gentitle('%s=>%s' % (name, realname)),
'endtitle': gentitle('end of %s=>%s' % (name, realname)),
'apiname': '#modulename#_use_%s_from_%s' % (realname, usemodulename)
}
nummap = {0: 'Ro', 1: 'Ri', 2: 'Rii', 3: 'Riii', 4: 'Riv',
5: 'Rv', 6: 'Rvi', 7: 'Rvii', 8: 'Rviii', 9: 'Rix'}
vrd['texnamename'] = name
for i in nummap.keys():
vrd['texnamename'] = vrd['texnamename'].replace(repr(i), nummap[i])
if hasnote(vars[realname]):
vrd['note'] = vars[realname]['note']
rd = dictappend({}, vrd)
print(name, realname, vars[realname])
ret = applyrules(usemodule_rules, rd)
return ret