view Tools/scripts/findnocoding.py @ 56121:ea697cde6882 3.1

Merged revisions 74881-74885,74888,74891-74895,74900,74905-74906,74931-74932,74934,74941-74942,74944,74956 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r74881 | r.david.murray | 2009-09-17 15:12:49 -0400 (Thu, 17 Sep 2009) | 2 lines Check in first draft of maintainers.rst. ........ r74882 | eric.smith | 2009-09-17 15:22:30 -0400 (Thu, 17 Sep 2009) | 1 line Typo. ........ r74883 | mark.dickinson | 2009-09-17 15:37:28 -0400 (Thu, 17 Sep 2009) | 1 line Add some more module maintainers. ........ r74884 | mark.dickinson | 2009-09-17 15:39:12 -0400 (Thu, 17 Sep 2009) | 1 line Revert accidental changes to Objects/longobject.c ........ r74885 | mark.dickinson | 2009-09-17 16:20:01 -0400 (Thu, 17 Sep 2009) | 1 line Add decimal maintainers ........ r74888 | r.david.murray | 2009-09-17 18:10:48 -0400 (Thu, 17 Sep 2009) | 2 lines Maintainer additions from MAL. ........ r74891 | georg.brandl | 2009-09-17 18:18:01 -0400 (Thu, 17 Sep 2009) | 1 line Some more maintainers. ........ r74892 | r.david.murray | 2009-09-17 19:23:56 -0400 (Thu, 17 Sep 2009) | 2 lines Add a couple interest areas for Nick per his request. ........ r74893 | r.david.murray | 2009-09-17 19:43:20 -0400 (Thu, 17 Sep 2009) | 2 lines Benajmin is also compiler-knowledgeable. ........ r74894 | alexandre.vassalotti | 2009-09-17 20:59:05 -0400 (Thu, 17 Sep 2009) | 2 lines Added myself to my areas of interest. ........ r74895 | brett.cannon | 2009-09-17 21:03:35 -0400 (Thu, 17 Sep 2009) | 1 line Add myself to a couple places as maintainer. ........ r74900 | georg.brandl | 2009-09-18 05:06:37 -0400 (Fri, 18 Sep 2009) | 1 line Add myself in interest areas. ........ r74905 | ezio.melotti | 2009-09-18 05:58:43 -0400 (Fri, 18 Sep 2009) | 1 line Add myself in interest areas and mark effbot as inactive in winsound ........ r74906 | antoine.pitrou | 2009-09-18 09:15:23 -0400 (Fri, 18 Sep 2009) | 3 lines Add myself in a couple of places ........ r74931 | r.david.murray | 2009-09-18 17:25:36 -0400 (Fri, 18 Sep 2009) | 5 lines Add some names gleaned from the "Tracker Archeology" thread on python-dev from back in February. Also consolidate the autoconf and makefiles topics into one, and add tracker and svn/hg topics. ........ r74932 | r.david.murray | 2009-09-18 17:32:16 -0400 (Fri, 18 Sep 2009) | 2 lines Remove non-committer mistakenly added. ........ r74934 | r.david.murray | 2009-09-18 17:40:30 -0400 (Fri, 18 Sep 2009) | 2 lines More descriptive/generic name for the svn/hg entry (version control) ........ r74941 | benjamin.peterson | 2009-09-18 18:45:59 -0400 (Fri, 18 Sep 2009) | 1 line add a new category for myself ........ r74942 | benjamin.peterson | 2009-09-18 18:50:55 -0400 (Fri, 18 Sep 2009) | 1 line add myself for symtable ........ r74944 | georg.brandl | 2009-09-19 03:39:05 -0400 (Sat, 19 Sep 2009) | 1 line I would like to maintain the token module! ........ r74956 | r.david.murray | 2009-09-19 14:40:08 -0400 (Sat, 19 Sep 2009) | 3 lines Add everyone who we know has been a release manager as a resource for the 'release management' topic. ........
author R. David Murray <rdmurray@bitdance.com>
date Sat, 19 Sep 2009 19:04:37 +0000
parents bd0e9a9cd283
children fcfe324663a6
line wrap: on
line source

#!/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("The pysource module is not available; "
                         "no sophisticated Python source file search will be done.", file=sys.stderr)


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:
        str(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 utf-8 characters
    rest = infile.read()
    infile.close()

    if has_correct_encoding(line1+line2+rest, "utf-8"):
        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 as msg:
    print(msg, file=sys.stderr)
    print(usage, file=sys.stderr)
    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(usage, file=sys.stderr)
    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)