__init__.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. #!/usr/bin/env python3
  2. """Fortran to Python Interface Generator.
  3. Copyright 1999 -- 2011 Pearu Peterson all rights reserved.
  4. Copyright 2011 -- present NumPy Developers.
  5. Permission to use, modify, and distribute this software is given under the terms
  6. of the NumPy License.
  7. NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
  8. """
  9. __all__ = ['run_main', 'compile', 'get_include']
  10. import sys
  11. import subprocess
  12. import os
  13. import warnings
  14. from numpy.exceptions import VisibleDeprecationWarning
  15. from . import f2py2e
  16. from . import diagnose
  17. run_main = f2py2e.run_main
  18. main = f2py2e.main
  19. def compile(source,
  20. modulename='untitled',
  21. extra_args='',
  22. verbose=True,
  23. source_fn=None,
  24. extension='.f',
  25. full_output=False
  26. ):
  27. """
  28. Build extension module from a Fortran 77 source string with f2py.
  29. Parameters
  30. ----------
  31. source : str or bytes
  32. Fortran source of module / subroutine to compile
  33. .. versionchanged:: 1.16.0
  34. Accept str as well as bytes
  35. modulename : str, optional
  36. The name of the compiled python module
  37. extra_args : str or list, optional
  38. Additional parameters passed to f2py
  39. .. versionchanged:: 1.16.0
  40. A list of args may also be provided.
  41. verbose : bool, optional
  42. Print f2py output to screen
  43. source_fn : str, optional
  44. Name of the file where the fortran source is written.
  45. The default is to use a temporary file with the extension
  46. provided by the ``extension`` parameter
  47. extension : ``{'.f', '.f90'}``, optional
  48. Filename extension if `source_fn` is not provided.
  49. The extension tells which fortran standard is used.
  50. The default is ``.f``, which implies F77 standard.
  51. .. versionadded:: 1.11.0
  52. full_output : bool, optional
  53. If True, return a `subprocess.CompletedProcess` containing
  54. the stdout and stderr of the compile process, instead of just
  55. the status code.
  56. .. versionadded:: 1.20.0
  57. Returns
  58. -------
  59. result : int or `subprocess.CompletedProcess`
  60. 0 on success, or a `subprocess.CompletedProcess` if
  61. ``full_output=True``
  62. Examples
  63. --------
  64. .. literalinclude:: ../../source/f2py/code/results/compile_session.dat
  65. :language: python
  66. """
  67. import tempfile
  68. import shlex
  69. if source_fn is None:
  70. f, fname = tempfile.mkstemp(suffix=extension)
  71. # f is a file descriptor so need to close it
  72. # carefully -- not with .close() directly
  73. os.close(f)
  74. else:
  75. fname = source_fn
  76. if not isinstance(source, str):
  77. source = str(source, 'utf-8')
  78. try:
  79. with open(fname, 'w') as f:
  80. f.write(source)
  81. args = ['-c', '-m', modulename, f.name]
  82. if isinstance(extra_args, str):
  83. is_posix = (os.name == 'posix')
  84. extra_args = shlex.split(extra_args, posix=is_posix)
  85. args.extend(extra_args)
  86. c = [sys.executable,
  87. '-c',
  88. 'import numpy.f2py as f2py2e;f2py2e.main()'] + args
  89. try:
  90. cp = subprocess.run(c, capture_output=True)
  91. except OSError:
  92. # preserve historic status code used by exec_command()
  93. cp = subprocess.CompletedProcess(c, 127, stdout=b'', stderr=b'')
  94. else:
  95. if verbose:
  96. print(cp.stdout.decode())
  97. finally:
  98. if source_fn is None:
  99. os.remove(fname)
  100. if full_output:
  101. return cp
  102. else:
  103. return cp.returncode
  104. def get_include():
  105. """
  106. Return the directory that contains the ``fortranobject.c`` and ``.h`` files.
  107. .. note::
  108. This function is not needed when building an extension with
  109. `numpy.distutils` directly from ``.f`` and/or ``.pyf`` files
  110. in one go.
  111. Python extension modules built with f2py-generated code need to use
  112. ``fortranobject.c`` as a source file, and include the ``fortranobject.h``
  113. header. This function can be used to obtain the directory containing
  114. both of these files.
  115. Returns
  116. -------
  117. include_path : str
  118. Absolute path to the directory containing ``fortranobject.c`` and
  119. ``fortranobject.h``.
  120. Notes
  121. -----
  122. .. versionadded:: 1.21.1
  123. Unless the build system you are using has specific support for f2py,
  124. building a Python extension using a ``.pyf`` signature file is a two-step
  125. process. For a module ``mymod``:
  126. * Step 1: run ``python -m numpy.f2py mymod.pyf --quiet``. This
  127. generates ``_mymodmodule.c`` and (if needed)
  128. ``_fblas-f2pywrappers.f`` files next to ``mymod.pyf``.
  129. * Step 2: build your Python extension module. This requires the
  130. following source files:
  131. * ``_mymodmodule.c``
  132. * ``_mymod-f2pywrappers.f`` (if it was generated in Step 1)
  133. * ``fortranobject.c``
  134. See Also
  135. --------
  136. numpy.get_include : function that returns the numpy include directory
  137. """
  138. return os.path.join(os.path.dirname(__file__), 'src')
  139. def __getattr__(attr):
  140. # Avoid importing things that aren't needed for building
  141. # which might import the main numpy module
  142. if attr == "test":
  143. from numpy._pytesttester import PytestTester
  144. test = PytestTester(__name__)
  145. return test
  146. else:
  147. raise AttributeError("module {!r} has no attribute "
  148. "{!r}".format(__name__, attr))
  149. def __dir__():
  150. return list(globals().keys() | {"test"})