Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

unittest_checker_format.py 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. # -*- coding: utf-8 -*-
  2. # Copyright (c) 2009-2011, 2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr>
  3. # Copyright (c) 2012 FELD Boris <lothiraldan@gmail.com>
  4. # Copyright (c) 2013-2014 Google, Inc.
  5. # Copyright (c) 2014-2017 Claudiu Popa <pcmanticore@gmail.com>
  6. # Copyright (c) 2014 buck <buck.2019@gmail.com>
  7. # Copyright (c) 2014 Arun Persaud <arun@nubati.net>
  8. # Copyright (c) 2015 Harut <yes@harutune.name>
  9. # Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro>
  10. # Copyright (c) 2016 Petr Pulc <petrpulc@gmail.com>
  11. # Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com>
  12. # Copyright (c) 2017 Krzysztof Czapla <k.czapla68@gmail.com>
  13. # Copyright (c) 2017 Łukasz Rogalski <rogalski.91@gmail.com>
  14. # Copyright (c) 2017 James M. Allen <james.m.allen@gmail.com>
  15. # Copyright (c) 2017 vinnyrose <vinnyrose@users.noreply.github.com>
  16. # Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  17. # For details: https://github.com/PyCQA/pylint/blob/master/COPYING
  18. """Check format checker helper functions"""
  19. from __future__ import unicode_literals
  20. import astroid
  21. from pylint.checkers.format import *
  22. from pylint.testutils import (
  23. CheckerTestCase, Message, set_config, _tokenize_str,
  24. )
  25. class TestMultiStatementLine(CheckerTestCase):
  26. CHECKER_CLASS = FormatChecker
  27. def testSingleLineIfStmts(self):
  28. stmt = astroid.extract_node("""
  29. if True: pass #@
  30. """)
  31. self.checker.config.single_line_if_stmt = False
  32. with self.assertAddsMessages(Message('multiple-statements', node=stmt.body[0])):
  33. self.visitFirst(stmt)
  34. self.checker.config.single_line_if_stmt = True
  35. with self.assertNoMessages():
  36. self.visitFirst(stmt)
  37. stmt = astroid.extract_node("""
  38. if True: pass #@
  39. else:
  40. pass
  41. """)
  42. with self.assertAddsMessages(Message('multiple-statements', node=stmt.body[0])):
  43. self.visitFirst(stmt)
  44. def testSingleLineClassStmts(self):
  45. stmt = astroid.extract_node("""
  46. class MyError(Exception): pass #@
  47. """)
  48. self.checker.config.single_line_class_stmt = False
  49. with self.assertAddsMessages(Message('multiple-statements', node=stmt.body[0])):
  50. self.visitFirst(stmt)
  51. self.checker.config.single_line_class_stmt = True
  52. with self.assertNoMessages():
  53. self.visitFirst(stmt)
  54. stmt = astroid.extract_node("""
  55. class MyError(Exception): a='a' #@
  56. """)
  57. self.checker.config.single_line_class_stmt = False
  58. with self.assertAddsMessages(Message('multiple-statements', node=stmt.body[0])):
  59. self.visitFirst(stmt)
  60. self.checker.config.single_line_class_stmt = True
  61. with self.assertNoMessages():
  62. self.visitFirst(stmt)
  63. stmt = astroid.extract_node("""
  64. class MyError(Exception): a='a'; b='b' #@
  65. """)
  66. self.checker.config.single_line_class_stmt = False
  67. with self.assertAddsMessages(Message('multiple-statements', node=stmt.body[0])):
  68. self.visitFirst(stmt)
  69. self.checker.config.single_line_class_stmt = True
  70. with self.assertAddsMessages(Message('multiple-statements', node=stmt.body[0])):
  71. self.visitFirst(stmt)
  72. def testTryExceptFinallyNoMultipleStatement(self):
  73. tree = astroid.extract_node("""
  74. try: #@
  75. pass
  76. except:
  77. pass
  78. finally:
  79. pass""")
  80. with self.assertNoMessages():
  81. self.visitFirst(tree)
  82. def visitFirst(self, tree):
  83. self.checker.process_tokens([])
  84. self.checker.visit_default(tree.body[0])
  85. class TestSuperfluousParentheses(CheckerTestCase):
  86. CHECKER_CLASS = FormatChecker
  87. def testCheckKeywordParensHandlesValidCases(self):
  88. self.checker._keywords_with_parens = set()
  89. cases = [
  90. 'if foo:',
  91. 'if foo():',
  92. 'if (x and y) or z:',
  93. 'assert foo()',
  94. 'assert ()',
  95. 'if (1, 2) in (3, 4):',
  96. 'if (a or b) in c:',
  97. 'return (x for x in x)',
  98. 'if (x for x in x):',
  99. 'for x in (x for x in x):',
  100. 'not (foo or bar)',
  101. 'not (foo or bar) and baz',
  102. ]
  103. with self.assertNoMessages():
  104. for code in cases:
  105. self.checker._check_keyword_parentheses(_tokenize_str(code), 0)
  106. def testCheckKeywordParensHandlesUnnecessaryParens(self):
  107. self.checker._keywords_with_parens = set()
  108. cases = [
  109. (Message('superfluous-parens', line=1, args='if'),
  110. 'if (foo):', 0),
  111. (Message('superfluous-parens', line=1, args='if'),
  112. 'if ((foo, bar)):', 0),
  113. (Message('superfluous-parens', line=1, args='if'),
  114. 'if (foo(bar)):', 0),
  115. (Message('superfluous-parens', line=1, args='return'),
  116. 'return ((x for x in x))', 0),
  117. (Message('superfluous-parens', line=1, args='not'),
  118. 'not (foo)', 0),
  119. (Message('superfluous-parens', line=1, args='not'),
  120. 'if not (foo):', 1),
  121. (Message('superfluous-parens', line=1, args='if'),
  122. 'if (not (foo)):', 0),
  123. (Message('superfluous-parens', line=1, args='not'),
  124. 'if (not (foo)):', 2),
  125. (Message('superfluous-parens', line=1, args='for'),
  126. 'for (x) in (1, 2, 3):', 0),
  127. (Message('superfluous-parens', line=1, args='if'),
  128. 'if (1) in (1, 2, 3):', 0),
  129. ]
  130. for msg, code, offset in cases:
  131. with self.assertAddsMessages(msg):
  132. self.checker._check_keyword_parentheses(_tokenize_str(code), offset)
  133. def testCheckIfArgsAreNotUnicode(self):
  134. self.checker._keywords_with_parens = set()
  135. cases = [(u'if (foo):', 0), (u'assert (1 == 1)', 0)]
  136. for code, offset in cases:
  137. self.checker._check_keyword_parentheses(_tokenize_str(code), offset)
  138. got = self.linter.release_messages()
  139. assert isinstance(got[-1].args, str)
  140. def testFuturePrintStatementWithoutParensWarning(self):
  141. code = """from __future__ import print_function
  142. print('Hello world!')
  143. """
  144. tree = astroid.parse(code)
  145. with self.assertNoMessages():
  146. self.checker.process_module(tree)
  147. self.checker.process_tokens(_tokenize_str(code))
  148. def testKeywordParensFalsePositive(self):
  149. self.checker._keywords_with_parens = set()
  150. code = "if 'bar' in (DICT or {}):"
  151. with self.assertNoMessages():
  152. self.checker._check_keyword_parentheses(_tokenize_str(code), start=2)
  153. class TestCheckSpace(CheckerTestCase):
  154. CHECKER_CLASS = FormatChecker
  155. def testParenthesesGood(self):
  156. good_cases = [
  157. '(a)\n',
  158. '(a * (b + c))\n',
  159. '(#\n a)\n',
  160. ]
  161. with self.assertNoMessages():
  162. for code in good_cases:
  163. self.checker.process_tokens(_tokenize_str(code))
  164. def testParenthesesBad(self):
  165. with self.assertAddsMessages(
  166. Message('bad-whitespace', line=1,
  167. args=('No', 'allowed', 'after', 'bracket', '( a)\n^'))):
  168. self.checker.process_tokens(_tokenize_str('( a)\n'))
  169. with self.assertAddsMessages(
  170. Message('bad-whitespace', line=1,
  171. args=('No', 'allowed', 'before', 'bracket', '(a )\n ^'))):
  172. self.checker.process_tokens(_tokenize_str('(a )\n'))
  173. with self.assertAddsMessages(
  174. Message('bad-whitespace', line=1,
  175. args=('No', 'allowed', 'before', 'bracket', 'foo (a)\n ^'))):
  176. self.checker.process_tokens(_tokenize_str('foo (a)\n'))
  177. with self.assertAddsMessages(
  178. Message('bad-whitespace', line=1,
  179. args=('No', 'allowed', 'before', 'bracket', '{1: 2} [1]\n ^'))):
  180. self.checker.process_tokens(_tokenize_str('{1: 2} [1]\n'))
  181. def testTrailingCommaGood(self):
  182. with self.assertNoMessages():
  183. self.checker.process_tokens(_tokenize_str('(a, )\n'))
  184. self.checker.process_tokens(_tokenize_str('(a,)\n'))
  185. self.checker.config.no_space_check = []
  186. with self.assertNoMessages():
  187. self.checker.process_tokens(_tokenize_str('(a,)\n'))
  188. @set_config(no_space_check=[])
  189. def testTrailingCommaBad(self):
  190. with self.assertAddsMessages(
  191. Message('bad-whitespace', line=1,
  192. args=('No', 'allowed', 'before', 'bracket', '(a, )\n ^'))):
  193. self.checker.process_tokens(_tokenize_str('(a, )\n'))
  194. def testComma(self):
  195. with self.assertAddsMessages(
  196. Message('bad-whitespace', line=1,
  197. args=('No', 'allowed', 'before', 'comma', '(a , b)\n ^'))):
  198. self.checker.process_tokens(_tokenize_str('(a , b)\n'))
  199. def testSpacesAllowedInsideSlices(self):
  200. good_cases = [
  201. '[a:b]\n',
  202. '[a : b]\n',
  203. '[a : ]\n',
  204. '[:a]\n',
  205. '[:]\n',
  206. '[::]\n',
  207. ]
  208. with self.assertNoMessages():
  209. for code in good_cases:
  210. self.checker.process_tokens(_tokenize_str(code))
  211. def testKeywordSpacingGood(self):
  212. with self.assertNoMessages():
  213. self.checker.process_tokens(_tokenize_str('foo(foo=bar)\n'))
  214. self.checker.process_tokens(_tokenize_str('foo(foo: int = bar)\n'))
  215. self.checker.process_tokens(_tokenize_str('foo(foo: module.classname = bar)\n'))
  216. self.checker.process_tokens(_tokenize_str('foo(foo: Dict[int, str] = bar)\n'))
  217. self.checker.process_tokens(_tokenize_str('foo(foo: \'int\' = bar)\n'))
  218. self.checker.process_tokens(_tokenize_str('foo(foo: Dict[int, \'str\'] = bar)\n'))
  219. self.checker.process_tokens(_tokenize_str('lambda x=1: x\n'))
  220. def testKeywordSpacingBad(self):
  221. with self.assertAddsMessages(
  222. Message('bad-whitespace', line=1,
  223. args=('No', 'allowed', 'before', 'keyword argument assignment',
  224. '(foo =bar)\n ^'))):
  225. self.checker.process_tokens(_tokenize_str('(foo =bar)\n'))
  226. with self.assertAddsMessages(
  227. Message('bad-whitespace', line=1,
  228. args=('No', 'allowed', 'after', 'keyword argument assignment',
  229. '(foo= bar)\n ^'))):
  230. self.checker.process_tokens(_tokenize_str('(foo= bar)\n'))
  231. with self.assertAddsMessages(
  232. Message('bad-whitespace', line=1,
  233. args=('No', 'allowed', 'around', 'keyword argument assignment',
  234. '(foo = bar)\n ^'))):
  235. self.checker.process_tokens(_tokenize_str('(foo = bar)\n'))
  236. with self.assertAddsMessages(
  237. Message('bad-whitespace', line=1,
  238. args=('Exactly one', 'required', 'before', 'keyword argument assignment',
  239. '(foo: int= bar)\n ^'))):
  240. self.checker.process_tokens(_tokenize_str('(foo: int= bar)\n'))
  241. with self.assertAddsMessages(
  242. Message('bad-whitespace', line=1,
  243. args=('Exactly one', 'required', 'after', 'keyword argument assignment',
  244. '(foo: int =bar)\n ^'))):
  245. self.checker.process_tokens(_tokenize_str('(foo: int =bar)\n'))
  246. with self.assertAddsMessages(
  247. Message('bad-whitespace', line=1,
  248. args=('Exactly one', 'required', 'around', 'keyword argument assignment',
  249. '(foo: int=bar)\n ^'))):
  250. self.checker.process_tokens(_tokenize_str('(foo: int=bar)\n'))
  251. with self.assertAddsMessages(
  252. Message('bad-whitespace', line=1,
  253. args=('Exactly one', 'required', 'around', 'keyword argument assignment',
  254. '(foo: List[int]=bar)\n ^'))):
  255. self.checker.process_tokens(_tokenize_str('(foo: List[int]=bar)\n'))
  256. def testOperatorSpacingGood(self):
  257. good_cases = [
  258. 'a = b\n'
  259. 'a < b\n'
  260. 'a\n< b\n',
  261. ]
  262. with self.assertNoMessages():
  263. for code in good_cases:
  264. self.checker.process_tokens(_tokenize_str(code))
  265. def testOperatorSpacingBad(self):
  266. with self.assertAddsMessages(
  267. Message('bad-whitespace', line=1,
  268. args=('Exactly one', 'required', 'before', 'comparison', 'a< b\n ^'))):
  269. self.checker.process_tokens(_tokenize_str('a< b\n'))
  270. with self.assertAddsMessages(
  271. Message('bad-whitespace', line=1,
  272. args=('Exactly one', 'required', 'after', 'comparison', 'a <b\n ^'))):
  273. self.checker.process_tokens(_tokenize_str('a <b\n'))
  274. with self.assertAddsMessages(
  275. Message('bad-whitespace', line=1,
  276. args=('Exactly one', 'required', 'around', 'comparison', 'a<b\n ^'))):
  277. self.checker.process_tokens(_tokenize_str('a<b\n'))
  278. with self.assertAddsMessages(
  279. Message('bad-whitespace', line=1,
  280. args=('Exactly one', 'required', 'around', 'comparison', 'a< b\n ^'))):
  281. self.checker.process_tokens(_tokenize_str('a< b\n'))
  282. def testEmptyLines(self):
  283. self.checker.config.no_space_check = []
  284. with self.assertAddsMessages(
  285. Message('trailing-whitespace', line=2)):
  286. self.checker.process_tokens(_tokenize_str('a = 1\n \nb = 2\n'))
  287. with self.assertAddsMessages(
  288. Message('trailing-whitespace', line=2)):
  289. self.checker.process_tokens(_tokenize_str('a = 1\n\t\nb = 2\n'))
  290. with self.assertAddsMessages(
  291. Message('trailing-whitespace', line=2)):
  292. self.checker.process_tokens(_tokenize_str('a = 1\n\v\nb = 2\n'))
  293. with self.assertNoMessages():
  294. self.checker.process_tokens(_tokenize_str('a = 1\n\f\nb = 2\n'))
  295. self.checker.config.no_space_check = ['empty-line']
  296. with self.assertNoMessages():
  297. self.checker.process_tokens(_tokenize_str('a = 1\n \nb = 2\n'))
  298. with self.assertNoMessages():
  299. self.checker.process_tokens(_tokenize_str('a = 1\n\t\nb = 2\n'))
  300. with self.assertNoMessages():
  301. self.checker.process_tokens(_tokenize_str('a = 1\n\v\nb = 2\n'))