Repository: numpy/numpy

Issue:
f2py: Error message when `list` is a Fortran functon argument.
I've been trying to clean up the warnings that are generated when SciPy is built, and I ran into this issue with f2py.  I'm using numpy 1.16.3.

In SciPy, we have a .pyf file that includes the following:

```
    subroutine idz_reconid(m,krank,col,n,list,proj,approx)
      integer, intent(in), optional, depend(col) :: m = shape(col,0), krank = shape(col,1)
      complex*16, intent(in) :: col(m,krank)
      integer, intent(in), depend(list) :: n = len(list)
      integer, intent(in) :: list(n)
      complex*16, intent(in), depend(krank,n) :: proj(krank,n-krank)
      complex*16, intent(out), depend(m,n) :: approx(m,n)
    end subroutine idz_reconid
```

The corresponding Fortran function is

```
        subroutine idz_reconid(m,krank,col,n,list,proj,approx)
        [...snip...]
        implicit none
        integer m,n,krank,j,k,l,list(n)
```
When the .pyf file is processed by f2py, it prints:

    "object of type 'type' has no len()" in evaluating 'len(list)' (available names: [])

but as far as I know, the generated wrappers work (we've been using them for quite a while).

The message is generated by the function [`_eval_scalar`](https://github.com/numpy/numpy/blob/c23bd98de665733dd090636f38b6aacf9f99450b/numpy/f2py/crackfortran.py#L2510) in 'crackfortran.py', when the argument `value` is `len(list)`:

```
def _eval_scalar(value, params):
    if _is_kind_number(value):
        value = value.split('_')[0]
    try:
        value = str(eval(value, {}, params))
    except (NameError, SyntaxError):
        return value
    except Exception as msg:
        errmess('"%s" in evaluating %r '
                '(available names: %s)\n'
                % (msg, value, list(params.keys())))
    return value
```
When `value` is `"len(list)"`, `eval(value, {}, params)` raises `TypeError: object of type 'type' has no len()`, which is not caught by the first `except` clause.  Instead, the `errmess()` function is called with the underlying error message from the exception included in the output.

I don't know why the code chooses to print this when a TypeError is raised, but not when a NameError or SyntaxError is raised.  That's the only difference in behavior when the `eval()` call results in an error.  In either case, the original `value` is returned.

@pearu, any ideas?  Is there any harm in also including TypeError with the ones that don't print a message?






Discussion:
Including `TypeError` to except list is fine.
Within the framework of existing tests, what would a test for this look like?
I think this does not deserve a unittest (https://dev.to/megazear7/when-not-to-add-unit-tests-2618).
Agreed. Just a 1 line patch and make the warnings go away. 

Thanks @WarrenWeckesser for tracking this down - I've seen these a lot and they can be a bit confusing when reading a build log.

Resolving patch:
diff --git a/numpy/f2py/crackfortran.py b/numpy/f2py/crackfortran.py
--- a/numpy/f2py/crackfortran.py
+++ b/numpy/f2py/crackfortran.py
@@ -2512,7 +2512,7 @@ def _eval_scalar(value, params):
         value = value.split('_')[0]
     try:
         value = str(eval(value, {}, params))
-    except (NameError, SyntaxError):
+    except (NameError, SyntaxError, TypeError):
         return value
     except Exception as msg:
         errmess('"%s" in evaluating %r '


Test patch: