Spaces:
Running
Running
File size: 5,964 Bytes
dc2106c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
#!/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
|