| #!/usr/bin/env python | |
| """List all those Python files that require a coding directive | |
| Usage: nocoding.py dir1 [dir2...] | |
| """ | |
| __author__ = "Oleg Broytmann, Georg Brandl" | |
| import sys, os, re, getopt | |
| # our pysource module finds Python source files | |
| try: | |
| import pysource | |
| except ImportError: | |
| # emulate the module with a simple os.walk | |
| class pysource: | |
| has_python_ext = looks_like_python = can_be_compiled = None | |
| def walk_python_files(self, paths, *args, **kwargs): | |
| for path in paths: | |
| if os.path.isfile(path): | |
| yield path.endswith(".py") | |
| elif os.path.isdir(path): | |
| for root, dirs, files in os.walk(path): | |
| for filename in files: | |
| if filename.endswith(".py"): | |
| yield os.path.join(root, filename) | |
| pysource = pysource() | |
| print >>sys.stderr, ("The pysource module is not available; " | |
| "no sophisticated Python source file search will be done.") | |
| decl_re = re.compile(r"coding[=:]\s*([-\w.]+)") | |
| def get_declaration(line): | |
| match = decl_re.search(line) | |
| if match: | |
| return match.group(1) | |
| return '' | |
| def has_correct_encoding(text, codec): | |
| try: | |
| unicode(text, codec) | |
| except UnicodeDecodeError: | |
| return False | |
| else: | |
| return True | |
| def needs_declaration(fullpath): | |
| try: | |
| infile = open(fullpath, 'rU') | |
| except IOError: # Oops, the file was removed - ignore it | |
| return None | |
| line1 = infile.readline() | |
| line2 = infile.readline() | |
| if get_declaration(line1) or get_declaration(line2): | |
| # the file does have an encoding declaration, so trust it | |
| infile.close() | |
| return False | |
| # check the whole file for non-ASCII characters | |
| rest = infile.read() | |
| infile.close() | |
| if has_correct_encoding(line1+line2+rest, "ascii"): | |
| return False | |
| return True | |
| usage = """Usage: %s [-cd] paths... | |
| -c: recognize Python source files trying to compile them | |
| -d: debug output""" % sys.argv[0] | |
| try: | |
| opts, args = getopt.getopt(sys.argv[1:], 'cd') | |
| except getopt.error, msg: | |
| print >>sys.stderr, msg | |
| print >>sys.stderr, usage | |
| sys.exit(1) | |
| is_python = pysource.looks_like_python | |
| debug = False | |
| for o, a in opts: | |
| if o == '-c': | |
| is_python = pysource.can_be_compiled | |
| elif o == '-d': | |
| debug = True | |
| if not args: | |
| print >>sys.stderr, usage | |
| sys.exit(1) | |
| for fullpath in pysource.walk_python_files(args, is_python): | |
| if debug: | |
| print "Testing for coding: %s" % fullpath | |
| result = needs_declaration(fullpath) | |
| if result: | |
| print fullpath |