summaryrefslogtreecommitdiff
path: root/doc/source
diff options
context:
space:
mode:
authorJonathan Deng <jonathan.j.deng@gmail.com>2022-03-02 21:19:16 -0500
committerJonathan Deng <jonathan.j.deng@gmail.com>2022-03-02 21:19:16 -0500
commite5214e2253ce9e4204932fa018bf6a84b77920bc (patch)
tree1d096951bbbd1870b5f88aecda60d6e2a662ecb3 /doc/source
parent12582800d2ec69957e4f28b089bffc772c92a721 (diff)
parent13e8ace9f1f87d1cc8fcca0124571454b06fae1e (diff)
downloadnumpy-e5214e2253ce9e4204932fa018bf6a84b77920bc.tar.gz
Merge branch 'main' into fix-sphinx-doc-errors
Diffstat (limited to 'doc/source')
-rw-r--r--doc/source/f2py/code/add-edited.pyf6
-rw-r--r--doc/source/f2py/code/add-improved.f16
-rw-r--r--doc/source/f2py/code/add.f11
-rw-r--r--doc/source/f2py/code/add.pyf6
-rw-r--r--doc/source/f2py/code/filter.f19
-rw-r--r--doc/source/f2py/code/myroutine-edited.pyf17
-rw-r--r--doc/source/f2py/code/myroutine.f9010
-rw-r--r--doc/source/f2py/code/myroutine.pyf17
-rw-r--r--doc/source/f2py/f2py-examples.rst245
-rw-r--r--doc/source/f2py/f2py-reference.rst12
-rw-r--r--doc/source/f2py/f2py-user.rst11
-rw-r--r--doc/source/f2py/f2py.getting-started.rst110
-rw-r--r--doc/source/f2py/index.rst34
-rw-r--r--doc/source/f2py/python-usage.rst276
-rw-r--r--doc/source/f2py/signature-file.rst146
-rw-r--r--doc/source/f2py/usage.rst425
-rw-r--r--doc/source/glossary.rst34
-rw-r--r--doc/source/reference/arrays.datetime.rst129
-rw-r--r--doc/source/reference/arrays.ndarray.rst17
-rw-r--r--doc/source/reference/distutils.rst5
-rw-r--r--doc/source/reference/distutils_guide.rst6
-rw-r--r--doc/source/reference/distutils_status_migration.rst138
-rw-r--r--doc/source/reference/global_state.rst18
-rw-r--r--doc/source/reference/index.rst1
-rw-r--r--doc/source/user/basics.indexing.rst8
-rw-r--r--doc/source/user/c-info.python-as-glue.rst298
26 files changed, 1204 insertions, 811 deletions
diff --git a/doc/source/f2py/code/add-edited.pyf b/doc/source/f2py/code/add-edited.pyf
new file mode 100644
index 000000000..4d2047274
--- /dev/null
+++ b/doc/source/f2py/code/add-edited.pyf
@@ -0,0 +1,6 @@
+subroutine zadd(a,b,c,n) ! in :add:add.f
+ double complex dimension(n) :: a
+ double complex dimension(n) :: b
+ double complex intent(out),dimension(n) :: c
+ integer intent(hide),depend(a) :: n=len(a)
+end subroutine zadd \ No newline at end of file
diff --git a/doc/source/f2py/code/add-improved.f b/doc/source/f2py/code/add-improved.f
new file mode 100644
index 000000000..65f70c9bc
--- /dev/null
+++ b/doc/source/f2py/code/add-improved.f
@@ -0,0 +1,16 @@
+C
+ SUBROUTINE ZADD(A,B,C,N)
+C
+CF2PY INTENT(OUT) :: C
+CF2PY INTENT(HIDE) :: N
+CF2PY DOUBLE COMPLEX :: A(N)
+CF2PY DOUBLE COMPLEX :: B(N)
+CF2PY DOUBLE COMPLEX :: C(N)
+ DOUBLE COMPLEX A(*)
+ DOUBLE COMPLEX B(*)
+ DOUBLE COMPLEX C(*)
+ INTEGER N
+ DO 20 J = 1, N
+ C(J) = A(J) + B(J)
+ 20 CONTINUE
+ END \ No newline at end of file
diff --git a/doc/source/f2py/code/add.f b/doc/source/f2py/code/add.f
new file mode 100644
index 000000000..5e7556b28
--- /dev/null
+++ b/doc/source/f2py/code/add.f
@@ -0,0 +1,11 @@
+C
+ SUBROUTINE ZADD(A,B,C,N)
+C
+ DOUBLE COMPLEX A(*)
+ DOUBLE COMPLEX B(*)
+ DOUBLE COMPLEX C(*)
+ INTEGER N
+ DO 20 J = 1, N
+ C(J) = A(J)+B(J)
+ 20 CONTINUE
+ END
diff --git a/doc/source/f2py/code/add.pyf b/doc/source/f2py/code/add.pyf
new file mode 100644
index 000000000..d2583e333
--- /dev/null
+++ b/doc/source/f2py/code/add.pyf
@@ -0,0 +1,6 @@
+subroutine zadd(a,b,c,n) ! in :add:add.f
+ double complex dimension(*) :: a
+ double complex dimension(*) :: b
+ double complex dimension(*) :: c
+ integer :: n
+end subroutine zadd \ No newline at end of file
diff --git a/doc/source/f2py/code/filter.f b/doc/source/f2py/code/filter.f
new file mode 100644
index 000000000..fb44343fa
--- /dev/null
+++ b/doc/source/f2py/code/filter.f
@@ -0,0 +1,19 @@
+C
+ SUBROUTINE DFILTER2D(A,B,M,N)
+C
+ DOUBLE PRECISION A(M,N)
+ DOUBLE PRECISION B(M,N)
+ INTEGER N, M
+CF2PY INTENT(OUT) :: B
+CF2PY INTENT(HIDE) :: N
+CF2PY INTENT(HIDE) :: M
+ DO 20 I = 2,M-1
+ DO 40 J = 2,N-1
+ B(I,J) = A(I,J) +
+ & (A(I-1,J)+A(I+1,J) +
+ & A(I,J-1)+A(I,J+1) )*0.5D0 +
+ & (A(I-1,J-1) + A(I-1,J+1) +
+ & A(I+1,J-1) + A(I+1,J+1))*0.25D0
+ 40 CONTINUE
+ 20 CONTINUE
+ END
diff --git a/doc/source/f2py/code/myroutine-edited.pyf b/doc/source/f2py/code/myroutine-edited.pyf
new file mode 100644
index 000000000..14e455416
--- /dev/null
+++ b/doc/source/f2py/code/myroutine-edited.pyf
@@ -0,0 +1,17 @@
+! -*- f90 -*-
+! Note: the context of this file is case sensitive.
+
+python module myroutine ! in
+ interface ! in :myroutine
+ subroutine s(n,m,c,x) ! in :myroutine:myroutine.f90
+ integer intent(in) :: n
+ integer intent(in) :: m
+ real(kind=8) dimension(:),intent(in) :: c
+ real(kind=8) dimension(n,m),intent(out) :: x
+ end subroutine s
+ end interface
+end python module myroutine
+
+! This file was auto-generated with f2py (version:1.23.0.dev0+120.g4da01f42d).
+! See:
+! https://web.archive.org/web/20140822061353/http://cens.ioc.ee/projects/f2py2e \ No newline at end of file
diff --git a/doc/source/f2py/code/myroutine.f90 b/doc/source/f2py/code/myroutine.f90
new file mode 100644
index 000000000..592796a6a
--- /dev/null
+++ b/doc/source/f2py/code/myroutine.f90
@@ -0,0 +1,10 @@
+subroutine s(n, m, c, x)
+ implicit none
+ integer, intent(in) :: n, m
+ real(kind=8), intent(out), dimension(n,m) :: x
+ real(kind=8), intent(in) :: c(:)
+
+ x = 0.0d0
+ x(1, 1) = c(1)
+
+end subroutine s \ No newline at end of file
diff --git a/doc/source/f2py/code/myroutine.pyf b/doc/source/f2py/code/myroutine.pyf
new file mode 100644
index 000000000..ef8f16789
--- /dev/null
+++ b/doc/source/f2py/code/myroutine.pyf
@@ -0,0 +1,17 @@
+! -*- f90 -*-
+! Note: the context of this file is case sensitive.
+
+python module myroutine ! in
+ interface ! in :myroutine
+ subroutine s(n,m,c,x) ! in :myroutine:myroutine.f90
+ integer intent(in) :: n
+ integer intent(in) :: m
+ real(kind=8) dimension(:),intent(in) :: c
+ real(kind=8) dimension(n,m),intent(out),depend(m,n) :: x
+ end subroutine s
+ end interface
+end python module myroutine
+
+! This file was auto-generated with f2py (version:1.23.0.dev0+120.g4da01f42d).
+! See:
+! https://web.archive.org/web/20140822061353/http://cens.ioc.ee/projects/f2py2e \ No newline at end of file
diff --git a/doc/source/f2py/f2py-examples.rst b/doc/source/f2py/f2py-examples.rst
new file mode 100644
index 000000000..8dcdec075
--- /dev/null
+++ b/doc/source/f2py/f2py-examples.rst
@@ -0,0 +1,245 @@
+.. _f2py-examples:
+
+F2PY examples
+=============
+
+Below are some examples of F2PY usage. This list is not comprehensive, but can
+be used as a starting point when wrapping your own code.
+
+F2PY walkthrough: a basic extension module
+------------------------------------------
+
+Creating source for a basic extension module
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Consider the following subroutine, contained in a file named :file:`add.f`
+
+.. literalinclude:: ./code/add.f
+ :language: fortran
+
+This routine simply adds the elements in two contiguous arrays and places the
+result in a third. The memory for all three arrays must be provided by the
+calling routine. A very basic interface to this routine can be automatically
+generated by f2py::
+
+ python -m numpy.f2py -m add add.f
+
+This command will produce an extension module named :file:`addmodule.c` in the
+current directory. This extension module can now be compiled and used from
+Python just like any other extension module.
+
+Creating a compiled extension module
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. note::
+
+ This usage depends heavily on ``numpy.distutils``, see :ref:`f2py-bldsys`
+ for more details.
+
+You can also get f2py to both compile :file:`add.f` along with the produced
+extension module leaving only a shared-library extension file that can
+be imported from Python::
+
+ python -m numpy.f2py -c -m add add.f
+
+This command produces a Python extension module compatible with your platform.
+This module may then be imported from Python. It will contain a method for each
+subroutine in ``add``. The docstring of each method contains information about
+how the module method may be called:
+
+.. code-block:: python
+
+ >>> import add
+ >>> print(add.zadd.__doc__)
+ zadd(a,b,c,n)
+
+ Wrapper for ``zadd``.
+
+ Parameters
+ ----------
+ a : input rank-1 array('D') with bounds (*)
+ b : input rank-1 array('D') with bounds (*)
+ c : input rank-1 array('D') with bounds (*)
+ n : input int
+
+Improving the basic interface
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The default interface is a very literal translation of the Fortran code into
+Python. The Fortran array arguments are converted to NumPy arrays and the
+integer argument should be mapped to a ``C`` integer. The interface will attempt
+to convert all arguments to their required types (and shapes) and issue an error
+if unsuccessful. However, because ``f2py`` knows nothing about the semantics of
+the arguments (such that ``C`` is an output and ``n`` should really match the
+array sizes), it is possible to abuse this function in ways that can cause
+Python to crash. For example:
+
+.. code-block:: python
+
+ >>> add.zadd([1, 2, 3], [1, 2], [3, 4], 1000)
+
+will cause a program crash on most systems. Under the hood, the lists are being
+converted to arrays but then the underlying ``add`` function is told to cycle
+way beyond the borders of the allocated memory.
+
+In order to improve the interface, ``f2py`` supports directives. This is
+accomplished by constructing a signature file. It is usually best to start from
+the interfaces that ``f2py`` produces in that file, which correspond to the
+default behavior. To get ``f2py`` to generate the interface file use the ``-h``
+option::
+
+ python -m numpy.f2py -h add.pyf -m add add.f
+
+This command creates the ``add.pyf`` file in the current directory. The section
+of this file corresponding to ``zadd`` is:
+
+.. literalinclude:: ./code/add.pyf
+ :language: fortran
+
+By placing intent directives and checking code, the interface can be cleaned up
+quite a bit so the Python module method is both easier to use and more robust to
+malformed inputs.
+
+.. literalinclude:: ./code/add-edited.pyf
+ :language: fortran
+
+The intent directive, intent(out) is used to tell f2py that ``c`` is
+an output variable and should be created by the interface before being
+passed to the underlying code. The intent(hide) directive tells f2py
+to not allow the user to specify the variable, ``n``, but instead to
+get it from the size of ``a``. The depend( ``a`` ) directive is
+necessary to tell f2py that the value of n depends on the input a (so
+that it won't try to create the variable n until the variable a is
+created).
+
+After modifying ``add.pyf``, the new Python module file can be generated
+by compiling both ``add.f`` and ``add.pyf``::
+
+ python -m numpy.f2py -c add.pyf add.f
+
+The new interface's docstring is:
+
+.. code-block:: python
+
+ >>> import add
+ >>> print(add.zadd.__doc__)
+ c = zadd(a,b)
+
+ Wrapper for ``zadd``.
+
+ Parameters
+ ----------
+ a : input rank-1 array('D') with bounds (n)
+ b : input rank-1 array('D') with bounds (n)
+
+ Returns
+ -------
+ c : rank-1 array('D') with bounds (n)
+
+Now, the function can be called in a much more robust way:
+
+.. code-block::
+
+ >>> add.zadd([1, 2, 3], [4, 5, 6])
+ array([5.+0.j, 7.+0.j, 9.+0.j])
+
+Notice the automatic conversion to the correct format that occurred.
+
+Inserting directives in Fortran source
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The robust interface of the previous section can also be generated automatically
+by placing the variable directives as special comments in the original Fortran
+code.
+
+.. note::
+
+ For projects where the Fortran code is being actively developed, this may be
+ preferred.
+
+Thus, if the source code is modified to contain:
+
+.. literalinclude:: ./code/add-improved.f
+ :language: fortran
+
+Then, one can compile the extension module using::
+
+ python -m numpy.f2py -c -m add add.f
+
+The resulting signature for the function add.zadd is exactly the same
+one that was created previously. If the original source code had
+contained ``A(N)`` instead of ``A(*)`` and so forth with ``B`` and ``C``,
+then nearly the same interface can be obtained by placing the
+``INTENT(OUT) :: C`` comment line in the source code. The only difference
+is that ``N`` would be an optional input that would default to the length
+of ``A``.
+
+A filtering example
+-------------------
+
+This example shows a function that filters a two-dimensional array of double
+precision floating-point numbers using a fixed averaging filter. The advantage
+of using Fortran to index into multi-dimensional arrays should be clear from
+this example.
+
+.. literalinclude:: ./code/filter.f
+ :language: fortran
+
+This code can be compiled and linked into an extension module named
+filter using::
+
+ python -m numpy.f2py -c -m filter filter.f
+
+This will produce an extension module in the current directory with a method
+named ``dfilter2d`` that returns a filtered version of the input.
+
+
+``depends`` keyword example
+---------------------------
+
+Consider the following code, saved in the file ``myroutine.f90``:
+
+.. literalinclude:: ./code/myroutine.f90
+ :language: fortran
+
+Wrapping this with ``python -m numpy.f2py -c myroutine.f90 -m myroutine``, we
+can do the following in Python::
+
+ >>> import numpy as np
+ >>> import myroutine
+ >>> x = myroutine.s(2, 3, np.array([5, 6, 7]))
+ >>> x
+ array([[5., 0., 0.],
+ [0., 0., 0.]])
+
+Now, instead of generating the extension module directly, we will create a
+signature file for this subroutine first. This is a common pattern for
+multi-step extension module generation. In this case, after running
+
+.. code-block:: python
+
+ python -m numpy.f2py myroutine.f90 -h myroutine.pyf
+
+the following signature file is generated:
+
+.. literalinclude:: ./code/myroutine.pyf
+ :language: fortran
+
+Now, if we run ``python -m numpy.f2py -c myroutine.pyf myroutine.f90`` we see an
+error; note that the signature file included a ``depend(m,n)`` statement for
+``x`` which is not necessary. Indeed, editing the file above to read
+
+.. literalinclude:: ./code/myroutine-edited.pyf
+ :language: fortran
+
+and running ``f2py -c myroutine.pyf myroutine.f90`` yields correct results.
+
+
+Read more
+---------
+
+* `Wrapping C codes using f2py <https://scipy.github.io/old-wiki/pages/Cookbook/f2py_and_NumPy.html>`_
+* `F2py section on the SciPy Cookbook <https://scipy-cookbook.readthedocs.io/items/F2Py.html>`_
+* `F2py example: Interactive System for Ice sheet Simulation <http://websrv.cs.umt.edu/isis/index.php/F2py_example>`_
+* `"Interfacing With Other Languages" section on the SciPy Cookbook.
+ <https://scipy-cookbook.readthedocs.io/items/idx_interfacing_with_other_languages.html>`_
diff --git a/doc/source/f2py/f2py-reference.rst b/doc/source/f2py/f2py-reference.rst
new file mode 100644
index 000000000..28db0bfee
--- /dev/null
+++ b/doc/source/f2py/f2py-reference.rst
@@ -0,0 +1,12 @@
+.. _f2py-reference:
+
+F2PY reference manual
+=====================
+
+.. toctree::
+ :maxdepth: 2
+
+ signature-file
+ python-usage
+ buildtools/index
+ advanced
diff --git a/doc/source/f2py/f2py-user.rst b/doc/source/f2py/f2py-user.rst
new file mode 100644
index 000000000..70d4aedd0
--- /dev/null
+++ b/doc/source/f2py/f2py-user.rst
@@ -0,0 +1,11 @@
+.. _f2py-user:
+
+F2PY user guide
+===============
+
+.. toctree::
+ :maxdepth: 2
+
+ f2py.getting-started
+ usage
+ f2py-examples \ No newline at end of file
diff --git a/doc/source/f2py/f2py.getting-started.rst b/doc/source/f2py/f2py.getting-started.rst
index c1a006f6f..da88b46f5 100644
--- a/doc/source/f2py/f2py.getting-started.rst
+++ b/doc/source/f2py/f2py.getting-started.rst
@@ -7,15 +7,14 @@
Wrapping Fortran or C functions to Python using F2PY consists of the
following steps:
-* Creating the so-called signature file that contains descriptions of
- wrappers to Fortran or C functions, also called the signatures of the
- functions. For Fortran routines, F2PY can create an initial
- signature file by scanning Fortran source codes and
- tracking all relevant information needed to create wrapper
- functions.
+* Creating the so-called :doc:`signature file <signature-file>` that contains
+ descriptions of wrappers to Fortran or C functions, also called the signatures
+ of the functions. For Fortran routines, F2PY can create an initial signature
+ file by scanning Fortran source codes and tracking all relevant information
+ needed to create wrapper functions.
- * Optionally, F2PY created signature files can be edited to optimize
- wrapper functions, to make them "smarter" and more "Pythonic".
+ * Optionally, F2PY-created signature files can be edited to optimize wrapper
+ functions, which can make them "smarter" and more "Pythonic".
* F2PY reads a signature file and writes a Python C/API module containing
Fortran/C/Python bindings.
@@ -24,7 +23,8 @@ following steps:
* In building the extension modules, F2PY uses ``numpy_distutils`` which
supports a number of Fortran 77/90/95 compilers, including Gnu, Intel, Sun
- Fortran, SGI MIPSpro, Absoft, NAG, Compaq etc.
+ Fortran, SGI MIPSpro, Absoft, NAG, Compaq etc. For different build systems,
+ see :ref:`f2py-bldsys`.
Depending on the situation, these steps can be carried out in a single composite
command or step-by-step; in which case some steps can be omitted or combined
@@ -40,6 +40,13 @@ illustration, save it as ``fib1.f``:
.. literalinclude:: ./code/fib1.f
:language: fortran
+.. note::
+
+ F2PY parses Fortran/C signatures to build wrapper functions to be used with
+ Python. However, it is not a compiler, and does not check for additional
+ errors in source code, nor does it implement the entire language standards.
+ Some errors may pass silently (or as warnings) and need to be verified by the
+ user.
The quick way
==============
@@ -51,6 +58,18 @@ run
python -m numpy.f2py -c fib1.f -m fib1
+or, alternatively, if the ``f2py`` command-line tool is available,
+
+::
+
+ f2py -c fib1.f -m fib1
+
+.. note::
+
+ Because the ``f2py`` command might not be available in all system, notably on
+ Windows, we will use the ``python -m numpy.f2py`` command throughout this
+ guide.
+
This command compiles and wraps ``fib1.f`` (``-c``) to create the extension
module ``fib1.so`` (``-m``) in the current directory. A list of command line
options can be seen by executing ``python -m numpy.f2py``. Now, in Python the
@@ -103,15 +122,15 @@ Fortran subroutine ``FIB`` is accessible via ``fib1.fib``::
F2PY implements basic compatibility checks between related
arguments in order to avoid unexpected crashes.
- * When a NumPy array, that is Fortran contiguous and has a ``dtype``
- corresponding to a presumed Fortran type, is used as an input array
- argument, then its C pointer is directly passed to Fortran.
+ * When a NumPy array that is :term:`Fortran <Fortran order>`
+ :term:`contiguous` and has a ``dtype`` corresponding to a presumed Fortran
+ type is used as an input array argument, then its C pointer is directly
+ passed to Fortran.
- Otherwise F2PY makes a contiguous copy (with the proper ``dtype``) of
- the input array and passes a C pointer of the copy to the Fortran
- subroutine. As a result, any possible changes to the (copy of)
- input array have no effect to the original argument, as
- demonstrated below::
+ Otherwise, F2PY makes a contiguous copy (with the proper ``dtype``) of the
+ input array and passes a C pointer of the copy to the Fortran subroutine. As
+ a result, any possible changes to the (copy of) input array have no effect
+ on the original argument, as demonstrated below::
>>> a = np.ones(8, 'i')
>>> fib1.fib(a)
@@ -121,11 +140,11 @@ Fortran subroutine ``FIB`` is accessible via ``fib1.fib``::
Clearly, this is unexpected, as Fortran typically passes by reference. That
the above example worked with ``dtype=float`` is considered accidental.
- F2PY provides an ``intent(inplace)`` attribute that modifies
- the attributes of an input array so that any changes made by
- Fortran routine will be reflected in the input argument. For example,
- if one specifies the ``intent(inplace) a`` directive (see subsequent
- sections on how), then the example above would read::
+ F2PY provides an ``intent(inplace)`` attribute that modifies the attributes
+ of an input array so that any changes made by the Fortran routine will be
+ reflected in the input argument. For example, if one specifies the
+ ``intent(inplace) a`` directive (see :ref:`f2py-attributes` for details),
+ then the example above would read::
>>> a = np.ones(8, 'i')
>>> fib1.fib(a)
@@ -133,8 +152,8 @@ Fortran subroutine ``FIB`` is accessible via ``fib1.fib``::
[ 0. 1. 1. 2. 3. 5. 8. 13.]
However, the recommended way to have changes made by Fortran subroutine
- propagate to Python is to use the ``intent(out)`` attribute. That approach is
- more efficient and also cleaner.
+ propagate to Python is to use the ``intent(out)`` attribute. That approach
+ is more efficient and also cleaner.
* The usage of ``fib1.fib`` in Python is very similar to using ``FIB`` in
Fortran. However, using *in situ* output arguments in Python is poor style,
@@ -145,23 +164,23 @@ Fortran subroutine ``FIB`` is accessible via ``fib1.fib``::
may lead to difficult to find bugs, not to mention the fact that the
codes will be less readable when all required type checks are implemented.
- Though the approach to wrapping Fortran routines for Python discussed so far is
- very straightforward, it has several drawbacks (see the comments above).
+ Though the approach to wrapping Fortran routines for Python discussed so far
+ is very straightforward, it has several drawbacks (see the comments above).
The drawbacks are due to the fact that there is no way for F2PY to determine
- the actual intention of the arguments; that is there is ambiguity in
+ the actual intention of the arguments; that is, there is ambiguity in
distinguishing between input and output arguments. Consequently, F2PY assumes
that all arguments are input arguments by default.
- However, there are ways (see below) to remove this ambiguity by "teaching"
- F2PY about the true intentions of function arguments, and F2PY is then able to
- generate more explicit, easier to use, and less error prone wrappers for
- Fortran functions.
+ There are ways (see below) to remove this ambiguity by "teaching" F2PY about
+ the true intentions of function arguments, and F2PY is then able to generate
+ more explicit, easier to use, and less error prone wrappers for Fortran
+ functions.
The smart way
==============
-Let us apply the steps for wrapping Fortran functions to Python one by
-one.
+If we want to have more control over how F2PY will treat the interface to our
+Fortran code, we can apply the wrapping steps one by one.
* First, we create a signature file from ``fib1.f`` by running:
@@ -169,21 +188,21 @@ one.
python -m numpy.f2py fib1.f -m fib2 -h fib1.pyf
- The signature file is saved to ``fib1.pyf`` (see the ``-h`` flag) and
- its contents are shown below.
+ The signature file is saved to ``fib1.pyf`` (see the ``-h`` flag) and its
+ contents are shown below.
.. literalinclude:: ./code/fib1.pyf
:language: fortran
* Next, we'll teach F2PY that the argument ``n`` is an input argument (using the
``intent(in)`` attribute) and that the result, i.e., the contents of ``a``
- after calling the Fortran function ``FIB``, should be returned to Python (using
- the ``intent(out)`` attribute). In addition, an array ``a`` should be created
- dynamically using the size determined by the input argument ``n`` (using the
- ``depend(n)`` attribute to indicate this dependence relation).
+ after calling the Fortran function ``FIB``, should be returned to Python
+ (using the ``intent(out)`` attribute). In addition, an array ``a`` should be
+ created dynamically using the size determined by the input argument ``n``
+ (using the ``depend(n)`` attribute to indicate this dependence relation).
The contents of a suitably modified version of ``fib1.pyf`` (saved as
- ``fib2.pyf``) is as follows:
+ ``fib2.pyf``) are as follows:
.. literalinclude:: ./code/fib2.pyf
:language: fortran
@@ -215,15 +234,18 @@ In Python::
.. note::
- * The signature of ``fib2.fib`` now more closely corresponds to the
- intention of Fortran subroutine ``FIB``: given the number ``n``,
- ``fib2.fib`` returns the first ``n`` Fibonacci numbers as a NumPy array.
- The new Python signature ``fib2.fib`` also rules out the unexpected behaviour in ``fib1.fib``.
+ * The signature of ``fib2.fib`` now more closely corresponds to the intention
+ of the Fortran subroutine ``FIB``: given the number ``n``, ``fib2.fib``
+ returns the first ``n`` Fibonacci numbers as a NumPy array. The new Python
+ signature ``fib2.fib`` also rules out the unexpected behaviour in
+ ``fib1.fib``.
* Note that by default, using a single ``intent(out)`` also implies
``intent(hide)``. Arguments that have the ``intent(hide)`` attribute
specified will not be listed in the argument list of a wrapper function.
+ For more details, see :doc:`signature-file`.
+
The quick and smart way
========================
diff --git a/doc/source/f2py/index.rst b/doc/source/f2py/index.rst
index 56df31b4e..913eacbb1 100644
--- a/doc/source/f2py/index.rst
+++ b/doc/source/f2py/index.rst
@@ -5,10 +5,10 @@ F2PY user guide and reference manual
=====================================
The purpose of the ``F2PY`` --*Fortran to Python interface generator*-- utility
-is to provide a connection between Python and Fortran
-languages. F2PY is a part of NumPy_ (``numpy.f2py``) and also available as a
-standalone command line tool ``f2py`` when ``numpy`` is installed that
-facilitates creating/building Python C/API extension modules that make it
+is to provide a connection between Python and Fortran. F2PY is a part of NumPy_
+(``numpy.f2py``) and also available as a standalone command line tool.
+
+F2PY facilitates creating/building Python C/API extension modules that make it
possible
* to call Fortran 77/90/95 external subroutines and Fortran 90/95
@@ -18,15 +18,25 @@ possible
from Python.
+F2PY can be used either as a command line tool ``f2py`` or as a Python
+module ``numpy.f2py``. While we try to provide the command line tool as part
+of the numpy setup, some platforms like Windows make it difficult to
+reliably put the executables on the ``PATH``. If the ``f2py`` command is not
+available in your system, you may have to run it as a module::
+
+ python -m numpy.f2py
+
+If you run ``f2py`` with no arguments, and the line ``numpy Version`` at the
+end matches the NumPy version printed from ``python -m numpy.f2py``, then you
+can use the shorter version. If not, or if you cannot run ``f2py``, you should
+replace all calls to ``f2py`` mentioned in this guide with the longer version.
+
.. toctree::
- :maxdepth: 2
-
- usage
- f2py.getting-started
- python-usage
- signature-file
- buildtools/index
- advanced
+ :maxdepth: 3
+
+ f2py-user
+ f2py-reference
+
.. _Python: https://www.python.org/
.. _NumPy: https://www.numpy.org/
diff --git a/doc/source/f2py/python-usage.rst b/doc/source/f2py/python-usage.rst
index ef8ccd7dd..c3379f6c5 100644
--- a/doc/source/f2py/python-usage.rst
+++ b/doc/source/f2py/python-usage.rst
@@ -2,41 +2,48 @@
Using F2PY bindings in Python
==================================
-All wrappers for Fortran/C routines, common blocks, or for Fortran
-90 module data generated by F2PY are exposed to Python as ``fortran``
-type objects. Routine wrappers are callable ``fortran`` type objects
-while wrappers to Fortran data have attributes referring to data
-objects.
+In this page, you can find a full description and a few examples of common usage
+patterns for F2PY with Python and different argument types. For more examples
+and use cases, see :ref:`f2py-examples`.
+
+Fortran type objects
+====================
+
+All wrappers for Fortran/C routines, common blocks, or for Fortran 90 module
+data generated by F2PY are exposed to Python as ``fortran`` type objects.
+Routine wrappers are callable ``fortran`` type objects while wrappers to Fortran
+data have attributes referring to data objects.
All ``fortran`` type objects have an attribute ``_cpointer`` that contains a
``CObject`` referring to the C pointer of the corresponding Fortran/C function
-or variable at the C level. Such ``CObjects`` can be used as a callback argument
+or variable at the C level. Such ``CObjects`` can be used as callback arguments
for F2PY generated functions to bypass the Python C/API layer for calling Python
-functions from Fortran or C when the computational aspects of such functions are
-implemented in C or Fortran and wrapped with F2PY (or any other tool capable of
-providing the ``CObject`` of a function).
+functions from Fortran or C. This can be useful when the computational aspects
+of such functions are implemented in C or Fortran and wrapped with F2PY (or any
+other tool capable of providing the ``CObject`` of a function).
Consider a Fortran 77 file ```ftype.f``:
- .. literalinclude:: ./code/ftype.f
- :language: fortran
+.. literalinclude:: ./code/ftype.f
+ :language: fortran
and a wrapper built using ``f2py -c ftype.f -m ftype``.
-In Python:
+In Python, you can observe the types of ``foo`` and ``data``, and how to access
+individual objects of the wrapped Fortran code.
- .. literalinclude:: ./code/results/ftype_session.dat
- :language: python
+.. literalinclude:: ./code/results/ftype_session.dat
+ :language: python
Scalar arguments
=================
-In general, a scalar argument for a F2PY generated wrapper function can
-be an ordinary Python scalar (integer, float, complex number) as well as
-an arbitrary sequence object (list, tuple, array, string) of
-scalars. In the latter case, the first element of the sequence object
-is passed to Fortran routine as a scalar argument.
+In general, a scalar argument for a F2PY generated wrapper function can be an
+ordinary Python scalar (integer, float, complex number) as well as an arbitrary
+sequence object (list, tuple, array, string) of scalars. In the latter case, the
+first element of the sequence object is passed to the Fortran routine as a
+scalar argument.
.. note::
@@ -44,52 +51,57 @@ is passed to Fortran routine as a scalar argument.
narrowing e.g. when type-casting float to integer or complex to float, F2PY
*does not* raise an exception.
- * For complex to real type-casting only the real part of a complex number is used.
+ * For complex to real type-casting only the real part of a complex number
+ is used.
* ``intent(inout)`` scalar arguments are assumed to be array objects in
order to have *in situ* changes be effective. It is recommended to use
- arrays with proper type but also other types work.
+ arrays with proper type but also other types work. :ref:`Read more about
+ the intent attribute <f2py-attributes>`.
Consider the following Fortran 77 code:
- .. literalinclude:: ./code/scalar.f
- :language: fortran
+.. literalinclude:: ./code/scalar.f
+ :language: fortran
and wrap it using ``f2py -c -m scalar scalar.f``.
In Python:
- .. literalinclude:: ./code/results/scalar_session.dat
- :language: python
+.. literalinclude:: ./code/results/scalar_session.dat
+ :language: python
String arguments
=================
-F2PY generated wrapper functions accept almost any Python object as
-a string argument, since ``str`` is applied for non-string objects.
-Exceptions are NumPy arrays that must have type code ``'c'`` or
-``'1'`` when used as string arguments.
+F2PY generated wrapper functions accept almost any Python object as a string
+argument, since ``str`` is applied for non-string objects. Exceptions are NumPy
+arrays that must have type code ``'S1'`` or ``'b'`` (corresponding to the
+outdated ``'c'`` or ``'1'`` typecodes, respectively) when used as string
+arguments. See :ref:`arrays.scalars` for more information on these typecodes.
-A string can have an arbitrary length when used as a string argument
-for an F2PY generated wrapper function. If the length is greater than
-expected, the string is truncated silently. If the length is smaller than
-expected, additional memory is allocated and filled with ``\0``.
+A string can have an arbitrary length when used as a string argument for an F2PY
+generated wrapper function. If the length is greater than expected, the string
+is truncated silently. If the length is smaller than expected, additional memory
+is allocated and filled with ``\0``.
-Because Python strings are immutable, an ``intent(inout)`` argument
-expects an array version of a string in order to have *in situ* changes be effective.
+.. TODO: review this section once https://github.com/numpy/numpy/pull/19388 is merged.
+
+Because Python strings are immutable, an ``intent(inout)`` argument expects an
+array version of a string in order to have *in situ* changes be effective.
Consider the following Fortran 77 code:
- .. literalinclude:: ./code/string.f
- :language: fortran
+.. literalinclude:: ./code/string.f
+ :language: fortran
and wrap it using ``f2py -c -m mystring string.f``.
Python session:
- .. literalinclude:: ./code/results/string_session.dat
- :language: python
+.. literalinclude:: ./code/results/string_session.dat
+ :language: python
Array arguments
@@ -99,40 +111,17 @@ In general, array arguments for F2PY generated wrapper functions accept
arbitrary sequences that can be transformed to NumPy array objects. There are
two notable exceptions:
-* ``intent(inout)`` array arguments must always be proper-contiguous (defined below) and have a
- compatible ``dtype``, otherwise an exception is raised.
+* ``intent(inout)`` array arguments must always be
+ :term:`proper-contiguous <contiguous>` and have a compatible ``dtype``,
+ otherwise an exception is raised.
* ``intent(inplace)`` array arguments will be changed *in situ* if the argument
- has a different type than expected (see the ``intent(inplace)`` attribute for
- more information).
-
-In general, if a NumPy array is proper-contiguous and has a proper type then it
-is directly passed to the wrapped Fortran/C function. Otherwise, an element-wise
-copy of the input array is made and the copy, being proper-contiguous and with
-proper type, is used as the array argument.
-
-There are two types of proper-contiguous NumPy arrays:
-
-* Fortran-contiguous arrays refer to data that is stored columnwise,
- i.e. the indexing of data as stored in memory starts from the lowest
- dimension;
-* C-contiguous, or simply contiguous arrays, refer to data that is stored
- rowwise, i.e. the indexing of data as stored in memory starts from the highest
- dimension.
-
-For one-dimensional arrays these notions coincide.
-
-For example, a 2x2 array ``A`` is Fortran-contiguous if its elements
-are stored in memory in the following order::
-
- A[0,0] A[1,0] A[0,1] A[1,1]
-
-and C-contiguous if the order is as follows::
-
- A[0,0] A[0,1] A[1,0] A[1,1]
+ has a different type than expected (see the ``intent(inplace)``
+ :ref:`attribute <f2py-attributes>` for more information).
-To test whether an array is C-contiguous, use the ``.flags.c_contiguous``
-attribute of NumPy arrays. To test for Fortran contiguity, use the
-``.flags.f_contiguous`` attribute.
+In general, if a NumPy array is :term:`proper-contiguous <contiguous>` and has
+a proper type then it is directly passed to the wrapped Fortran/C function.
+Otherwise, an element-wise copy of the input array is made and the copy, being
+proper-contiguous and with proper type, is used as the array argument.
Usually there is no need to worry about how the arrays are stored in memory and
whether the wrapped functions, being either Fortran or C functions, assume one
@@ -144,19 +133,19 @@ physical memory in your computer, then care must be taken to ensure the usage of
proper-contiguous and proper type arguments.
To transform input arrays to column major storage order before passing
-them to Fortran routines, use the function ``numpy.asfortranarray(<array>)``.
+them to Fortran routines, use the function `numpy.asfortranarray`.
Consider the following Fortran 77 code:
- .. literalinclude:: ./code/array.f
- :language: fortran
+.. literalinclude:: ./code/array.f
+ :language: fortran
and wrap it using ``f2py -c -m arr array.f -DF2PY_REPORT_ON_ARRAY_COPY=1``.
In Python:
- .. literalinclude:: ./code/results/array_session.dat
- :language: python
+.. literalinclude:: ./code/results/array_session.dat
+ :language: python
.. _Call-back arguments:
@@ -167,15 +156,15 @@ F2PY supports calling Python functions from Fortran or C codes.
Consider the following Fortran 77 code:
- .. literalinclude:: ./code/callback.f
- :language: fortran
+.. literalinclude:: ./code/callback.f
+ :language: fortran
and wrap it using ``f2py -c -m callback callback.f``.
In Python:
- .. literalinclude:: ./code/results/callback_session.dat
- :language: python
+.. literalinclude:: ./code/results/callback_session.dat
+ :language: python
In the above example F2PY was able to guess accurately the signature
of the call-back function. However, sometimes F2PY cannot establish the
@@ -183,13 +172,13 @@ appropriate signature; in these cases the signature of the call-back
function must be explicitly defined in the signature file.
To facilitate this, signature files may contain special modules (the names of
-these modules contain the special ``__user__`` sub-string) that defines the
+these modules contain the special ``__user__`` sub-string) that define the
various signatures for call-back functions. Callback arguments in routine
signatures have the ``external`` attribute (see also the ``intent(callback)``
-attribute). To relate a callback argument with its signature in a ``__user__``
-module block, a ``use`` statement can be utilized as illustrated below. The same
-signature for a callback argument can be referred to in different routine
-signatures.
+:ref:`attribute <f2py-attributes>`). To relate a callback argument with its
+signature in a ``__user__`` module block, a ``use`` statement can be utilized as
+illustrated below. The same signature for a callback argument can be referred to
+in different routine signatures.
We use the same Fortran 77 code as in the previous example but now
we will pretend that F2PY was not able to guess the signatures of
@@ -200,69 +189,67 @@ file ``callback2.pyf`` using F2PY::
Then modify it as follows
- .. include:: ./code/callback2.pyf
- :literal:
+.. include:: ./code/callback2.pyf
+ :literal:
-Finally, we build the extension module using ``f2py -c callback2.pyf callback.f``.
+Finally, we build the extension module using
+``f2py -c callback2.pyf callback.f``.
An example Python session for this snippet would be identical to the previous
example except that the argument names would differ.
-Sometimes a Fortran package may require that users provide routines
-that the package will use. F2PY can construct an interface to such
-routines so that Python functions can be called from Fortran.
+Sometimes a Fortran package may require that users provide routines that the
+package will use. F2PY can construct an interface to such routines so that
+Python functions can be called from Fortran.
Consider the following Fortran 77 subroutine that takes an array as its input
and applies a function ``func`` to its elements.
- .. literalinclude:: ./code/calculate.f
- :language: fortran
+.. literalinclude:: ./code/calculate.f
+ :language: fortran
The Fortran code expects that the function ``func`` has been defined externally.
In order to use a Python function for ``func``, it must have an attribute
-``intent(callback)`` and, it must be specified before the ``external`` statement.
+``intent(callback)`` and it must be specified before the ``external`` statement.
Finally, build an extension module using ``f2py -c -m foo calculate.f``
In Python:
- .. literalinclude:: ./code/results/calculate_session.dat
- :language: python
+.. literalinclude:: ./code/results/calculate_session.dat
+ :language: python
The function is included as an argument to the python function call to the
Fortran subroutine even though it was *not* in the Fortran subroutine argument
list. The "external" keyword refers to the C function generated by f2py, not the
-python function itself. The python function is essentially being supplied to the
+Python function itself. The python function is essentially being supplied to the
C function.
-The callback function may also be explicitly set in the module.
-Then it is not necessary to pass the function in the argument list to
-the Fortran function. This may be desired if the Fortran function calling
-the python callback function is itself called by another Fortran function.
+The callback function may also be explicitly set in the module. Then it is not
+necessary to pass the function in the argument list to the Fortran function.
+This may be desired if the Fortran function calling the Python callback function
+is itself called by another Fortran function.
Consider the following Fortran 77 subroutine:
- .. literalinclude:: ./code/extcallback.f
- :language: fortran
+.. literalinclude:: ./code/extcallback.f
+ :language: fortran
and wrap it using ``f2py -c -m pfromf extcallback.f``.
In Python:
- .. literalinclude:: ./code/results/extcallback_session.dat
- :language: python
+.. literalinclude:: ./code/results/extcallback_session.dat
+ :language: python
Resolving arguments to call-back functions
-===========================================
+------------------------------------------
-F2PY generated interfaces are very flexible with respect to call-back
-arguments. For each call-back argument an additional optional
-argument ``<name>_extra_args`` is introduced by F2PY. This argument
-can be used to pass extra arguments to user provided call-back
-functions.
+F2PY generated interfaces are very flexible with respect to call-back arguments. For each call-back argument an additional optional
+argument ``<name>_extra_args`` is introduced by F2PY. This argument can be used
+to pass extra arguments to user provided call-back functions.
-If a F2PY generated wrapper function expects the following call-back
-argument::
+If a F2PY generated wrapper function expects the following call-back argument::
def fun(a_1,...,a_n):
...
@@ -282,20 +269,20 @@ is provided by a user, and in addition,
fun_extra_args = (e_1,...,e_p)
-is used, then the following rules are applied when a Fortran or C
-function evaluates the call-back argument ``gun``:
+is used, then the following rules are applied when a Fortran or C function
+evaluates the call-back argument ``gun``:
* If ``p == 0`` then ``gun(a_1, ..., a_q)`` is called, here
``q = min(m, n)``.
* If ``n + p <= m`` then ``gun(a_1, ..., a_n, e_1, ..., e_p)`` is called.
-* If ``p <= m < n + p`` then ``gun(a_1, ..., a_q, e_1, ..., e_p)`` is called, here
- ``q=m-p``.
+* If ``p <= m < n + p`` then ``gun(a_1, ..., a_q, e_1, ..., e_p)`` is called,
+ and here ``q=m-p``.
* If ``p > m`` then ``gun(e_1, ..., e_m)`` is called.
-* If ``n + p`` is less than the number of required arguments to ``gun``
- then an exception is raised.
+* If ``n + p`` is less than the number of required arguments to ``gun`` then an
+ exception is raised.
-If the function ``gun`` may return any number of objects as a tuple; then
-the following rules are applied:
+If the function ``gun`` may return any number of objects as a tuple; then the
+following rules are applied:
* If ``k < l``, then ``y_{k + 1}, ..., y_l`` are ignored.
* If ``k > l``, then only ``x_1, ..., x_l`` are set.
@@ -304,48 +291,47 @@ the following rules are applied:
Common blocks
==============
-F2PY generates wrappers to ``common`` blocks defined in a routine
-signature block. Common blocks are visible to all Fortran codes linked
-to the current extension module, but not to other extension modules
-(this restriction is due to the way Python imports shared libraries). In
-Python, the F2PY wrappers to ``common`` blocks are ``fortran`` type
-objects that have (dynamic) attributes related to the data members of
-the common blocks. When accessed, these attributes return as NumPy array
-objects (multidimensional arrays are Fortran-contiguous) which
-directly link to data members in common blocks. Data members can be
-changed by direct assignment or by in-place changes to the
+F2PY generates wrappers to ``common`` blocks defined in a routine signature
+block. Common blocks are visible to all Fortran codes linked to the current
+extension module, but not to other extension modules (this restriction is due to
+the way Python imports shared libraries). In Python, the F2PY wrappers to
+``common`` blocks are ``fortran`` type objects that have (dynamic) attributes
+related to the data members of the common blocks. When accessed, these
+attributes return as NumPy array objects (multidimensional arrays are
+Fortran-contiguous) which directly link to data members in common blocks. Data
+members can be changed by direct assignment or by in-place changes to the
corresponding array objects.
Consider the following Fortran 77 code:
- .. literalinclude:: ./code/common.f
- :language: fortran
+.. literalinclude:: ./code/common.f
+ :language: fortran
and wrap it using ``f2py -c -m common common.f``.
In Python:
- .. literalinclude:: ./code/results/common_session.dat
- :language: python
+.. literalinclude:: ./code/results/common_session.dat
+ :language: python
Fortran 90 module data
=======================
-The F2PY interface to Fortran 90 module data is similar to the handling of Fortran 77
-common blocks.
+The F2PY interface to Fortran 90 module data is similar to the handling of
+Fortran 77 common blocks.
Consider the following Fortran 90 code:
- .. literalinclude:: ./code/moddata.f90
- :language: fortran
+.. literalinclude:: ./code/moddata.f90
+ :language: fortran
and wrap it using ``f2py -c -m moddata moddata.f90``.
In Python:
- .. literalinclude:: ./code/results/moddata_session.dat
- :language: python
+.. literalinclude:: ./code/results/moddata_session.dat
+ :language: python
Allocatable arrays
@@ -355,12 +341,12 @@ F2PY has basic support for Fortran 90 module allocatable arrays.
Consider the following Fortran 90 code:
- .. literalinclude:: ./code/allocarr.f90
- :language: fortran
+.. literalinclude:: ./code/allocarr.f90
+ :language: fortran
and wrap it using ``f2py -c -m allocarr allocarr.f90``.
In Python:
- .. literalinclude:: ./code/results/allocarr_session.dat
- :language: python
+.. literalinclude:: ./code/results/allocarr_session.dat
+ :language: python
diff --git a/doc/source/f2py/signature-file.rst b/doc/source/f2py/signature-file.rst
index b80b31509..cea3682c2 100644
--- a/doc/source/f2py/signature-file.rst
+++ b/doc/source/f2py/signature-file.rst
@@ -2,28 +2,39 @@
Signature file
==================
-The syntax specification for signature files (.pyf files) is modeled on the
-Fortran 90/95 language specification. Almost all Fortran 90/95 standard
-constructs are understood, both in free and fixed format (recall that Fortran 77
-is a subset of Fortran 90/95). F2PY introduces some extensions to the Fortran
-90/95 language specification that help in the design of the Fortran to Python
-interface, making it more "Pythonic".
+The interface definition file (.pyf) is how you can fine-tune the interface
+between Python and Fortran. The syntax specification for signature files
+(``.pyf`` files) is modeled on the Fortran 90/95 language specification. Almost
+all Fortran 90/95 standard constructs are understood, both in free and fixed
+format (recall that Fortran 77 is a subset of Fortran 90/95). F2PY introduces
+some extensions to the Fortran 90/95 language specification that help in the
+design of the Fortran to Python interface, making it more "Pythonic".
Signature files may contain arbitrary Fortran code so that any Fortran 90/95
-codes can be treated as signature files. F2PY silently ignores
-Fortran constructs that are irrelevant for creating the interface.
-However, this also means that syntax errors are not caught by F2PY and will only
-be caught when the library is built.
+codes can be treated as signature files. F2PY silently ignores Fortran
+constructs that are irrelevant for creating the interface. However, this also
+means that syntax errors are not caught by F2PY and will only be caught when the
+library is built.
+
+.. note::
+
+ Currently, F2PY may fail with valid Fortran constructs, such as intrinsic
+ modules. If this happens, you can check the
+ `NumPy GitHub issue tracker <https://github.com/numpy/numpy/issues>`_ for
+ possible workarounds or work-in-progress ideas.
In general, the contents of the signature files are case-sensitive. When
-scanning Fortran codes to generate a signature file, F2PY lowers all
-cases automatically except in multi-line blocks or when the ``--no-lower``
-option is used.
+scanning Fortran codes to generate a signature file, F2PY lowers all cases
+automatically except in multi-line blocks or when the ``--no-lower`` option is
+used.
The syntax of signature files is presented below.
+Signature files syntax
+======================
+
Python module block
-=====================
+-------------------
A signature file may contain one (recommended) or more ``python
module`` blocks. The ``python module`` block describes the contents of
@@ -63,7 +74,7 @@ previous section.
Fortran/C routine signatures
-=============================
+----------------------------
The signature of a Fortran routine has the following structure::
@@ -93,8 +104,10 @@ The signature of a Fortran block data has the following structure::
[<include statements>]
end [ block data [<block data name>] ]
+.. _type-declarations:
+
Type declarations
-=================
+-----------------
The definition of the ``<argument/variable type declaration>`` part
is
@@ -128,27 +141,27 @@ and
* ``<arrayspec>`` is a comma separated list of dimension bounds;
-* ``<init_expr>`` is a `C expression`__;
+* ``<init_expr>`` is a :ref:`C expression <c-expressions>`;
* ``<intlen>`` may be negative integer for ``integer`` type
specifications. In such cases ``integer*<negintlen>`` represents
unsigned C integers;
-__ `C expressions`_
-
If an argument has no ``<argument type declaration>``, its type is
determined by applying ``implicit`` rules to its name.
Statements
-==========
+----------
Attribute statements
^^^^^^^^^^^^^^^^^^^^^
-* The ``<argument/variable attribute statement>`` is
- ``<argument/variable type declaration>`` without ``<typespec>``.
-* In addition, in an attribute statement one cannot use other
- attributes, also ``<entitydecl>`` can be only a list of names.
+The ``<argument/variable attribute statement>`` is similar to the
+``<argument/variable type declaration>``, but without ``<typespec>``.
+
+An attribute statement cannot contain other attributes, and ``<entitydecl>`` can
+be only a list of names. See :ref:`f2py-attributes` for more details on the
+attributes that can be used by F2PY.
Use statements
^^^^^^^^^^^^^^^
@@ -165,9 +178,8 @@ Use statements
<rename_list> := <local_name> => <use_name> [ , <rename_list> ]
-* Currently F2PY uses ``use`` statement only for linking call-back
- modules and ``external`` arguments (call-back functions), see
- :ref:`Call-back arguments`.
+* Currently F2PY uses ``use`` statements only for linking call-back modules and
+ ``external`` arguments (call-back functions). See :ref:`Call-back arguments`.
Common block statements
^^^^^^^^^^^^^^^^^^^^^^^
@@ -199,9 +211,7 @@ Other statements
except the following:
+ ``call`` statements and function calls of ``external`` arguments
- (`more details`__?);
-
- __ external_
+ (see :ref:`more details on external arguments <external>`);
+ ``include`` statements
::
@@ -256,7 +266,7 @@ Other statements
F2PY statements
^^^^^^^^^^^^^^^^
- In addition, F2PY introduces the following statements:
+In addition, F2PY introduces the following statements:
``threadsafe``
Uses a ``Py_BEGIN_ALLOW_THREADS .. Py_END_ALLOW_THREADS`` block
@@ -271,10 +281,9 @@ F2PY statements
block>``.
``callprotoargument <C-typespecs>``
- When the ``callstatement`` statement is used then F2PY may not
- generate proper prototypes for Fortran/C functions (because
- ``<C-expr>`` may contain any function calls and F2PY has no way
- to determine what should be the proper prototype).
+ When the ``callstatement`` statement is used, F2PY may not generate proper
+ prototypes for Fortran/C functions (because ``<C-expr>`` may contain function
+ calls, and F2PY has no way to determine what should be the proper prototype).
With this statement you can explicitly specify the arguments of the
corresponding prototype::
@@ -321,61 +330,64 @@ F2PY statements
__ https://docs.python.org/extending/index.html
+.. _f2py-attributes:
+
Attributes
-============
+----------
-The following attributes are used by F2PY:
+The following attributes can be used by F2PY.
``optional``
- The corresponding argument is moved to the end of ``<optional
- arguments>`` list. A default value for an optional argument can be
- specified via ``<init_expr>``, see the ``entitydecl`` definition.
-
+ The corresponding argument is moved to the end of ``<optional arguments>``
+ list. A default value for an optional argument can be specified via
+ ``<init_expr>`` (see the ``entitydecl`` :ref:`definition <type-declarations>`)
.. note::
* The default value must be given as a valid C expression.
- * Whenever ``<init_expr>`` is used, ``optional`` attribute
- is set automatically by F2PY.
+ * Whenever ``<init_expr>`` is used, the ``optional`` attribute is set
+ automatically by F2PY.
* For an optional array argument, all its dimensions must be bounded.
``required``
- The corresponding argument with this attribute considered mandatory. This is
- the default. ``required`` should only be specified if there is a need to
+ The corresponding argument with this attribute is considered mandatory. This
+ is the default. ``required`` should only be specified if there is a need to
disable the automatic ``optional`` setting when ``<init_expr>`` is used.
- If a Python ``None`` object is used as a required argument, the
- argument is treated as optional. That is, in the case of array
- argument, the memory is allocated. If ``<init_expr>`` is given, then the
- corresponding initialization is carried out.
+ If a Python ``None`` object is used as a required argument, the argument is
+ treated as optional. That is, in the case of array arguments, the memory is
+ allocated. If ``<init_expr>`` is given, then the corresponding initialization
+ is carried out.
``dimension(<arrayspec>)``
The corresponding variable is considered as an array with dimensions given in
``<arrayspec>``.
``intent(<intentspec>)``
- This specifies the "intention" of the corresponding
- argument. ``<intentspec>`` is a comma separated list of the
- following keys:
+ This specifies the "intention" of the corresponding argument. ``<intentspec>``
+ is a comma separated list of the following keys:
* ``in``
- The corresponding argument is considered to be input-only. This means that the value of
- the argument is passed to a Fortran/C function and that the function is
- expected to not change the value of this argument.
+ The corresponding argument is considered to be input-only. This means that
+ the value of the argument is passed to a Fortran/C function and that the
+ function is expected to not change the value of this argument.
* ``inout``
- The corresponding argument is marked for input/output or as an *in situ* output
- argument. ``intent(inout)`` arguments can be only "contiguous" NumPy
- arrays with proper type and size. Here "contiguous" can be either in the
- Fortran or C sense. The latter coincides with the default contiguous
+ The corresponding argument is marked for input/output or as an *in situ*
+ output argument. ``intent(inout)`` arguments can be only
+ :term:`contiguous` NumPy arrays (in either the Fortran or C sense) with
+ proper type and size. The latter coincides with the default contiguous
concept used in NumPy and is effective only if ``intent(c)`` is used. F2PY
assumes Fortran contiguous arguments by default.
.. note::
- Using ``intent(inout)`` is generally not recommended, use ``intent(in,out)`` instead.
+ Using ``intent(inout)`` is generally not recommended, as it can cause
+ unexpected results. For example, scalar arguments using
+ ``intent(inout)`` are assumed to be array objects in order to have
+ *in situ* changes be effective. Use ``intent(in,out)`` instead.
- See also the ``intent(inplace)`` attribute.
+ See also the ``intent(inplace)`` attribute.
* ``inplace``
The corresponding argument is considered to be an input/output or *in situ* output
@@ -586,15 +598,15 @@ The following attributes are used by F2PY:
values.
Extensions
-============
+----------
F2PY directives
^^^^^^^^^^^^^^^^
-The F2PY directives allow using F2PY signature file constructs in
-Fortran 77/90 source codes. With this feature one can (almost) completely skip
-the intermediate signature file generation and apply F2PY directly to Fortran
-source codes.
+The F2PY directives allow using F2PY signature file constructs in Fortran 77/90
+source codes. With this feature one can (almost) completely skip the
+intermediate signature file generation and apply F2PY directly to Fortran source
+codes.
F2PY directives have the following form::
@@ -613,6 +625,8 @@ For fixed format Fortran codes, ``<comment char>`` must be at the
first column of a file, of course. For free format Fortran codes,
the F2PY directives can appear anywhere in a file.
+.. _c-expressions:
+
C expressions
^^^^^^^^^^^^^^
diff --git a/doc/source/f2py/usage.rst b/doc/source/f2py/usage.rst
index 1bf406ff2..332cc5bce 100644
--- a/doc/source/f2py/usage.rst
+++ b/doc/source/f2py/usage.rst
@@ -2,250 +2,291 @@
Using F2PY
===========
-F2PY can be used either as a command line tool ``f2py`` or as a Python
-module ``numpy.f2py``. While we try to provide the command line tool as part
-of the numpy setup, some platforms like Windows make it difficult to
-reliably put the executables on the ``PATH``. We will refer to ``f2py``
-in this document but you may have to run it as a module::
+This page contains a reference to all command-line options for the ``f2py``
+command, as well as a reference to internal functions of the ``numpy.f2py``
+module.
- python -m numpy.f2py
+Using ``f2py`` as a command-line tool
+=====================================
-If you run ``f2py`` with no arguments, and the line ``numpy Version`` at the
-end matches the NumPy version printed from ``python -m numpy.f2py``, then you
-can use the shorter version. If not, or if you cannot run ``f2py``, you should
-replace all calls to ``f2py`` here with the longer version.
+When used as a command-line tool, ``f2py`` has three major modes, distinguished
+by the usage of ``-c`` and ``-h`` switches.
-Command ``f2py``
-=================
+1. Signature file generation
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-When used as a command line tool, ``f2py`` has three major modes,
-distinguished by the usage of ``-c`` and ``-h`` switches:
+To scan Fortran sources and generate a signature file, use
-Signature file generation
-^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. code-block:: sh
-1. To scan Fortran sources and generate a signature file, use
+ f2py -h <filename.pyf> <options> <fortran files> \
+ [[ only: <fortran functions> : ] \
+ [ skip: <fortran functions> : ]]... \
+ [<fortran files> ...]
- .. code-block:: sh
+.. note::
- f2py -h <filename.pyf> <options> <fortran files> \
- [[ only: <fortran functions> : ] \
- [ skip: <fortran functions> : ]]... \
- [<fortran files> ...]
+ A Fortran source file can contain many routines, and it is often not
+ necessary to allow all routines to be usable from Python. In such cases,
+ either specify which routines should be wrapped (in the ``only: .. :`` part)
+ or which routines F2PY should ignore (in the ``skip: .. :`` part).
- .. note::
+If ``<filename.pyf>`` is specified as ``stdout``, then signatures are written to
+standard output instead of a file.
- A Fortran source file can contain many routines, and it is often
- not necessary to allow all routines be usable from Python. In such cases,
- either specify which routines should be wrapped (in the ``only: .. :`` part)
- or which routines F2PY should ignored (in the ``skip: .. :`` part).
+Among other options (see below), the following can be used in this mode:
- If ``<filename.pyf>`` is specified as ``stdout`` then signatures
- are written to standard output instead of a file.
+ ``--overwrite-signature``
+ Overwrites an existing signature file.
- Among other options (see below), the following can be used
- in this mode:
+2. Extension module construction
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- ``--overwrite-signature``
- Overwrites an existing signature file.
+To construct an extension module, use
-Extension module construction
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. code-block:: sh
-2. To construct an extension module, use
+ f2py -m <modulename> <options> <fortran files> \
+ [[ only: <fortran functions> : ] \
+ [ skip: <fortran functions> : ]]... \
+ [<fortran files> ...]
- .. code-block:: sh
+The constructed extension module is saved as ``<modulename>module.c`` to the
+current directory.
- f2py -m <modulename> <options> <fortran files> \
- [[ only: <fortran functions> : ] \
- [ skip: <fortran functions> : ]]... \
- [<fortran files> ...]
+Here ``<fortran files>`` may also contain signature files. Among other options
+(see below), the following options can be used in this mode:
- The constructed extension module is saved as
- ``<modulename>module.c`` to the current directory.
+ ``--debug-capi``
+ Adds debugging hooks to the extension module. When using this extension
+ module, various diagnostic information about the wrapper is written to the
+ standard output, for example, the values of variables, the steps taken, etc.
- Here ``<fortran files>`` may also contain signature files.
- Among other options (see below), the following options can be used
- in this mode:
+ ``-include'<includefile>'``
+ Add a CPP ``#include`` statement to the extension module source.
+ ``<includefile>`` should be given in one of the following forms
- ``--debug-capi``
- Adds debugging hooks to the extension module. When using this extension
- module, various diagnostic information about the wrapper is written to
- the standard output, for example, the values of variables, the steps taken,
- etc.
+ .. code-block:: cpp
- ``-include'<includefile>'``
- Add a CPP ``#include`` statement to the extension module source.
- ``<includefile>`` should be given in one of the following forms
+ "filename.ext"
+ <filename.ext>
- .. code-block:: cpp
+ The include statement is inserted just before the wrapper functions. This
+ feature enables using arbitrary C functions (defined in ``<includefile>``)
+ in F2PY generated wrappers.
- "filename.ext"
- <filename.ext>
+ .. note:: This option is deprecated. Use ``usercode`` statement to specify
+ C code snippets directly in signature files.
- The include statement is inserted just before the wrapper
- functions. This feature enables using arbitrary C functions
- (defined in ``<includefile>``) in F2PY generated wrappers.
+ ``--[no-]wrap-functions``
+ Create Fortran subroutine wrappers to Fortran functions.
+ ``--wrap-functions`` is default because it ensures maximum portability and
+ compiler independence.
- .. note:: This option is deprecated. Use ``usercode`` statement to specify C code snippets directly in signature files.
+ ``--include-paths <path1>:<path2>:..``
+ Search include files from given directories.
- ``--[no-]wrap-functions``
- Create Fortran subroutine wrappers to Fortran functions.
- ``--wrap-functions`` is default because it ensures maximum
- portability and compiler independence.
+ ``--help-link [<list of resources names>]``
+ List system resources found by ``numpy_distutils/system_info.py``. For
+ example, try ``f2py --help-link lapack_opt``.
- ``--include-paths <path1>:<path2>:..``
- Search include files from given directories.
+3. Building a module
+^^^^^^^^^^^^^^^^^^^^
- ``--help-link [<list of resources names>]``
- List system resources found by ``numpy_distutils/system_info.py``.
- For example, try ``f2py --help-link lapack_opt``.
+To build an extension module, use
-Building a module
-^^^^^^^^^^^^^^^^^
+.. code-block:: sh
-3. To build an extension module, use
-
- .. code-block:: sh
-
- f2py -c <options> <fortran files> \
- [[ only: <fortran functions> : ] \
- [ skip: <fortran functions> : ]]... \
- [ <fortran/c source files> ] [ <.o, .a, .so files> ]
+ f2py -c <options> <fortran files> \
+ [[ only: <fortran functions> : ] \
+ [ skip: <fortran functions> : ]]... \
+ [ <fortran/c source files> ] [ <.o, .a, .so files> ]
- If ``<fortran files>`` contains a signature file, then the source for
- an extension module is constructed, all Fortran and C sources are
- compiled, and finally all object and library files are linked to the
- extension module ``<modulename>.so`` which is saved into the current
- directory.
-
- If ``<fortran files>`` does not contain a signature file, then an
- extension module is constructed by scanning all Fortran source codes
- for routine signatures, before proceeding to build the extension module.
+If ``<fortran files>`` contains a signature file, then the source for an
+extension module is constructed, all Fortran and C sources are compiled, and
+finally all object and library files are linked to the extension module
+``<modulename>.so`` which is saved into the current directory.
+
+If ``<fortran files>`` does not contain a signature file, then an extension
+module is constructed by scanning all Fortran source codes for routine
+signatures, before proceeding to build the extension module.
- Among other options (see below) and options described for previous
- modes, the following options can be used in this mode:
+Among other options (see below) and options described for previous modes, the
+following options can be used in this mode:
- ``--help-fcompiler``
- List the available Fortran compilers.
- ``--help-compiler`` **[depreciated]**
- List the available Fortran compilers.
- ``--fcompiler=<Vendor>``
- Specify a Fortran compiler type by vendor.
- ``--f77exec=<path>``
- Specify the path to a F77 compiler
- ``--fcompiler-exec=<path>`` **[depreciated]**
- Specify the path to a F77 compiler
- ``--f90exec=<path>``
- Specify the path to a F90 compiler
- ``--f90compiler-exec=<path>`` **[depreciated]**
- Specify the path to a F90 compiler
- ``--f77flags=<string>``
- Specify F77 compiler flags
- ``--f90flags=<string>``
- Specify F90 compiler flags
- ``--opt=<string>``
- Specify optimization flags
- ``--arch=<string>``
- Specify architecture specific optimization flags
- ``--noopt``
- Compile without optimization flags
- ``--noarch``
- Compile without arch-dependent optimization flags
- ``--debug``
- Compile with debugging information
- ``-l<libname>``
- Use the library ``<libname>`` when linking.
- ``-D<macro>[=<defn=1>]``
- Define macro ``<macro>`` as ``<defn>``.
- ``-U<macro>``
- Define macro ``<macro>``
- ``-I<dir>``
- Append directory ``<dir>`` to the list of directories searched for
- include files.
- ``-L<dir>``
- Add directory ``<dir>`` to the list of directories to be searched
- for ``-l``.
- ``link-<resource>``
- Link the extension module with <resource> as defined by
- ``numpy_distutils/system_info.py``. E.g. to link with optimized
- LAPACK libraries (vecLib on MacOSX, ATLAS elsewhere), use
- ``--link-lapack_opt``. See also ``--help-link`` switch.
-
- .. note:: The ``f2py -c`` option must be applied either to an existing ``.pyf`` file (plus the source/object/library files) or one must specify the ``-m <modulename>`` option (plus the sources/object/library files). Use one of the following options:
-
- .. code-block:: sh
-
- f2py -c -m fib1 fib1.f
-
- or
-
- .. code-block:: sh
-
- f2py -m fib1 fib1.f -h fib1.pyf
- f2py -c fib1.pyf fib1.f
-
- For more information, see the `Building C and C++ Extensions`__ Python documentation for details.
+ ``--help-fcompiler``
+ List the available Fortran compilers.
+ ``--help-compiler`` **[depreciated]**
+ List the available Fortran compilers.
+ ``--fcompiler=<Vendor>``
+ Specify a Fortran compiler type by vendor.
+ ``--f77exec=<path>``
+ Specify the path to a F77 compiler
+ ``--fcompiler-exec=<path>`` **[depreciated]**
+ Specify the path to a F77 compiler
+ ``--f90exec=<path>``
+ Specify the path to a F90 compiler
+ ``--f90compiler-exec=<path>`` **[depreciated]**
+ Specify the path to a F90 compiler
+ ``--f77flags=<string>``
+ Specify F77 compiler flags
+ ``--f90flags=<string>``
+ Specify F90 compiler flags
+ ``--opt=<string>``
+ Specify optimization flags
+ ``--arch=<string>``
+ Specify architecture specific optimization flags
+ ``--noopt``
+ Compile without optimization flags
+ ``--noarch``
+ Compile without arch-dependent optimization flags
+ ``--debug``
+ Compile with debugging information
+ ``-l<libname>``
+ Use the library ``<libname>`` when linking.
+ ``-D<macro>[=<defn=1>]``
+ Define macro ``<macro>`` as ``<defn>``.
+ ``-U<macro>``
+ Define macro ``<macro>``
+ ``-I<dir>``
+ Append directory ``<dir>`` to the list of directories searched for include
+ files.
+ ``-L<dir>``
+ Add directory ``<dir>`` to the list of directories to be searched for
+ ``-l``.
+ ``link-<resource>``
+ Link the extension module with <resource> as defined by
+ ``numpy_distutils/system_info.py``. E.g. to link with optimized LAPACK
+ libraries (vecLib on MacOSX, ATLAS elsewhere), use ``--link-lapack_opt``.
+ See also ``--help-link`` switch.
+
+.. note::
+
+ The ``f2py -c`` option must be applied either to an existing ``.pyf`` file
+ (plus the source/object/library files) or one must specify the
+ ``-m <modulename>`` option (plus the sources/object/library files). Use one of
+ the following options:
+
+ .. code-block:: sh
+
+ f2py -c -m fib1 fib1.f
+
+ or
+
+ .. code-block:: sh
+
+ f2py -m fib1 fib1.f -h fib1.pyf
+ f2py -c fib1.pyf fib1.f
+
+ For more information, see the `Building C and C++ Extensions`__ Python
+ documentation for details.
__ https://docs.python.org/3/extending/building.html
- When building an extension module, a combination of the following
- macros may be required for non-gcc Fortran compilers:
+When building an extension module, a combination of the following macros may be
+required for non-gcc Fortran compilers:
- .. code-block:: sh
+.. code-block:: sh
- -DPREPEND_FORTRAN
- -DNO_APPEND_FORTRAN
- -DUPPERCASE_FORTRAN
+ -DPREPEND_FORTRAN
+ -DNO_APPEND_FORTRAN
+ -DUPPERCASE_FORTRAN
- To test the performance of F2PY generated interfaces, use
- ``-DF2PY_REPORT_ATEXIT``. Then a report of various timings is
- printed out at the exit of Python. This feature may not work on
- all platforms, currently only Linux platform is supported.
+To test the performance of F2PY generated interfaces, use
+``-DF2PY_REPORT_ATEXIT``. Then a report of various timings is printed out at the
+exit of Python. This feature may not work on all platforms, and currently only
+Linux is supported.
- To see whether F2PY generated interface performs copies of array
- arguments, use ``-DF2PY_REPORT_ON_ARRAY_COPY=<int>``. When the size
- of an array argument is larger than ``<int>``, a message about
- the coping is sent to ``stderr``.
+To see whether F2PY generated interface performs copies of array arguments, use
+``-DF2PY_REPORT_ON_ARRAY_COPY=<int>``. When the size of an array argument is
+larger than ``<int>``, a message about the copying is sent to ``stderr``.
Other options
^^^^^^^^^^^^^
-``-m <modulename>``
- Name of an extension module. Default is ``untitled``.
-
- .. warning:: Don't use this option if a signature file (\*.pyf) is used.
-``--[no-]lower``
- Do [not] lower the cases in ``<fortran files>``. By default,
- ``--lower`` is assumed with ``-h`` switch, and ``--no-lower``
- without the ``-h`` switch.
-``-include<header>``
- Writes additional headers in the C wrapper, can be passed multiple times,
- generates #include <header> each time. Note that this is meant to be passed in
- single quotes and without spaces, for example ``'-include<stdbool.h>'``
-``--build-dir <dirname>``
- All F2PY generated files are created in ``<dirname>``. Default is
- ``tempfile.mkdtemp()``.
-``--quiet``
- Run quietly.
-``--verbose``
- Run with extra verbosity.
-``-v``
- Print the F2PY version and exit.
-
-Execute ``f2py`` without any options to get an up-to-date list of
-available options.
+ ``-m <modulename>``
+ Name of an extension module. Default is ``untitled``.
+
+ .. warning:: Don't use this option if a signature file (``*.pyf``) is used.
+
+ ``--[no-]lower``
+ Do [not] lower the cases in ``<fortran files>``. By default, ``--lower`` is
+ assumed with ``-h`` switch, and ``--no-lower`` without the ``-h`` switch.
+ ``-include<header>``
+ Writes additional headers in the C wrapper, can be passed multiple times,
+ generates #include <header> each time. Note that this is meant to be passed
+ in single quotes and without spaces, for example ``'-include<stdbool.h>'``
+ ``--build-dir <dirname>``
+ All F2PY generated files are created in ``<dirname>``. Default is
+ ``tempfile.mkdtemp()``.
+ ``--quiet``
+ Run quietly.
+ ``--verbose``
+ Run with extra verbosity.
+ ``-v``
+ Print the F2PY version and exit.
+
+Execute ``f2py`` without any options to get an up-to-date list of available
+options.
Python module ``numpy.f2py``
============================
-.. warning::
+The f2py program is written in Python and can be run from inside your code
+to compile Fortran code at runtime, as follows:
+
+.. code-block:: python
- The current Python interface to the ``f2py`` module is not mature and
- may change in the future.
+ from numpy import f2py
+ with open("add.f") as sourcefile:
+ sourcecode = sourcefile.read()
+ f2py.compile(sourcecode, modulename='add')
+ import add
+
+The source string can be any valid Fortran code. If you want to save
+the extension-module source code then a suitable file-name can be
+provided by the ``source_fn`` keyword to the compile function.
+
+When using ``numpy.f2py`` as a module, the following functions can be invoked.
+
+.. warning::
+ The current Python interface to the ``f2py`` module is not mature and may
+ change in the future.
.. automodule:: numpy.f2py
:members:
+Automatic extension module generation
+=====================================
+
+If you want to distribute your f2py extension module, then you only
+need to include the .pyf file and the Fortran code. The distutils
+extensions in NumPy allow you to define an extension module entirely
+in terms of this interface file. A valid ``setup.py`` file allowing
+distribution of the ``add.f`` module (as part of the package
+``f2py_examples`` so that it would be loaded as ``f2py_examples.add``) is:
+
+.. code-block:: python
+
+ def configuration(parent_package='', top_path=None)
+ from numpy.distutils.misc_util import Configuration
+ config = Configuration('f2py_examples',parent_package, top_path)
+ config.add_extension('add', sources=['add.pyf','add.f'])
+ return config
+
+ if __name__ == '__main__':
+ from numpy.distutils.core import setup
+ setup(**configuration(top_path='').todict())
+
+Installation of the new package is easy using::
+
+ pip install .
+
+assuming you have the proper permissions to write to the main site-
+packages directory for the version of Python you are using. For the
+resulting package to work, you need to create a file named ``__init__.py``
+(in the same directory as ``add.pyf``). Notice the extension module is
+defined entirely in terms of the ``add.pyf`` and ``add.f`` files. The
+conversion of the .pyf file to a .c file is handled by `numpy.distutils`. \ No newline at end of file
diff --git a/doc/source/glossary.rst b/doc/source/glossary.rst
index aa2dc13df..bd75bf274 100644
--- a/doc/source/glossary.rst
+++ b/doc/source/glossary.rst
@@ -280,10 +280,36 @@ Glossary
contiguous
- An array is contiguous if
- * it occupies an unbroken block of memory, and
- * array elements with higher indexes occupy higher addresses (that
- is, no :term:`stride` is negative).
+
+ An array is contiguous if:
+
+ - it occupies an unbroken block of memory, and
+ - array elements with higher indexes occupy higher addresses (that
+ is, no :term:`stride` is negative).
+
+ There are two types of proper-contiguous NumPy arrays:
+
+ - Fortran-contiguous arrays refer to data that is stored column-wise,
+ i.e. the indexing of data as stored in memory starts from the
+ lowest dimension;
+ - C-contiguous, or simply contiguous arrays, refer to data that is
+ stored row-wise, i.e. the indexing of data as stored in memory
+ starts from the highest dimension.
+
+ For one-dimensional arrays these notions coincide.
+
+ For example, a 2x2 array ``A`` is Fortran-contiguous if its elements are
+ stored in memory in the following order::
+
+ A[0,0] A[1,0] A[0,1] A[1,1]
+
+ and C-contiguous if the order is as follows::
+
+ A[0,0] A[0,1] A[1,0] A[1,1]
+
+ To test whether an array is C-contiguous, use the ``.flags.c_contiguous``
+ attribute of NumPy arrays. To test for Fortran contiguity, use the
+ ``.flags.f_contiguous`` attribute.
copy
diff --git a/doc/source/reference/arrays.datetime.rst b/doc/source/reference/arrays.datetime.rst
index 63c93821b..76539c24e 100644
--- a/doc/source/reference/arrays.datetime.rst
+++ b/doc/source/reference/arrays.datetime.rst
@@ -9,23 +9,51 @@ Datetimes and Timedeltas
.. versionadded:: 1.7.0
Starting in NumPy 1.7, there are core array data types which natively
-support datetime functionality. The data type is called "datetime64",
-so named because "datetime" is already taken by the datetime library
-included in Python.
+support datetime functionality. The data type is called :class:`datetime64`,
+so named because :class:`~datetime.datetime` is already taken by the Python standard library.
+
+Datetime64 Conventions and Assumptions
+======================================
+
+Similar to the Python `~datetime.date` class, dates are expressed in the current
+Gregorian Calendar, indefinitely extended both in the future and in the past.
+[#]_ Contrary to Python `~datetime.date`, which supports only years in the 1 AD — 9999
+AD range, `datetime64` allows also for dates BC; years BC follow the `Astronomical
+year numbering <https://en.wikipedia.org/wiki/Astronomical_year_numbering>`_
+convention, i.e. year 2 BC is numbered −1, year 1 BC is numbered 0, year 1 AD is
+numbered 1.
+
+Time instants, say 16:23:32.234, are represented counting hours, minutes,
+seconds and fractions from midnight: i.e. 00:00:00.000 is midnight, 12:00:00.000
+is noon, etc. Each calendar day has exactly 86400 seconds. This is a "naive"
+time, with no explicit notion of timezones or specific time scales (UT1, UTC, TAI,
+etc.). [#]_
+
+.. [#] The calendar obtained by extending the Gregorian calendar before its
+ official adoption on Oct. 15, 1582 is called `Proleptic Gregorian Calendar
+ <https://en.wikipedia.org/wiki/Proleptic_Gregorian_calendar>`_
+
+.. [#] The assumption of 86400 seconds per calendar day is not valid for UTC,
+ the present day civil time scale. In fact due to the presence of
+ `leap seconds <https://en.wikipedia.org/wiki/Leap_second>`_ on rare occasions
+ a day may be 86401 or 86399 seconds long. On the contrary the 86400s day
+ assumption holds for the TAI timescale. An explicit support for TAI and
+ TAI to UTC conversion, accounting for leap seconds, is proposed but not
+ yet implemented. See also the `shortcomings`_ section below.
Basic Datetimes
===============
-The most basic way to create datetimes is from strings in ISO 8601 date
-or datetime format. It is also possible to create datetimes from an integer by
+The most basic way to create datetimes is from strings in ISO 8601 date
+or datetime format. It is also possible to create datetimes from an integer by
offset relative to the Unix epoch (00:00:00 UTC on 1 January 1970).
-The unit for internal storage is automatically selected from the
+The unit for internal storage is automatically selected from the
form of the string, and can be either a :ref:`date unit <arrays.dtypes.dateunits>` or a
:ref:`time unit <arrays.dtypes.timeunits>`. The date units are years ('Y'),
months ('M'), weeks ('W'), and days ('D'), while the time units are
hours ('h'), minutes ('m'), seconds ('s'), milliseconds ('ms'), and
-some additional SI-prefix seconds-based units. The datetime64 data type
+some additional SI-prefix seconds-based units. The `datetime64` data type
also accepts the string "NAT", in any combination of lowercase/uppercase
letters, for a "Not A Time" value.
@@ -35,11 +63,11 @@ letters, for a "Not A Time" value.
>>> np.datetime64('2005-02-25')
numpy.datetime64('2005-02-25')
-
+
From an integer and a date unit, 1 year since the UNIX epoch:
>>> np.datetime64(1, 'Y')
- numpy.datetime64('1971')
+ numpy.datetime64('1971')
Using months for the unit:
@@ -122,19 +150,19 @@ because the moment of time is still being represented exactly.
NumPy does not store timezone information. For backwards compatibility, datetime64
still parses timezone offsets, which it handles by converting to
- UTC. This behaviour is deprecated and will raise an error in the
+ UTC±00:00 (Zulu time). This behaviour is deprecated and will raise an error in the
future.
Datetime and Timedelta Arithmetic
=================================
-NumPy allows the subtraction of two Datetime values, an operation which
+NumPy allows the subtraction of two datetime values, an operation which
produces a number with a time unit. Because NumPy doesn't have a physical
-quantities system in its core, the timedelta64 data type was created
-to complement datetime64. The arguments for timedelta64 are a number,
+quantities system in its core, the `timedelta64` data type was created
+to complement `datetime64`. The arguments for `timedelta64` are a number,
to represent the number of units, and a date/time unit, such as
-(D)ay, (M)onth, (Y)ear, (h)ours, (m)inutes, or (s)econds. The timedelta64
+(D)ay, (M)onth, (Y)ear, (h)ours, (m)inutes, or (s)econds. The `timedelta64`
data type also accepts the string "NAT" in place of the number for a "Not A Time" value.
.. admonition:: Example
@@ -199,9 +227,8 @@ The Datetime and Timedelta data types support a large number of time
units, as well as generic units which can be coerced into any of the
other units based on input data.
-Datetimes are always stored based on POSIX time (though having a TAI
-mode which allows for accounting of leap-seconds is proposed), with
-an epoch of 1970-01-01T00:00Z. This means the supported dates are
+Datetimes are always stored with
+an epoch of 1970-01-01T00:00. This means the supported dates are
always a symmetric interval around the epoch, called "time span" in the
table below.
@@ -328,7 +355,7 @@ in an optimized form.
np.is_busday():
```````````````
-To test a datetime64 value to see if it is a valid day, use :func:`is_busday`.
+To test a `datetime64` value to see if it is a valid day, use :func:`is_busday`.
.. admonition:: Example
@@ -384,3 +411,69 @@ Some examples::
weekmask = "Mon Tue Wed Thu Fri"
# any amount of whitespace is allowed; abbreviations are case-sensitive.
weekmask = "MonTue Wed Thu\tFri"
+
+
+.. _shortcomings:
+
+Datetime64 shortcomings
+=======================
+
+The assumption that all days are exactly 86400 seconds long makes `datetime64`
+largely compatible with Python `datetime` and "POSIX time" semantics; therefore
+they all share the same well known shortcomings with respect to the UTC
+timescale and historical time determination. A brief non exhaustive summary is
+given below.
+
+- It is impossible to parse valid UTC timestamps occurring during a positive
+ leap second.
+
+ .. admonition:: Example
+
+ "2016-12-31 23:59:60 UTC" was a leap second, therefore "2016-12-31
+ 23:59:60.450 UTC" is a valid timestamp which is not parseable by
+ `datetime64`:
+
+ >>> np.datetime64("2016-12-31 23:59:60.450")
+ Traceback (most recent call last):
+ File "<stdin>", line 1, in <module>
+ ValueError: Seconds out of range in datetime string "2016-12-31 23:59:60.450"
+
+- Timedelta64 computations between two UTC dates can be wrong by an integer
+ number of SI seconds.
+
+ .. admonition:: Example
+
+ Compute the number of SI seconds between "2021-01-01 12:56:23.423 UTC" and
+ "2001-01-01 00:00:00.000 UTC":
+
+ >>> (
+ ... np.datetime64("2021-01-01 12:56:23.423")
+ ... - np.datetime64("2001-01-01")
+ ... ) / np.timedelta64(1, "s")
+ 631198583.423
+
+ however correct answer is `631198588.423` SI seconds because there were 5
+ leap seconds between 2001 and 2021.
+
+- Timedelta64 computations for dates in the past do not return SI seconds, as
+ one would expect.
+
+ .. admonition:: Example
+
+ Compute the number of seconds between "000-01-01 UT" and "1600-01-01 UT",
+ where UT is `universal time
+ <https://en.wikipedia.org/wiki/Universal_Time>`_:
+
+ >>> a = np.datetime64("0000-01-01", "us")
+ >>> b = np.datetime64("1600-01-01", "us")
+ >>> b - a
+ numpy.timedelta64(50491123200000000,'us')
+
+ The computed results, `50491123200` seconds, is obtained as the elapsed
+ number of days (`584388`) times `86400` seconds; this is the number of
+ seconds of a clock in sync with earth rotation. The exact value in SI
+ seconds can only be estimated, e.g using data published in `Measurement of
+ the Earth's rotation: 720 BC to AD 2015, 2016, Royal Society's Proceedings
+ A 472, by Stephenson et.al. <https://doi.org/10.1098/rspa.2016.0404>`_. A
+ sensible estimate is `50491112870 ± 90` seconds, with a difference of 10330
+ seconds.
diff --git a/doc/source/reference/arrays.ndarray.rst b/doc/source/reference/arrays.ndarray.rst
index 66ebb66fb..985a11c88 100644
--- a/doc/source/reference/arrays.ndarray.rst
+++ b/doc/source/reference/arrays.ndarray.rst
@@ -161,26 +161,15 @@ An array is considered aligned if the memory offsets for all elements and the
base offset itself is a multiple of `self.itemsize`. Understanding
`memory-alignment` leads to better performance on most hardware.
-.. note::
-
- Points (1) and (2) can currently be disabled by the compile time
- environmental variable ``NPY_RELAXED_STRIDES_CHECKING=0``,
- which was the default before NumPy 1.10.
- No users should have to do this. ``NPY_RELAXED_STRIDES_DEBUG=1``
- can be used to help find errors when incorrectly relying on the strides
- in C-extension code (see below warning).
-
- You can check whether this option was enabled when your NumPy was
- built by looking at the value of ``np.ones((10,1),
- order='C').flags.f_contiguous``. If this is ``True``, then your
- NumPy has relaxed strides checking enabled.
-
.. warning::
It does *not* generally hold that ``self.strides[-1] == self.itemsize``
for C-style contiguous arrays or ``self.strides[0] == self.itemsize`` for
Fortran-style contiguous arrays is true.
+ ``NPY_RELAXED_STRIDES_DEBUG=1`` can be used to help find errors when
+ incorrectly relying on the strides in C-extension code (see below warning).
+
Data in new :class:`ndarrays <ndarray>` is in the :term:`row-major`
(C) order, unless otherwise specified, but, for example, :ref:`basic
array slicing <arrays.indexing>` often produces :term:`views <view>`
diff --git a/doc/source/reference/distutils.rst b/doc/source/reference/distutils.rst
index 9db757c89..ff1ba3b0d 100644
--- a/doc/source/reference/distutils.rst
+++ b/doc/source/reference/distutils.rst
@@ -4,6 +4,11 @@ Packaging (:mod:`numpy.distutils`)
.. module:: numpy.distutils
+.. warning::
+
+ ``numpy.distutils`` is deprecated, and will be removed for
+ Python >= 3.12. For more details, see :ref:`distutils-status-migration`
+
NumPy provides enhanced distutils functionality to make it easier to
build and install sub-packages, auto-generate code, and extension
modules that use Fortran-compiled libraries. To use features of NumPy
diff --git a/doc/source/reference/distutils_guide.rst b/doc/source/reference/distutils_guide.rst
index 081719d16..5bb4c2878 100644
--- a/doc/source/reference/distutils_guide.rst
+++ b/doc/source/reference/distutils_guide.rst
@@ -3,5 +3,11 @@
NumPy Distutils - Users Guide
=============================
+.. warning::
+
+ ``numpy.distutils`` is deprecated, and will be removed for
+ Python >= 3.12. For more details, see :ref:`distutils-status-migration`
+
+
.. include:: ../../DISTUTILS.rst.txt
:start-line: 6
diff --git a/doc/source/reference/distutils_status_migration.rst b/doc/source/reference/distutils_status_migration.rst
new file mode 100644
index 000000000..9ef5f7232
--- /dev/null
+++ b/doc/source/reference/distutils_status_migration.rst
@@ -0,0 +1,138 @@
+.. _distutils-status-migration:
+
+Status of ``numpy.distutils`` and migration advice
+==================================================
+
+`numpy.distutils` has been deprecated in NumPy ``1.23.0``. It will be removed
+for Python 3.12; for Python <= 3.11 it will not be removed until 2 years after
+the Python 3.12 release (Oct 2025).
+
+
+.. warning::
+
+ ``numpy.distutils`` is only tested with ``setuptools < 60.0``, newer
+ versions may break. See :ref:`numpy-setuptools-interaction` for details.
+
+
+Migration advice
+----------------
+
+It is **not necessary** to migrate immediately - the release date for Python 3.12
+is October 2023. It may be beneficial to wait with migrating until there are
+examples from other projects to follow (see below).
+
+There are several build systems which are good options to migrate to. Assuming
+you have compiled code in your package (if not, we recommend using Flit_) and
+you want to be using a well-designed, modern and reliable build system, we
+recommend:
+
+1. Meson_
+2. CMake_ (or scikit-build_ as an interface to CMake)
+
+If you have modest needs (only simple Cython/C extensions, and perhaps nested
+``setup.py`` files) and have been happy with ``numpy.distutils`` so far, you
+can also consider switching to ``setuptools``. Note that most functionality of
+``numpy.disutils`` is unlikely to be ported to ``setuptools``.
+
+
+Moving to Meson
+```````````````
+
+SciPy is moving to Meson for its 1.9.0 release, planned for July 2022. During
+this process, any remaining issues with Meson's Python support and achieving
+feature parity with ``numpy.distutils`` will be resolved. *Note: parity means a
+large superset, but right now some BLAS/LAPACK support is missing and there are
+a few open issues related to Cython.* SciPy uses almost all functionality that
+``numpy.distutils`` offers, so if SciPy has successfully made a release with
+Meson as the build system, there should be no blockers left to migrate, and
+SciPy will be a good reference for other packages who are migrating.
+For more details about the SciPy migration, see:
+
+- `RFC: switch to Meson as a build system <https://github.com/scipy/scipy/issues/13615>`__
+- `Tracking issue for Meson support <https://github.com/rgommers/scipy/issues/22>`__
+
+NumPy itself will very likely migrate to Meson as well, once the SciPy
+migration is done.
+
+
+Moving to CMake / scikit-build
+``````````````````````````````
+
+See the `scikit-build documentation <https://scikit-build.readthedocs.io/en/latest/>`__
+for how to use scikit-build. Please note that as of Feb 2022, scikit-build
+still relies on setuptools, so it's probably not quite ready yet for a
+post-distutils world. How quickly this changes depends on funding, the current
+(Feb 2022) estimate is that if funding arrives then a viable ``numpy.distutils``
+replacement will be ready at the end of 2022, and a very polished replacement
+mid-2023. For more details on this, see
+`this blog post by Henry Schreiner <https://iscinumpy.gitlab.io/post/scikit-build-proposal/>`__.
+
+
+Moving to ``setuptools``
+````````````````````````
+
+For projects that only use ``numpy.distutils`` for historical reasons, and do
+not actually use features beyond those that ``setuptools`` also supports,
+moving to ``setuptools`` is likely the solution which costs the least effort.
+To assess that, there are the ``numpy.distutils`` features that are *not*
+present in ``setuptools``:
+
+- Nested ``setup.py`` files
+- Fortran build support
+- BLAS/LAPACK library support (OpenBLAS, MKL, ATLAS, Netlib LAPACK/BLAS, BLIS, 64-bit ILP interface, etc.)
+- Support for a few other scientific libraries, like FFTW and UMFPACK
+- Better MinGW support
+- Per-compiler build flag customization (e.g. `-O3` and `SSE2` flags are default)
+- a simple user build config system, see [site.cfg.example](https://github.com/numpy/numpy/blob/master/site.cfg.example)
+- SIMD intrinsics support
+
+The most widely used feature is nested ``setup.py`` files. This feature will
+likely be ported to ``setuptools`` (see
+`gh-18588 <https://github.com/numpy/numpy/issues/18588>`__ for status).
+Projects only using that feature could move to ``setuptools`` after that is
+done. In case a project uses only a couple of ``setup.py`` files, it also could
+make sense to simply aggregate all the content of those files into a single
+``setup.py`` file and then move to ``setuptools``. This involves dropping all
+``Configuration`` instances, and using ``Extension`` instead. E.g.,::
+
+ from distutils.core import setup
+ from distutils.extension import Extension
+ setup(name='foobar',
+ version='1.0',
+ ext_modules=[
+ Extension('foopkg.foo', ['foo.c']),
+ Extension('barpkg.bar', ['bar.c']),
+ ],
+ )
+
+For more details, see the
+`setuptools documentation <https://setuptools.pypa.io/en/latest/setuptools.html>`__
+
+
+.. _numpy-setuptools-interaction:
+
+Interaction of ``numpy.disutils`` with ``setuptools``
+-----------------------------------------------------
+
+It is recommended to use ``setuptools < 60.0``. Newer versions may work, but
+are not guaranteed to. The reason for this is that ``setuptools`` 60.0 enabled
+a vendored copy of ``distutils``, including backwards incompatible changes that
+affect some functionality in ``numpy.distutils``.
+
+If you are using only simple Cython or C extensions with minimal use of
+``numpy.distutils`` functionality beyond nested ``setup.py`` files (its most
+popular feature, see :class:`Configuration <numpy.distutils.misc_util.Configuration>`),
+then latest ``setuptools`` is likely to continue working. In case of problems,
+you can also try ``SETUPTOOLS_USE_DISTUTILS=stdlib`` to avoid the backwards
+incompatible changes in ``setuptools``.
+
+Whatever you do, it is recommended to put an upper bound on your ``setuptools``
+build requirement in ``pyproject.toml`` to avoid future breakage - see
+:ref:`for-downstream-package-authors`.
+
+
+.. _Flit: https://flit.readthedocs.io
+.. _CMake: https://cmake.org/
+.. _Meson: https://mesonbuild.com/
+.. _scikit-build: https://scikit-build.readthedocs.io/
+
diff --git a/doc/source/reference/global_state.rst b/doc/source/reference/global_state.rst
index 20874ceaa..81685ec7d 100644
--- a/doc/source/reference/global_state.rst
+++ b/doc/source/reference/global_state.rst
@@ -70,19 +70,15 @@ Debugging-Related Options
Relaxed Strides Checking
------------------------
-The *compile-time* environment variables::
+The *compile-time* environment variable::
NPY_RELAXED_STRIDES_DEBUG=0
- NPY_RELAXED_STRIDES_CHECKING=1
-
-control how NumPy reports contiguity for arrays.
-The default that it is enabled and the debug mode is disabled.
-This setting should always be enabled. Setting the
-debug option can be interesting for testing code written
-in C which iterates through arrays that may or may not be
-contiguous in memory.
-Most users will have no reason to change these; for details
-see the :ref:`memory layout <memory-layout>` documentation.
+
+can be set to help debug code written in C which iteraters through arrays
+manually. When an array is contiguous and iterated in a contiguous manner,
+its ``strides`` should not be queried. This option can help find errors where
+the ``strides`` are incorrectly used.
+For details see the :ref:`memory layout <memory-layout>` documentation.
Warn if no memory allocation policy when deallocating data
diff --git a/doc/source/reference/index.rst b/doc/source/reference/index.rst
index 00c929d66..66bb45d6a 100644
--- a/doc/source/reference/index.rst
+++ b/doc/source/reference/index.rst
@@ -25,6 +25,7 @@ For learning how to use NumPy, see the :ref:`complete documentation <numpy_docs_
global_state
distutils
distutils_guide
+ distutils_status_migration
c-api/index
simd/index
swig
diff --git a/doc/source/user/basics.indexing.rst b/doc/source/user/basics.indexing.rst
index 5d95d8314..334047f9c 100644
--- a/doc/source/user/basics.indexing.rst
+++ b/doc/source/user/basics.indexing.rst
@@ -104,14 +104,6 @@ integer, or a tuple of slice objects and integers. :py:data:`Ellipsis`
and :const:`newaxis` objects can be interspersed with these as
well.
-.. deprecated:: 1.15.0
-
- In order to remain backward compatible with a common usage in
- Numeric, basic slicing is also initiated if the selection object is
- any non-ndarray and non-tuple sequence (such as a :class:`list`) containing
- :class:`slice` objects, the :py:data:`Ellipsis` object, or the :const:`newaxis`
- object, but not for integer arrays or other embedded sequences.
-
.. index::
triple: ndarray; special methods; getitem
triple: ndarray; special methods; setitem
diff --git a/doc/source/user/c-info.python-as-glue.rst b/doc/source/user/c-info.python-as-glue.rst
index 6d514f146..4db789856 100644
--- a/doc/source/user/c-info.python-as-glue.rst
+++ b/doc/source/user/c-info.python-as-glue.rst
@@ -116,303 +116,7 @@ signatures for the subroutines it encounters, or you can guide how the
subroutine interfaces with Python by constructing an interface-definition-file
(or modifying the f2py-produced one).
-.. index::
- single: f2py
-
-Creating source for a basic extension module
---------------------------------------------
-
-Probably the easiest way to introduce f2py is to offer a simple
-example. Here is one of the subroutines contained in a file named
-:file:`add.f`
-
-.. code-block:: fortran
-
- C
- SUBROUTINE ZADD(A,B,C,N)
- C
- DOUBLE COMPLEX A(*)
- DOUBLE COMPLEX B(*)
- DOUBLE COMPLEX C(*)
- INTEGER N
- DO 20 J = 1, N
- C(J) = A(J)+B(J)
- 20 CONTINUE
- END
-
-This routine simply adds the elements in two contiguous arrays and
-places the result in a third. The memory for all three arrays must be
-provided by the calling routine. A very basic interface to this
-routine can be automatically generated by f2py::
-
- f2py -m add add.f
-
-You should be able to run this command assuming your search-path is
-set-up properly. This command will produce an extension module named
-:file:`addmodule.c` in the current directory. This extension module can now be
-compiled and used from Python just like any other extension module.
-
-
-Creating a compiled extension module
-------------------------------------
-
-You can also get f2py to both compile :file:`add.f` along with the produced
-extension module leaving only a shared-library extension file that can
-be imported from Python::
-
- f2py -c -m add add.f
-
-This command leaves a file named add.{ext} in the current directory
-(where {ext} is the appropriate extension for a Python extension
-module on your platform --- so, pyd, *etc.* ). This module may then be
-imported from Python. It will contain a method for each subroutine in
-add (zadd, cadd, dadd, sadd). The docstring of each method contains
-information about how the module method may be called::
-
- >>> import add
- >>> print(add.zadd.__doc__)
- zadd(a,b,c,n)
-
- Wrapper for ``zadd``.
-
- Parameters
- ----------
- a : input rank-1 array('D') with bounds (*)
- b : input rank-1 array('D') with bounds (*)
- c : input rank-1 array('D') with bounds (*)
- n : input int
-
-Improving the basic interface
------------------------------
-
-The default interface is a very literal translation of the Fortran
-code into Python. The Fortran array arguments must now be NumPy arrays
-and the integer argument should be an integer. The interface will
-attempt to convert all arguments to their required types (and shapes)
-and issue an error if unsuccessful. However, because it knows nothing
-about the semantics of the arguments (such that C is an output and n
-should really match the array sizes), it is possible to abuse this
-function in ways that can cause Python to crash. For example::
-
- >>> add.zadd([1, 2, 3], [1, 2], [3, 4], 1000)
-
-will cause a program crash on most systems. Under the covers, the
-lists are being converted to proper arrays but then the underlying add
-loop is told to cycle way beyond the borders of the allocated memory.
-
-In order to improve the interface, directives should be provided. This
-is accomplished by constructing an interface definition file. It is
-usually best to start from the interface file that f2py can produce
-(where it gets its default behavior from). To get f2py to generate the
-interface file use the -h option::
-
- f2py -h add.pyf -m add add.f
-
-This command leaves the file add.pyf in the current directory. The
-section of this file corresponding to zadd is:
-
-.. code-block:: fortran
-
- subroutine zadd(a,b,c,n) ! in :add:add.f
- double complex dimension(*) :: a
- double complex dimension(*) :: b
- double complex dimension(*) :: c
- integer :: n
- end subroutine zadd
-
-By placing intent directives and checking code, the interface can be
-cleaned up quite a bit until the Python module method is both easier
-to use and more robust.
-
-.. code-block:: fortran
-
- subroutine zadd(a,b,c,n) ! in :add:add.f
- double complex dimension(n) :: a
- double complex dimension(n) :: b
- double complex intent(out),dimension(n) :: c
- integer intent(hide),depend(a) :: n=len(a)
- end subroutine zadd
-
-The intent directive, intent(out) is used to tell f2py that ``c`` is
-an output variable and should be created by the interface before being
-passed to the underlying code. The intent(hide) directive tells f2py
-to not allow the user to specify the variable, ``n``, but instead to
-get it from the size of ``a``. The depend( ``a`` ) directive is
-necessary to tell f2py that the value of n depends on the input a (so
-that it won't try to create the variable n until the variable a is
-created).
-
-After modifying ``add.pyf``, the new Python module file can be generated
-by compiling both ``add.f`` and ``add.pyf``::
-
- f2py -c add.pyf add.f
-
-The new interface has docstring::
-
- >>> import add
- >>> print(add.zadd.__doc__)
- c = zadd(a,b)
-
- Wrapper for ``zadd``.
-
- Parameters
- ----------
- a : input rank-1 array('D') with bounds (n)
- b : input rank-1 array('D') with bounds (n)
-
- Returns
- -------
- c : rank-1 array('D') with bounds (n)
-
-Now, the function can be called in a much more robust way::
-
- >>> add.zadd([1, 2, 3], [4, 5, 6])
- array([5.+0.j, 7.+0.j, 9.+0.j])
-
-Notice the automatic conversion to the correct format that occurred.
-
-
-Inserting directives in Fortran source
---------------------------------------
-
-The nice interface can also be generated automatically by placing the
-variable directives as special comments in the original Fortran code.
-Thus, if the source code is modified to contain:
-
-.. code-block:: fortran
-
- C
- SUBROUTINE ZADD(A,B,C,N)
- C
- CF2PY INTENT(OUT) :: C
- CF2PY INTENT(HIDE) :: N
- CF2PY DOUBLE COMPLEX :: A(N)
- CF2PY DOUBLE COMPLEX :: B(N)
- CF2PY DOUBLE COMPLEX :: C(N)
- DOUBLE COMPLEX A(*)
- DOUBLE COMPLEX B(*)
- DOUBLE COMPLEX C(*)
- INTEGER N
- DO 20 J = 1, N
- C(J) = A(J) + B(J)
- 20 CONTINUE
- END
-
-Then, one can compile the extension module using::
-
- f2py -c -m add add.f
-
-The resulting signature for the function add.zadd is exactly the same
-one that was created previously. If the original source code had
-contained ``A(N)`` instead of ``A(*)`` and so forth with ``B`` and ``C``,
-then nearly the same interface can be obtained by placing the
-``INTENT(OUT) :: C`` comment line in the source code. The only difference
-is that ``N`` would be an optional input that would default to the length
-of ``A``.
-
-
-A filtering example
--------------------
-
-For comparison with the other methods to be discussed. Here is another
-example of a function that filters a two-dimensional array of double
-precision floating-point numbers using a fixed averaging filter. The
-advantage of using Fortran to index into multi-dimensional arrays
-should be clear from this example.
-
-.. code-block::
-
- SUBROUTINE DFILTER2D(A,B,M,N)
- C
- DOUBLE PRECISION A(M,N)
- DOUBLE PRECISION B(M,N)
- INTEGER N, M
- CF2PY INTENT(OUT) :: B
- CF2PY INTENT(HIDE) :: N
- CF2PY INTENT(HIDE) :: M
- DO 20 I = 2,M-1
- DO 40 J=2,N-1
- B(I,J) = A(I,J) +
- $ (A(I-1,J)+A(I+1,J) +
- $ A(I,J-1)+A(I,J+1) )*0.5D0 +
- $ (A(I-1,J-1) + A(I-1,J+1) +
- $ A(I+1,J-1) + A(I+1,J+1))*0.25D0
- 40 CONTINUE
- 20 CONTINUE
- END
-
-This code can be compiled and linked into an extension module named
-filter using::
-
- f2py -c -m filter filter.f
-
-This will produce an extension module named filter.so in the current
-directory with a method named dfilter2d that returns a filtered
-version of the input.
-
-
-Calling f2py from Python
-------------------------
-
-The f2py program is written in Python and can be run from inside your code
-to compile Fortran code at runtime, as follows:
-
-.. code-block:: python
-
- from numpy import f2py
- with open("add.f") as sourcefile:
- sourcecode = sourcefile.read()
- f2py.compile(sourcecode, modulename='add')
- import add
-
-The source string can be any valid Fortran code. If you want to save
-the extension-module source code then a suitable file-name can be
-provided by the ``source_fn`` keyword to the compile function.
-
-
-Automatic extension module generation
--------------------------------------
-
-If you want to distribute your f2py extension module, then you only
-need to include the .pyf file and the Fortran code. The distutils
-extensions in NumPy allow you to define an extension module entirely
-in terms of this interface file. A valid ``setup.py`` file allowing
-distribution of the ``add.f`` module (as part of the package
-``f2py_examples`` so that it would be loaded as ``f2py_examples.add``) is:
-
-.. code-block:: python
-
- def configuration(parent_package='', top_path=None)
- from numpy.distutils.misc_util import Configuration
- config = Configuration('f2py_examples',parent_package, top_path)
- config.add_extension('add', sources=['add.pyf','add.f'])
- return config
-
- if __name__ == '__main__':
- from numpy.distutils.core import setup
- setup(**configuration(top_path='').todict())
-
-Installation of the new package is easy using::
-
- pip install .
-
-assuming you have the proper permissions to write to the main site-
-packages directory for the version of Python you are using. For the
-resulting package to work, you need to create a file named ``__init__.py``
-(in the same directory as ``add.pyf``). Notice the extension module is
-defined entirely in terms of the ``add.pyf`` and ``add.f`` files. The
-conversion of the .pyf file to a .c file is handled by `numpy.disutils`.
-
-
-Conclusion
-----------
-
-The interface definition file (.pyf) is how you can fine-tune the interface
-between Python and Fortran. There is decent documentation for f2py at
-:ref:`f2py`. There is also more information on using f2py (including how to use
-it to wrap C codes) at the `"Interfacing With Other Languages" heading of the
-SciPy Cookbook.
-<https://scipy-cookbook.readthedocs.io/items/idx_interfacing_with_other_languages.html>`_
+See the :ref:`F2PY documentation <f2py>` for more information and examples.
The f2py method of linking compiled code is currently the most
sophisticated and integrated approach. It allows clean separation of