Create the first tests for the pydocstyle finder.

This commit is contained in:
Dave Halter
2017-06-04 23:59:44 +02:00
parent 660bbe1971
commit d1d02ba3f5
5 changed files with 167 additions and 18 deletions

View File

@@ -4,11 +4,14 @@ Some Python files have been taken from the standard library and are therefore
PSF licensed. Modifications on these files are dual licensed (both MIT and PSF licensed. Modifications on these files are dual licensed (both MIT and
PSF). These files are: PSF). These files are:
- parso/pgen2 - parso/pgen2/*
- parso/tokenize.py - parso/tokenize.py
- parso/token.py - parso/token.py
- test/test_pgen2.py - test/test_pgen2.py
Also some test files under test/normalizer_issue_files have been copied from
https://github.com/PyCQA/pycodestyle (Expat License == MIT License).
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
The MIT License (MIT) The MIT License (MIT)

View File

@@ -53,25 +53,20 @@ class PEP8Normalizer(Normalizer):
for child in node.children: for child in node.children:
# Here we can simply check if it's an except, because otherwise # Here we can simply check if it's an except, because otherwise
# it would be an except_clause. # it would be an except_clause.
if child == 'except': if child.type == 'keyword' and child.value == 'except':
self.add_issue(722, 'Do not use bare except, specify exception instead', node) self.add_issue(722, 'Do not use bare except, specify exception instead', child)
elif typ == 'comparison': elif typ == 'comparison':
odd = False
for child in node.children: for child in node.children:
if odd: if child.type != 'atom_expr':
if child not in ('is', '=='): continue
break if len(child.children) > 2:
else: continue
if child.type != 'atom_expr': trailer = child.children[1]
break atom = child.children[0]
trailer = child.children[-1] if trailer.type == 'trailer' and atom.type == 'name' \
atom = child.children[-1] and atom.value == 'type':
if not (trailer.type == 'trailer' and atom.type == 'name' self.add_issue(721, "Do not compare types, use 'isinstance()", node)
and atom.value == 'type'): break
break
odd = not odd
else:
self.add_issue(721, "Do not compare types, use 'isinstance()", node)
if typ in IMPORT_TYPES: if typ in IMPORT_TYPES:
module = node.parent module = node.parent

View File

@@ -0,0 +1,78 @@
#: E721
if type(res) == type(42):
pass
#: E721
if type(res) != type(""):
pass
import types
if res == types.IntType:
pass
import types
#: E721:3
if type(res) is not types.ListType:
pass
#: E721:7 E721:35
assert type(res) == type(False) or type(res) == type(None)
#: E721:7
assert type(res) == type([])
#: E721:7
assert type(res) == type(())
#: E721:7
assert type(res) == type((0,))
#: E721:7
assert type(res) == type((0))
#: E721:7
assert type(res) != type((1, ))
#: E721:7
assert type(res) is type((1, ))
#: E721:7
assert type(res) is not type((1, ))
# Okay
import types
if isinstance(res, int):
pass
if isinstance(res, str):
pass
if isinstance(res, types.MethodType):
pass
#: E721:3 E721:25
if type(a) != type(b) or type(a) == type(ccc):
pass
#: E721
type(a) != type(b)
#: E721
1 != type(b)
#: E721
type(b) != 1
1 != 1
try:
pass
#: E722
except:
pass
try:
pass
except Exception:
pass
#: E722
except:
pass
# Okay
fake_code = """"
try:
do_something()
except:
pass
"""
try:
pass
except Exception:
pass

View File

@@ -0,0 +1,29 @@
Copyright © 2006-2009 Johann C. Rocholl <johann@rocholl.net>
Copyright © 2009-2014 Florent Xicluna <florent.xicluna@gmail.com>
Copyright © 2014-2016 Ian Lee <IanLee1521@gmail.com>
Copyright © 2014-2017 Dave Halter <davidhalter88@gmail.com>
Dave: The files in this folder were ported from pydocstyle and some
modifications where made.
Licensed under the terms of the Expat License
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,44 @@
"""
To easily verify if our normalizer raises the right error codes, just use the
tests of pydocstyle.
"""
import re
from textwrap import dedent
import parso
def collect_errors(code):
for line_nr, line in enumerate(code.splitlines(), 1):
match = re.match(r'(\s*)#: (.*)$', line)
if match is not None:
codes = match.group(2)
for code in codes.split():
column = len(match.group(1))
if ':' in code:
code, _, add_indent = code.partition(':')
column += int(add_indent)
yield "%s@(%s,%s)" % (code, line_nr + 1, column)
def test_normalizer_issue(normalizer_issue_file):
with open(normalizer_issue_file.path) as f:
code = f.read()
desired = list(collect_errors(code))
module = parso.parse(code)
issues = module._get_normalizer_issues()
i = set("E%s@(%s,%s)" % (i.code, i.start_pos[0], i.start_pos[1]) for i in issues)
d = set(desired)
assert i == d, dedent("""
Test %r failed (%s of %s passed).
not raised = %s
unspecified = %s
""") % (
normalizer_issue_file.name, len(i & d), len(d),
sorted(d - i), sorted(i - d)
)