summaryrefslogtreecommitdiff
path: root/numpy/f2py
diff options
context:
space:
mode:
authorRohit Goswami <rgoswami@quansight.com>2022-03-31 14:51:57 +0000
committerGitHub <noreply@github.com>2022-03-31 11:51:57 -0300
commit04bf4057d565f3d47e984fa0f21929bbb8d9ab7c (patch)
treef28f654e4c8373cf9a0b60fc8a174139a9935405 /numpy/f2py
parenta8fd84da447a5af7434cbff1e7e84a2e7a0cfb5a (diff)
downloadnumpy-04bf4057d565f3d47e984fa0f21929bbb8d9ab7c.tar.gz
BUG,ENH: Fix negative bounds for F2PY (#21256)
Co-authored-by: Pearu Peterson <pearu.peterson@gmail.com>
Diffstat (limited to 'numpy/f2py')
-rwxr-xr-xnumpy/f2py/crackfortran.py11
-rw-r--r--numpy/f2py/tests/src/negative_bounds/issue_20853.f907
-rw-r--r--numpy/f2py/tests/test_regression.py19
3 files changed, 35 insertions, 2 deletions
diff --git a/numpy/f2py/crackfortran.py b/numpy/f2py/crackfortran.py
index 0374ae8d7..eb9ae03c6 100755
--- a/numpy/f2py/crackfortran.py
+++ b/numpy/f2py/crackfortran.py
@@ -2689,7 +2689,7 @@ def analyzevars(block):
n_checks = []
n_is_input = l_or(isintent_in, isintent_inout,
isintent_inplace)(vars[n])
- if 'dimension' in vars[n]: # n is array
+ if isarray(vars[n]): # n is array
for i, d in enumerate(vars[n]['dimension']):
coeffs_and_deps = dimension_exprs.get(d)
if coeffs_and_deps is None:
@@ -2700,6 +2700,13 @@ def analyzevars(block):
# may define variables used in dimension
# specifications.
for v, (solver, deps) in coeffs_and_deps.items():
+ def compute_deps(v, deps):
+ for v1 in coeffs_and_deps.get(v, [None, []])[1]:
+ if v1 not in deps:
+ deps.add(v1)
+ compute_deps(v1, deps)
+ all_deps = set()
+ compute_deps(v, all_deps)
if ((v in n_deps
or '=' in vars[v]
or 'depend' in vars[v])):
@@ -2708,7 +2715,7 @@ def analyzevars(block):
# - has user-defined initialization expression
# - has user-defined dependencies
continue
- if solver is not None:
+ if solver is not None and v not in all_deps:
# v can be solved from d, hence, we
# make it an optional argument with
# initialization expression:
diff --git a/numpy/f2py/tests/src/negative_bounds/issue_20853.f90 b/numpy/f2py/tests/src/negative_bounds/issue_20853.f90
new file mode 100644
index 000000000..bf1fa9285
--- /dev/null
+++ b/numpy/f2py/tests/src/negative_bounds/issue_20853.f90
@@ -0,0 +1,7 @@
+subroutine foo(is_, ie_, arr, tout)
+ implicit none
+ integer :: is_,ie_
+ real, intent(in) :: arr(is_:ie_)
+ real, intent(out) :: tout(is_:ie_)
+ tout = arr
+end
diff --git a/numpy/f2py/tests/test_regression.py b/numpy/f2py/tests/test_regression.py
index 40b9d4327..044f952f2 100644
--- a/numpy/f2py/tests/test_regression.py
+++ b/numpy/f2py/tests/test_regression.py
@@ -22,6 +22,25 @@ class TestIntentInOut(util.F2PyTest):
assert np.allclose(x, [3, 1, 2])
+class TestNegativeBounds(util.F2PyTest):
+ # Check that negative bounds work correctly
+ sources = [util.getpath("tests", "src", "negative_bounds", "issue_20853.f90")]
+
+ @pytest.mark.slow
+ def test_negbound(self):
+ xvec = np.arange(12)
+ xlow = -6
+ xhigh = 4
+ # Calculate the upper bound,
+ # Keeping the 1 index in mind
+ def ubound(xl, xh):
+ return xh - xl + 1
+ rval = self.module.foo(is_=xlow, ie_=xhigh,
+ arr=xvec[:ubound(xlow, xhigh)])
+ expval = np.arange(11, dtype = np.float32)
+ assert np.allclose(rval, expval)
+
+
class TestNumpyVersionAttribute(util.F2PyTest):
# Check that th attribute __f2py_numpy_version__ is present
# in the compiled module and that has the value np.__version__.