4 List python source files.
6 There are three functions to check whether a file is a Python source, listed
7 here with increasing complexity:
9 - has_python_ext() checks whether a file name ends in '.py[w]'.
10 - look_like_python() checks whether the file is not binary and either has
11 the '.py[w]' extension or the first line contains the word 'python'.
12 - can_be_compiled() checks whether the file can be compiled by compile().
14 The file also must be of appropriate size - not bigger than a megabyte.
16 walk_python_files() recursively lists all Python files under the given directories.
18 __author__
= "Oleg Broytmann, Georg Brandl"
20 __all__
= ["has_python_ext", "looks_like_python", "can_be_compiled", "walk_python_files"]
25 binary_re
= re
.compile('[\x00-\x08\x0E-\x1F\x7F]')
35 size
= os
.stat(fullpath
).st_size
36 except OSError, err
: # Permission denied - ignore the file
37 print_debug("%s: permission denied: %s" % (fullpath
, err
))
40 if size
> 1024*1024: # too big
41 print_debug("%s: the file is too big: %d bytes" % (fullpath
, size
))
45 return open(fullpath
, 'rU')
46 except IOError, err
: # Access denied, or a special file - ignore it
47 print_debug("%s: access denied: %s" % (fullpath
, err
))
50 def has_python_ext(fullpath
):
51 return fullpath
.endswith(".py") or fullpath
.endswith(".pyw")
53 def looks_like_python(fullpath
):
54 infile
= _open(fullpath
)
58 line
= infile
.readline()
61 if binary_re
.search(line
):
62 # file appears to be binary
63 print_debug("%s: appears to be binary" % fullpath
)
66 if fullpath
.endswith(".py") or fullpath
.endswith(".pyw"):
68 elif "python" in line
:
69 # disguised Python script (e.g. CGI)
74 def can_be_compiled(fullpath
):
75 infile
= _open(fullpath
)
83 compile(code
, fullpath
, "exec")
84 except Exception, err
:
85 print_debug("%s: cannot compile: %s" % (fullpath
, err
))
91 def walk_python_files(paths
, is_python
=looks_like_python
, exclude_dirs
=None):
93 Recursively yield all Python source files below the given paths.
95 paths: a list of files and/or directories to be checked.
96 is_python: a function that takes a file name and checks whether it is a
98 exclude_dirs: a list of directory base names that should be excluded in
101 if exclude_dirs
is None:
105 print_debug("testing: %s" % path
)
106 if os
.path
.isfile(path
):
109 elif os
.path
.isdir(path
):
110 print_debug(" it is a directory")
111 for dirpath
, dirnames
, filenames
in os
.walk(path
):
112 for exclude
in exclude_dirs
:
113 if exclude
in dirnames
:
114 dirnames
.remove(exclude
)
115 for filename
in filenames
:
116 fullpath
= os
.path
.join(dirpath
, filename
)
117 print_debug("testing: %s" % fullpath
)
118 if is_python(fullpath
):
121 print_debug(" unknown type")
124 if __name__
== "__main__":
125 # Two simple examples/tests
126 for fullpath
in walk_python_files(['.']):
129 for fullpath
in walk_python_files(['.'], is_python
=can_be_compiled
):