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_python3.py 37KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041
  1. # -*- coding: utf-8 -*-
  2. # Copyright (c) 2014-2018 Claudiu Popa <pcmanticore@gmail.com>
  3. # Copyright (c) 2014-2015 Brett Cannon <brett@python.org>
  4. # Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro>
  5. # Copyright (c) 2015 Cosmin Poieana <cmin@ropython.org>
  6. # Copyright (c) 2015 Viorel Stirbu <viorels@gmail.com>
  7. # Copyright (c) 2016-2017 Roy Williams <roy.williams.iii@gmail.com>
  8. # Copyright (c) 2016 Roy Williams <rwilliams@lyft.com>
  9. # Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com>
  10. # Copyright (c) 2017 Daniel Miller <millerdev@gmail.com>
  11. # Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com>
  12. # Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  13. # For details: https://github.com/PyCQA/pylint/blob/master/COPYING
  14. """Tests for the python3 checkers."""
  15. from __future__ import absolute_import
  16. import sys
  17. import textwrap
  18. import pytest
  19. import astroid
  20. from pylint import testutils
  21. from pylint.checkers import python3 as checker
  22. from pylint.interfaces import INFERENCE_FAILURE, INFERENCE
  23. # Decorator for any tests that will fail under Python 3
  24. python2_only = pytest.mark.skipif(sys.version_info[0] > 2, reason='Python 2 only')
  25. # TODO(cpopa): Port these to the functional test framework instead.
  26. class TestPython3Checker(testutils.CheckerTestCase):
  27. CHECKER_CLASS = checker.Python3Checker
  28. def check_bad_builtin(self, builtin_name):
  29. node = astroid.extract_node(builtin_name + ' #@')
  30. message = builtin_name.lower() + '-builtin'
  31. with self.assertAddsMessages(testutils.Message(message, node=node)):
  32. self.checker.visit_name(node)
  33. @python2_only
  34. def test_bad_builtins(self):
  35. builtins = [
  36. 'apply',
  37. 'buffer',
  38. 'cmp',
  39. 'coerce',
  40. 'execfile',
  41. 'file',
  42. 'input',
  43. 'intern',
  44. 'long',
  45. 'raw_input',
  46. 'round',
  47. 'reduce',
  48. 'StandardError',
  49. 'unichr',
  50. 'unicode',
  51. 'xrange',
  52. 'reload',
  53. ]
  54. for builtin in builtins:
  55. self.check_bad_builtin(builtin)
  56. def as_iterable_in_for_loop_test(self, fxn):
  57. code = "for x in {}(): pass".format(fxn)
  58. module = astroid.parse(code)
  59. with self.assertNoMessages():
  60. self.walk(module)
  61. def as_used_by_iterable_in_for_loop_test(self, fxn):
  62. checker = '{}-builtin-not-iterating'.format(fxn)
  63. node = astroid.extract_node("""
  64. for x in (whatever(
  65. {}() #@
  66. )):
  67. pass
  68. """.format(fxn))
  69. message = testutils.Message(checker, node=node)
  70. with self.assertAddsMessages(message):
  71. self.checker.visit_call(node)
  72. def as_iterable_in_genexp_test(self, fxn):
  73. code = "x = (x for x in {}())".format(fxn)
  74. module = astroid.parse(code)
  75. with self.assertNoMessages():
  76. self.walk(module)
  77. def as_iterable_in_listcomp_test(self, fxn):
  78. code = "x = [x for x in {}(None, [1])]".format(fxn)
  79. module = astroid.parse(code)
  80. with self.assertNoMessages():
  81. self.walk(module)
  82. def as_used_in_variant_in_genexp_test(self, fxn):
  83. checker = '{}-builtin-not-iterating'.format(fxn)
  84. node = astroid.extract_node("""
  85. list(
  86. __({}(x))
  87. for x in [1]
  88. )
  89. """.format(fxn))
  90. message = testutils.Message(checker, node=node)
  91. with self.assertAddsMessages(message):
  92. self.checker.visit_call(node)
  93. def as_used_in_variant_in_listcomp_test(self, fxn):
  94. checker = '{}-builtin-not-iterating'.format(fxn)
  95. node = astroid.extract_node("""
  96. [
  97. __({}(None, x))
  98. for x in [[1]]]
  99. """.format(fxn))
  100. message = testutils.Message(checker, node=node)
  101. with self.assertAddsMessages(message):
  102. self.checker.visit_call(node)
  103. def as_argument_to_callable_constructor_test(self, fxn, callable_fn):
  104. module = astroid.parse("x = {}({}())".format(callable_fn, fxn))
  105. with self.assertNoMessages():
  106. self.walk(module)
  107. def as_argument_to_materialized_filter(self, callable_fn):
  108. module = astroid.parse("list(filter(None, {}()))".format(callable_fn))
  109. with self.assertNoMessages():
  110. self.walk(module)
  111. def as_argument_to_random_fxn_test(self, fxn):
  112. checker = '{}-builtin-not-iterating'.format(fxn)
  113. node = astroid.extract_node("""
  114. y(
  115. {}() #@
  116. )
  117. """.format(fxn))
  118. message = testutils.Message(checker, node=node)
  119. with self.assertAddsMessages(message):
  120. self.checker.visit_call(node)
  121. def as_argument_to_str_join_test(self, fxn):
  122. code = "x = ''.join({}())".format(fxn)
  123. module = astroid.parse(code)
  124. with self.assertNoMessages():
  125. self.walk(module)
  126. def as_iterable_in_unpacking(self, fxn):
  127. node = astroid.extract_node("""
  128. a, b = __({}())
  129. """.format(fxn))
  130. with self.assertNoMessages():
  131. self.checker.visit_call(node)
  132. def as_assignment(self, fxn):
  133. checker = '{}-builtin-not-iterating'.format(fxn)
  134. node = astroid.extract_node("""
  135. a = __({}())
  136. """.format(fxn))
  137. message = testutils.Message(checker, node=node)
  138. with self.assertAddsMessages(message):
  139. self.checker.visit_call(node)
  140. def iterating_context_tests(self, fxn):
  141. """Helper for verifying a function isn't used as an iterator."""
  142. self.as_iterable_in_for_loop_test(fxn)
  143. self.as_used_by_iterable_in_for_loop_test(fxn)
  144. self.as_iterable_in_genexp_test(fxn)
  145. self.as_iterable_in_listcomp_test(fxn)
  146. self.as_used_in_variant_in_genexp_test(fxn)
  147. self.as_used_in_variant_in_listcomp_test(fxn)
  148. self.as_argument_to_random_fxn_test(fxn)
  149. self.as_argument_to_str_join_test(fxn)
  150. self.as_iterable_in_unpacking(fxn)
  151. self.as_assignment(fxn)
  152. self.as_argument_to_materialized_filter(fxn)
  153. for func in ('iter', 'list', 'tuple', 'sorted',
  154. 'set', 'sum', 'any', 'all',
  155. 'enumerate', 'dict'):
  156. self.as_argument_to_callable_constructor_test(fxn, func)
  157. def test_dict_subclasses_methods_in_iterating_context(self):
  158. iterating, not_iterating = astroid.extract_node('''
  159. from __future__ import absolute_import
  160. from collections import defaultdict
  161. d = defaultdict(list)
  162. a, b = d.keys() #@
  163. x = d.keys() #@
  164. ''')
  165. with self.assertNoMessages():
  166. self.checker.visit_call(iterating.value)
  167. message = testutils.Message('dict-keys-not-iterating', node=not_iterating.value)
  168. with self.assertAddsMessages(message):
  169. self.checker.visit_call(not_iterating.value)
  170. def test_dict_methods_in_iterating_context(self):
  171. iterating_code = [
  172. 'for x in {}: pass',
  173. '(x for x in {})',
  174. '[x for x in {}]',
  175. 'func({})',
  176. 'a, b = {}',
  177. ]
  178. non_iterating_code = [
  179. 'x = __({}())',
  180. '__({}())[0]',
  181. ]
  182. for method in ('keys', 'items', 'values'):
  183. dict_method = '{{}}.{}'.format(method)
  184. for code in iterating_code:
  185. with_value = code.format(dict_method)
  186. module = astroid.parse(with_value)
  187. with self.assertNoMessages():
  188. self.walk(module)
  189. for code in non_iterating_code:
  190. with_value = code.format(dict_method)
  191. node = astroid.extract_node(with_value)
  192. checker = 'dict-{}-not-iterating'.format(method)
  193. message = testutils.Message(checker, node=node)
  194. with self.assertAddsMessages(message):
  195. self.checker.visit_call(node)
  196. def test_map_in_iterating_context(self):
  197. self.iterating_context_tests('map')
  198. def test_zip_in_iterating_context(self):
  199. self.iterating_context_tests('zip')
  200. def test_range_in_iterating_context(self):
  201. self.iterating_context_tests('range')
  202. def test_filter_in_iterating_context(self):
  203. self.iterating_context_tests('filter')
  204. def defined_method_test(self, method, warning):
  205. """Helper for verifying that a certain method is not defined."""
  206. node = astroid.extract_node("""
  207. class Foo(object):
  208. def __{0}__(self, other): #@
  209. pass""".format(method))
  210. message = testutils.Message(warning, node=node)
  211. with self.assertAddsMessages(message):
  212. self.checker.visit_functiondef(node)
  213. def test_delslice_method(self):
  214. self.defined_method_test('delslice', 'delslice-method')
  215. def test_getslice_method(self):
  216. self.defined_method_test('getslice', 'getslice-method')
  217. def test_setslice_method(self):
  218. self.defined_method_test('setslice', 'setslice-method')
  219. def test_coerce_method(self):
  220. self.defined_method_test('coerce', 'coerce-method')
  221. def test_oct_method(self):
  222. self.defined_method_test('oct', 'oct-method')
  223. def test_hex_method(self):
  224. self.defined_method_test('hex', 'hex-method')
  225. def test_nonzero_method(self):
  226. self.defined_method_test('nonzero', 'nonzero-method')
  227. def test_cmp_method(self):
  228. self.defined_method_test('cmp', 'cmp-method')
  229. def test_div_method(self):
  230. self.defined_method_test('div', 'div-method')
  231. def test_idiv_method(self):
  232. self.defined_method_test('idiv', 'idiv-method')
  233. def test_rdiv_method(self):
  234. self.defined_method_test('rdiv', 'rdiv-method')
  235. def test_eq_and_hash_method(self):
  236. """Helper for verifying that a certain method is not defined."""
  237. node = astroid.extract_node("""
  238. class Foo(object): #@
  239. def __eq__(self, other):
  240. pass
  241. def __hash__(self):
  242. pass""")
  243. with self.assertNoMessages():
  244. self.checker.visit_classdef(node)
  245. def test_eq_and_hash_is_none(self):
  246. """Helper for verifying that a certain method is not defined."""
  247. node = astroid.extract_node("""
  248. class Foo(object): #@
  249. def __eq__(self, other):
  250. pass
  251. __hash__ = None""")
  252. with self.assertNoMessages():
  253. self.checker.visit_classdef(node)
  254. def test_eq_without_hash_method(self):
  255. """Helper for verifying that a certain method is not defined."""
  256. node = astroid.extract_node("""
  257. class Foo(object): #@
  258. def __eq__(self, other):
  259. pass""")
  260. message = testutils.Message('eq-without-hash', node=node)
  261. with self.assertAddsMessages(message):
  262. self.checker.visit_classdef(node)
  263. @python2_only
  264. def test_print_statement(self):
  265. node = astroid.extract_node('print "Hello, World!" #@')
  266. message = testutils.Message('print-statement', node=node)
  267. with self.assertAddsMessages(message):
  268. self.checker.visit_print(node)
  269. @python2_only
  270. def test_backtick(self):
  271. node = astroid.extract_node('`test`')
  272. message = testutils.Message('backtick', node=node)
  273. with self.assertAddsMessages(message):
  274. self.checker.visit_repr(node)
  275. def test_relative_import(self):
  276. node = astroid.extract_node('import string #@')
  277. message = testutils.Message('no-absolute-import', node=node)
  278. with self.assertAddsMessages(message):
  279. self.checker.visit_import(node)
  280. with self.assertNoMessages():
  281. # message should only be added once
  282. self.checker.visit_import(node)
  283. def test_relative_from_import(self):
  284. node = astroid.extract_node('from os import path #@')
  285. message = testutils.Message('no-absolute-import', node=node)
  286. with self.assertAddsMessages(message):
  287. self.checker.visit_importfrom(node)
  288. with self.assertNoMessages():
  289. # message should only be added once
  290. self.checker.visit_importfrom(node)
  291. def test_absolute_import(self):
  292. module_import = astroid.parse(
  293. 'from __future__ import absolute_import; import os')
  294. module_from = astroid.parse(
  295. 'from __future__ import absolute_import; from os import path')
  296. with self.assertNoMessages():
  297. for module in (module_import, module_from):
  298. self.walk(module)
  299. def test_import_star_module_level(self):
  300. node = astroid.extract_node('''
  301. def test():
  302. from lala import * #@
  303. ''')
  304. absolute = testutils.Message('no-absolute-import', node=node)
  305. star = testutils.Message('import-star-module-level', node=node)
  306. with self.assertAddsMessages(absolute, star):
  307. self.checker.visit_importfrom(node)
  308. def test_division(self):
  309. node = astroid.extract_node('3 / 2 #@')
  310. message = testutils.Message('old-division', node=node)
  311. with self.assertAddsMessages(message):
  312. self.checker.visit_binop(node)
  313. def test_division_with_future_statement(self):
  314. module = astroid.parse('from __future__ import division; 3 / 2')
  315. with self.assertNoMessages():
  316. self.walk(module)
  317. def test_floor_division(self):
  318. node = astroid.extract_node(' 3 // 2 #@')
  319. with self.assertNoMessages():
  320. self.checker.visit_binop(node)
  321. def test_division_by_float(self):
  322. left_node = astroid.extract_node('3.0 / 2 #@')
  323. right_node = astroid.extract_node(' 3 / 2.0 #@')
  324. with self.assertNoMessages():
  325. for node in (left_node, right_node):
  326. self.checker.visit_binop(node)
  327. def test_dict_iter_method(self):
  328. for meth in ('keys', 'values', 'items'):
  329. node = astroid.extract_node('x.iter%s() #@' % meth)
  330. message = testutils.Message('dict-iter-method', node=node)
  331. with self.assertAddsMessages(message):
  332. self.checker.visit_call(node)
  333. def test_dict_iter_method_on_dict(self):
  334. nodes = astroid.extract_node('''
  335. from collections import defaultdict
  336. {}.iterkeys() #@
  337. defaultdict(list).iterkeys() #@
  338. class Someclass(dict):
  339. pass
  340. Someclass().iterkeys() #@
  341. ''')
  342. for node in nodes:
  343. message = testutils.Message('dict-iter-method', node=node)
  344. with self.assertAddsMessages(message):
  345. self.checker.visit_call(node)
  346. def test_dict_not_iter_method(self):
  347. arg_node = astroid.extract_node('x.iterkeys(x) #@')
  348. stararg_node = astroid.extract_node('x.iterkeys(*x) #@')
  349. kwarg_node = astroid.extract_node('x.iterkeys(y=x) #@')
  350. non_dict_node = astroid.extract_node('x=[]\nx.iterkeys() #@')
  351. with self.assertNoMessages():
  352. for node in (arg_node, stararg_node, kwarg_node, non_dict_node):
  353. self.checker.visit_call(node)
  354. def test_dict_view_method(self):
  355. for meth in ('keys', 'values', 'items'):
  356. node = astroid.extract_node('x.view%s() #@' % meth)
  357. message = testutils.Message('dict-view-method', node=node)
  358. with self.assertAddsMessages(message):
  359. self.checker.visit_call(node)
  360. def test_dict_view_method_on_dict(self):
  361. nodes = astroid.extract_node('''
  362. from collections import defaultdict
  363. {}.viewkeys() #@
  364. defaultdict(list).viewkeys() #@
  365. class Someclass(dict):
  366. pass
  367. Someclass().viewkeys() #@
  368. ''')
  369. for node in nodes:
  370. message = testutils.Message('dict-view-method', node=node)
  371. with self.assertAddsMessages(message):
  372. self.checker.visit_call(node)
  373. def test_dict_not_view_method(self):
  374. arg_node = astroid.extract_node('x.viewkeys(x) #@')
  375. stararg_node = astroid.extract_node('x.viewkeys(*x) #@')
  376. kwarg_node = astroid.extract_node('x.viewkeys(y=x) #@')
  377. non_dict_node = astroid.extract_node('x=[]\nx.viewkeys() #@')
  378. with self.assertNoMessages():
  379. for node in (arg_node, stararg_node, kwarg_node, non_dict_node):
  380. self.checker.visit_call(node)
  381. def test_next_method(self):
  382. node = astroid.extract_node('x.next() #@')
  383. message = testutils.Message('next-method-called', node=node)
  384. with self.assertAddsMessages(message):
  385. self.checker.visit_call(node)
  386. def test_not_next_method(self):
  387. arg_node = astroid.extract_node('x.next(x) #@')
  388. stararg_node = astroid.extract_node('x.next(*x) #@')
  389. kwarg_node = astroid.extract_node('x.next(y=x) #@')
  390. with self.assertNoMessages():
  391. for node in (arg_node, stararg_node, kwarg_node):
  392. self.checker.visit_call(node)
  393. def test_metaclass_assignment(self):
  394. node = astroid.extract_node("""
  395. class Foo(object): #@
  396. __metaclass__ = type""")
  397. message = testutils.Message('metaclass-assignment', node=node)
  398. with self.assertAddsMessages(message):
  399. self.checker.visit_classdef(node)
  400. def test_metaclass_global_assignment(self):
  401. module = astroid.parse('__metaclass__ = type')
  402. with self.assertNoMessages():
  403. self.walk(module)
  404. @python2_only
  405. def test_parameter_unpacking(self):
  406. node = astroid.extract_node('def func((a, b)):#@\n pass')
  407. arg = node.args.args[0]
  408. with self.assertAddsMessages(testutils.Message('parameter-unpacking', node=arg)):
  409. self.checker.visit_arguments(node.args)
  410. @python2_only
  411. def test_old_raise_syntax(self):
  412. node = astroid.extract_node('raise Exception, "test"')
  413. message = testutils.Message('old-raise-syntax', node=node)
  414. with self.assertAddsMessages(message):
  415. self.checker.visit_raise(node)
  416. node = astroid.extract_node('raise Exception, "test", tb')
  417. message = testutils.Message('old-raise-syntax', node=node)
  418. with self.assertAddsMessages(message):
  419. self.checker.visit_raise(node)
  420. def test_xreadlines_attribute(self):
  421. node = astroid.extract_node("""
  422. f.xreadlines #@
  423. """)
  424. message = testutils.Message('xreadlines-attribute', node=node)
  425. with self.assertAddsMessages(message):
  426. self.checker.visit_attribute(node)
  427. def test_exception_message_attribute(self):
  428. node = astroid.extract_node("""
  429. try:
  430. raise Exception("test")
  431. except Exception as e:
  432. e.message #@
  433. """)
  434. message = testutils.Message('exception-message-attribute', node=node)
  435. with self.assertAddsMessages(message):
  436. self.checker.visit_attribute(node)
  437. def test_normal_message_attribute(self):
  438. node = astroid.extract_node("""
  439. e.message #@
  440. """)
  441. with self.assertNoMessages():
  442. self.checker.visit_attribute(node)
  443. def test_invalid_codec(self):
  444. node = astroid.extract_node('foobar.encode("hex") #@')
  445. message = testutils.Message('invalid-str-codec', node=node)
  446. with self.assertAddsMessages(message):
  447. self.checker.visit_call(node)
  448. def test_valid_codec(self):
  449. node = astroid.extract_node('foobar.encode("ascii", "ignore") #@')
  450. with self.assertNoMessages():
  451. self.checker.visit_call(node)
  452. def test_visit_call_with_kwarg(self):
  453. node = astroid.extract_node('foobar.raz(encoding="hex") #@')
  454. with self.assertNoMessages():
  455. self.checker.visit_call(node)
  456. def test_invalid_open_codec(self):
  457. node = astroid.extract_node('open(foobar, encoding="hex") #@')
  458. message = testutils.Message('invalid-str-codec', node=node)
  459. with self.assertAddsMessages(message):
  460. self.checker.visit_call(node)
  461. def test_valid_open_codec(self):
  462. node = astroid.extract_node('open(foobar, encoding="palmos") #@')
  463. with self.assertNoMessages():
  464. self.checker.visit_call(node)
  465. @python2_only
  466. def test_raising_string(self):
  467. node = astroid.extract_node('raise "Test"')
  468. message = testutils.Message('raising-string', node=node)
  469. with self.assertAddsMessages(message):
  470. self.checker.visit_raise(node)
  471. @python2_only
  472. def test_checker_disabled_by_default(self):
  473. node = astroid.parse(textwrap.dedent("""
  474. abc = 1l
  475. raise Exception, "test"
  476. raise "test"
  477. `abc`
  478. """))
  479. with self.assertNoMessages():
  480. self.walk(node)
  481. def test_using_cmp_argument(self):
  482. nodes = astroid.extract_node("""
  483. [].sort(cmp=lambda x: x) #@
  484. a = list(range(x))
  485. a.sort(cmp=lambda x: x) #@
  486. sorted([], cmp=lambda x: x) #@
  487. """)
  488. for node in nodes:
  489. message = testutils.Message('using-cmp-argument', node=node)
  490. with self.assertAddsMessages(message):
  491. self.checker.visit_call(node)
  492. def test_sys_maxint(self):
  493. node = astroid.extract_node('''
  494. import sys
  495. sys.maxint #@
  496. ''')
  497. message = testutils.Message('sys-max-int', node=node)
  498. with self.assertAddsMessages(message):
  499. self.checker.visit_attribute(node)
  500. def test_itertools_izip(self):
  501. node = astroid.extract_node('''
  502. from itertools import izip #@
  503. ''')
  504. absolute_import_message = testutils.Message('no-absolute-import', node=node)
  505. message = testutils.Message('deprecated-itertools-function', node=node)
  506. with self.assertAddsMessages(absolute_import_message, message):
  507. self.checker.visit_importfrom(node)
  508. def test_deprecated_types_fields(self):
  509. node = astroid.extract_node('''
  510. from types import StringType #@
  511. ''')
  512. absolute_import_message = testutils.Message('no-absolute-import', node=node)
  513. message = testutils.Message('deprecated-types-field', node=node)
  514. with self.assertAddsMessages(absolute_import_message, message):
  515. self.checker.visit_importfrom(node)
  516. def test_sys_maxint_imort_from(self):
  517. node = astroid.extract_node('''
  518. from sys import maxint #@
  519. ''')
  520. absolute_import_message = testutils.Message('no-absolute-import', node=node)
  521. message = testutils.Message('sys-max-int', node=node)
  522. with self.assertAddsMessages(absolute_import_message, message):
  523. self.checker.visit_importfrom(node)
  524. def test_object_maxint(self):
  525. node = astroid.extract_node('''
  526. sys = object()
  527. sys.maxint #@
  528. ''')
  529. with self.assertNoMessages():
  530. self.checker.visit_attribute(node)
  531. def test_bad_import(self):
  532. node = astroid.extract_node('''
  533. import urllib2, sys #@
  534. ''')
  535. absolute_import_message = testutils.Message('no-absolute-import', node=node)
  536. message = testutils.Message('bad-python3-import', node=node)
  537. with self.assertAddsMessages(absolute_import_message, message):
  538. self.checker.visit_import(node)
  539. @python2_only
  540. def test_bad_import_not_on_relative(self):
  541. samples = [
  542. 'from .commands import titi',
  543. 'from . import commands',
  544. ]
  545. for code in samples:
  546. node = astroid.extract_node(code)
  547. absolute_import_message = testutils.Message('no-absolute-import', node=node)
  548. with self.assertAddsMessages(absolute_import_message):
  549. self.checker.visit_importfrom(node)
  550. self.checker._future_absolute_import = False
  551. def test_bad_import_conditional(self):
  552. node = astroid.extract_node('''
  553. import six
  554. if six.PY2:
  555. import urllib2 #@
  556. ''')
  557. absolute_import_message = testutils.Message('no-absolute-import', node=node)
  558. with self.assertAddsMessages(absolute_import_message):
  559. self.checker.visit_import(node)
  560. def test_bad_import_try_except_handler(self):
  561. node = astroid.extract_node('''
  562. try:
  563. from hashlib import sha
  564. except:
  565. import sha #@
  566. ''')
  567. absolute_import_message = testutils.Message('no-absolute-import', node=node)
  568. with self.assertAddsMessages(absolute_import_message):
  569. self.checker.visit_import(node)
  570. def test_bad_import_try(self):
  571. node = astroid.extract_node('''
  572. try:
  573. import md5 #@
  574. except:
  575. from hashlib import md5
  576. finally:
  577. pass
  578. ''')
  579. absolute_import_message = testutils.Message('no-absolute-import', node=node)
  580. with self.assertAddsMessages(absolute_import_message):
  581. self.checker.visit_import(node)
  582. def test_bad_import_try_finally(self):
  583. node = astroid.extract_node('''
  584. try:
  585. import Queue #@
  586. finally:
  587. import queue
  588. ''')
  589. absolute_import_message = testutils.Message('no-absolute-import', node=node)
  590. message = testutils.Message('bad-python3-import', node=node)
  591. with self.assertAddsMessages(absolute_import_message, message):
  592. self.checker.visit_import(node)
  593. def test_bad_import_from(self):
  594. node = astroid.extract_node('''
  595. from cStringIO import StringIO #@
  596. ''')
  597. absolute_import_message = testutils.Message('no-absolute-import', node=node)
  598. message = testutils.Message('bad-python3-import', node=node)
  599. with self.assertAddsMessages(absolute_import_message, message):
  600. self.checker.visit_importfrom(node)
  601. def test_bad_string_attribute(self):
  602. node = astroid.extract_node('''
  603. import string
  604. string.maketrans #@
  605. ''')
  606. message = testutils.Message('deprecated-string-function', node=node)
  607. with self.assertAddsMessages(message):
  608. self.checker.visit_attribute(node)
  609. def test_bad_operator_attribute(self):
  610. node = astroid.extract_node('''
  611. import operator
  612. operator.div #@
  613. ''')
  614. message = testutils.Message('deprecated-operator-function', node=node)
  615. with self.assertAddsMessages(message):
  616. self.checker.visit_attribute(node)
  617. def test_comprehension_escape(self):
  618. assign, escaped_node = astroid.extract_node('''
  619. a = [i for i in range(10)] #@
  620. i #@
  621. ''')
  622. good_module = astroid.parse('''
  623. {c for c in range(10)} #@
  624. {j:j for j in range(10)} #@
  625. [image_child] = [x for x in range(10)]
  626. thumbnail = func(__(image_child))
  627. ''')
  628. message = testutils.Message('comprehension-escape', node=escaped_node)
  629. with self.assertAddsMessages(message):
  630. self.checker.visit_listcomp(assign.value)
  631. with self.assertNoMessages():
  632. self.walk(good_module)
  633. def test_comprehension_escape_newly_introduced(self):
  634. node = astroid.extract_node('''
  635. [i for i in range(3)]
  636. for i in range(3):
  637. i
  638. ''')
  639. with self.assertNoMessages():
  640. self.walk(node)
  641. def test_exception_escape(self):
  642. module = astroid.parse('''
  643. try: 1/0
  644. except ValueError as exc:
  645. pass
  646. exc #@
  647. try:
  648. 2/0
  649. except (ValueError, TypeError) as exc:
  650. exc = 2
  651. exc #@
  652. try:
  653. 2/0
  654. except (ValueError, TypeError): #@
  655. exc = 2
  656. ''')
  657. message = testutils.Message('exception-escape', node=module.body[1].value)
  658. with self.assertAddsMessages(message):
  659. self.checker.visit_excepthandler(module.body[0].handlers[0])
  660. with self.assertNoMessages():
  661. self.checker.visit_excepthandler(module.body[2].handlers[0])
  662. self.checker.visit_excepthandler(module.body[4].handlers[0])
  663. def test_bad_sys_attribute(self):
  664. node = astroid.extract_node('''
  665. import sys
  666. sys.exc_clear #@
  667. ''')
  668. message = testutils.Message('deprecated-sys-function', node=node)
  669. with self.assertAddsMessages(message):
  670. self.checker.visit_attribute(node)
  671. def test_bad_urllib_attribute(self):
  672. nodes = astroid.extract_node('''
  673. import urllib
  674. urllib.addbase #@
  675. urllib.splithost #@
  676. urllib.urlretrieve #@
  677. urllib.urlopen #@
  678. urllib.urlencode #@
  679. ''')
  680. for node in nodes:
  681. message = testutils.Message('deprecated-urllib-function', node=node)
  682. with self.assertAddsMessages(message):
  683. self.checker.visit_attribute(node)
  684. def test_ok_string_attribute(self):
  685. node = astroid.extract_node('''
  686. import string
  687. string.ascii_letters #@
  688. ''')
  689. with self.assertNoMessages():
  690. self.checker.visit_attribute(node)
  691. def test_bad_string_call(self):
  692. node = astroid.extract_node('''
  693. import string
  694. string.upper("hello world") #@
  695. ''')
  696. message = testutils.Message('deprecated-string-function', node=node)
  697. with self.assertAddsMessages(message):
  698. self.checker.visit_call(node)
  699. def test_ok_shadowed_call(self):
  700. node = astroid.extract_node('''
  701. import six.moves.configparser
  702. six.moves.configparser.ConfigParser() #@
  703. ''')
  704. with self.assertNoMessages():
  705. self.checker.visit_call(node)
  706. def test_ok_string_call(self):
  707. node = astroid.extract_node('''
  708. import string
  709. string.Foramtter() #@
  710. ''')
  711. with self.assertNoMessages():
  712. self.checker.visit_call(node)
  713. def test_bad_string_import_from(self):
  714. node = astroid.extract_node('''
  715. from string import atoi #@
  716. ''')
  717. absolute_import_message = testutils.Message('no-absolute-import', node=node)
  718. message = testutils.Message('deprecated-string-function', node=node)
  719. with self.assertAddsMessages(absolute_import_message, message):
  720. self.checker.visit_importfrom(node)
  721. def test_ok_string_import_from(self):
  722. node = astroid.extract_node('''
  723. from string import digits #@
  724. ''')
  725. absolute_import_message = testutils.Message('no-absolute-import', node=node)
  726. with self.assertAddsMessages(absolute_import_message):
  727. self.checker.visit_importfrom(node)
  728. def test_bad_str_translate_call_string_literal(self):
  729. node = astroid.extract_node('''
  730. foobar.translate(None, 'abc123') #@
  731. ''')
  732. message = testutils.Message('deprecated-str-translate-call', node=node,
  733. confidence=INFERENCE_FAILURE)
  734. with self.assertAddsMessages(message):
  735. self.checker.visit_call(node)
  736. def test_bad_str_translate_call_variable(self):
  737. node = astroid.extract_node('''
  738. def raz(foobar):
  739. foobar.translate(None, 'hello') #@
  740. ''')
  741. message = testutils.Message('deprecated-str-translate-call', node=node,
  742. confidence=INFERENCE_FAILURE)
  743. with self.assertAddsMessages(message):
  744. self.checker.visit_call(node)
  745. def test_bad_str_translate_call_infer_str(self):
  746. node = astroid.extract_node('''
  747. foobar = "hello world"
  748. foobar.translate(None, foobar) #@
  749. ''')
  750. message = testutils.Message('deprecated-str-translate-call', node=node,
  751. confidence=INFERENCE)
  752. with self.assertAddsMessages(message):
  753. self.checker.visit_call(node)
  754. def test_ok_str_translate_call_integer(self):
  755. node = astroid.extract_node('''
  756. foobar.translate(None, 33) #@
  757. ''')
  758. with self.assertNoMessages():
  759. self.checker.visit_call(node)
  760. def test_ok_str_translate_call_keyword(self):
  761. node = astroid.extract_node('''
  762. foobar.translate(None, 'foobar', raz=33) #@
  763. ''')
  764. with self.assertNoMessages():
  765. self.checker.visit_call(node)
  766. def test_ok_str_translate_call_not_str(self):
  767. node = astroid.extract_node('''
  768. foobar = {}
  769. foobar.translate(None, 'foobar') #@
  770. ''')
  771. with self.assertNoMessages():
  772. self.checker.visit_call(node)
  773. def test_non_py2_conditional(self):
  774. code = '''
  775. from __future__ import absolute_import
  776. import sys
  777. x = {}
  778. if sys.maxsize:
  779. x.iterkeys() #@
  780. '''
  781. node = astroid.extract_node(code)
  782. module = node.parent.parent
  783. message = testutils.Message('dict-iter-method', node=node)
  784. with self.assertAddsMessages(message):
  785. self.walk(module)
  786. def test_six_conditional(self):
  787. code = '''
  788. from __future__ import absolute_import
  789. import six
  790. x = {}
  791. if six.PY2:
  792. x.iterkeys()
  793. '''
  794. module = astroid.parse(code)
  795. with self.assertNoMessages():
  796. self.walk(module)
  797. def test_versioninfo_conditional(self):
  798. code = '''
  799. from __future__ import absolute_import
  800. import sys
  801. x = {}
  802. if sys.version_info[0] == 2:
  803. x.iterkeys()
  804. '''
  805. module = astroid.parse(code)
  806. with self.assertNoMessages():
  807. self.walk(module)
  808. def test_versioninfo_tuple_conditional(self):
  809. code = '''
  810. from __future__ import absolute_import
  811. import sys
  812. x = {}
  813. if sys.version_info == (2, 7):
  814. x.iterkeys()
  815. '''
  816. module = astroid.parse(code)
  817. with self.assertNoMessages():
  818. self.walk(module)
  819. def test_six_ifexp_conditional(self):
  820. code = '''
  821. from __future__ import absolute_import
  822. import six
  823. import string
  824. string.translate if six.PY2 else None
  825. '''
  826. module = astroid.parse(code)
  827. with self.assertNoMessages():
  828. self.walk(module)
  829. def test_next_defined(self):
  830. node = astroid.extract_node("""
  831. class Foo(object):
  832. def next(self): #@
  833. pass""")
  834. message = testutils.Message('next-method-defined', node=node)
  835. with self.assertAddsMessages(message):
  836. self.checker.visit_functiondef(node)
  837. def test_next_defined_too_many_args(self):
  838. node = astroid.extract_node("""
  839. class Foo(object):
  840. def next(self, foo=None): #@
  841. pass""")
  842. with self.assertNoMessages():
  843. self.checker.visit_functiondef(node)
  844. def test_next_defined_static_method_too_many_args(self):
  845. node = astroid.extract_node("""
  846. class Foo(object):
  847. @staticmethod
  848. def next(self): #@
  849. pass""")
  850. with self.assertNoMessages():
  851. self.checker.visit_functiondef(node)
  852. def test_next_defined_static_method(self):
  853. node = astroid.extract_node("""
  854. class Foo(object):
  855. @staticmethod
  856. def next(): #@
  857. pass""")
  858. message = testutils.Message('next-method-defined', node=node)
  859. with self.assertAddsMessages(message):
  860. self.checker.visit_functiondef(node)
  861. def test_next_defined_class_method(self):
  862. node = astroid.extract_node("""
  863. class Foo(object):
  864. @classmethod
  865. def next(cls): #@
  866. pass""")
  867. message = testutils.Message('next-method-defined', node=node)
  868. with self.assertAddsMessages(message):
  869. self.checker.visit_functiondef(node)
  870. @python2_only
  871. class TestPython3TokenChecker(testutils.CheckerTestCase):
  872. CHECKER_CLASS = checker.Python3TokenChecker
  873. def _test_token_message(self, code, symbolic_message):
  874. tokens = testutils._tokenize_str(code)
  875. message = testutils.Message(symbolic_message, line=1)
  876. with self.assertAddsMessages(message):
  877. self.checker.process_tokens(tokens)
  878. def test_long_suffix(self):
  879. for code in ("1l", "1L"):
  880. self._test_token_message(code, 'long-suffix')
  881. def test_old_ne_operator(self):
  882. self._test_token_message("1 <> 2", "old-ne-operator")
  883. def test_invalid_string_literal(self):
  884. self._test_token_message("a = ur'aaa'", 'invalid-unicode-literal')
  885. def test_old_octal_literal(self):
  886. for octal in ("045", "055", "075", "077", "076543"):
  887. self._test_token_message(octal, "old-octal-literal")
  888. # Make sure we are catching only octals.
  889. for non_octal in ("45", "00", "085", "08", "1"):
  890. tokens = testutils._tokenize_str(non_octal)
  891. with self.assertNoMessages():
  892. self.checker.process_tokens(tokens)
  893. def test_non_ascii_bytes_literal(self):
  894. code = 'b"测试"'
  895. self._test_token_message(code, 'non-ascii-bytes-literal')
  896. for code in ("测试", u"测试", u'abcdef', b'\x80'):
  897. tokens = testutils._tokenize_str(code)
  898. with self.assertNoMessages():
  899. self.checker.process_tokens(tokens)