summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--numpy/f2py/lib/main.py112
-rw-r--r--numpy/f2py/lib/nary.py32
-rw-r--r--numpy/f2py/lib/test_module_module.py83
-rw-r--r--numpy/f2py/lib/test_module_scalar.py83
-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.py61
-rw-r--r--numpy/f2py/lib/tests/test_module_scalar.py58
-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 *