8th day of python challenges 111-117
This commit is contained in:
121
venv/lib/python3.6/site-packages/numpy/f2py/__init__.py
Normal file
121
venv/lib/python3.6/site-packages/numpy/f2py/__init__.py
Normal file
@@ -0,0 +1,121 @@
|
||||
#!/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
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
import numpy as np
|
||||
|
||||
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 a Fortran 77 source string with f2py.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
source : str or bytes
|
||||
Fortran source of module / subroutine to compile
|
||||
|
||||
.. versionchanged:: 1.16.0
|
||||
Accept str as well as bytes
|
||||
|
||||
modulename : str, optional
|
||||
The name of the compiled python module
|
||||
extra_args : str or list, optional
|
||||
Additional parameters passed to f2py
|
||||
|
||||
.. versionchanged:: 1.16.0
|
||||
A list of args may also be provided.
|
||||
|
||||
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
|
||||
|
||||
Returns
|
||||
-------
|
||||
result : int
|
||||
0 on success
|
||||
|
||||
Examples
|
||||
--------
|
||||
.. include:: compile_session.dat
|
||||
:literal:
|
||||
|
||||
"""
|
||||
import tempfile
|
||||
import shlex
|
||||
|
||||
if source_fn is None:
|
||||
f, fname = tempfile.mkstemp(suffix=extension)
|
||||
# f is a file descriptor so need to close it
|
||||
# carefully -- not with .close() directly
|
||||
os.close(f)
|
||||
else:
|
||||
fname = source_fn
|
||||
|
||||
if not isinstance(source, str):
|
||||
source = str(source, 'utf-8')
|
||||
try:
|
||||
with open(fname, 'w') as f:
|
||||
f.write(source)
|
||||
|
||||
args = ['-c', '-m', modulename, f.name]
|
||||
|
||||
if isinstance(extra_args, np.compat.basestring):
|
||||
is_posix = (os.name == 'posix')
|
||||
extra_args = shlex.split(extra_args, posix=is_posix)
|
||||
|
||||
args.extend(extra_args)
|
||||
|
||||
c = [sys.executable,
|
||||
'-c',
|
||||
'import numpy.f2py as f2py2e;f2py2e.main()'] + args
|
||||
try:
|
||||
output = subprocess.check_output(c)
|
||||
except subprocess.CalledProcessError as exc:
|
||||
status = exc.returncode
|
||||
output = ''
|
||||
except OSError:
|
||||
# preserve historic status code used by exec_command()
|
||||
status = 127
|
||||
output = ''
|
||||
else:
|
||||
status = 0
|
||||
if verbose:
|
||||
print(output)
|
||||
finally:
|
||||
if source_fn is None:
|
||||
os.remove(fname)
|
||||
return status
|
||||
|
||||
from numpy._pytesttester import PytestTester
|
||||
test = PytestTester(__name__)
|
||||
del PytestTester
|
||||
6
venv/lib/python3.6/site-packages/numpy/f2py/__main__.py
Normal file
6
venv/lib/python3.6/site-packages/numpy/f2py/__main__.py
Normal file
@@ -0,0 +1,6 @@
|
||||
# See http://cens.ioc.ee/projects/f2py2e/
|
||||
from __future__ import division, print_function
|
||||
|
||||
from numpy.f2py.f2py2e import main
|
||||
|
||||
main()
|
||||
10
venv/lib/python3.6/site-packages/numpy/f2py/__version__.py
Normal file
10
venv/lib/python3.6/site-packages/numpy/f2py/__version__.py
Normal 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)
|
||||
854
venv/lib/python3.6/site-packages/numpy/f2py/auxfuncs.py
Normal file
854
venv/lib/python3.6/site-packages/numpy/f2py/auxfuncs.py
Normal 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
|
||||
837
venv/lib/python3.6/site-packages/numpy/f2py/capi_maps.py
Normal file
837
venv/lib/python3.6/site-packages/numpy/f2py/capi_maps.py
Normal file
@@ -0,0 +1,837 @@
|
||||
#!/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 dependencies
|
||||
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}
|
||||
ret['varname_i'] = ret['varname']
|
||||
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
|
||||
578
venv/lib/python3.6/site-packages/numpy/f2py/cb_rules.py
Normal file
578
venv/lib/python3.6/site-packages/numpy/f2py/cb_rules.py
Normal 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 #############
|
||||
1262
venv/lib/python3.6/site-packages/numpy/f2py/cfuncs.py
Normal file
1262
venv/lib/python3.6/site-packages/numpy/f2py/cfuncs.py
Normal file
File diff suppressed because it is too large
Load Diff
148
venv/lib/python3.6/site-packages/numpy/f2py/common_rules.py
Normal file
148
venv/lib/python3.6/site-packages/numpy/f2py/common_rules.py
Normal file
@@ -0,0 +1,148 @@
|
||||
#!/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 key, value in block['common'].items():
|
||||
vars_ = {v: block['vars'][v] for v in value}
|
||||
ret.append((key, value, 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]
|
||||
3345
venv/lib/python3.6/site-packages/numpy/f2py/crackfortran.py
Normal file
3345
venv/lib/python3.6/site-packages/numpy/f2py/crackfortran.py
Normal file
File diff suppressed because it is too large
Load Diff
156
venv/lib/python3.6/site-packages/numpy/f2py/diagnose.py
Normal file
156
venv/lib/python3.6/site-packages/numpy/f2py/diagnose.py
Normal 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()
|
||||
685
venv/lib/python3.6/site-packages/numpy/f2py/f2py2e.py
Normal file
685
venv/lib/python3.6/site-packages/numpy/f2py/f2py2e.py
Normal file
@@ -0,0 +1,685 @@
|
||||
#!/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:
|
||||
with open(l):
|
||||
pass
|
||||
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:
|
||||
with open(options['signsfile'], 'w') as f:
|
||||
f.write(pyf)
|
||||
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):
|
||||
"""
|
||||
Equivalent to running::
|
||||
|
||||
f2py <args>
|
||||
|
||||
where ``<args>=string.join(<list>,' ')``, but in Python. Unless
|
||||
``-h`` is used, this function returns a dictionary containing
|
||||
information on generated modules and their dependencies on source
|
||||
files. For example, the command ``f2py -m scalar scalar.f`` can be
|
||||
executed from Python as follows
|
||||
|
||||
You cannot build extension modules with this function, that is,
|
||||
using ``-c`` is not allowed. Use ``compile`` command instead
|
||||
|
||||
Examples
|
||||
--------
|
||||
.. include:: run_main_session.dat
|
||||
:literal:
|
||||
|
||||
"""
|
||||
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
|
||||
|
||||
# Probably outdated options that were not working before 1.16
|
||||
if '--g3-numpy' in sys.argv[1:]:
|
||||
sys.stderr.write("G3 f2py support is not implemented, yet.\\n")
|
||||
sys.exit(1)
|
||||
elif '--2e-numeric' in sys.argv[1:]:
|
||||
sys.argv.remove('--2e-numeric')
|
||||
elif '--2e-numarray' in sys.argv[1:]:
|
||||
# Note that this errors becaust the -DNUMARRAY argument is
|
||||
# not recognized. Just here for back compatibility and the
|
||||
# error message.
|
||||
sys.argv.append("-DNUMARRAY")
|
||||
sys.argv.remove('--2e-numarray')
|
||||
elif '--2e-numpy' in sys.argv[1:]:
|
||||
sys.argv.remove('--2e-numpy')
|
||||
else:
|
||||
pass
|
||||
|
||||
if '-c' in sys.argv[1:]:
|
||||
run_compile()
|
||||
else:
|
||||
run_main(sys.argv[1:])
|
||||
48
venv/lib/python3.6/site-packages/numpy/f2py/f2py_testing.py
Normal file
48
venv/lib/python3.6/site-packages/numpy/f2py/f2py_testing.py
Normal 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')
|
||||
272
venv/lib/python3.6/site-packages/numpy/f2py/f90mod_rules.py
Normal file
272
venv/lib/python3.6/site-packages/numpy/f2py/f90mod_rules.py
Normal 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]
|
||||
299
venv/lib/python3.6/site-packages/numpy/f2py/func2subr.py
Normal file
299
venv/lib/python3.6/site-packages/numpy/f2py/func2subr.py
Normal 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, ''
|
||||
6
venv/lib/python3.6/site-packages/numpy/f2py/info.py
Normal file
6
venv/lib/python3.6/site-packages/numpy/f2py/info.py
Normal file
@@ -0,0 +1,6 @@
|
||||
"""Fortran to Python Interface Generator.
|
||||
|
||||
"""
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
postpone_import = True
|
||||
1468
venv/lib/python3.6/site-packages/numpy/f2py/rules.py
Normal file
1468
venv/lib/python3.6/site-packages/numpy/f2py/rules.py
Normal file
File diff suppressed because it is too large
Load Diff
73
venv/lib/python3.6/site-packages/numpy/f2py/setup.py
Normal file
73
venv/lib/python3.6/site-packages/numpy/f2py/setup.py
Normal file
@@ -0,0 +1,73 @@
|
||||
#!/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
|
||||
|
||||
from numpy.distutils.core import setup
|
||||
from numpy.distutils.misc_util import Configuration
|
||||
|
||||
|
||||
from __version__ import version
|
||||
|
||||
|
||||
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')
|
||||
return config
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
config = configuration(top_path='')
|
||||
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 Generator",
|
||||
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)
|
||||
1089
venv/lib/python3.6/site-packages/numpy/f2py/src/fortranobject.c
Normal file
1089
venv/lib/python3.6/site-packages/numpy/f2py/src/fortranobject.c
Normal file
File diff suppressed because it is too large
Load Diff
162
venv/lib/python3.6/site-packages/numpy/f2py/src/fortranobject.h
Normal file
162
venv/lib/python3.6/site-packages/numpy/f2py/src/fortranobject.h
Normal 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 */
|
||||
@@ -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
|
||||
@@ -0,0 +1 @@
|
||||
dict(real=dict(rk="double"))
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,4 @@
|
||||
module precision
|
||||
integer, parameter :: rk = selected_real_kind(8)
|
||||
integer, parameter :: ik = selected_real_kind(4)
|
||||
end module
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,5 @@
|
||||
subroutine bar11(a)
|
||||
cf2py intent(out) a
|
||||
integer a
|
||||
a = 11
|
||||
end
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,581 @@
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import os
|
||||
import sys
|
||||
import copy
|
||||
import pytest
|
||||
|
||||
from numpy import (
|
||||
array, alltrue, ndarray, zeros, dtype, intp, clongdouble
|
||||
)
|
||||
from numpy.testing import assert_, assert_equal
|
||||
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():
|
||||
pytest.skip("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 not isinstance(i, type) and dtype0.type is i.type:
|
||||
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()
|
||||
info = typeinfo[self.NAME]
|
||||
self.type_num = getattr(wrap, 'NPY_' + self.NAME)
|
||||
assert_equal(self.type_num, info.num)
|
||||
self.dtype = info.type
|
||||
self.elsize = info.bits / 8
|
||||
self.dtypechar = info.char
|
||||
|
||||
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].alignment
|
||||
types = []
|
||||
for name in _type_names:
|
||||
if typeinfo[name].alignment < bits:
|
||||
types.append(Type(name))
|
||||
return types
|
||||
|
||||
def equal_types(self):
|
||||
bits = typeinfo[self.NAME].alignment
|
||||
types = []
|
||||
for name in _type_names:
|
||||
if name == self.NAME:
|
||||
continue
|
||||
if typeinfo[name].alignment == bits:
|
||||
types.append(Type(name))
|
||||
return types
|
||||
|
||||
def larger_types(self):
|
||||
bits = typeinfo[self.NAME].alignment
|
||||
types = []
|
||||
for name in _type_names:
|
||||
if typeinfo[name].alignment > 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 TestSharedMemory(object):
|
||||
num2seq = [1, 2]
|
||||
num23seq = [[1, 2, 3], [4, 5, 6]]
|
||||
|
||||
@pytest.fixture(autouse=True, scope='class', params=_type_names)
|
||||
def setup_type(self, request):
|
||||
request.cls.type = Type(request.param)
|
||||
request.cls.array = lambda self, dims, intent, obj: \
|
||||
Array(Type(request.param), dims, intent, obj)
|
||||
|
||||
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!
|
||||
@@ -0,0 +1,33 @@
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import os
|
||||
import pytest
|
||||
|
||||
from numpy.testing import assert_
|
||||
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'),
|
||||
]
|
||||
|
||||
@pytest.mark.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))
|
||||
@@ -0,0 +1,24 @@
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import sys
|
||||
import pytest
|
||||
from . import util
|
||||
|
||||
from numpy.testing import assert_equal, IS_PYPY
|
||||
|
||||
class TestBlockDocString(util.F2PyTest):
|
||||
code = """
|
||||
SUBROUTINE FOO()
|
||||
INTEGER BAR(2, 3)
|
||||
|
||||
COMMON /BLOCK/ BAR
|
||||
RETURN
|
||||
END
|
||||
"""
|
||||
|
||||
@pytest.mark.skipif(sys.platform=='win32',
|
||||
reason='Fails with MinGW64 Gfortran (Issue #9673)')
|
||||
@pytest.mark.xfail(IS_PYPY, reason="PyPy does not modify tp_doc")
|
||||
def test_block_docstring(self):
|
||||
expected = "'i'-array(2,3)\n"
|
||||
assert_equal(self.module.block.__doc__, expected)
|
||||
@@ -0,0 +1,165 @@
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import math
|
||||
import textwrap
|
||||
import sys
|
||||
import pytest
|
||||
|
||||
import numpy as np
|
||||
from numpy.testing import assert_, assert_equal
|
||||
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
|
||||
"""
|
||||
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.parametrize('name', 't,t2'.split(','))
|
||||
def test_all(self, name):
|
||||
self.check_function(name)
|
||||
|
||||
@pytest.mark.slow
|
||||
def test_docstring(self):
|
||||
expected = textwrap.dedent("""\
|
||||
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__, expected)
|
||||
|
||||
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))
|
||||
|
||||
@pytest.mark.skipif(sys.platform=='win32',
|
||||
reason='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))
|
||||
|
||||
@pytest.mark.skipif(sys.platform=='win32',
|
||||
reason='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))
|
||||
@@ -0,0 +1,27 @@
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import os
|
||||
import sys
|
||||
import pytest
|
||||
|
||||
import numpy as np
|
||||
from . import util
|
||||
|
||||
from numpy.testing import assert_array_equal
|
||||
|
||||
def _path(*a):
|
||||
return os.path.join(*((os.path.dirname(__file__),) + a))
|
||||
|
||||
class TestCommonBlock(util.F2PyTest):
|
||||
sources = [_path('src', 'common', 'block.f')]
|
||||
|
||||
@pytest.mark.skipif(sys.platform=='win32',
|
||||
reason='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))
|
||||
@@ -0,0 +1,125 @@
|
||||
"""See https://github.com/numpy/numpy/pull/11937.
|
||||
|
||||
"""
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import sys
|
||||
import os
|
||||
import uuid
|
||||
from importlib import import_module
|
||||
import pytest
|
||||
|
||||
import numpy.f2py
|
||||
|
||||
from numpy.testing import assert_equal
|
||||
from . import util
|
||||
|
||||
|
||||
def setup_module():
|
||||
if sys.platform == 'win32' and sys.version_info[0] < 3:
|
||||
pytest.skip('Fails with MinGW64 Gfortran (Issue #9673)')
|
||||
if not util.has_c_compiler():
|
||||
pytest.skip("Needs C compiler")
|
||||
if not util.has_f77_compiler():
|
||||
pytest.skip('Needs FORTRAN 77 compiler')
|
||||
|
||||
|
||||
# extra_args can be a list (since gh-11937) or string.
|
||||
# also test absence of extra_args
|
||||
@pytest.mark.parametrize(
|
||||
"extra_args", [['--noopt', '--debug'], '--noopt --debug', '']
|
||||
)
|
||||
def test_f2py_init_compile(extra_args):
|
||||
# flush through the f2py __init__ compile() function code path as a
|
||||
# crude test for input handling following migration from
|
||||
# exec_command() to subprocess.check_output() in gh-11937
|
||||
|
||||
# the Fortran 77 syntax requires 6 spaces before any commands, but
|
||||
# more space may be added/
|
||||
fsource = """
|
||||
integer function foo()
|
||||
foo = 10 + 5
|
||||
return
|
||||
end
|
||||
"""
|
||||
# use various helper functions in util.py to enable robust build /
|
||||
# compile and reimport cycle in test suite
|
||||
moddir = util.get_module_dir()
|
||||
modname = util.get_temp_module_name()
|
||||
|
||||
cwd = os.getcwd()
|
||||
target = os.path.join(moddir, str(uuid.uuid4()) + '.f')
|
||||
# try running compile() with and without a source_fn provided so
|
||||
# that the code path where a temporary file for writing Fortran
|
||||
# source is created is also explored
|
||||
for source_fn in [target, None]:
|
||||
# mimic the path changing behavior used by build_module() in
|
||||
# util.py, but don't actually use build_module() because it has
|
||||
# its own invocation of subprocess that circumvents the
|
||||
# f2py.compile code block under test
|
||||
try:
|
||||
os.chdir(moddir)
|
||||
ret_val = numpy.f2py.compile(
|
||||
fsource,
|
||||
modulename=modname,
|
||||
extra_args=extra_args,
|
||||
source_fn=source_fn
|
||||
)
|
||||
finally:
|
||||
os.chdir(cwd)
|
||||
|
||||
# check for compile success return value
|
||||
assert_equal(ret_val, 0)
|
||||
|
||||
# we are not currently able to import the Python-Fortran
|
||||
# interface module on Windows / Appveyor, even though we do get
|
||||
# successful compilation on that platform with Python 3.x
|
||||
if sys.platform != 'win32':
|
||||
# check for sensible result of Fortran function; that means
|
||||
# we can import the module name in Python and retrieve the
|
||||
# result of the sum operation
|
||||
return_check = import_module(modname)
|
||||
calc_result = return_check.foo()
|
||||
assert_equal(calc_result, 15)
|
||||
|
||||
|
||||
def test_f2py_init_compile_failure():
|
||||
# verify an appropriate integer status value returned by
|
||||
# f2py.compile() when invalid Fortran is provided
|
||||
ret_val = numpy.f2py.compile(b"invalid")
|
||||
assert_equal(ret_val, 1)
|
||||
|
||||
|
||||
def test_f2py_init_compile_bad_cmd():
|
||||
# verify that usage of invalid command in f2py.compile() returns
|
||||
# status value of 127 for historic consistency with exec_command()
|
||||
# error handling
|
||||
|
||||
# patch the sys Python exe path temporarily to induce an OSError
|
||||
# downstream NOTE: how bad of an idea is this patching?
|
||||
try:
|
||||
temp = sys.executable
|
||||
sys.executable = 'does not exist'
|
||||
|
||||
# the OSError should take precedence over invalid Fortran
|
||||
ret_val = numpy.f2py.compile(b"invalid")
|
||||
assert_equal(ret_val, 127)
|
||||
finally:
|
||||
sys.executable = temp
|
||||
|
||||
|
||||
@pytest.mark.parametrize('fsource',
|
||||
['program test_f2py\nend program test_f2py',
|
||||
b'program test_f2py\nend program test_f2py',])
|
||||
def test_compile_from_strings(tmpdir, fsource):
|
||||
# Make sure we can compile str and bytes gh-12796
|
||||
cwd = os.getcwd()
|
||||
try:
|
||||
os.chdir(str(tmpdir))
|
||||
ret_val = numpy.f2py.compile(
|
||||
fsource,
|
||||
modulename='test_compile_from_strings',
|
||||
extension='.f90')
|
||||
assert_equal(ret_val, 0)
|
||||
finally:
|
||||
os.chdir(cwd)
|
||||
@@ -0,0 +1,34 @@
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import os
|
||||
import pytest
|
||||
|
||||
from numpy.testing import assert_
|
||||
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')]
|
||||
|
||||
@pytest.mark.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)))
|
||||
@@ -0,0 +1,37 @@
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import os
|
||||
import textwrap
|
||||
import pytest
|
||||
|
||||
from numpy.testing import assert_, assert_equal
|
||||
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')]
|
||||
|
||||
@pytest.mark.slow
|
||||
def test_all(self):
|
||||
assert_(self.module.bar11() == 11)
|
||||
assert_(self.module.foo_fixed.bar12() == 12)
|
||||
assert_(self.module.foo_free.bar13() == 13)
|
||||
|
||||
@pytest.mark.slow
|
||||
def test_docstring(self):
|
||||
expected = textwrap.dedent("""\
|
||||
a = bar11()
|
||||
|
||||
Wrapper for ``bar11``.
|
||||
|
||||
Returns
|
||||
-------
|
||||
a : int
|
||||
""")
|
||||
assert_equal(self.module.bar11.__doc__, expected)
|
||||
@@ -0,0 +1,118 @@
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import os
|
||||
import pytest
|
||||
|
||||
import numpy as np
|
||||
from numpy.testing import 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'),
|
||||
]
|
||||
|
||||
@pytest.mark.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])
|
||||
|
||||
@pytest.mark.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])
|
||||
|
||||
@pytest.mark.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])
|
||||
|
||||
@pytest.mark.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])
|
||||
|
||||
@pytest.mark.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])
|
||||
|
||||
@pytest.mark.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])
|
||||
|
||||
@pytest.mark.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])
|
||||
|
||||
@pytest.mark.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])
|
||||
|
||||
@pytest.mark.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])
|
||||
@@ -0,0 +1,35 @@
|
||||
"""See https://github.com/numpy/numpy/pull/10676.
|
||||
|
||||
"""
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import sys
|
||||
from importlib import import_module
|
||||
import pytest
|
||||
|
||||
from numpy.testing import assert_equal
|
||||
from . import util
|
||||
|
||||
|
||||
class TestQuotedCharacter(util.F2PyTest):
|
||||
code = """
|
||||
SUBROUTINE FOO(OUT1, OUT2, OUT3, OUT4, OUT5, OUT6)
|
||||
CHARACTER SINGLE, DOUBLE, SEMICOL, EXCLA, OPENPAR, CLOSEPAR
|
||||
PARAMETER (SINGLE="'", DOUBLE='"', SEMICOL=';', EXCLA="!",
|
||||
1 OPENPAR="(", CLOSEPAR=")")
|
||||
CHARACTER OUT1, OUT2, OUT3, OUT4, OUT5, OUT6
|
||||
Cf2py intent(out) OUT1, OUT2, OUT3, OUT4, OUT5, OUT6
|
||||
OUT1 = SINGLE
|
||||
OUT2 = DOUBLE
|
||||
OUT3 = SEMICOL
|
||||
OUT4 = EXCLA
|
||||
OUT5 = OPENPAR
|
||||
OUT6 = CLOSEPAR
|
||||
RETURN
|
||||
END
|
||||
"""
|
||||
|
||||
@pytest.mark.skipif(sys.platform=='win32',
|
||||
reason='Fails with MinGW64 Gfortran (Issue #9673)')
|
||||
def test_quoted_character(self):
|
||||
assert_equal(self.module.foo(), (b"'", b'"', b';', b'!', b'(', b')'))
|
||||
@@ -0,0 +1,29 @@
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import os
|
||||
import pytest
|
||||
|
||||
import numpy as np
|
||||
from numpy.testing import 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')]
|
||||
|
||||
@pytest.mark.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])
|
||||
@@ -0,0 +1,146 @@
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import pytest
|
||||
|
||||
from numpy import array
|
||||
from numpy.testing import assert_
|
||||
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
|
||||
"""
|
||||
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.parametrize('name', 't0,t1,t5,s0,s1,s5,ss'.split(','))
|
||||
def test_all(self, name):
|
||||
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
|
||||
"""
|
||||
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.parametrize('name', 't0,t1,t5,ts,s0,s1,s5,ss'.split(','))
|
||||
def test_all(self, name):
|
||||
self.check_function(getattr(self.module.f90_return_char, name))
|
||||
@@ -0,0 +1,169 @@
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import pytest
|
||||
|
||||
from numpy import array
|
||||
from numpy.compat import long
|
||||
from numpy.testing import assert_, assert_raises
|
||||
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
|
||||
"""
|
||||
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.parametrize('name', 't0,t8,t16,td,s0,s8,s16,sd'.split(','))
|
||||
def test_all(self, name):
|
||||
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
|
||||
"""
|
||||
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.parametrize('name', 't0,t8,t16,td,s0,s8,s16,sd'.split(','))
|
||||
def test_all(self, name):
|
||||
self.check_function(getattr(self.module.f90_return_complex, name))
|
||||
@@ -0,0 +1,181 @@
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import pytest
|
||||
|
||||
from numpy import array
|
||||
from numpy.compat import long
|
||||
from numpy.testing import assert_, assert_raises
|
||||
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
|
||||
"""
|
||||
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.parametrize('name',
|
||||
't0,t1,t2,t4,t8,s0,s1,s2,s4,s8'.split(','))
|
||||
def test_all(self, name):
|
||||
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
|
||||
"""
|
||||
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.parametrize('name',
|
||||
't0,t1,t2,t4,t8,s0,s1,s2,s4,s8'.split(','))
|
||||
def test_all(self, name):
|
||||
self.check_function(getattr(self.module.f90_return_integer, name))
|
||||
@@ -0,0 +1,189 @@
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import pytest
|
||||
|
||||
from numpy import array
|
||||
from numpy.compat import long
|
||||
from numpy.testing import assert_, assert_raises
|
||||
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
|
||||
"""
|
||||
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.parametrize('name', 't0,t1,t2,t4,s0,s1,s2,s4'.split(','))
|
||||
def test_all(self, name):
|
||||
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
|
||||
"""
|
||||
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.parametrize('name',
|
||||
't0,t1,t2,t4,t8,s0,s1,s2,s4,s8'.split(','))
|
||||
def test_all(self, name):
|
||||
self.check_function(getattr(self.module.f90_return_logical, name))
|
||||
@@ -0,0 +1,210 @@
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import platform
|
||||
import pytest
|
||||
|
||||
from numpy import array
|
||||
from numpy.compat import long
|
||||
from numpy.testing import assert_, assert_raises
|
||||
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
|
||||
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
platform.system() == 'Darwin',
|
||||
reason="Prone to error when run with numpy/f2py/tests on mac os, "
|
||||
"but not when run in isolation")
|
||||
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
|
||||
"""
|
||||
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.parametrize('name', 't4,t8,s4,s8'.split(','))
|
||||
def test_all(self, name):
|
||||
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
|
||||
"""
|
||||
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.parametrize('name', 't0,t4,t8,td,s0,s4,s8,sd'.split(','))
|
||||
def test_all(self, name):
|
||||
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
|
||||
"""
|
||||
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.parametrize('name', 't0,t4,t8,td,s0,s4,s8,sd'.split(','))
|
||||
def test_all(self, name):
|
||||
self.check_function(getattr(self.module.f90_return_real, name))
|
||||
@@ -0,0 +1,65 @@
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import platform
|
||||
import pytest
|
||||
|
||||
from . import util
|
||||
from numpy.testing import assert_equal
|
||||
|
||||
@pytest.mark.skipif(
|
||||
platform.system() == 'Darwin',
|
||||
reason="Prone to error when run with numpy/f2py/tests on mac os, "
|
||||
"but not when run in isolation")
|
||||
class TestMultiline(util.F2PyTest):
|
||||
suffix = ".pyf"
|
||||
module_name = "multiline"
|
||||
code = """
|
||||
python module {module}
|
||||
usercode '''
|
||||
void foo(int* x) {{
|
||||
char dummy = ';';
|
||||
*x = 42;
|
||||
}}
|
||||
'''
|
||||
interface
|
||||
subroutine foo(x)
|
||||
intent(c) foo
|
||||
integer intent(out) :: x
|
||||
end subroutine foo
|
||||
end interface
|
||||
end python module {module}
|
||||
""".format(module=module_name)
|
||||
|
||||
def test_multiline(self):
|
||||
assert_equal(self.module.foo(), 42)
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
platform.system() == 'Darwin',
|
||||
reason="Prone to error when run with numpy/f2py/tests on mac os, "
|
||||
"but not when run in isolation")
|
||||
class TestCallstatement(util.F2PyTest):
|
||||
suffix = ".pyf"
|
||||
module_name = "callstatement"
|
||||
code = """
|
||||
python module {module}
|
||||
usercode '''
|
||||
void foo(int* x) {{
|
||||
}}
|
||||
'''
|
||||
interface
|
||||
subroutine foo(x)
|
||||
intent(c) foo
|
||||
integer intent(out) :: x
|
||||
callprotoargument int*
|
||||
callstatement {{ &
|
||||
; &
|
||||
x = 42; &
|
||||
}}
|
||||
end subroutine foo
|
||||
end interface
|
||||
end python module {module}
|
||||
""".format(module=module_name)
|
||||
|
||||
def test_callstatement(self):
|
||||
assert_equal(self.module.foo(), 42)
|
||||
@@ -0,0 +1,51 @@
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import os
|
||||
import pytest
|
||||
|
||||
from numpy.testing import assert_equal
|
||||
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')]
|
||||
|
||||
@pytest.mark.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))
|
||||
|
||||
@pytest.mark.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))
|
||||
|
||||
@pytest.mark.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))
|
||||
@@ -0,0 +1,24 @@
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import os
|
||||
import pytest
|
||||
|
||||
from numpy.testing import assert_array_equal
|
||||
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')]
|
||||
|
||||
@pytest.mark.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)
|
||||
360
venv/lib/python3.6/site-packages/numpy/f2py/tests/util.py
Normal file
360
venv/lib/python3.6/site-packages/numpy/f2py/tests/util.py
Normal file
@@ -0,0 +1,360 @@
|
||||
"""
|
||||
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 pytest
|
||||
|
||||
from numpy.compat import asbytes, asstr
|
||||
from numpy.testing import temppath
|
||||
from importlib import import_module
|
||||
|
||||
try:
|
||||
from hashlib import md5
|
||||
except ImportError:
|
||||
from md5 import new as md5 # noqa: F401
|
||||
|
||||
#
|
||||
# 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 = textwrap.dedent("""\
|
||||
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 = textwrap.dedent("""\
|
||||
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
|
||||
|
||||
def setup(self):
|
||||
if sys.platform == 'win32':
|
||||
pytest.skip('Fails with MinGW64 Gfortran (Issue #9673)')
|
||||
|
||||
if self.module is not None:
|
||||
return
|
||||
|
||||
# Check compiler availability first
|
||||
if not has_c_compiler():
|
||||
pytest.skip("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():
|
||||
pytest.skip("No Fortran 77 compiler available")
|
||||
if needs_f90 and not has_f90_compiler():
|
||||
pytest.skip("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)
|
||||
115
venv/lib/python3.6/site-packages/numpy/f2py/use_rules.py
Normal file
115
venv/lib/python3.6/site-packages/numpy/f2py/use_rules.py
Normal 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
|
||||
Reference in New Issue
Block a user