summaryrefslogtreecommitdiff
path: root/scripts/check_sources.py
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2014-10-08 09:09:18 +0200
committerGeorg Brandl <georg@python.org>2014-10-08 09:09:18 +0200
commit6d063d8d28bda60f37b03c7fe130074f92932398 (patch)
tree946af08ab0d46558c58b246dd5d13fee9bcdfae3 /scripts/check_sources.py
parent342f9b5f2720ab257cea0ca934f1c82d9cbfab72 (diff)
parentac3a01c3b86d36b4dc88a11dfe2dfe042ea1c208 (diff)
downloadpygments-6d063d8d28bda60f37b03c7fe130074f92932398.tar.gz
Merged in protz/pygments-main/add-envname (pull request #235)
Diffstat (limited to 'scripts/check_sources.py')
-rwxr-xr-xscripts/check_sources.py121
1 files changed, 45 insertions, 76 deletions
diff --git a/scripts/check_sources.py b/scripts/check_sources.py
index d9e5c2ae..5f233887 100755
--- a/scripts/check_sources.py
+++ b/scripts/check_sources.py
@@ -7,20 +7,26 @@
Make sure each Python file has a correct file header
including copyright and license information.
- :copyright: Copyright 2006-2013 by the Pygments team, see AUTHORS.
+ :copyright: Copyright 2006-2014 by the Pygments team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
-import sys, os, re
+from __future__ import print_function
+
+import io
+import os
+import re
+import sys
import getopt
-import cStringIO
from os.path import join, splitext, abspath
checkers = {}
+
def checker(*suffixes, **kwds):
only_pkg = kwds.pop('only_pkg', False)
+
def deco(func):
for suffix in suffixes:
checkers.setdefault(suffix, []).append(func)
@@ -30,12 +36,10 @@ def checker(*suffixes, **kwds):
name_mail_re = r'[\w ]+(<.*?>)?'
-copyright_re = re.compile(r'^ :copyright: Copyright 2006-2013 by '
+copyright_re = re.compile(r'^ :copyright: Copyright 2006-2014 by '
r'the Pygments team, see AUTHORS\.$', re.UNICODE)
copyright_2_re = re.compile(r'^ %s(, %s)*[,.]$' %
(name_mail_re, name_mail_re), re.UNICODE)
-coding_re = re.compile(r'coding[:=]\s*([-\w.]+)')
-not_ix_re = re.compile(r'\bnot\s+\S+?\s+i[sn]\s\S+')
is_const_re = re.compile(r'if.*?==\s+(None|False|True)\b')
misspellings = ["developement", "adress", "verificate", # ALLOW-MISSPELLING
@@ -44,41 +48,30 @@ misspellings = ["developement", "adress", "verificate", # ALLOW-MISSPELLING
@checker('.py')
def check_syntax(fn, lines):
+ if '#!/' in lines[0]:
+ lines = lines[1:]
+ if 'coding:' in lines[0]:
+ lines = lines[1:]
try:
- compile(''.join(lines), fn, "exec")
- except SyntaxError, err:
+ compile('\n'.join(lines), fn, "exec")
+ except SyntaxError as err:
yield 0, "not compilable: %s" % err
@checker('.py')
def check_style_and_encoding(fn, lines):
- encoding = 'ascii'
for lno, line in enumerate(lines):
- if len(line) > 90:
+ if len(line) > 110:
yield lno+1, "line too long"
- m = not_ix_re.search(line)
- if m:
- yield lno+1, '"' + m.group() + '"'
if is_const_re.search(line):
yield lno+1, 'using == None/True/False'
- if lno < 2:
- co = coding_re.search(line)
- if co:
- encoding = co.group(1)
- try:
- line.decode(encoding)
- except UnicodeDecodeError, err:
- yield lno+1, "not decodable: %s\n Line: %r" % (err, line)
- except LookupError, err:
- yield 0, "unknown encoding: %s" % encoding
- encoding = 'latin1'
@checker('.py', only_pkg=True)
def check_fileheader(fn, lines):
# line number correction
c = 1
- if lines[0:1] == ['#!/usr/bin/env python\n']:
+ if lines[0:1] == ['#!/usr/bin/env python']:
lines = lines[1:]
c = 2
@@ -87,31 +80,28 @@ def check_fileheader(fn, lines):
for lno, l in enumerate(lines):
llist.append(l)
if lno == 0:
- if l == '# -*- coding: rot13 -*-\n':
- # special-case pony package
- return
- elif l != '# -*- coding: utf-8 -*-\n':
+ if l != '# -*- coding: utf-8 -*-':
yield 1, "missing coding declaration"
elif lno == 1:
- if l != '"""\n' and l != 'r"""\n':
+ if l != '"""' and l != 'r"""':
yield 2, 'missing docstring begin (""")'
else:
docopen = True
elif docopen:
- if l == '"""\n':
+ if l == '"""':
# end of docstring
if lno <= 4:
yield lno+c, "missing module name in docstring"
break
- if l != "\n" and l[:4] != ' ' and docopen:
+ if l != "" and l[:4] != ' ' and docopen:
yield lno+c, "missing correct docstring indentation"
if lno == 2:
# if not in package, don't check the module name
modname = fn[:-3].replace('/', '.').replace('.__init__', '')
while modname:
- if l.lower()[4:-1] == modname:
+ if l.lower()[4:] == modname:
break
modname = '.'.join(modname.split('.')[1:])
else:
@@ -126,11 +116,11 @@ def check_fileheader(fn, lines):
# check for copyright and license fields
license = llist[-2:-1]
- if license != [" :license: BSD, see LICENSE for details.\n"]:
+ if license != [" :license: BSD, see LICENSE for details."]:
yield 0, "no correct license info"
ci = -3
- copyright = [s.decode('utf-8') for s in llist[ci:ci+1]]
+ copyright = llist[ci:ci+1]
while copyright and copyright_2_re.match(copyright[0]):
ci -= 1
copyright = llist[ci:ci+1]
@@ -138,34 +128,11 @@ def check_fileheader(fn, lines):
yield 0, "no correct copyright info"
-@checker('.py', '.html', '.js')
-def check_whitespace_and_spelling(fn, lines):
- for lno, line in enumerate(lines):
- if "\t" in line:
- yield lno+1, "OMG TABS!!!1 "
- if line[:-1].rstrip(' \t') != line[:-1]:
- yield lno+1, "trailing whitespace"
- for word in misspellings:
- if word in line and 'ALLOW-MISSPELLING' not in line:
- yield lno+1, '"%s" used' % word
-
-
-bad_tags = ('<b>', '<i>', '<u>', '<s>', '<strike>'
- '<center>', '<big>', '<small>', '<font')
-
-@checker('.html')
-def check_xhtml(fn, lines):
- for lno, line in enumerate(lines):
- for bad_tag in bad_tags:
- if bad_tag in line:
- yield lno+1, "used " + bad_tag
-
-
def main(argv):
try:
gopts, args = getopt.getopt(argv[1:], "vi:")
except getopt.GetoptError:
- print "Usage: %s [-v] [-i ignorepath]* [path]" % argv[0]
+ print("Usage: %s [-v] [-i ignorepath]* [path]" % argv[0])
return 2
opts = {}
for opt, val in gopts:
@@ -178,30 +145,33 @@ def main(argv):
elif len(args) == 1:
path = args[0]
else:
- print "Usage: %s [-v] [-i ignorepath]* [path]" % argv[0]
+ print("Usage: %s [-v] [-i ignorepath]* [path]" % argv[0])
return 2
verbose = '-v' in opts
num = 0
- out = cStringIO.StringIO()
+ out = io.StringIO()
# TODO: replace os.walk run with iteration over output of
# `svn list -R`.
for root, dirs, files in os.walk(path):
- if '.svn' in dirs:
- dirs.remove('.svn')
+ if '.hg' in dirs:
+ dirs.remove('.hg')
+ if 'examplefiles' in dirs:
+ dirs.remove('examplefiles')
if '-i' in opts and abspath(root) in opts['-i']:
del dirs[:]
continue
# XXX: awkward: for the Makefile call: don't check non-package
# files for file headers
- in_pocoo_pkg = root.startswith('./pygments')
+ in_pygments_pkg = root.startswith('./pygments')
for fn in files:
fn = join(root, fn)
- if fn[:2] == './': fn = fn[2:]
+ if fn[:2] == './':
+ fn = fn[2:]
if '-i' in opts and abspath(fn) in opts['-i']:
continue
@@ -212,29 +182,28 @@ def main(argv):
continue
if verbose:
- print "Checking %s..." % fn
+ print("Checking %s..." % fn)
try:
- f = open(fn, 'r')
- lines = list(f)
- except (IOError, OSError), err:
- print "%s: cannot open: %s" % (fn, err)
+ lines = open(fn, 'rb').read().decode('utf-8').splitlines()
+ except (IOError, OSError) as err:
+ print("%s: cannot open: %s" % (fn, err))
num += 1
continue
for checker in checkerlist:
- if not in_pocoo_pkg and checker.only_pkg:
+ if not in_pygments_pkg and checker.only_pkg:
continue
for lno, msg in checker(fn, lines):
- print >>out, "%s:%d: %s" % (fn, lno, msg)
+ print(u"%s:%d: %s" % (fn, lno, msg), file=out)
num += 1
if verbose:
- print
+ print()
if num == 0:
- print "No errors found."
+ print("No errors found.")
else:
- print out.getvalue().rstrip('\n')
- print "%d error%s found." % (num, num > 1 and "s" or "")
+ print(out.getvalue().rstrip('\n'))
+ print("%d error%s found." % (num, num > 1 and "s" or ""))
return int(num > 0)