Spaces:
Sleeping
Sleeping
| #!/usr/bin/env python3 | |
| """Fortran to Python Interface Generator. | |
| """ | |
| __all__ = ['run_main', 'compile', 'get_include', 'f2py_testing'] | |
| import sys | |
| import subprocess | |
| import os | |
| from . import f2py2e | |
| 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', | |
| full_output=False | |
| ): | |
| """ | |
| 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 | |
| full_output : bool, optional | |
| If True, return a `subprocess.CompletedProcess` containing | |
| the stdout and stderr of the compile process, instead of just | |
| the status code. | |
| .. versionadded:: 1.20.0 | |
| Returns | |
| ------- | |
| result : int or `subprocess.CompletedProcess` | |
| 0 on success, or a `subprocess.CompletedProcess` if | |
| ``full_output=True`` | |
| 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: | |
| cp = subprocess.run(c, stdout=subprocess.PIPE, | |
| stderr=subprocess.PIPE) | |
| except OSError: | |
| # preserve historic status code used by exec_command() | |
| cp = subprocess.CompletedProcess(c, 127, stdout=b'', stderr=b'') | |
| else: | |
| if verbose: | |
| print(cp.stdout.decode()) | |
| finally: | |
| if source_fn is None: | |
| os.remove(fname) | |
| if full_output: | |
| return cp | |
| else: | |
| return cp.returncode | |
| def get_include(): | |
| """ | |
| Return the directory that contains the fortranobject.c and .h files. | |
| .. note:: | |
| This function is not needed when building an extension with | |
| `numpy.distutils` directly from ``.f`` and/or ``.pyf`` files | |
| in one go. | |
| Python extension modules built with f2py-generated code need to use | |
| ``fortranobject.c`` as a source file, and include the ``fortranobject.h`` | |
| header. This function can be used to obtain the directory containing | |
| both of these files. | |
| Returns | |
| ------- | |
| include_path : str | |
| Absolute path to the directory containing ``fortranobject.c`` and | |
| ``fortranobject.h``. | |
| Notes | |
| ----- | |
| .. versionadded:: 1.22.0 | |
| Unless the build system you are using has specific support for f2py, | |
| building a Python extension using a ``.pyf`` signature file is a two-step | |
| process. For a module ``mymod``: | |
| - Step 1: run ``python -m numpy.f2py mymod.pyf --quiet``. This | |
| generates ``_mymodmodule.c`` and (if needed) | |
| ``_fblas-f2pywrappers.f`` files next to ``mymod.pyf``. | |
| - Step 2: build your Python extension module. This requires the | |
| following source files: | |
| - ``_mymodmodule.c`` | |
| - ``_mymod-f2pywrappers.f`` (if it was generated in step 1) | |
| - ``fortranobject.c`` | |
| See Also | |
| -------- | |
| numpy.get_include : function that returns the numpy include directory | |
| """ | |
| return os.path.join(os.path.dirname(__file__), 'src') | |
| if sys.version_info[:2] >= (3, 7): | |
| # module level getattr is only supported in 3.7 onwards | |
| # https://www.python.org/dev/peps/pep-0562/ | |
| def __getattr__(attr): | |
| # Avoid importing things that aren't needed for building | |
| # which might import the main numpy module | |
| if attr == "f2py_testing": | |
| import numpy.f2py.f2py_testing as f2py_testing | |
| return f2py_testing | |
| elif attr == "test": | |
| from numpy._pytesttester import PytestTester | |
| test = PytestTester(__name__) | |
| return test | |
| else: | |
| raise AttributeError("module {!r} has no attribute " | |
| "{!r}".format(__name__, attr)) | |
| def __dir__(): | |
| return list(globals().keys() | {"f2py_testing", "test"}) | |
| else: | |
| from . import f2py_testing | |
| from numpy._pytesttester import PytestTester | |
| test = PytestTester(__name__) | |
| del PytestTester | |