Created starter files for the project.
This commit is contained in:
commit
73f0c0db42
1992 changed files with 769897 additions and 0 deletions
118
venv/Lib/site-packages/numpy/f2py/__init__.py
Normal file
118
venv/Lib/site-packages/numpy/f2py/__init__.py
Normal file
|
@ -0,0 +1,118 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Fortran to Python Interface Generator.
|
||||
|
||||
"""
|
||||
__all__ = ['run_main', 'compile', 'f2py_testing']
|
||||
|
||||
import sys
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
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, str):
|
||||
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
|
||||
output = output.decode()
|
||||
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
|
4
venv/Lib/site-packages/numpy/f2py/__main__.py
Normal file
4
venv/Lib/site-packages/numpy/f2py/__main__.py
Normal file
|
@ -0,0 +1,4 @@
|
|||
# See http://cens.ioc.ee/projects/f2py2e/
|
||||
from numpy.f2py.f2py2e import main
|
||||
|
||||
main()
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
8
venv/Lib/site-packages/numpy/f2py/__version__.py
Normal file
8
venv/Lib/site-packages/numpy/f2py/__version__.py
Normal file
|
@ -0,0 +1,8 @@
|
|||
major = 2
|
||||
|
||||
try:
|
||||
from __svn_version__ import version
|
||||
version_info = (major, version)
|
||||
version = '%s_%s' % version_info
|
||||
except (ImportError, ValueError):
|
||||
version = str(major)
|
852
venv/Lib/site-packages/numpy/f2py/auxfuncs.py
Normal file
852
venv/Lib/site-packages/numpy/f2py/auxfuncs.py
Normal file
|
@ -0,0 +1,852 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
|
||||
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
|
||||
|
||||
"""
|
||||
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:
|
||||
|
||||
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
|
840
venv/Lib/site-packages/numpy/f2py/capi_maps.py
Normal file
840
venv/Lib/site-packages/numpy/f2py/capi_maps.py
Normal file
|
@ -0,0 +1,840 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
|
||||
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
|
||||
|
||||
"""
|
||||
__version__ = "$Revision: 1.60 $"[10:-1]
|
||||
|
||||
from . import __version__
|
||||
f2py_version = __version__.version
|
||||
|
||||
import copy
|
||||
import re
|
||||
import os
|
||||
from .crackfortran import markoutercomma
|
||||
from . import cb_rules
|
||||
|
||||
# The environment 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 anywhere 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': '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'}
|
||||
}
|
||||
|
||||
f2cmap_default = copy.deepcopy(f2cmap_all)
|
||||
|
||||
|
||||
def load_f2cmap_file(f2cmap_file):
|
||||
global f2cmap_all
|
||||
|
||||
f2cmap_all = copy.deepcopy(f2cmap_default)
|
||||
|
||||
if f2cmap_file is None:
|
||||
# Default value
|
||||
f2cmap_file = '.f2py_f2cmap'
|
||||
if not os.path.isfile(f2cmap_file):
|
||||
return
|
||||
|
||||
# User defined additions to f2cmap_all.
|
||||
# f2cmap_file must contain a dictionary of dictionaries, only. For
|
||||
# example, {'real':{'low':'float'}} means that Fortran 'real(low)' is
|
||||
# interpreted as C 'float'. This feature is useful for F90/95 users if
|
||||
# they use PARAMETERSs in type specifications.
|
||||
try:
|
||||
outmess('Reading f2cmap from {!r} ...\n'.format(f2cmap_file))
|
||||
with open(f2cmap_file, 'r') as f:
|
||||
d = eval(f.read(), {}, {})
|
||||
for k, d1 in list(d.items()):
|
||||
for k1 in list(d1.keys()):
|
||||
d1[k1.lower()] = d1[k1]
|
||||
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 f2cmap changes\n')
|
||||
except Exception as msg:
|
||||
errmess(
|
||||
'Failed to apply user defined f2cmap changes: %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):
|
||||
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
|
||||
"""
|
||||
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
|
574
venv/Lib/site-packages/numpy/f2py/cb_rules.py
Normal file
574
venv/Lib/site-packages/numpy/f2py/cb_rules.py
Normal file
|
@ -0,0 +1,574 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
|
||||
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 . 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):
|
||||
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):
|
||||
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 #############
|
1263
venv/Lib/site-packages/numpy/f2py/cfuncs.py
Normal file
1263
venv/Lib/site-packages/numpy/f2py/cfuncs.py
Normal file
File diff suppressed because it is too large
Load diff
147
venv/Lib/site-packages/numpy/f2py/common_rules.py
Normal file
147
venv/Lib/site-packages/numpy/f2py/common_rules.py
Normal file
|
@ -0,0 +1,147 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
|
||||
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
|
||||
|
||||
"""
|
||||
__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('\ttmp = PyFortranObject_New(f2py_%s_def,f2py_init_%s);' % (name, name))
|
||||
iadd('\tF2PyDict_SetItemString(d, \"%s\", tmp);' % name)
|
||||
iadd('\tPy_DECREF(tmp);')
|
||||
tname = name.replace('_', '\\_')
|
||||
dadd('\\subsection{Common block \\texttt{%s}}\n' % (tname))
|
||||
dadd('\\begin{description}')
|
||||
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]
|
3347
venv/Lib/site-packages/numpy/f2py/crackfortran.py
Normal file
3347
venv/Lib/site-packages/numpy/f2py/crackfortran.py
Normal file
File diff suppressed because it is too large
Load diff
154
venv/Lib/site-packages/numpy/f2py/diagnose.py
Normal file
154
venv/Lib/site-packages/numpy/f2py/diagnose.py
Normal file
|
@ -0,0 +1,154 @@
|
|||
#!/usr/bin/env python3
|
||||
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()
|
694
venv/Lib/site-packages/numpy/f2py/f2py2e.py
Normal file
694
venv/Lib/site-packages/numpy/f2py/f2py2e.py
Normal file
|
@ -0,0 +1,694 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
|
||||
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
|
||||
|
||||
"""
|
||||
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__
|
||||
from . import capi_maps
|
||||
|
||||
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'.
|
||||
|
||||
--f2cmap <filename> Load Fortran-to-Python KIND specification from the given
|
||||
file. Default: .f2py_f2cmap in current directory.
|
||||
|
||||
--quiet Run quietly.
|
||||
--verbose Run with extra verbosity.
|
||||
-v Print f2py version ID and exit.
|
||||
|
||||
|
||||
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 3.5 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, f10 = 1, 0, 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 == '--f2cmap':
|
||||
f10 = 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 f10:
|
||||
f10 = 0
|
||||
options["f2cmap_file"] = 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
|
||||
options.setdefault('f2cmap_file', None)
|
||||
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
|
||||
capi_maps.load_f2cmap_file(options['f2cmap_file'])
|
||||
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', '--f2cmap']:
|
||||
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:])
|
46
venv/Lib/site-packages/numpy/f2py/f2py_testing.py
Normal file
46
venv/Lib/site-packages/numpy/f2py/f2py_testing.py
Normal file
|
@ -0,0 +1,46 @@
|
|||
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')
|
269
venv/Lib/site-packages/numpy/f2py/f90mod_rules.py
Normal file
269
venv/Lib/site-packages/numpy/f2py/f90mod_rules.py
Normal file
|
@ -0,0 +1,269 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
|
||||
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
|
||||
|
||||
"""
|
||||
__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 environment 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):
|
||||
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 = range(1, int(dm['rank']) + 1)
|
||||
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]
|
297
venv/Lib/site-packages/numpy/f2py/func2subr.py
Normal file
297
venv/Lib/site-packages/numpy/f2py/func2subr.py
Normal file
|
@ -0,0 +1,297 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
|
||||
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
|
||||
|
||||
"""
|
||||
__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, ''
|
1455
venv/Lib/site-packages/numpy/f2py/rules.py
Normal file
1455
venv/Lib/site-packages/numpy/f2py/rules.py
Normal file
File diff suppressed because it is too large
Load diff
72
venv/Lib/site-packages/numpy/f2py/setup.py
Normal file
72
venv/Lib/site-packages/numpy/f2py/setup.py
Normal file
|
@ -0,0 +1,72 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
setup.py for installing F2PY
|
||||
|
||||
Usage:
|
||||
pip 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 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_subpackage('tests')
|
||||
config.add_data_dir('tests/src')
|
||||
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)
|
1042
venv/Lib/site-packages/numpy/f2py/src/fortranobject.c
Normal file
1042
venv/Lib/site-packages/numpy/f2py/src/fortranobject.c
Normal file
File diff suppressed because it is too large
Load diff
129
venv/Lib/site-packages/numpy/f2py/src/fortranobject.h
Normal file
129
venv/Lib/site-packages/numpy/f2py/src/fortranobject.h
Normal file
|
@ -0,0 +1,129 @@
|
|||
#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"
|
||||
#include "numpy/npy_3kcompat.h"
|
||||
|
||||
|
||||
#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);
|
||||
|
||||
PyObject * F2PyCapsule_FromVoidPtr(void *ptr, void (*dtor)(PyObject *));
|
||||
void * F2PyCapsule_AsVoidPtr(PyObject *obj);
|
||||
int F2PyCapsule_Check(PyObject *ptr);
|
||||
|
||||
#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
venv/Lib/site-packages/numpy/f2py/tests/__init__.py
Normal file
0
venv/Lib/site-packages/numpy/f2py/tests/__init__.py
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,233 @@
|
|||
/* 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) {
|
||||
PyObject *tmp;
|
||||
tmp = PySequence_GetItem(dims_capi, i);
|
||||
if (tmp == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
dims[i] = (npy_intp)PyInt_AsLong(tmp);
|
||||
Py_DECREF(tmp);
|
||||
if (dims[i] == -1 && PyErr_Occurred()) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
capi_arr_tmp = array_from_pyobj(type_num,dims,rank,intent|F2PY_INTENT_OUT,arr_capi);
|
||||
if (capi_arr_tmp == NULL) {
|
||||
free(dims);
|
||||
return NULL;
|
||||
}
|
||||
capi_buildvalue = Py_BuildValue("N",capi_arr_tmp);
|
||||
free(dims);
|
||||
return capi_buildvalue;
|
||||
|
||||
fail:
|
||||
free(dims);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char doc_f2py_rout_wrap_attrs[] = "\
|
||||
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("siNNO(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}
|
||||
};
|
||||
|
||||
static struct PyModuleDef moduledef = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"test_array_from_pyobj_ext",
|
||||
NULL,
|
||||
-1,
|
||||
f2py_module_methods,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC PyInit_test_array_from_pyobj_ext(void) {
|
||||
PyObject *m,*d, *s;
|
||||
m = wrap_module = PyModule_Create(&moduledef);
|
||||
Py_SET_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);
|
||||
|
||||
#define ADDCONST(NAME, CONST) \
|
||||
s = PyInt_FromLong(CONST); \
|
||||
PyDict_SetItemString(d, NAME, s); \
|
||||
Py_DECREF(s)
|
||||
|
||||
ADDCONST("F2PY_INTENT_IN", F2PY_INTENT_IN);
|
||||
ADDCONST("F2PY_INTENT_INOUT", F2PY_INTENT_INOUT);
|
||||
ADDCONST("F2PY_INTENT_OUT", F2PY_INTENT_OUT);
|
||||
ADDCONST("F2PY_INTENT_HIDE", F2PY_INTENT_HIDE);
|
||||
ADDCONST("F2PY_INTENT_CACHE", F2PY_INTENT_CACHE);
|
||||
ADDCONST("F2PY_INTENT_COPY", F2PY_INTENT_COPY);
|
||||
ADDCONST("F2PY_INTENT_C", F2PY_INTENT_C);
|
||||
ADDCONST("F2PY_OPTIONAL", F2PY_OPTIONAL);
|
||||
ADDCONST("F2PY_INTENT_INPLACE", F2PY_INTENT_INPLACE);
|
||||
ADDCONST("NPY_BOOL", NPY_BOOL);
|
||||
ADDCONST("NPY_BYTE", NPY_BYTE);
|
||||
ADDCONST("NPY_UBYTE", NPY_UBYTE);
|
||||
ADDCONST("NPY_SHORT", NPY_SHORT);
|
||||
ADDCONST("NPY_USHORT", NPY_USHORT);
|
||||
ADDCONST("NPY_INT", NPY_INT);
|
||||
ADDCONST("NPY_UINT", NPY_UINT);
|
||||
ADDCONST("NPY_INTP", NPY_INTP);
|
||||
ADDCONST("NPY_UINTP", NPY_UINTP);
|
||||
ADDCONST("NPY_LONG", NPY_LONG);
|
||||
ADDCONST("NPY_ULONG", NPY_ULONG);
|
||||
ADDCONST("NPY_LONGLONG", NPY_LONGLONG);
|
||||
ADDCONST("NPY_ULONGLONG", NPY_ULONGLONG);
|
||||
ADDCONST("NPY_FLOAT", NPY_FLOAT);
|
||||
ADDCONST("NPY_DOUBLE", NPY_DOUBLE);
|
||||
ADDCONST("NPY_LONGDOUBLE", NPY_LONGDOUBLE);
|
||||
ADDCONST("NPY_CFLOAT", NPY_CFLOAT);
|
||||
ADDCONST("NPY_CDOUBLE", NPY_CDOUBLE);
|
||||
ADDCONST("NPY_CLONGDOUBLE", NPY_CLONGDOUBLE);
|
||||
ADDCONST("NPY_OBJECT", NPY_OBJECT);
|
||||
ADDCONST("NPY_STRING", NPY_STRING);
|
||||
ADDCONST("NPY_UNICODE", NPY_UNICODE);
|
||||
ADDCONST("NPY_VOID", NPY_VOID);
|
||||
ADDCONST("NPY_NTYPES", NPY_NTYPES);
|
||||
ADDCONST("NPY_NOTYPE", NPY_NOTYPE);
|
||||
ADDCONST("NPY_USERDEF", NPY_USERDEF);
|
||||
|
||||
ADDCONST("CONTIGUOUS", NPY_ARRAY_C_CONTIGUOUS);
|
||||
ADDCONST("FORTRAN", NPY_ARRAY_F_CONTIGUOUS);
|
||||
ADDCONST("OWNDATA", NPY_ARRAY_OWNDATA);
|
||||
ADDCONST("FORCECAST", NPY_ARRAY_FORCECAST);
|
||||
ADDCONST("ENSURECOPY", NPY_ARRAY_ENSURECOPY);
|
||||
ADDCONST("ENSUREARRAY", NPY_ARRAY_ENSUREARRAY);
|
||||
ADDCONST("ALIGNED", NPY_ARRAY_ALIGNED);
|
||||
ADDCONST("WRITEABLE", NPY_ARRAY_WRITEABLE);
|
||||
ADDCONST("UPDATEIFCOPY", NPY_ARRAY_UPDATEIFCOPY);
|
||||
ADDCONST("WRITEBACKIFCOPY", NPY_ARRAY_WRITEBACKIFCOPY);
|
||||
|
||||
ADDCONST("BEHAVED", NPY_ARRAY_BEHAVED);
|
||||
ADDCONST("BEHAVED_NS", NPY_ARRAY_BEHAVED_NS);
|
||||
ADDCONST("CARRAY", NPY_ARRAY_CARRAY);
|
||||
ADDCONST("FARRAY", NPY_ARRAY_FARRAY);
|
||||
ADDCONST("CARRAY_RO", NPY_ARRAY_CARRAY_RO);
|
||||
ADDCONST("FARRAY_RO", NPY_ARRAY_FARRAY_RO);
|
||||
ADDCONST("DEFAULT", NPY_ARRAY_DEFAULT);
|
||||
ADDCONST("UPDATE_ALL", NPY_ARRAY_UPDATE_ALL);
|
||||
|
||||
#undef ADDCONST(
|
||||
|
||||
if (PyErr_Occurred())
|
||||
Py_FatalError("can't initialize module wrap");
|
||||
|
||||
#ifdef F2PY_REPORT_ATEXIT
|
||||
on_exit(f2py_report_on_exit,(void*)"array_from_pyobj.wrap.call");
|
||||
#endif
|
||||
|
||||
return m;
|
||||
}
|
||||
#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
|
11
venv/Lib/site-packages/numpy/f2py/tests/src/common/block.f
Normal file
11
venv/Lib/site-packages/numpy/f2py/tests/src/common/block.f
Normal file
|
@ -0,0 +1,11 @@
|
|||
SUBROUTINE INITCB
|
||||
DOUBLE PRECISION LONG
|
||||
CHARACTER STRING
|
||||
INTEGER OK
|
||||
|
||||
COMMON /BLOCK/ LONG, STRING, OK
|
||||
LONG = 1.0
|
||||
STRING = '2'
|
||||
OK = 3
|
||||
RETURN
|
||||
END
|
20
venv/Lib/site-packages/numpy/f2py/tests/src/kind/foo.f90
Normal file
20
venv/Lib/site-packages/numpy/f2py/tests/src/kind/foo.f90
Normal file
|
@ -0,0 +1,20 @@
|
|||
|
||||
|
||||
subroutine selectedrealkind(p, r, res)
|
||||
implicit none
|
||||
|
||||
integer, intent(in) :: p, r
|
||||
!f2py integer :: r=0
|
||||
integer, intent(out) :: res
|
||||
res = selected_real_kind(p, r)
|
||||
|
||||
end subroutine
|
||||
|
||||
subroutine selectedintkind(p, res)
|
||||
implicit none
|
||||
|
||||
integer, intent(in) :: p
|
||||
integer, intent(out) :: res
|
||||
res = selected_int_kind(p)
|
||||
|
||||
end subroutine
|
5
venv/Lib/site-packages/numpy/f2py/tests/src/mixed/foo.f
Normal file
5
venv/Lib/site-packages/numpy/f2py/tests/src/mixed/foo.f
Normal file
|
@ -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
|
44
venv/Lib/site-packages/numpy/f2py/tests/src/size/foo.f90
Normal file
44
venv/Lib/site-packages/numpy/f2py/tests/src/size/foo.f90
Normal file
|
@ -0,0 +1,44 @@
|
|||
|
||||
subroutine foo(a, n, m, b)
|
||||
implicit none
|
||||
|
||||
real, intent(in) :: a(n, m)
|
||||
integer, intent(in) :: n, m
|
||||
real, intent(out) :: b(size(a, 1))
|
||||
|
||||
integer :: i
|
||||
|
||||
do i = 1, size(b)
|
||||
b(i) = sum(a(i,:))
|
||||
enddo
|
||||
end subroutine
|
||||
|
||||
subroutine trans(x,y)
|
||||
implicit none
|
||||
real, intent(in), dimension(:,:) :: x
|
||||
real, intent(out), dimension( size(x,2), size(x,1) ) :: y
|
||||
integer :: N, M, i, j
|
||||
N = size(x,1)
|
||||
M = size(x,2)
|
||||
DO i=1,N
|
||||
do j=1,M
|
||||
y(j,i) = x(i,j)
|
||||
END DO
|
||||
END DO
|
||||
end subroutine trans
|
||||
|
||||
subroutine flatten(x,y)
|
||||
implicit none
|
||||
real, intent(in), dimension(:,:) :: x
|
||||
real, intent(out), dimension( size(x) ) :: y
|
||||
integer :: N, M, i, j, k
|
||||
N = size(x,1)
|
||||
M = size(x,2)
|
||||
k = 1
|
||||
DO i=1,N
|
||||
do j=1,M
|
||||
y(k) = x(i,j)
|
||||
k = k + 1
|
||||
END DO
|
||||
END DO
|
||||
end subroutine flatten
|
29
venv/Lib/site-packages/numpy/f2py/tests/src/string/char.f90
Normal file
29
venv/Lib/site-packages/numpy/f2py/tests/src/string/char.f90
Normal file
|
@ -0,0 +1,29 @@
|
|||
MODULE char_test
|
||||
|
||||
CONTAINS
|
||||
|
||||
SUBROUTINE change_strings(strings, n_strs, out_strings)
|
||||
IMPLICIT NONE
|
||||
|
||||
! Inputs
|
||||
INTEGER, INTENT(IN) :: n_strs
|
||||
CHARACTER, INTENT(IN), DIMENSION(2,n_strs) :: strings
|
||||
CHARACTER, INTENT(OUT), DIMENSION(2,n_strs) :: out_strings
|
||||
|
||||
!f2py INTEGER, INTENT(IN) :: n_strs
|
||||
!f2py CHARACTER, INTENT(IN), DIMENSION(2,n_strs) :: strings
|
||||
!f2py CHARACTER, INTENT(OUT), DIMENSION(2,n_strs) :: strings
|
||||
|
||||
! Misc.
|
||||
INTEGER*4 :: j
|
||||
|
||||
|
||||
DO j=1, n_strs
|
||||
out_strings(1,j) = strings(1,j)
|
||||
out_strings(2,j) = 'A'
|
||||
END DO
|
||||
|
||||
END SUBROUTINE change_strings
|
||||
|
||||
END MODULE char_test
|
||||
|
579
venv/Lib/site-packages/numpy/f2py/tests/test_array_from_pyobj.py
Normal file
579
venv/Lib/site-packages/numpy/f2py/tests/test_array_from_pyobj.py
Normal file
|
@ -0,0 +1,579 @@
|
|||
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:
|
||||
|
||||
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:
|
||||
_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:
|
||||
|
||||
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:
|
||||
|
||||
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:
|
||||
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,53 @@
|
|||
import os
|
||||
import pytest
|
||||
import tempfile
|
||||
|
||||
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'),
|
||||
_path('src', 'assumed_shape', '.f2py_f2cmap'),
|
||||
]
|
||||
|
||||
@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))
|
||||
|
||||
|
||||
class TestF2cmapOption(TestAssumedShapeSumExample):
|
||||
def setup(self):
|
||||
# Use a custom file name for .f2py_f2cmap
|
||||
self.sources = list(self.sources)
|
||||
f2cmap_src = self.sources.pop(-1)
|
||||
|
||||
self.f2cmap_file = tempfile.NamedTemporaryFile(delete=False)
|
||||
with open(f2cmap_src, 'rb') as f:
|
||||
self.f2cmap_file.write(f.read())
|
||||
self.f2cmap_file.close()
|
||||
|
||||
self.sources.append(self.f2cmap_file.name)
|
||||
self.options = ["--f2cmap", self.f2cmap_file.name]
|
||||
|
||||
super(TestF2cmapOption, self).setup()
|
||||
|
||||
def teardown(self):
|
||||
os.unlink(self.f2cmap_file.name)
|
|
@ -0,0 +1,23 @@
|
|||
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 cannot modify tp_doc after PyType_Ready")
|
||||
def test_block_docstring(self):
|
||||
expected = "'i'-array(2,3)\n"
|
||||
assert_equal(self.module.block.__doc__, expected)
|
163
venv/Lib/site-packages/numpy/f2py/tests/test_callback.py
Normal file
163
venv/Lib/site-packages/numpy/f2py/tests/test_callback.py
Normal file
|
@ -0,0 +1,163 @@
|
|||
import math
|
||||
import textwrap
|
||||
import sys
|
||||
import pytest
|
||||
|
||||
import numpy as np
|
||||
from numpy.testing import assert_, assert_equal, IS_PYPY
|
||||
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.parametrize('name', 't,t2'.split(','))
|
||||
def test_all(self, name):
|
||||
self.check_function(name)
|
||||
|
||||
@pytest.mark.xfail(IS_PYPY,
|
||||
reason="PyPy cannot modify tp_doc after PyType_Ready")
|
||||
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:
|
||||
|
||||
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))
|
25
venv/Lib/site-packages/numpy/f2py/tests/test_common.py
Normal file
25
venv/Lib/site-packages/numpy/f2py/tests/test_common.py
Normal file
|
@ -0,0 +1,25 @@
|
|||
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))
|
125
venv/Lib/site-packages/numpy/f2py/tests/test_compile_function.py
Normal file
125
venv/Lib/site-packages/numpy/f2py/tests/test_compile_function.py
Normal file
|
@ -0,0 +1,125 @@
|
|||
"""See https://github.com/numpy/numpy/pull/11937.
|
||||
|
||||
"""
|
||||
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 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', '']
|
||||
)
|
||||
@pytest.mark.leaks_references(reason="Imported module seems never deleted.")
|
||||
def test_f2py_init_compile(extra_args):
|
||||
# flush through the f2py __init__ compile() function code path as a
|
||||
# crude test for input handling following migration from
|
||||
# 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)
|
||||
# Removal from sys.modules, is not as such necessary. Even with
|
||||
# removal, the module (dict) stays alive.
|
||||
del sys.modules[modname]
|
||||
|
||||
|
||||
def test_f2py_init_compile_failure():
|
||||
# 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)
|
88
venv/Lib/site-packages/numpy/f2py/tests/test_crackfortran.py
Normal file
88
venv/Lib/site-packages/numpy/f2py/tests/test_crackfortran.py
Normal file
|
@ -0,0 +1,88 @@
|
|||
import numpy as np
|
||||
from numpy.testing import assert_array_equal
|
||||
from . import util
|
||||
from numpy.f2py import crackfortran
|
||||
import tempfile
|
||||
import textwrap
|
||||
|
||||
|
||||
class TestNoSpace(util.F2PyTest):
|
||||
# issue gh-15035: add handling for endsubroutine, endfunction with no space
|
||||
# between "end" and the block name
|
||||
code = """
|
||||
subroutine subb(k)
|
||||
real(8), intent(inout) :: k(:)
|
||||
k=k+1
|
||||
endsubroutine
|
||||
|
||||
subroutine subc(w,k)
|
||||
real(8), intent(in) :: w(:)
|
||||
real(8), intent(out) :: k(size(w))
|
||||
k=w+1
|
||||
endsubroutine
|
||||
|
||||
function t0(value)
|
||||
character value
|
||||
character t0
|
||||
t0 = value
|
||||
endfunction
|
||||
"""
|
||||
|
||||
def test_module(self):
|
||||
k = np.array([1, 2, 3], dtype=np.float64)
|
||||
w = np.array([1, 2, 3], dtype=np.float64)
|
||||
self.module.subb(k)
|
||||
assert_array_equal(k, w + 1)
|
||||
self.module.subc([w, k])
|
||||
assert_array_equal(k, w + 1)
|
||||
assert self.module.t0(23) == b'2'
|
||||
|
||||
class TestPublicPrivate():
|
||||
def test_defaultPrivate(self, tmp_path):
|
||||
f_path = tmp_path / "mod.f90"
|
||||
with f_path.open('w') as ff:
|
||||
ff.write(textwrap.dedent("""\
|
||||
module foo
|
||||
private
|
||||
integer :: a
|
||||
public :: setA
|
||||
integer :: b
|
||||
contains
|
||||
subroutine setA(v)
|
||||
integer, intent(in) :: v
|
||||
a = v
|
||||
end subroutine setA
|
||||
end module foo
|
||||
"""))
|
||||
mod = crackfortran.crackfortran([str(f_path)])
|
||||
assert len(mod) == 1
|
||||
mod = mod[0]
|
||||
assert 'private' in mod['vars']['a']['attrspec']
|
||||
assert 'public' not in mod['vars']['a']['attrspec']
|
||||
assert 'private' in mod['vars']['b']['attrspec']
|
||||
assert 'public' not in mod['vars']['b']['attrspec']
|
||||
assert 'private' not in mod['vars']['seta']['attrspec']
|
||||
assert 'public' in mod['vars']['seta']['attrspec']
|
||||
|
||||
def test_defaultPublic(self, tmp_path):
|
||||
f_path = tmp_path / "mod.f90"
|
||||
with f_path.open('w') as ff:
|
||||
ff.write(textwrap.dedent("""\
|
||||
module foo
|
||||
public
|
||||
integer, private :: a
|
||||
public :: setA
|
||||
contains
|
||||
subroutine setA(v)
|
||||
integer, intent(in) :: v
|
||||
a = v
|
||||
end subroutine setA
|
||||
end module foo
|
||||
"""))
|
||||
mod = crackfortran.crackfortran([str(f_path)])
|
||||
assert len(mod) == 1
|
||||
mod = mod[0]
|
||||
assert 'private' in mod['vars']['a']['attrspec']
|
||||
assert 'public' not in mod['vars']['a']['attrspec']
|
||||
assert 'private' not in mod['vars']['seta']['attrspec']
|
||||
assert 'public' in mod['vars']['seta']['attrspec']
|
32
venv/Lib/site-packages/numpy/f2py/tests/test_kind.py
Normal file
32
venv/Lib/site-packages/numpy/f2py/tests/test_kind.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
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)))
|
35
venv/Lib/site-packages/numpy/f2py/tests/test_mixed.py
Normal file
35
venv/Lib/site-packages/numpy/f2py/tests/test_mixed.py
Normal file
|
@ -0,0 +1,35 @@
|
|||
import os
|
||||
import textwrap
|
||||
import pytest
|
||||
|
||||
from numpy.testing import assert_, assert_equal, IS_PYPY
|
||||
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')]
|
||||
|
||||
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.xfail(IS_PYPY,
|
||||
reason="PyPy cannot modify tp_doc after PyType_Ready")
|
||||
def test_docstring(self):
|
||||
expected = textwrap.dedent("""\
|
||||
a = bar11()
|
||||
|
||||
Wrapper for ``bar11``.
|
||||
|
||||
Returns
|
||||
-------
|
||||
a : int
|
||||
""")
|
||||
assert_equal(self.module.bar11.__doc__, expected)
|
116
venv/Lib/site-packages/numpy/f2py/tests/test_parameter.py
Normal file
116
venv/Lib/site-packages/numpy/f2py/tests/test_parameter.py
Normal file
|
@ -0,0 +1,116 @@
|
|||
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,32 @@
|
|||
"""See https://github.com/numpy/numpy/pull/10676.
|
||||
|
||||
"""
|
||||
import sys
|
||||
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')'))
|
27
venv/Lib/site-packages/numpy/f2py/tests/test_regression.py
Normal file
27
venv/Lib/site-packages/numpy/f2py/tests/test_regression.py
Normal file
|
@ -0,0 +1,27 @@
|
|||
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])
|
145
venv/Lib/site-packages/numpy/f2py/tests/test_return_character.py
Normal file
145
venv/Lib/site-packages/numpy/f2py/tests/test_return_character.py
Normal file
|
@ -0,0 +1,145 @@
|
|||
import pytest
|
||||
|
||||
from numpy import array
|
||||
from numpy.testing import assert_
|
||||
from . import util
|
||||
import platform
|
||||
IS_S390X = platform.machine() == 's390x'
|
||||
|
||||
|
||||
class TestReturnCharacter(util.F2PyTest):
|
||||
|
||||
def check_function(self, t, tname):
|
||||
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.xfail(IS_S390X, reason="calback returns ' '")
|
||||
@pytest.mark.parametrize('name', 't0,t1,t5,s0,s1,s5,ss'.split(','))
|
||||
def test_all(self, name):
|
||||
self.check_function(getattr(self.module, name), 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.xfail(IS_S390X, reason="calback returns ' '")
|
||||
@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), name)
|
163
venv/Lib/site-packages/numpy/f2py/tests/test_return_complex.py
Normal file
163
venv/Lib/site-packages/numpy/f2py/tests/test_return_complex.py
Normal file
|
@ -0,0 +1,163 @@
|
|||
import pytest
|
||||
|
||||
from numpy import array
|
||||
from numpy.testing import assert_, assert_raises
|
||||
from . import util
|
||||
|
||||
|
||||
class TestReturnComplex(util.F2PyTest):
|
||||
|
||||
def check_function(self, t, tname):
|
||||
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(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.parametrize('name', 't0,t8,t16,td,s0,s8,s16,sd'.split(','))
|
||||
def test_all(self, name):
|
||||
self.check_function(getattr(self.module, name), 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.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), name)
|
175
venv/Lib/site-packages/numpy/f2py/tests/test_return_integer.py
Normal file
175
venv/Lib/site-packages/numpy/f2py/tests/test_return_integer.py
Normal file
|
@ -0,0 +1,175 @@
|
|||
import pytest
|
||||
|
||||
from numpy import array
|
||||
from numpy.testing import assert_, assert_raises
|
||||
from . import util
|
||||
|
||||
|
||||
class TestReturnInteger(util.F2PyTest):
|
||||
|
||||
def check_function(self, t, tname):
|
||||
assert_(t(123) == 123, repr(t(123)))
|
||||
assert_(t(123.6) == 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 tname 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.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), 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.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), name)
|
185
venv/Lib/site-packages/numpy/f2py/tests/test_return_logical.py
Normal file
185
venv/Lib/site-packages/numpy/f2py/tests/test_return_logical.py
Normal file
|
@ -0,0 +1,185 @@
|
|||
import pytest
|
||||
|
||||
from numpy import array
|
||||
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(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))
|
203
venv/Lib/site-packages/numpy/f2py/tests/test_return_real.py
Normal file
203
venv/Lib/site-packages/numpy/f2py/tests/test_return_real.py
Normal file
|
@ -0,0 +1,203 @@
|
|||
import platform
|
||||
import pytest
|
||||
|
||||
from numpy import array
|
||||
from numpy.testing import assert_, assert_raises
|
||||
from . import util
|
||||
|
||||
|
||||
class TestReturnReal(util.F2PyTest):
|
||||
|
||||
def check_function(self, t, tname):
|
||||
if tname 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('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 tname 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.parametrize('name', 't4,t8,s4,s8'.split(','))
|
||||
def test_all(self, name):
|
||||
self.check_function(getattr(self.module, name), 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.parametrize('name', 't0,t4,t8,td,s0,s4,s8,sd'.split(','))
|
||||
def test_all(self, name):
|
||||
self.check_function(getattr(self.module, name), 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.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), name)
|
|
@ -0,0 +1,63 @@
|
|||
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)
|
49
venv/Lib/site-packages/numpy/f2py/tests/test_size.py
Normal file
49
venv/Lib/site-packages/numpy/f2py/tests/test_size.py
Normal file
|
@ -0,0 +1,49 @@
|
|||
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))
|
22
venv/Lib/site-packages/numpy/f2py/tests/test_string.py
Normal file
22
venv/Lib/site-packages/numpy/f2py/tests/test_string.py
Normal file
|
@ -0,0 +1,22 @@
|
|||
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)
|
361
venv/Lib/site-packages/numpy/f2py/tests/util.py
Normal file
361
venv/Lib/site-packages/numpy/f2py/tests/util.py
Normal file
|
@ -0,0 +1,361 @@
|
|||
"""
|
||||
Utility functions for
|
||||
|
||||
- building and importing modules on test time, using a temporary location
|
||||
- detecting if compilers are present
|
||||
|
||||
"""
|
||||
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
|
||||
|
||||
from hashlib import md5
|
||||
|
||||
#
|
||||
# Maintaining a temporary module directory
|
||||
#
|
||||
|
||||
_module_dir = None
|
||||
_module_num = 5403
|
||||
|
||||
|
||||
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
|
||||
global _module_num
|
||||
d = get_module_dir()
|
||||
name = "_test_ext_module_%d" % _module_num
|
||||
_module_num += 1
|
||||
if name in sys.modules:
|
||||
# this should not be possible, but check anyway
|
||||
raise RuntimeError("Temporary module name already in use.")
|
||||
return name
|
||||
|
||||
|
||||
def _memoize(func):
|
||||
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 = []
|
||||
f2py_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)
|
||||
|
||||
base, ext = os.path.splitext(dst)
|
||||
if ext in ('.f90', '.f', '.c', '.pyf'):
|
||||
f2py_sources.append(dst)
|
||||
|
||||
# Prepare options
|
||||
if module_name is None:
|
||||
module_name = get_temp_module_name()
|
||||
f2py_opts = ['-c', '-m', module_name] + options + f2py_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))
|
||||
|
||||
tmpdir = tempfile.mkdtemp()
|
||||
try:
|
||||
script = os.path.join(tmpdir, 'setup.py')
|
||||
|
||||
with open(script, 'w') as f:
|
||||
f.write(code)
|
||||
|
||||
cmd = [sys.executable, 'setup.py', 'config']
|
||||
p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
cwd=tmpdir)
|
||||
out, err = p.communicate()
|
||||
finally:
|
||||
shutil.rmtree(tmpdir)
|
||||
|
||||
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)
|
||||
with open(script, 'wb') as f:
|
||||
f.write(asbytes(code))
|
||||
|
||||
# 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:
|
||||
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)
|
113
venv/Lib/site-packages/numpy/f2py/use_rules.py
Normal file
113
venv/Lib/site-packages/numpy/f2py/use_rules.py
Normal file
|
@ -0,0 +1,113 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
|
||||
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
|
||||
|
||||
"""
|
||||
__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
|
Loading…
Add table
Add a link
Reference in a new issue