Skip to content

Commit

Permalink
Merge pull request #87 from w3c/jgraham/open_mode_lint; r=Ms2ger
Browse files Browse the repository at this point in the history
Add a lint to check that open() and file() calls in Python specify a mode.
  • Loading branch information
Ms2ger authored Jul 22, 2016
2 parents 157ef0a + 98e0cb7 commit 2f34984
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 2 deletions.
40 changes: 39 additions & 1 deletion lint/lint.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from __future__ import print_function, unicode_literals

import abc
import argparse
import ast
import fnmatch
import json
import os
Expand Down Expand Up @@ -238,6 +240,42 @@ def check_parsed(repo_root, path, f):

return errors

class ASTCheck(object):
__metaclass__ = abc.ABCMeta
error = None
description = None

@abc.abstractmethod
def check(self, root):
pass

class OpenModeCheck(ASTCheck):
error = "OPEN-NO-MODE"
description = "File opened without providing an explicit mode (note: binary files must be read with 'b' in the mode flags)"

def check(self, root):
errors = []
for node in ast.walk(root):
if isinstance(node, ast.Call):
if hasattr(node.func, "id") and node.func.id in ("open", "file"):
if (len(node.args) < 2 and
all(item.arg != "mode" for item in node.keywords)):
errors.append(node.lineno)
return errors

ast_checkers = [item() for item in [OpenModeCheck]]

def check_python_ast(repo_root, path, f):
if not path.endswith(".py"):
return []

errors = []
root = ast.parse(f.read())
for checker in ast_checkers:
for lineno in checker.check(root):
errors.append((checker.error, checker.description, path, lineno))
return errors

def output_errors_text(errors):
for error_type, description, path, line_number in errors:
pos_string = path
Expand Down Expand Up @@ -316,7 +354,7 @@ def run_lint(path, fn, last, *args):
return sum(error_count.itervalues())

path_lints = [check_path_length]
file_lints = [check_regexp_line, check_parsed]
file_lints = [check_regexp_line, check_parsed, check_python_ast]

if __name__ == "__main__":
error_count = main()
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[flake8]
ignore = E128,E221,E226,E231,E251,E265,E302,E303,E402,E901,F401,F821,F841
ignore = E128,E129,E221,E226,E231,E251,E265,E302,E303,E402,E901,F401,F821,F841
max-line-length = 141
exclude = html5lib,py,pytest,pywebsocket,six,webdriver,wptserve

0 comments on commit 2f34984

Please sign in to comment.