Added debug statement hook.

This commit is contained in:
Anthony Sottile 2014-03-14 14:23:08 -07:00
parent 5e713f8878
commit 4fc86a807b
8 changed files with 152 additions and 1 deletions

1
.gitignore vendored
View File

@ -9,3 +9,4 @@ build
dist
*.egg-info
*.iml
.pre-commit-files

19
.pre-commit-config.yaml Normal file
View File

@ -0,0 +1,19 @@
-
repo: git@github.com:pre-commit/pre-commit-hooks
sha: 5e713f8878b7d100c0e059f8cc34be4fc2e8f897
hooks:
-
id: pyflakes
files: '\.py$'
-
repo: git@github.com:pre-commit/pre-commit
sha: c77d65d9cbbcf30e2be005f5ba8b63447deedc1e
hooks:
-
id: validate_manifest
files: /manifest.yaml
-
id: validate_config
files: /\.pre-commit-config.yaml

View File

@ -30,7 +30,7 @@ coverage: py_env
coverage run `which py.test` tests $(TEST_TARGETS) && \
coverage report -m'
py_env: requirements.txt
py_env: requirements.txt setup.py
rm -rf py_env
virtualenv py_env
bash -c 'source py_env/bin/activate && \

View File

@ -5,3 +5,9 @@
description: This validator runs pyflakes.
entry: pyflakes
language: python
-
id: debug-statements
name: Debug Statements (Python)
description: This hook checks that debug statements (pdb, ipdb, pudb) are not imported on commit.
entry: debug-statement-hook
language: python

View File

@ -0,0 +1,63 @@
import argparse
import ast
import collections
import sys
DEBUG_STATEMENTS = set(['pdb', 'ipdb', 'pudb'])
DebugStatement = collections.namedtuple(
'DebugStatement', ['name', 'line', 'col'],
)
class ImportStatementParser(ast.NodeVisitor):
def __init__(self):
self.debug_import_statements = []
def visit_Import(self, node):
for node_name in node.names:
if node_name.name in DEBUG_STATEMENTS:
self.debug_import_statements.append(
DebugStatement(node_name.name, node.lineno, node.col_offset),
)
def visit_ImportFrom(self, node):
if node.module in DEBUG_STATEMENTS:
self.debug_import_statements.append(
DebugStatement(node.module, node.lineno, node.col_offset)
)
def check_file_for_debug_statements(filename):
ast_obj = ast.parse(open(filename).read())
visitor = ImportStatementParser()
visitor.visit(ast_obj)
if visitor.debug_import_statements:
for debug_statement in visitor.debug_import_statements:
print '{0}:{2}:{3} - {1} imported'.format(filename, *debug_statement)
return 1
else:
return 0
def debug_statement_hook(argv):
parser = argparse.ArgumentParser()
parser.add_argument('filenames', nargs='+', help='Filenames to run')
args = parser.parse_args()
retv = 0
for filename in args.filenames:
retv |= check_file_for_debug_statements(filename)
return retv
def entry():
return debug_statement_hook(sys.argv[1:])
if __name__ == '__main__':
sys.exit(entry())

View File

@ -6,4 +6,5 @@ simplejson
coverage
ipdb
mock
git+git://github.com/pre-commit/pre-commit#egg=pre-commit
pytest

View File

@ -10,4 +10,9 @@ setup(
'pyflakes',
'simplejson',
],
entry_points={
'console_scripts': [
'debug-statement-hook = pre_commit_hooks.debug_statement_hook:entry',
],
},
)

View File

@ -0,0 +1,56 @@
import ast
import pytest
from pre_commit_hooks.debug_statement_hook import ImportStatementParser, \
DebugStatement
@pytest.fixture
def ast_with_no_debug_imports():
return ast.parse("""
import foo
import bar
import baz
from foo import bar
""")
@pytest.fixture
def ast_with_debug_import_form_1():
return ast.parse("""
import ipdb; ipdb.set_trace()
""")
@pytest.fixture
def ast_with_debug_import_form_2():
return ast.parse("""
from pudb import set_trace; set_trace()
""")
def test_returns_no_debug_statements(ast_with_no_debug_imports):
visitor = ImportStatementParser()
visitor.visit(ast_with_no_debug_imports)
assert visitor.debug_import_statements == []
def test_returns_one_form_1(ast_with_debug_import_form_1):
visitor = ImportStatementParser()
visitor.visit(ast_with_debug_import_form_1)
assert visitor.debug_import_statements == [
DebugStatement('ipdb', 3, 0)
]
def test_returns_one_form_2(ast_with_debug_import_form_2):
visitor = ImportStatementParser()
visitor.visit(ast_with_debug_import_form_2)
assert visitor.debug_import_statements == [
DebugStatement('pudb', 3, 0)
]