summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRohit Goswami <rgoswami@quansight.com>2022-04-29 16:04:04 +0000
committerGitHub <noreply@github.com>2022-04-29 16:04:04 +0000
commitcec19d76586c7861f3c636cddadb75431494ae4e (patch)
treeeefcaaac48d1fb2a856414c7923843397bdae6c7
parent91a3e3a500aa121cf53223b1cc75adb46979bb15 (diff)
parent691db8b812a793c2d5f467b98ec1e049524cf963 (diff)
downloadnumpy-cec19d76586c7861f3c636cddadb75431494ae4e.tar.gz
Merge pull request #21187 from HaoZeke/f2pyDeterminism
ENH: F2PY build output determinism
-rw-r--r--doc/release/upcoming_changes/21187.new_feature.rst8
-rw-r--r--doc/source/f2py/buildtools/index.rst5
-rw-r--r--doc/source/f2py/buildtools/meson.rst7
-rw-r--r--doc/source/f2py/code/meson.build6
-rw-r--r--doc/source/f2py/code/meson_upd.build6
-rw-r--r--doc/source/f2py/usage.rst5
-rwxr-xr-xnumpy/f2py/f2py2e.py6
-rwxr-xr-xnumpy/f2py/rules.py17
8 files changed, 52 insertions, 8 deletions
diff --git a/doc/release/upcoming_changes/21187.new_feature.rst b/doc/release/upcoming_changes/21187.new_feature.rst
new file mode 100644
index 000000000..3781cfd04
--- /dev/null
+++ b/doc/release/upcoming_changes/21187.new_feature.rst
@@ -0,0 +1,8 @@
+deterministic output files for F2PY
+-----------------------------------
+For F77 inputs, ``f2py`` will generate ``modname-f2pywrappers.f``
+unconditionally, though these may be empty. For free-form inputs,
+``modname-f2pywrappers.f``, ``modname-f2pywrappers2.f90`` will both be generated
+unconditionally, and may be empty. This allows writing generic output rules in
+``cmake`` or ``meson`` and other build systems. Older behavior can be restored
+by passing ``--skip-empty-wrappers`` to ``f2py``. :ref:`f2py-meson` details usage.
diff --git a/doc/source/f2py/buildtools/index.rst b/doc/source/f2py/buildtools/index.rst
index e7492f191..48ff927df 100644
--- a/doc/source/f2py/buildtools/index.rst
+++ b/doc/source/f2py/buildtools/index.rst
@@ -80,7 +80,10 @@ Signature files
.. note::
- The signature file output situation is being reconsidered in `issue 20385`_ .
+ From NumPy ``1.22.4`` onwards, ``f2py`` will deterministically generate
+ wrapper files based on the input file Fortran standard (F77 or greater).
+ ``--skip-empty-wrappers`` can be passed to ``f2py`` to restore the previous
+ behaviour of only generating wrappers when needed by the input .
In theory keeping the above requirements in hand, any build system can be
diff --git a/doc/source/f2py/buildtools/meson.rst b/doc/source/f2py/buildtools/meson.rst
index d98752e65..502d3e211 100644
--- a/doc/source/f2py/buildtools/meson.rst
+++ b/doc/source/f2py/buildtools/meson.rst
@@ -83,6 +83,13 @@ A major pain point in the workflow defined above, is the manual tracking of
inputs. Although it would require more effort to figure out the actual outputs
for reasons discussed in :ref:`f2py-bldsys`.
+.. note::
+
+ From NumPy ``1.22.4`` onwards, ``f2py`` will deterministically generate
+ wrapper files based on the input file Fortran standard (F77 or greater).
+ ``--skip-empty-wrappers`` can be passed to ``f2py`` to restore the previous
+ behaviour of only generating wrappers when needed by the input .
+
However, we can augment our workflow in a straightforward to take into account
files for which the outputs are known when the build system is set up.
diff --git a/doc/source/f2py/code/meson.build b/doc/source/f2py/code/meson.build
index b756abf8f..b84bf52a9 100644
--- a/doc/source/f2py/code/meson.build
+++ b/doc/source/f2py/code/meson.build
@@ -21,10 +21,10 @@ incdir_f2py = run_command(py3,
).stdout().strip()
fibby_source = custom_target('fibbymodule.c',
- input : ['fib1.f'],
- output : ['fibbymodule.c'],
+ input : ['fib1.f'], # .f so no F90 wrappers
+ output : ['fibbymodule.c', 'fibby-f2pywrappers.f'],
command : [ py3, '-m', 'numpy.f2py', '@INPUT@',
- '-m', 'fibby', '--lower' ]
+ '-m', 'fibby', '--lower']
)
inc_np = include_directories(incdir_numpy, incdir_f2py)
diff --git a/doc/source/f2py/code/meson_upd.build b/doc/source/f2py/code/meson_upd.build
index 97bd8d175..44d69d182 100644
--- a/doc/source/f2py/code/meson_upd.build
+++ b/doc/source/f2py/code/meson_upd.build
@@ -21,10 +21,10 @@ incdir_f2py = run_command(py3,
).stdout().strip()
fibby_source = custom_target('fibbymodule.c',
- input : ['fib1.f'],
- output : ['fibbymodule.c'],
+ input : ['fib1.f'], # .f so no F90 wrappers
+ output : ['fibbymodule.c', 'fibby-f2pywrappers.f'],
command : [ py3, '-m', 'numpy.f2py', '@INPUT@',
- '-m', 'fibby', '--lower' ])
+ '-m', 'fibby', '--lower'])
inc_np = include_directories(incdir_numpy, incdir_f2py)
diff --git a/doc/source/f2py/usage.rst b/doc/source/f2py/usage.rst
index 332cc5bce..dbd33e36e 100644
--- a/doc/source/f2py/usage.rst
+++ b/doc/source/f2py/usage.rst
@@ -224,6 +224,9 @@ Other options
Run quietly.
``--verbose``
Run with extra verbosity.
+ ``--skip-empty-wrappers``
+ Do not generate wrapper files unless required by the inputs.
+ This is a backwards compatibility flag to restore pre 1.22.4 behavior.
``-v``
Print the F2PY version and exit.
@@ -289,4 +292,4 @@ 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
+conversion of the .pyf file to a .c file is handled by `numpy.distutils`.
diff --git a/numpy/f2py/f2py2e.py b/numpy/f2py/f2py2e.py
index 5bc9113af..5732c1e19 100755
--- a/numpy/f2py/f2py2e.py
+++ b/numpy/f2py/f2py2e.py
@@ -18,6 +18,7 @@ import sys
import os
import pprint
import re
+from pathlib import Path
from . import crackfortran
from . import rules
@@ -121,6 +122,7 @@ Options:
--quiet Run quietly.
--verbose Run with extra verbosity.
+ --skip-empty-wrappers Only generate wrapper files when needed.
-v Print f2py version ID and exit.
@@ -178,6 +180,7 @@ def scaninputline(inputline):
files, skipfuncs, onlyfuncs, debug = [], [], [], []
f, f2, f3, f5, f6, f7, f8, f9, f10 = 1, 0, 0, 0, 0, 0, 0, 0, 0
verbose = 1
+ emptygen = True
dolc = -1
dolatexdoc = 0
dorestdoc = 0
@@ -249,6 +252,8 @@ def scaninputline(inputline):
f7 = 1
elif l[:15] in '--include-paths':
f7 = 1
+ elif l == '--skip-empty-wrappers':
+ emptygen = False
elif l[0] == '-':
errmess('Unknown option %s\n' % repr(l))
sys.exit()
@@ -298,6 +303,7 @@ def scaninputline(inputline):
'Signature file "%s" exists!!! Use --overwrite-signature to overwrite.\n' % (signsfile))
sys.exit()
+ options['emptygen'] = emptygen
options['debug'] = debug
options['verbose'] = verbose
if dolc == -1 and not signsfile:
diff --git a/numpy/f2py/rules.py b/numpy/f2py/rules.py
index feb181bcb..c56225032 100755
--- a/numpy/f2py/rules.py
+++ b/numpy/f2py/rules.py
@@ -53,6 +53,7 @@ Pearu Peterson
import os, sys
import time
import copy
+from pathlib import Path
# __version__.version is now the same as the NumPy version
from . import __version__
@@ -1217,6 +1218,22 @@ def buildmodule(m, um):
# requiresf90wrapper must be called before buildapi as it
# rewrites assumed shape arrays as automatic arrays.
isf90 = requiresf90wrapper(nb)
+ # options is in scope here
+ if options['emptygen']:
+ b_path = options['buildpath']
+ m_name = vrd['modulename']
+ outmess(' Generating possibly empty wrappers"\n')
+ Path(f"{b_path}/{vrd['coutput']}").touch()
+ if isf90:
+ # f77 + f90 wrappers
+ outmess(f' Maybe empty "{m_name}-f2pywrappers2.f90"\n')
+ Path(f'{b_path}/{m_name}-f2pywrappers2.f90').touch()
+ outmess(f' Maybe empty "{m_name}-f2pywrappers.f"\n')
+ Path(f'{b_path}/{m_name}-f2pywrappers.f').touch()
+ else:
+ # only f77 wrappers
+ outmess(f' Maybe empty "{m_name}-f2pywrappers.f"\n')
+ Path(f'{b_path}/{m_name}-f2pywrappers.f').touch()
api, wrap = buildapi(nb)
if wrap:
if isf90: