diff options
-rw-r--r-- | numpy/f2py/lib/main.py | 112 | ||||
-rw-r--r-- | numpy/f2py/lib/nary.py | 32 | ||||
-rw-r--r-- | numpy/f2py/lib/test_module_module.py | 83 | ||||
-rw-r--r-- | numpy/f2py/lib/test_module_scalar.py | 83 | ||||
-rw-r--r-- | numpy/f2py/lib/tests/test_derived_scalar.py (renamed from numpy/f2py/lib/test_derived_scalar.py) | 33 | ||||
-rw-r--r-- | numpy/f2py/lib/tests/test_module_module.py | 61 | ||||
-rw-r--r-- | numpy/f2py/lib/tests/test_module_scalar.py | 58 | ||||
-rw-r--r-- | numpy/f2py/lib/tests/test_scalar_function_in.py (renamed from numpy/f2py/lib/test_scalar_function_in.py) | 36 | ||||
-rw-r--r-- | numpy/f2py/lib/tests/test_scalar_in_out.py (renamed from numpy/f2py/lib/test_scalar_in_out.py) | 31 |
9 files changed, 264 insertions, 265 deletions
diff --git a/numpy/f2py/lib/main.py b/numpy/f2py/lib/main.py index 911576d7d..8d61c1e67 100644 --- a/numpy/f2py/lib/main.py +++ b/numpy/f2py/lib/main.py @@ -21,7 +21,7 @@ try: except ImportError: numpy_version = 'N/A' -__all__ = ['main'] +__all__ = ['main', 'compile'] __usage__ = """ F2PY G3 --- The third generation of Fortran to Python Interface Generator @@ -100,7 +100,8 @@ Extra options effective only with -c import re import shutil import parser.api -from parser.api import parse, PythonModule, EndStatement, Module, Subroutine, Function +from parser.api import parse, PythonModule, EndStatement, Module, Subroutine, Function,\ + get_reader def get_values(sys_argv, prefix='', suffix='', strip_prefix=False, strip_suffix=False): """ @@ -200,9 +201,11 @@ def dump_signature(sys_argv): if os.path.isfile(signature_output): overwrite = get_option(sys_argv, '--overwrite-signature', False) if not overwrite: - print >> sys.stderr, 'Signature file %r exists. Use --overwrite-signature to overwrite.' % (signature_output) + print >> sys.stderr, 'Signature file %r exists. '\ + 'Use --overwrite-signature to overwrite.' % (signature_output) sys.exit() - modulename = get_option_value(sys_argv,'-m',os.path.basename(name),os.path.basename(name)) + modulename = get_option_value(sys_argv,'-m',os.path.basename(name), + os.path.basename(name)) output_stream = open(signature_output,'w') flag = 'file' @@ -217,7 +220,8 @@ def dump_signature(sys_argv): elif word==':': flag = 'file' elif word.startswith('--'): options.append(word) else: - {'file': file_names,'only': only_names, 'skip': skip_names}[flag].append(word) + {'file': file_names,'only': only_names, + 'skip': skip_names}[flag].append(word) if options: sys.stderr.write('Unused options: %s\n' % (', '.join(options))) @@ -286,7 +290,7 @@ def construct_extension_sources(modulename, parse_files, include_dirs, build_dir f = open(f_fn,'w') f.write(f_code) f.close() - f_lib = '%s_f_wrappers_f2py' % (block.name) + #f_lib = '%s_f_wrappers_f2py' % (block.name) module_info = {'name':block.name, 'c_sources':[c_fn], 'f_sources':[f_fn], 'language':'f90'} module_infos.append(module_info) @@ -371,7 +375,7 @@ def build_extension(sys_argv, sources_only = False): if sources_only: return - def configuration(parent_package='', top_path=None): + def configuration(parent_package='', top_path=None or ''): from numpy.distutils.misc_util import Configuration config = Configuration('',parent_package,top_path) flibname = modulename + '_fortran_f2py' @@ -403,10 +407,18 @@ def build_extension(sys_argv, sources_only = False): return config old_sys_argv = sys.argv[:] - new_sys_argv = [sys.argv[0]] + ['build', - '--build-temp',build_dir, - '--build-base',build_dir, - '--build-platlib','.'] + build_dir_ext_temp = os.path.join(build_dir,'ext_temp') + build_dir_clib_temp = os.path.join(build_dir,'clib_temp') + build_dir_clib_clib = os.path.join(build_dir,'clib_clib') + new_sys_argv = [sys.argv[0]] + ['build_ext', + '--build-temp',build_dir_ext_temp, + '--build-lib',build_dir, + 'build_clib', + '--build-temp',build_dir_clib_temp, + '--build-clib',build_dir_clib_clib, + ] + temp_dirs = [build_dir_ext_temp, build_dir_clib_temp, build_dir_clib_clib] + if fc_flags: new_sys_argv += ['config_fc'] + fc_flags sys.argv[:] = new_sys_argv @@ -418,9 +430,11 @@ def build_extension(sys_argv, sources_only = False): sys.argv[:] = old_sys_argv - if clean_build_dir and os.path.exists(build_dir): - sys.stderr.write('Removing build directory %s\n'%(build_dir)) - shutil.rmtree(build_dir) + if 1 or clean_build_dir: + for d in temp_dirs: + if os.path.exists(d): + sys.stderr.write('Removing build directory %s\n'%(d)) + shutil.rmtree(d) return def main(sys_argv = None): @@ -449,3 +463,73 @@ def main(sys_argv = None): build_extension(sys_argv, sources_only = True) return + +def compile(source, + jobname = 'untitled', + extra_args = [], + source_ext = None, + modulenames = None + ): + """ + Build extension module from processing source with f2py. + + jobname - the name of compile job. For non-module source + this will be also the name of extension module. + modulenames - the list of extension module names that + the given compilation job should create. + extra_args - a list of extra arguments for numpy style + setup.py command line. + source_ext - extension of the Fortran source file: .f90 or .f + + Extension modules are saved to current working directory. + Returns a list of module objects according to modulenames + input. + """ + from nary import encode + tempdir = tempfile.gettempdir() + s = 'f2pyjob_%s_%s' % (jobname, encode(source)) + tmpdir = os.path.join(tempdir, s) + if source_ext is None: + reader = get_reader(source) + source_ext = {'free90':'.f90','fix90':'.f90','fix77':'.f','pyf':'.pyf'}[reader.mode] + + if modulenames is None: + modulenames = jobname, + if os.path.isdir(tmpdir): + try: + sys.path.insert(0, tmpdir) + modules = [] + for modulename in modulenames: + exec('import %s as m' % (modulename)) + modules.append(m) + sys.path.pop(0) + return modules + except ImportError: + pass + finally: + sys.path.pop(0) + else: + os.mkdir(tmpdir) + + fname = os.path.join(tmpdir,'%s_src%s' % (jobname, source_ext)) + + f = open(fname,'w') + f.write(source) + f.close() + + sys_argv = [] + sys_argv.extend(['--build-dir',tmpdir]) + #sys_argv.extend(['-DF2PY_DEBUG_PYOBJ_TOFROM']) + sys_argv.extend(['-m',jobname, fname]) + + build_extension(sys_argv + extra_args) + + sys.path.insert(0, tmpdir) + modules = [] + for modulename in modulenames: + exec('import %s as m' % (modulename)) + modules.append(m) + sys.path.pop(0) + return modules + +#EOF diff --git a/numpy/f2py/lib/nary.py b/numpy/f2py/lib/nary.py new file mode 100644 index 000000000..948672b8c --- /dev/null +++ b/numpy/f2py/lib/nary.py @@ -0,0 +1,32 @@ +""" +nary - convert integer to a number with an arbitrary base. +""" + +__all__ = ['nary'] + +_alphabet='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' +def _getalpha(r): + if r>=len(_alphabet): + return '_'+nary(r-len(_alphabet),len(_alphabet)) + return _alphabet[r] + +def nary(number, base=64): + """ + Return string representation of a number with a given base. + """ + if isinstance(number, str): + number = eval(number) + n = number + s = '' + while n: + n1 = n // base + r = n - n1*base + n = n1 + s = _getalpha(r) + s + return s + +def encode(string): + import md5 + return nary('0x'+md5.new(string).hexdigest()) + +#print nary(12345124254252525522512324,64) diff --git a/numpy/f2py/lib/test_module_module.py b/numpy/f2py/lib/test_module_module.py deleted file mode 100644 index d567dce20..000000000 --- a/numpy/f2py/lib/test_module_module.py +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env python -""" -Tests for module with scalar derived types and subprograms. - ------ -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. See http://scipy.org. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -Author: Pearu Peterson <pearu@cens.ioc.ee> -Created: Oct 2006 ------ -""" - -import os -import sys -from numpy.testing import * - -def build(fortran_code, rebuild=True, build_dir = 'tmp'): - modulename = os.path.splitext(os.path.basename(__file__))[0] + '_ext' - try: - exec ('import %s as m' % (modulename)) - if rebuild and os.stat(m.__file__)[8] < os.stat(__file__)[8]: - del sys.modules[m.__name__] # soft unload extension module - os.remove(m.__file__) - raise ImportError,'%s is newer than %s' % (__file__, m.__file__) - except ImportError,msg: - assert str(msg)==('No module named %s' % (modulename)) \ - or str(msg).startswith('%s is newer than' % (__file__)),str(msg) - print msg, ', recompiling %s.' % (modulename) - if not os.path.isdir(build_dir): os.makedirs(build_dir) - fname = os.path.join(build_dir, modulename + '_source.f90') - f = open(fname,'w') - f.write(fortran_code) - f.close() - sys_argv = [] - sys_argv.extend(['--build-dir',build_dir]) - #sys_argv.extend(['-DF2PY_DEBUG_PYOBJ_TOFROM']) - from main import build_extension - sys_argv.extend(['-m',modulename, fname]) - build_extension(sys_argv) - status = os.system(' '.join([sys.executable] + sys.argv)) - sys.exit(status) - return m - -fortran_code = ''' -module test_module_module_ext2 - type rat - integer n,d - end type rat - contains - subroutine foo2() - print*,"In foo2" - end subroutine foo2 -end module -module test_module_module_ext - contains - subroutine foo - use test_module_module_ext2 - print*,"In foo" - call foo2 - end subroutine foo - subroutine bar(a) - use test_module_module_ext2 - type(rat) a - print*,"In bar,a=",a - end subroutine bar -end module test_module_module_ext -''' - -# tester note: set rebuild=True when changing fortan_code and for SVN -m = build(fortran_code, rebuild=True) - -from numpy import * - -class test_m(NumpyTestCase): - - def check_foo_simple(self, level=1): - foo = m.foo - foo() - -if __name__ == "__main__": - NumpyTest().run() diff --git a/numpy/f2py/lib/test_module_scalar.py b/numpy/f2py/lib/test_module_scalar.py deleted file mode 100644 index cd04a0b23..000000000 --- a/numpy/f2py/lib/test_module_scalar.py +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env python -""" -Tests for module with scalar derived types and subprograms. - ------ -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. See http://scipy.org. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -Author: Pearu Peterson <pearu@cens.ioc.ee> -Created: Oct 2006 ------ -""" - -import os -import sys -from numpy.testing import * - -def build(fortran_code, rebuild=True): - modulename = os.path.splitext(os.path.basename(__file__))[0] + '_ext' - try: - exec ('import %s as m' % (modulename)) - if rebuild and os.stat(m.__file__)[8] < os.stat(__file__)[8]: - del sys.modules[m.__name__] # soft unload extension module - os.remove(m.__file__) - raise ImportError,'%s is newer than %s' % (__file__, m.__file__) - except ImportError,msg: - assert str(msg)==('No module named %s' % (modulename)),str(msg) - print msg, ', recompiling %s.' % (modulename) - import tempfile - fname = tempfile.mktemp() + '.f90' - f = open(fname,'w') - f.write(fortran_code) - f.close() - sys_argv = [] - sys_argv.extend(['--build-dir','tmp']) - #sys_argv.extend(['-DF2PY_DEBUG_PYOBJ_TOFROM']) - from main import build_extension - sys_argv.extend(['-m',modulename, fname]) - build_extension(sys_argv) - os.remove(fname) - status = os.system(' '.join([sys.executable] + sys.argv)) - sys.exit(status) - return m - -fortran_code = ''' -module test_module_scalar_ext - - contains - subroutine foo(a) - integer a -!f2py intent(in,out) a - a = a + 1 - end subroutine foo - function foo2(a) - integer a - integer foo2 - foo2 = a + 2 - end function foo2 -end module test_module_scalar_ext -''' - -# tester note: set rebuild=True when changing fortan_code and for SVN -m = build(fortran_code, rebuild=True) - -from numpy import * - -class test_m(NumpyTestCase): - - def check_foo_simple(self, level=1): - foo = m.foo - r = foo(2) - assert isinstance(r,int32),`type(r)` - assert_equal(r,3) - - def check_foo2_simple(self, level=1): - foo2 = m.foo2 - r = foo2(2) - assert isinstance(r,int32),`type(r)` - assert_equal(r,4) - -if __name__ == "__main__": - NumpyTest().run() diff --git a/numpy/f2py/lib/test_derived_scalar.py b/numpy/f2py/lib/tests/test_derived_scalar.py index 5e6ff249f..c57778020 100644 --- a/numpy/f2py/lib/test_derived_scalar.py +++ b/numpy/f2py/lib/tests/test_derived_scalar.py @@ -15,33 +15,9 @@ Created: Oct 2006 import os import sys from numpy.testing import * - -def build(fortran_code, rebuild=True): - modulename = os.path.splitext(os.path.basename(__file__))[0]+'_ext' - try: - exec ('import %s as m' % (modulename)) - if rebuild and os.stat(m.__file__)[8] < os.stat(__file__)[8]: - del sys.modules[m.__name__] # soft unload extension module - os.remove(m.__file__) - raise ImportError,'%s is newer than %s' % (__file__, m.__file__) - except ImportError,msg: - assert str(msg).startswith('No module named'),str(msg) - print msg, ', recompiling %s.' % (modulename) - import tempfile - fname = tempfile.mktemp() + '.f90' - f = open(fname,'w') - f.write(fortran_code) - f.close() - sys_argv = [] - sys_argv.extend(['--build-dir','tmp']) - #sys_argv.extend(['-DF2PY_DEBUG_PYOBJ_TOFROM']) - from main import build_extension - sys_argv.extend(['-m',modulename, fname]) - build_extension(sys_argv) - os.remove(fname) - status = os.system(' '.join([sys.executable] + sys.argv)) - sys.exit(status) - return m +set_package_path() +from lib.main import build_extension, compile +restore_path() fortran_code = ''' subroutine foo(a) @@ -62,8 +38,7 @@ function foo2(a) end ''' -# tester note: set rebuild=True when changing fortan_code and for SVN -m = build(fortran_code, rebuild=True) +m, = compile(fortran_code, 'test_derived_scalar_ext') from numpy import * diff --git a/numpy/f2py/lib/tests/test_module_module.py b/numpy/f2py/lib/tests/test_module_module.py new file mode 100644 index 000000000..4d242ed54 --- /dev/null +++ b/numpy/f2py/lib/tests/test_module_module.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python +""" +Tests for module with scalar derived types and subprograms. + +----- +Permission to use, modify, and distribute this software is given under the +terms of the NumPy License. See http://scipy.org. + +NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. +Author: Pearu Peterson <pearu@cens.ioc.ee> +Created: Oct 2006 +----- +""" + +import os +import sys +from numpy.testing import * + +set_package_path() +from lib.main import build_extension, compile +restore_path() + +fortran_code = ''' +module test_module_module_ext2 + type rat + integer n,d + end type rat + contains + subroutine foo2() + print*,"In foo2" + end subroutine foo2 +end module +module test_module_module_ext + contains + subroutine foo + use test_module_module_ext2 + print*,"In foo" + call foo2 + end subroutine foo + subroutine bar(a) + use test_module_module_ext2 + type(rat) a + print*,"In bar,a=",a + end subroutine bar +end module test_module_module_ext +''' + +m,m2 = compile(fortran_code, modulenames=['test_module_module_ext', + 'test_module_module_ext2', + ]) + +from numpy import * + +class test_m(NumpyTestCase): + + def check_foo_simple(self, level=1): + foo = m.foo + foo() + +if __name__ == "__main__": + NumpyTest().run() diff --git a/numpy/f2py/lib/tests/test_module_scalar.py b/numpy/f2py/lib/tests/test_module_scalar.py new file mode 100644 index 000000000..e11a1e0ae --- /dev/null +++ b/numpy/f2py/lib/tests/test_module_scalar.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python +""" +Tests for module with scalar derived types and subprograms. + +----- +Permission to use, modify, and distribute this software is given under the +terms of the NumPy License. See http://scipy.org. + +NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. +Author: Pearu Peterson <pearu@cens.ioc.ee> +Created: Oct 2006 +----- +""" + +import os +import sys +from numpy.testing import * +set_package_path() +from lib.main import build_extension, compile +restore_path() + +fortran_code = ''' +module test_module_scalar_ext + + contains + subroutine foo(a) + integer a +!f2py intent(in,out) a + a = a + 1 + end subroutine foo + function foo2(a) + integer a + integer foo2 + foo2 = a + 2 + end function foo2 +end module test_module_scalar_ext +''' + +m, = compile(fortran_code, modulenames = ['test_module_scalar_ext']) + +from numpy import * + +class test_m(NumpyTestCase): + + def check_foo_simple(self, level=1): + foo = m.foo + r = foo(2) + assert isinstance(r,int32),`type(r)` + assert_equal(r,3) + + def check_foo2_simple(self, level=1): + foo2 = m.foo2 + r = foo2(2) + assert isinstance(r,int32),`type(r)` + assert_equal(r,4) + +if __name__ == "__main__": + NumpyTest().run() diff --git a/numpy/f2py/lib/test_scalar_function_in.py b/numpy/f2py/lib/tests/test_scalar_function_in.py index 7c2539fe5..9c5cd8aba 100644 --- a/numpy/f2py/lib/test_scalar_function_in.py +++ b/numpy/f2py/lib/tests/test_scalar_function_in.py @@ -16,33 +16,12 @@ import os import sys from numpy.testing import * -def build(fortran_code, rebuild=True): - modulename = os.path.splitext(os.path.basename(__file__))[0]+'_ext' - try: - exec ('import %s as m' % (modulename)) - if rebuild and os.stat(m.__file__)[8] < os.stat(__file__)[8]: - del sys.modules[m.__name__] # soft unload extension module - os.remove(m.__file__) - raise ImportError,'%s is newer than %s' % (__file__, m.__file__) - except ImportError,msg: - assert str(msg).startswith('No module named'),str(msg) - print msg, ', recompiling %s.' % (modulename) - import tempfile - fname = tempfile.mktemp() + '.f' - f = open(fname,'w') - f.write(fortran_code) - f.close() - sys_argv = ['--build-dir','tmp'] - #sys_argv.extend(['-DF2PY_DEBUG_PYOBJ_TOFROM']) - from main import build_extension - sys_argv.extend(['-m',modulename, fname]) - build_extension(sys_argv) - os.remove(fname) - os.system(' '.join([sys.executable] + sys.argv)) - sys.exit(0) - return m - -fortran_code = ''' +set_package_path() +from lib.main import build_extension, compile +restore_path() + +fortran_code = '''\ +! -*- f77 -*- function fooint1(a) integer*1 a integer*1 fooint1 @@ -124,8 +103,7 @@ fortran_code = ''' ! end ''' -# tester note: set rebuild=True when changing fortan_code and for SVN -m = build(fortran_code, rebuild=True) +m, = compile(fortran_code, 'test_scalar_function_in_ext') from numpy import * diff --git a/numpy/f2py/lib/test_scalar_in_out.py b/numpy/f2py/lib/tests/test_scalar_in_out.py index 37cf4d8d9..b73036848 100644 --- a/numpy/f2py/lib/test_scalar_in_out.py +++ b/numpy/f2py/lib/tests/test_scalar_in_out.py @@ -16,31 +16,9 @@ import os import sys from numpy.testing import * -def build(fortran_code, rebuild=True, build_dir='tmp'): - modulename = os.path.splitext(os.path.basename(__file__))[0]+'_ext' - try: - exec ('import %s as m' % (modulename)) - if rebuild and os.stat(m.__file__)[8] < os.stat(__file__)[8]: - del sys.modules[m.__name__] # soft unload extension module - os.remove(m.__file__) - raise ImportError,'%s is newer than %s' % (__file__, m.__file__) - except ImportError,msg: - assert str(msg)==('No module named %s' % (modulename)) \ - or str(msg).startswith('%s is newer than' % (__file__)),str(msg) - print msg, ', recompiling %s.' % (modulename) - if not os.path.isdir(build_dir): os.makedirs(build_dir) - fname = os.path.join(build_dir,'%s_source.f' % (modulename)) - f = open(fname,'w') - f.write(fortran_code) - f.close() - sys_argv = ['--build-dir',build_dir] - #sys_argv.extend(['-DF2PY_DEBUG_PYOBJ_TOFROM']) - from main import build_extension - sys_argv.extend(['-m',modulename, fname]) - build_extension(sys_argv) - status = os.system(' '.join([sys.executable] + sys.argv)) - sys.exit(status) - return m +set_package_path() +from lib.main import build_extension, compile +restore_path() fortran_code = ''' subroutine fooint1(a) @@ -122,8 +100,7 @@ fortran_code = ''' end ''' -# tester note: set rebuild=True when changing fortan_code and for SVN -m = build(fortran_code, rebuild=True) +m, = compile(fortran_code, 'test_scalar_in_out_ext', source_ext = '.f') from numpy import * |