|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356 |
- # -*- coding: utf-8 -*-
- # Copyright (c) 2009-2011, 2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr>
- # Copyright (c) 2012 FELD Boris <lothiraldan@gmail.com>
- # Copyright (c) 2013-2014 Google, Inc.
- # Copyright (c) 2014-2017 Claudiu Popa <pcmanticore@gmail.com>
- # Copyright (c) 2014 buck <buck.2019@gmail.com>
- # Copyright (c) 2014 Arun Persaud <arun@nubati.net>
- # Copyright (c) 2015 Harut <yes@harutune.name>
- # Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro>
- # Copyright (c) 2016 Petr Pulc <petrpulc@gmail.com>
- # Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com>
- # Copyright (c) 2017 Krzysztof Czapla <k.czapla68@gmail.com>
- # Copyright (c) 2017 Łukasz Rogalski <rogalski.91@gmail.com>
- # Copyright (c) 2017 James M. Allen <james.m.allen@gmail.com>
- # Copyright (c) 2017 vinnyrose <vinnyrose@users.noreply.github.com>
-
- # Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
- # For details: https://github.com/PyCQA/pylint/blob/master/COPYING
-
- """Check format checker helper functions"""
-
- from __future__ import unicode_literals
-
- import astroid
-
- from pylint.checkers.format import *
-
- from pylint.testutils import (
- CheckerTestCase, Message, set_config, _tokenize_str,
- )
-
-
- class TestMultiStatementLine(CheckerTestCase):
- CHECKER_CLASS = FormatChecker
-
- def testSingleLineIfStmts(self):
- stmt = astroid.extract_node("""
- if True: pass #@
- """)
- self.checker.config.single_line_if_stmt = False
- with self.assertAddsMessages(Message('multiple-statements', node=stmt.body[0])):
- self.visitFirst(stmt)
- self.checker.config.single_line_if_stmt = True
- with self.assertNoMessages():
- self.visitFirst(stmt)
- stmt = astroid.extract_node("""
- if True: pass #@
- else:
- pass
- """)
- with self.assertAddsMessages(Message('multiple-statements', node=stmt.body[0])):
- self.visitFirst(stmt)
-
- def testSingleLineClassStmts(self):
- stmt = astroid.extract_node("""
- class MyError(Exception): pass #@
- """)
- self.checker.config.single_line_class_stmt = False
- with self.assertAddsMessages(Message('multiple-statements', node=stmt.body[0])):
- self.visitFirst(stmt)
- self.checker.config.single_line_class_stmt = True
- with self.assertNoMessages():
- self.visitFirst(stmt)
-
- stmt = astroid.extract_node("""
- class MyError(Exception): a='a' #@
- """)
- self.checker.config.single_line_class_stmt = False
- with self.assertAddsMessages(Message('multiple-statements', node=stmt.body[0])):
- self.visitFirst(stmt)
- self.checker.config.single_line_class_stmt = True
- with self.assertNoMessages():
- self.visitFirst(stmt)
-
- stmt = astroid.extract_node("""
- class MyError(Exception): a='a'; b='b' #@
- """)
- self.checker.config.single_line_class_stmt = False
- with self.assertAddsMessages(Message('multiple-statements', node=stmt.body[0])):
- self.visitFirst(stmt)
- self.checker.config.single_line_class_stmt = True
- with self.assertAddsMessages(Message('multiple-statements', node=stmt.body[0])):
- self.visitFirst(stmt)
-
- def testTryExceptFinallyNoMultipleStatement(self):
- tree = astroid.extract_node("""
- try: #@
- pass
- except:
- pass
- finally:
- pass""")
- with self.assertNoMessages():
- self.visitFirst(tree)
-
- def visitFirst(self, tree):
- self.checker.process_tokens([])
- self.checker.visit_default(tree.body[0])
-
-
- class TestSuperfluousParentheses(CheckerTestCase):
- CHECKER_CLASS = FormatChecker
-
- def testCheckKeywordParensHandlesValidCases(self):
- self.checker._keywords_with_parens = set()
- cases = [
- 'if foo:',
- 'if foo():',
- 'if (x and y) or z:',
- 'assert foo()',
- 'assert ()',
- 'if (1, 2) in (3, 4):',
- 'if (a or b) in c:',
- 'return (x for x in x)',
- 'if (x for x in x):',
- 'for x in (x for x in x):',
- 'not (foo or bar)',
- 'not (foo or bar) and baz',
- ]
- with self.assertNoMessages():
- for code in cases:
- self.checker._check_keyword_parentheses(_tokenize_str(code), 0)
-
- def testCheckKeywordParensHandlesUnnecessaryParens(self):
- self.checker._keywords_with_parens = set()
- cases = [
- (Message('superfluous-parens', line=1, args='if'),
- 'if (foo):', 0),
- (Message('superfluous-parens', line=1, args='if'),
- 'if ((foo, bar)):', 0),
- (Message('superfluous-parens', line=1, args='if'),
- 'if (foo(bar)):', 0),
- (Message('superfluous-parens', line=1, args='return'),
- 'return ((x for x in x))', 0),
- (Message('superfluous-parens', line=1, args='not'),
- 'not (foo)', 0),
- (Message('superfluous-parens', line=1, args='not'),
- 'if not (foo):', 1),
- (Message('superfluous-parens', line=1, args='if'),
- 'if (not (foo)):', 0),
- (Message('superfluous-parens', line=1, args='not'),
- 'if (not (foo)):', 2),
- (Message('superfluous-parens', line=1, args='for'),
- 'for (x) in (1, 2, 3):', 0),
- (Message('superfluous-parens', line=1, args='if'),
- 'if (1) in (1, 2, 3):', 0),
- ]
- for msg, code, offset in cases:
- with self.assertAddsMessages(msg):
- self.checker._check_keyword_parentheses(_tokenize_str(code), offset)
-
- def testCheckIfArgsAreNotUnicode(self):
- self.checker._keywords_with_parens = set()
- cases = [(u'if (foo):', 0), (u'assert (1 == 1)', 0)]
-
- for code, offset in cases:
- self.checker._check_keyword_parentheses(_tokenize_str(code), offset)
- got = self.linter.release_messages()
- assert isinstance(got[-1].args, str)
-
-
- def testFuturePrintStatementWithoutParensWarning(self):
- code = """from __future__ import print_function
- print('Hello world!')
- """
- tree = astroid.parse(code)
- with self.assertNoMessages():
- self.checker.process_module(tree)
- self.checker.process_tokens(_tokenize_str(code))
-
- def testKeywordParensFalsePositive(self):
- self.checker._keywords_with_parens = set()
- code = "if 'bar' in (DICT or {}):"
- with self.assertNoMessages():
- self.checker._check_keyword_parentheses(_tokenize_str(code), start=2)
-
-
- class TestCheckSpace(CheckerTestCase):
- CHECKER_CLASS = FormatChecker
-
- def testParenthesesGood(self):
- good_cases = [
- '(a)\n',
- '(a * (b + c))\n',
- '(#\n a)\n',
- ]
- with self.assertNoMessages():
- for code in good_cases:
- self.checker.process_tokens(_tokenize_str(code))
-
- def testParenthesesBad(self):
- with self.assertAddsMessages(
- Message('bad-whitespace', line=1,
- args=('No', 'allowed', 'after', 'bracket', '( a)\n^'))):
- self.checker.process_tokens(_tokenize_str('( a)\n'))
-
- with self.assertAddsMessages(
- Message('bad-whitespace', line=1,
- args=('No', 'allowed', 'before', 'bracket', '(a )\n ^'))):
- self.checker.process_tokens(_tokenize_str('(a )\n'))
-
- with self.assertAddsMessages(
- Message('bad-whitespace', line=1,
- args=('No', 'allowed', 'before', 'bracket', 'foo (a)\n ^'))):
- self.checker.process_tokens(_tokenize_str('foo (a)\n'))
-
- with self.assertAddsMessages(
- Message('bad-whitespace', line=1,
- args=('No', 'allowed', 'before', 'bracket', '{1: 2} [1]\n ^'))):
- self.checker.process_tokens(_tokenize_str('{1: 2} [1]\n'))
-
- def testTrailingCommaGood(self):
- with self.assertNoMessages():
- self.checker.process_tokens(_tokenize_str('(a, )\n'))
- self.checker.process_tokens(_tokenize_str('(a,)\n'))
-
- self.checker.config.no_space_check = []
- with self.assertNoMessages():
- self.checker.process_tokens(_tokenize_str('(a,)\n'))
-
- @set_config(no_space_check=[])
- def testTrailingCommaBad(self):
- with self.assertAddsMessages(
- Message('bad-whitespace', line=1,
- args=('No', 'allowed', 'before', 'bracket', '(a, )\n ^'))):
- self.checker.process_tokens(_tokenize_str('(a, )\n'))
-
- def testComma(self):
- with self.assertAddsMessages(
- Message('bad-whitespace', line=1,
- args=('No', 'allowed', 'before', 'comma', '(a , b)\n ^'))):
- self.checker.process_tokens(_tokenize_str('(a , b)\n'))
-
- def testSpacesAllowedInsideSlices(self):
- good_cases = [
- '[a:b]\n',
- '[a : b]\n',
- '[a : ]\n',
- '[:a]\n',
- '[:]\n',
- '[::]\n',
- ]
- with self.assertNoMessages():
- for code in good_cases:
- self.checker.process_tokens(_tokenize_str(code))
-
- def testKeywordSpacingGood(self):
- with self.assertNoMessages():
- self.checker.process_tokens(_tokenize_str('foo(foo=bar)\n'))
- self.checker.process_tokens(_tokenize_str('foo(foo: int = bar)\n'))
- self.checker.process_tokens(_tokenize_str('foo(foo: module.classname = bar)\n'))
- self.checker.process_tokens(_tokenize_str('foo(foo: Dict[int, str] = bar)\n'))
- self.checker.process_tokens(_tokenize_str('foo(foo: \'int\' = bar)\n'))
- self.checker.process_tokens(_tokenize_str('foo(foo: Dict[int, \'str\'] = bar)\n'))
- self.checker.process_tokens(_tokenize_str('lambda x=1: x\n'))
-
- def testKeywordSpacingBad(self):
- with self.assertAddsMessages(
- Message('bad-whitespace', line=1,
- args=('No', 'allowed', 'before', 'keyword argument assignment',
- '(foo =bar)\n ^'))):
- self.checker.process_tokens(_tokenize_str('(foo =bar)\n'))
-
- with self.assertAddsMessages(
- Message('bad-whitespace', line=1,
- args=('No', 'allowed', 'after', 'keyword argument assignment',
- '(foo= bar)\n ^'))):
- self.checker.process_tokens(_tokenize_str('(foo= bar)\n'))
-
- with self.assertAddsMessages(
- Message('bad-whitespace', line=1,
- args=('No', 'allowed', 'around', 'keyword argument assignment',
- '(foo = bar)\n ^'))):
- self.checker.process_tokens(_tokenize_str('(foo = bar)\n'))
-
- with self.assertAddsMessages(
- Message('bad-whitespace', line=1,
- args=('Exactly one', 'required', 'before', 'keyword argument assignment',
- '(foo: int= bar)\n ^'))):
- self.checker.process_tokens(_tokenize_str('(foo: int= bar)\n'))
-
- with self.assertAddsMessages(
- Message('bad-whitespace', line=1,
- args=('Exactly one', 'required', 'after', 'keyword argument assignment',
- '(foo: int =bar)\n ^'))):
- self.checker.process_tokens(_tokenize_str('(foo: int =bar)\n'))
-
- with self.assertAddsMessages(
- Message('bad-whitespace', line=1,
- args=('Exactly one', 'required', 'around', 'keyword argument assignment',
- '(foo: int=bar)\n ^'))):
- self.checker.process_tokens(_tokenize_str('(foo: int=bar)\n'))
-
- with self.assertAddsMessages(
- Message('bad-whitespace', line=1,
- args=('Exactly one', 'required', 'around', 'keyword argument assignment',
- '(foo: List[int]=bar)\n ^'))):
- self.checker.process_tokens(_tokenize_str('(foo: List[int]=bar)\n'))
-
- def testOperatorSpacingGood(self):
- good_cases = [
- 'a = b\n'
- 'a < b\n'
- 'a\n< b\n',
- ]
- with self.assertNoMessages():
- for code in good_cases:
- self.checker.process_tokens(_tokenize_str(code))
-
- def testOperatorSpacingBad(self):
- with self.assertAddsMessages(
- Message('bad-whitespace', line=1,
- args=('Exactly one', 'required', 'before', 'comparison', 'a< b\n ^'))):
- self.checker.process_tokens(_tokenize_str('a< b\n'))
-
- with self.assertAddsMessages(
- Message('bad-whitespace', line=1,
- args=('Exactly one', 'required', 'after', 'comparison', 'a <b\n ^'))):
- self.checker.process_tokens(_tokenize_str('a <b\n'))
-
- with self.assertAddsMessages(
- Message('bad-whitespace', line=1,
- args=('Exactly one', 'required', 'around', 'comparison', 'a<b\n ^'))):
- self.checker.process_tokens(_tokenize_str('a<b\n'))
-
- with self.assertAddsMessages(
- Message('bad-whitespace', line=1,
- args=('Exactly one', 'required', 'around', 'comparison', 'a< b\n ^'))):
- self.checker.process_tokens(_tokenize_str('a< b\n'))
-
- def testEmptyLines(self):
- self.checker.config.no_space_check = []
- with self.assertAddsMessages(
- Message('trailing-whitespace', line=2)):
- self.checker.process_tokens(_tokenize_str('a = 1\n \nb = 2\n'))
-
- with self.assertAddsMessages(
- Message('trailing-whitespace', line=2)):
- self.checker.process_tokens(_tokenize_str('a = 1\n\t\nb = 2\n'))
-
- with self.assertAddsMessages(
- Message('trailing-whitespace', line=2)):
- self.checker.process_tokens(_tokenize_str('a = 1\n\v\nb = 2\n'))
-
- with self.assertNoMessages():
- self.checker.process_tokens(_tokenize_str('a = 1\n\f\nb = 2\n'))
-
- self.checker.config.no_space_check = ['empty-line']
- with self.assertNoMessages():
- self.checker.process_tokens(_tokenize_str('a = 1\n \nb = 2\n'))
-
- with self.assertNoMessages():
- self.checker.process_tokens(_tokenize_str('a = 1\n\t\nb = 2\n'))
-
- with self.assertNoMessages():
- self.checker.process_tokens(_tokenize_str('a = 1\n\v\nb = 2\n'))
|