Skip to content

Commit

Permalink
Merge pull request #12 from jayvdb/logical_lines
Browse files Browse the repository at this point in the history
Use pep8 logical lines checker
  • Loading branch information
JBKahn committed Nov 13, 2015
2 parents 04a06a0 + 8ecf72e commit b6dbbc2
Show file tree
Hide file tree
Showing 5 changed files with 262 additions and 85 deletions.
17 changes: 16 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,22 @@ language: python
python:
- "2.7"
- "2.6"
- "3.3"
- "3.4"
- "3.5"

install: "python setup.py install"
env:
matrix:
- FLAKE8_VERSION=""
- FLAKE8_VERSION="1.5"
- FLAKE8_VERSION="2.1"

matrix:
exclude:
- python: "3.5"
env: FLAKE8_VERSION="1.5"

install:
- if [[ -n "$FLAKE8_VERSION" ]]; then pip install flake8=="$FLAKE8_VERSION"; fi
- python setup.py install
script: "nosetests"
17 changes: 10 additions & 7 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,24 @@ You can install or upgrade ``flake8-print`` with these commands::
Plugin for Flake8
-----------------

When both ``flake8 2.2`` and ``flake8-print`` are installed, the plugin is
When both ``flake8 2.4.1`` and ``flake8-print`` are installed, the plugin is
available in ``flake8``::

$ flake8 --version
2.0 (pep8: 1.4.5, flake8-print: 1.0, pyflakes: 0.6.1)

Stdin
-----

Testing with `flake8==2.2.1`, and `2.2.4`. There was a bug in flake8 that was subsequently fixed.
2.4.1 (pep8: 1.5.7, flake8-print: 2.0.0, mccabe: 0.3.1, pyflakes: 0.8.1)


Changes
-------

2.0 - 2015-11-10
````````````````
* Support noqa at end of multiline print statement
* Performance improvements
* Removed PrintStatementChecker class and other functions
* Added T101 for 'Python 2.x reserved word print used.'
* Added testing for Python 3.3 and 3.5, and different flake8 versions

1.6.1 - 2015-05-22
````````````````
* Fix bug introduced in 1.6.
Expand Down
75 changes: 26 additions & 49 deletions flake8_print.py
Original file line number Diff line number Diff line change
@@ -1,54 +1,31 @@
import ast
import tokenize
"""Extension for flake8 that finds usage of print."""
import re

from sys import stdin

__version__ = '1.6.1'
__version__ = '2.0.0'

PRINT_ERROR_CODE = 'T001'
PRINT_ERROR_MESSAGE = 'print statement found.'


class PrintStatementChecker(object):
name = 'flake8-print'
version = __version__

def __init__(self, tree, filename='(none)', builtins=None):
self.tree = tree
self.filename = (filename == 'stdin' and stdin) or filename

def run(self):
if self.filename == stdin:
noqa = get_noqa_lines(self.filename)
else:
with open(self.filename, 'r') as file_to_check:
noqa = get_noqa_lines(file_to_check.readlines())

errors = check_tree_for_print_statements(self.tree, noqa)

for error in errors:
yield (error.get("line"), error.get("col"), error.get("message"), type(self))


def get_noqa_lines(code):
tokens = tokenize.generate_tokens(lambda L=iter(code): next(L))
noqa = [token[2][0] for token in tokens if token[0] == tokenize.COMMENT and (token[1].endswith('noqa') or (isinstance(token[0], str) and token[0].endswith('noqa')))]
return noqa


def check_code_for_print_statements(code):
tree = ast.parse(code)
noqa = get_noqa_lines(code.split("\n"))
return check_tree_for_print_statements(tree, noqa)


def check_tree_for_print_statements(tree, noqa):
errors = []
for node in ast.walk(tree):
if ((isinstance(node, ast.Call) and getattr(node.func, 'id', None) == 'print') or (hasattr(ast, 'Print') and isinstance(node, ast.Print) and node.lineno not in noqa)) and node.lineno not in noqa:
errors.append({
"message": '{0} {1}'.format(PRINT_ERROR_CODE, PRINT_ERROR_MESSAGE),
"line": node.lineno,
"col": node.col_offset
})
return errors
RE_PRINT_STATEMENT = re.compile(r"(?<![=\s])\s*\bprint\b\s+[^(=]")
RE_PRINT_FUNCTION = re.compile(r"(?<!def\s)\bprint\b\s*\([^)]*\)")
RE_PRINT_NAME = re.compile(r"\bprint\b")


def print_usage(logical_line, noqa=None):
if noqa:
return
m = RE_PRINT_STATEMENT.search(logical_line)
if m:
yield m.start(), '{0} {1}'.format(
PRINT_ERROR_CODE, PRINT_ERROR_MESSAGE)
return

m = RE_PRINT_FUNCTION.search(logical_line)
if m:
yield m.start(), '{0} {1}'.format(
PRINT_ERROR_CODE, 'print function found.')
return

m = RE_PRINT_NAME.search(logical_line)
if m:
yield m.start(), 'T101 Python 2.x reserved word print used.'
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def get_long_description():

install_requires = ['flake8']

test_requires = ['nose']
test_requires = ['nose', 'flake8>=1.5']

setup(
name='flake8-print',
Expand All @@ -36,7 +36,7 @@ def get_long_description():
zip_safe=False,
entry_points={
'flake8.extension': [
'flake8_print = flake8_print:PrintStatementChecker',
'flake8_print = flake8_print:print_usage',
],
},
install_requires=install_requires,
Expand Down
Loading

0 comments on commit b6dbbc2

Please sign in to comment.