Repository: numpy/numpy

Issue:
f2py: Intent(out) broken in recent versions of numpy
As of recently, the intent(out) is no longer taken over into the signature file. This concerns both the information from a Fortran90 variable declaration and the f2py hint with the syntax 
`!f2py intent(out) var`.

The fib3.f example from the [f2py documentation](http://docs.scipy.org/doc/numpy/f2py/getting-started.html) is affected as well and can serve as a minimal example.

The reason seems to be that the function isintent_out() is not imported from auxfuncs.py into crackfortran.py . Intent(out) does hence pass not through the true_intent_list filter.



Discussion:
fib3.f in numpy 1.9

```
!    -*- f90 -*-
! Note: the context of this file is case sensitive.

python module fib3 ! in 
    interface  ! in :fib3
        subroutine fib(a,n) ! in :fib3:fib3.f
            real*8 dimension(n),intent(out),depend(n) :: a
            integer intent(in) :: n
        end subroutine fib
    end interface 
end python module fib3
```

vs numpy 1.10.1

```
!    -*- f90 -*-
! Note: the context of this file is case sensitive.

python module fib3 ! in 
    interface  ! in :fib3
        subroutine fib(a,n) ! in :fib3:fib3.f
            real*8 dimension(n),depend(n) :: a
            integer intent(in) :: n
        end subroutine fib
    end interface 
end python module fib3

! This file was auto-generated with f2py (version:2).
! See http://cens.ioc.ee/projects/f2py2e/
```

Bisect gives b80d1f97 as the first bad commit. The problem is that `crackfortran.py` uses `eval` all over the place and it is executed in the current environment, hence pyflakes and pylint are unable to detect everything that needs to be imported from a static analysis of the code. Ugh.

The proximate cause seems to be

```
def true_intent_list(var):
    lst = var['intent']
    ret = []
    for intent in lst:
        try:
            c = eval('isintent_%s(var)' % intent)
        except NameError:
            c = 0
        if c:
            ret.append(intent)
    return ret
```

Which not only depends on the default environment, but hides the `NameError`. Hmm, what to do. Go back to a `*` import or just import everything `isintent_*`.

The files `capi_maps.py`, `f90mod_rule.py`, and `crackfortran.py` all contained both `from .auxfuncs import *` and called `eval` without explicit environments in some spots. Pending a big refactor of `f2py`, it is probably safest to revert the PEP8 fixups to those files and use `import *` as before.


Resolving patch:
diff --git a/numpy/f2py/capi_maps.py b/numpy/f2py/capi_maps.py
--- a/numpy/f2py/capi_maps.py
+++ b/numpy/f2py/capi_maps.py
@@ -22,20 +22,14 @@
 import re
 import os
 import sys
-from .auxfuncs import (
-    debugcapi, dictappend, errmess, gentitle, getcallprotoargument,
-    getcallstatement, getfortranname, getpymethoddef, getrestdoc,
-    getusercode, getusercode1, hasinitvalue, hasnote, hasresultnote,
-    isarray, iscomplex, iscomplexarray, iscomplexfunction, isexternal,
-    isfunction, isintent_aux, isintent_callback, isintent_dict,
-    isintent_hide, isintent_in, isintent_inout, isintent_out, ismodule,
-    isoptional, isrequired, isscalar, isstring, isstringarray,
-    isstringfunction, issubroutine, l_and, l_not, l_or, outmess
-)
-
 from .crackfortran import markoutercomma
 from . import cb_rules
 
+# The eviroment provided by auxfuncs.py is needed for some calls to eval.
+# As the needed functions cannot be determined by static inspection of the
+# code, it is safest to use import * pending a major refactoring of f2py.
+from .auxfuncs import *
+
 __all__ = [
     'getctype', 'getstrlength', 'getarrdims', 'getpydocsign',
     'getarrdocsign', 'getinit', 'sign2map', 'routsign2map', 'modsign2map',
diff --git a/numpy/f2py/crackfortran.py b/numpy/f2py/crackfortran.py
--- a/numpy/f2py/crackfortran.py
+++ b/numpy/f2py/crackfortran.py
@@ -149,12 +149,11 @@
 import platform
 
 from . import __version__
-from .auxfuncs import (
-    errmess, hascommon, isdouble, iscomplex, isexternal, isinteger,
-    isintent_aux, isintent_c, isintent_callback, isintent_in,
-    isintent_inout, isintent_inplace, islogical, isoptional, isscalar,
-    isstring, isstringarray, l_or, show
-)
+
+# The eviroment provided by auxfuncs.py is needed for some calls to eval.
+# As the needed functions cannot be determined by static inspection of the
+# code, it is safest to use import * pending a major refactoring of f2py.
+from .auxfuncs import *
 
 
 f2py_version = __version__.version
diff --git a/numpy/f2py/f90mod_rules.py b/numpy/f2py/f90mod_rules.py
--- a/numpy/f2py/f90mod_rules.py
+++ b/numpy/f2py/f90mod_rules.py
@@ -21,15 +21,15 @@
 
 import numpy as np
 
-from .auxfuncs import (
-    applyrules, dictappend, hasbody, hasnote, isallocatable, isfunction,
-    isintent_hide, ismodule, isprivate, isroutine, isstringarray, l_or,
-    outmess
-)
 from . import capi_maps
 from . import func2subr
 from .crackfortran import undo_rmbadname, undo_rmbadname1
 
+# The eviroment provided by auxfuncs.py is needed for some calls to eval.
+# As the needed functions cannot be determined by static inspection of the
+# code, it is safest to use import * pending a major refactoring of f2py.
+from .auxfuncs import *
+
 options = {}
 
 


Test patch: