PageRenderTime 64ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 1ms

/pymode/libs/pylint/checkers/variables.py

https://gitlab.com/vim-IDE/python-mode
Python | 1069 lines | 938 code | 38 blank | 93 comment | 49 complexity | ac5d65c35172225683215370b5a6aa03 MD5 | raw file
  1. # Copyright (c) 2003-2014 LOGILAB S.A. (Paris, FRANCE).
  2. # http://www.logilab.fr/ -- mailto:contact@logilab.fr
  3. #
  4. # This program is free software; you can redistribute it and/or modify it under
  5. # the terms of the GNU General Public License as published by the Free Software
  6. # Foundation; either version 2 of the License, or (at your option) any later
  7. # version.
  8. #
  9. # This program is distributed in the hope that it will be useful, but WITHOUT
  10. # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  11. # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License along with
  14. # this program; if not, write to the Free Software Foundation, Inc.,
  15. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  16. """variables checkers for Python code
  17. """
  18. import os
  19. import sys
  20. import re
  21. from copy import copy
  22. import astroid
  23. from astroid import are_exclusive, builtin_lookup
  24. from astroid import modutils
  25. from pylint.interfaces import IAstroidChecker, INFERENCE, INFERENCE_FAILURE, HIGH
  26. from pylint.utils import get_global_option
  27. from pylint.checkers import BaseChecker
  28. from pylint.checkers.utils import (
  29. PYMETHODS, is_ancestor_name, is_builtin,
  30. is_defined_before, is_error, is_func_default, is_func_decorator,
  31. assign_parent, check_messages, is_inside_except, clobber_in_except,
  32. get_all_elements, has_known_bases)
  33. import six
  34. SPECIAL_OBJ = re.compile("^_{2}[a-z]+_{2}$")
  35. PY3K = sys.version_info >= (3, 0)
  36. def in_for_else_branch(parent, stmt):
  37. """Returns True if stmt in inside the else branch for a parent For stmt."""
  38. return (isinstance(parent, astroid.For) and
  39. any(else_stmt.parent_of(stmt) for else_stmt in parent.orelse))
  40. def overridden_method(klass, name):
  41. """get overridden method if any"""
  42. try:
  43. parent = next(klass.local_attr_ancestors(name))
  44. except (StopIteration, KeyError):
  45. return None
  46. try:
  47. meth_node = parent[name]
  48. except KeyError:
  49. # We have found an ancestor defining <name> but it's not in the local
  50. # dictionary. This may happen with astroid built from living objects.
  51. return None
  52. if isinstance(meth_node, astroid.Function):
  53. return meth_node
  54. return None
  55. def _get_unpacking_extra_info(node, infered):
  56. """return extra information to add to the message for unpacking-non-sequence
  57. and unbalanced-tuple-unpacking errors
  58. """
  59. more = ''
  60. infered_module = infered.root().name
  61. if node.root().name == infered_module:
  62. if node.lineno == infered.lineno:
  63. more = ' %s' % infered.as_string()
  64. elif infered.lineno:
  65. more = ' defined at line %s' % infered.lineno
  66. elif infered.lineno:
  67. more = ' defined at line %s of %s' % (infered.lineno, infered_module)
  68. return more
  69. def _detect_global_scope(node, frame, defframe):
  70. """ Detect that the given frames shares a global
  71. scope.
  72. Two frames shares a global scope when neither
  73. of them are hidden under a function scope, as well
  74. as any of parent scope of them, until the root scope.
  75. In this case, depending from something defined later on
  76. will not work, because it is still undefined.
  77. Example:
  78. class A:
  79. # B has the same global scope as `C`, leading to a NameError.
  80. class B(C): ...
  81. class C: ...
  82. """
  83. def_scope = scope = None
  84. if frame and frame.parent:
  85. scope = frame.parent.scope()
  86. if defframe and defframe.parent:
  87. def_scope = defframe.parent.scope()
  88. if isinstance(frame, astroid.Function):
  89. # If the parent of the current node is a
  90. # function, then it can be under its scope
  91. # (defined in, which doesn't concern us) or
  92. # the `->` part of annotations. The same goes
  93. # for annotations of function arguments, they'll have
  94. # their parent the Arguments node.
  95. if not isinstance(node.parent,
  96. (astroid.Function, astroid.Arguments)):
  97. return False
  98. elif any(not isinstance(f, (astroid.Class, astroid.Module))
  99. for f in (frame, defframe)):
  100. # Not interested in other frames, since they are already
  101. # not in a global scope.
  102. return False
  103. break_scopes = []
  104. for s in (scope, def_scope):
  105. # Look for parent scopes. If there is anything different
  106. # than a module or a class scope, then they frames don't
  107. # share a global scope.
  108. parent_scope = s
  109. while parent_scope:
  110. if not isinstance(parent_scope, (astroid.Class, astroid.Module)):
  111. break_scopes.append(parent_scope)
  112. break
  113. if parent_scope.parent:
  114. parent_scope = parent_scope.parent.scope()
  115. else:
  116. break
  117. if break_scopes and len(set(break_scopes)) != 1:
  118. # Store different scopes than expected.
  119. # If the stored scopes are, in fact, the very same, then it means
  120. # that the two frames (frame and defframe) shares the same scope,
  121. # and we could apply our lineno analysis over them.
  122. # For instance, this works when they are inside a function, the node
  123. # that uses a definition and the definition itself.
  124. return False
  125. # At this point, we are certain that frame and defframe shares a scope
  126. # and the definition of the first depends on the second.
  127. return frame.lineno < defframe.lineno
  128. def _fix_dot_imports(not_consumed):
  129. """ Try to fix imports with multiple dots, by returning a dictionary
  130. with the import names expanded. The function unflattens root imports,
  131. like 'xml' (when we have both 'xml.etree' and 'xml.sax'), to 'xml.etree'
  132. and 'xml.sax' respectively.
  133. """
  134. # TODO: this should be improved in issue astroid #46
  135. names = {}
  136. for name, stmts in six.iteritems(not_consumed):
  137. if any(isinstance(stmt, astroid.AssName)
  138. and isinstance(stmt.ass_type(), astroid.AugAssign)
  139. for stmt in stmts):
  140. continue
  141. for stmt in stmts:
  142. if not isinstance(stmt, (astroid.From, astroid.Import)):
  143. continue
  144. for imports in stmt.names:
  145. second_name = None
  146. if imports[0] == "*":
  147. # In case of wildcard imports,
  148. # pick the name from inside the imported module.
  149. second_name = name
  150. else:
  151. if imports[0].find(".") > -1 or name in imports:
  152. # Most likely something like 'xml.etree',
  153. # which will appear in the .locals as 'xml'.
  154. # Only pick the name if it wasn't consumed.
  155. second_name = imports[0]
  156. if second_name and second_name not in names:
  157. names[second_name] = stmt
  158. return sorted(names.items(), key=lambda a: a[1].fromlineno)
  159. def _find_frame_imports(name, frame):
  160. """
  161. Detect imports in the frame, with the required
  162. *name*. Such imports can be considered assignments.
  163. Returns True if an import for the given name was found.
  164. """
  165. imports = frame.nodes_of_class((astroid.Import, astroid.From))
  166. for import_node in imports:
  167. for import_name, import_alias in import_node.names:
  168. # If the import uses an alias, check only that.
  169. # Otherwise, check only the import name.
  170. if import_alias:
  171. if import_alias == name:
  172. return True
  173. elif import_name and import_name == name:
  174. return True
  175. MSGS = {
  176. 'E0601': ('Using variable %r before assignment',
  177. 'used-before-assignment',
  178. 'Used when a local variable is accessed before it\'s \
  179. assignment.'),
  180. 'E0602': ('Undefined variable %r',
  181. 'undefined-variable',
  182. 'Used when an undefined variable is accessed.'),
  183. 'E0603': ('Undefined variable name %r in __all__',
  184. 'undefined-all-variable',
  185. 'Used when an undefined variable name is referenced in __all__.'),
  186. 'E0604': ('Invalid object %r in __all__, must contain only strings',
  187. 'invalid-all-object',
  188. 'Used when an invalid (non-string) object occurs in __all__.'),
  189. 'E0611': ('No name %r in module %r',
  190. 'no-name-in-module',
  191. 'Used when a name cannot be found in a module.'),
  192. 'W0601': ('Global variable %r undefined at the module level',
  193. 'global-variable-undefined',
  194. 'Used when a variable is defined through the "global" statement \
  195. but the variable is not defined in the module scope.'),
  196. 'W0602': ('Using global for %r but no assignment is done',
  197. 'global-variable-not-assigned',
  198. 'Used when a variable is defined through the "global" statement \
  199. but no assignment to this variable is done.'),
  200. 'W0603': ('Using the global statement', # W0121
  201. 'global-statement',
  202. 'Used when you use the "global" statement to update a global \
  203. variable. Pylint just try to discourage this \
  204. usage. That doesn\'t mean you can not use it !'),
  205. 'W0604': ('Using the global statement at the module level', # W0103
  206. 'global-at-module-level',
  207. 'Used when you use the "global" statement at the module level \
  208. since it has no effect'),
  209. 'W0611': ('Unused %s',
  210. 'unused-import',
  211. 'Used when an imported module or variable is not used.'),
  212. 'W0612': ('Unused variable %r',
  213. 'unused-variable',
  214. 'Used when a variable is defined but not used.'),
  215. 'W0613': ('Unused argument %r',
  216. 'unused-argument',
  217. 'Used when a function or method argument is not used.'),
  218. 'W0614': ('Unused import %s from wildcard import',
  219. 'unused-wildcard-import',
  220. 'Used when an imported module or variable is not used from a \
  221. \'from X import *\' style import.'),
  222. 'W0621': ('Redefining name %r from outer scope (line %s)',
  223. 'redefined-outer-name',
  224. 'Used when a variable\'s name hide a name defined in the outer \
  225. scope.'),
  226. 'W0622': ('Redefining built-in %r',
  227. 'redefined-builtin',
  228. 'Used when a variable or function override a built-in.'),
  229. 'W0623': ('Redefining name %r from %s in exception handler',
  230. 'redefine-in-handler',
  231. 'Used when an exception handler assigns the exception \
  232. to an existing name'),
  233. 'W0631': ('Using possibly undefined loop variable %r',
  234. 'undefined-loop-variable',
  235. 'Used when an loop variable (i.e. defined by a for loop or \
  236. a list comprehension or a generator expression) is used outside \
  237. the loop.'),
  238. 'W0632': ('Possible unbalanced tuple unpacking with '
  239. 'sequence%s: '
  240. 'left side has %d label(s), right side has %d value(s)',
  241. 'unbalanced-tuple-unpacking',
  242. 'Used when there is an unbalanced tuple unpacking in assignment'),
  243. 'W0633': ('Attempting to unpack a non-sequence%s',
  244. 'unpacking-non-sequence',
  245. 'Used when something which is not '
  246. 'a sequence is used in an unpack assignment'),
  247. 'W0640': ('Cell variable %s defined in loop',
  248. 'cell-var-from-loop',
  249. 'A variable used in a closure is defined in a loop. '
  250. 'This will result in all closures using the same value for '
  251. 'the closed-over variable.'),
  252. }
  253. class VariablesChecker(BaseChecker):
  254. """checks for
  255. * unused variables / imports
  256. * undefined variables
  257. * redefinition of variable from builtins or from an outer scope
  258. * use of variable before assignment
  259. * __all__ consistency
  260. """
  261. __implements__ = IAstroidChecker
  262. name = 'variables'
  263. msgs = MSGS
  264. priority = -1
  265. options = (("init-import",
  266. {'default': 0, 'type' : 'yn', 'metavar' : '<y_or_n>',
  267. 'help' : 'Tells whether we should check for unused import in \
  268. __init__ files.'}),
  269. ("dummy-variables-rgx",
  270. {'default': ('_$|dummy'),
  271. 'type' :'regexp', 'metavar' : '<regexp>',
  272. 'help' : 'A regular expression matching the name of dummy \
  273. variables (i.e. expectedly not used).'}),
  274. ("additional-builtins",
  275. {'default': (), 'type' : 'csv',
  276. 'metavar' : '<comma separated list>',
  277. 'help' : 'List of additional names supposed to be defined in \
  278. builtins. Remember that you should avoid to define new builtins when possible.'
  279. }),
  280. ("callbacks",
  281. {'default' : ('cb_', '_cb'), 'type' : 'csv',
  282. 'metavar' : '<callbacks>',
  283. 'help' : 'List of strings which can identify a callback '
  284. 'function by name. A callback name must start or '
  285. 'end with one of those strings.'}
  286. )
  287. )
  288. def __init__(self, linter=None):
  289. BaseChecker.__init__(self, linter)
  290. self._to_consume = None
  291. self._checking_mod_attr = None
  292. def visit_module(self, node):
  293. """visit module : update consumption analysis variable
  294. checks globals doesn't overrides builtins
  295. """
  296. self._to_consume = [(copy(node.locals), {}, 'module')]
  297. for name, stmts in six.iteritems(node.locals):
  298. if is_builtin(name) and not is_inside_except(stmts[0]):
  299. # do not print Redefining builtin for additional builtins
  300. self.add_message('redefined-builtin', args=name, node=stmts[0])
  301. @check_messages('unused-import', 'unused-wildcard-import',
  302. 'redefined-builtin', 'undefined-all-variable',
  303. 'invalid-all-object')
  304. def leave_module(self, node):
  305. """leave module: check globals
  306. """
  307. assert len(self._to_consume) == 1
  308. not_consumed = self._to_consume.pop()[0]
  309. # attempt to check for __all__ if defined
  310. if '__all__' in node.locals:
  311. assigned = next(node.igetattr('__all__'))
  312. if assigned is not astroid.YES:
  313. for elt in getattr(assigned, 'elts', ()):
  314. try:
  315. elt_name = next(elt.infer())
  316. except astroid.InferenceError:
  317. continue
  318. if not isinstance(elt_name, astroid.Const) \
  319. or not isinstance(elt_name.value, six.string_types):
  320. self.add_message('invalid-all-object',
  321. args=elt.as_string(), node=elt)
  322. continue
  323. elt_name = elt_name.value
  324. # If elt is in not_consumed, remove it from not_consumed
  325. if elt_name in not_consumed:
  326. del not_consumed[elt_name]
  327. continue
  328. if elt_name not in node.locals:
  329. if not node.package:
  330. self.add_message('undefined-all-variable',
  331. args=elt_name,
  332. node=elt)
  333. else:
  334. basename = os.path.splitext(node.file)[0]
  335. if os.path.basename(basename) == '__init__':
  336. name = node.name + "." + elt_name
  337. try:
  338. modutils.file_from_modpath(name.split("."))
  339. except ImportError:
  340. self.add_message('undefined-all-variable',
  341. args=elt_name,
  342. node=elt)
  343. except SyntaxError:
  344. # don't yield an syntax-error warning,
  345. # because it will be later yielded
  346. # when the file will be checked
  347. pass
  348. # don't check unused imports in __init__ files
  349. if not self.config.init_import and node.package:
  350. return
  351. self._check_imports(not_consumed)
  352. def _check_imports(self, not_consumed):
  353. local_names = _fix_dot_imports(not_consumed)
  354. checked = set()
  355. for name, stmt in local_names:
  356. for imports in stmt.names:
  357. real_name = imported_name = imports[0]
  358. if imported_name == "*":
  359. real_name = name
  360. as_name = imports[1]
  361. if real_name in checked:
  362. continue
  363. if name not in (real_name, as_name):
  364. continue
  365. checked.add(real_name)
  366. if (isinstance(stmt, astroid.Import) or
  367. (isinstance(stmt, astroid.From) and
  368. not stmt.modname)):
  369. if (isinstance(stmt, astroid.From) and
  370. SPECIAL_OBJ.search(imported_name)):
  371. # Filter special objects (__doc__, __all__) etc.,
  372. # because they can be imported for exporting.
  373. continue
  374. if as_name is None:
  375. msg = "import %s" % imported_name
  376. else:
  377. msg = "%s imported as %s" % (imported_name, as_name)
  378. self.add_message('unused-import', args=msg, node=stmt)
  379. elif isinstance(stmt, astroid.From) and stmt.modname != '__future__':
  380. if SPECIAL_OBJ.search(imported_name):
  381. # Filter special objects (__doc__, __all__) etc.,
  382. # because they can be imported for exporting.
  383. continue
  384. if imported_name == '*':
  385. self.add_message('unused-wildcard-import',
  386. args=name, node=stmt)
  387. else:
  388. if as_name is None:
  389. msg = "%s imported from %s" % (imported_name, stmt.modname)
  390. else:
  391. fields = (imported_name, stmt.modname, as_name)
  392. msg = "%s imported from %s as %s" % fields
  393. self.add_message('unused-import', args=msg, node=stmt)
  394. del self._to_consume
  395. def visit_class(self, node):
  396. """visit class: update consumption analysis variable
  397. """
  398. self._to_consume.append((copy(node.locals), {}, 'class'))
  399. def leave_class(self, _):
  400. """leave class: update consumption analysis variable
  401. """
  402. # do not check for not used locals here (no sense)
  403. self._to_consume.pop()
  404. def visit_lambda(self, node):
  405. """visit lambda: update consumption analysis variable
  406. """
  407. self._to_consume.append((copy(node.locals), {}, 'lambda'))
  408. def leave_lambda(self, _):
  409. """leave lambda: update consumption analysis variable
  410. """
  411. # do not check for not used locals here
  412. self._to_consume.pop()
  413. def visit_genexpr(self, node):
  414. """visit genexpr: update consumption analysis variable
  415. """
  416. self._to_consume.append((copy(node.locals), {}, 'comprehension'))
  417. def leave_genexpr(self, _):
  418. """leave genexpr: update consumption analysis variable
  419. """
  420. # do not check for not used locals here
  421. self._to_consume.pop()
  422. def visit_dictcomp(self, node):
  423. """visit dictcomp: update consumption analysis variable
  424. """
  425. self._to_consume.append((copy(node.locals), {}, 'comprehension'))
  426. def leave_dictcomp(self, _):
  427. """leave dictcomp: update consumption analysis variable
  428. """
  429. # do not check for not used locals here
  430. self._to_consume.pop()
  431. def visit_setcomp(self, node):
  432. """visit setcomp: update consumption analysis variable
  433. """
  434. self._to_consume.append((copy(node.locals), {}, 'comprehension'))
  435. def leave_setcomp(self, _):
  436. """leave setcomp: update consumption analysis variable
  437. """
  438. # do not check for not used locals here
  439. self._to_consume.pop()
  440. def visit_function(self, node):
  441. """visit function: update consumption analysis variable and check locals
  442. """
  443. self._to_consume.append((copy(node.locals), {}, 'function'))
  444. if not (self.linter.is_message_enabled('redefined-outer-name') or
  445. self.linter.is_message_enabled('redefined-builtin')):
  446. return
  447. globs = node.root().globals
  448. for name, stmt in node.items():
  449. if is_inside_except(stmt):
  450. continue
  451. if name in globs and not isinstance(stmt, astroid.Global):
  452. line = globs[name][0].fromlineno
  453. dummy_rgx = self.config.dummy_variables_rgx
  454. if not dummy_rgx.match(name):
  455. self.add_message('redefined-outer-name', args=(name, line), node=stmt)
  456. elif is_builtin(name):
  457. # do not print Redefining builtin for additional builtins
  458. self.add_message('redefined-builtin', args=name, node=stmt)
  459. def leave_function(self, node):
  460. """leave function: check function's locals are consumed"""
  461. not_consumed = self._to_consume.pop()[0]
  462. if not (self.linter.is_message_enabled('unused-variable') or
  463. self.linter.is_message_enabled('unused-argument')):
  464. return
  465. # don't check arguments of function which are only raising an exception
  466. if is_error(node):
  467. return
  468. # don't check arguments of abstract methods or within an interface
  469. is_method = node.is_method()
  470. klass = node.parent.frame()
  471. if is_method and (klass.type == 'interface' or node.is_abstract()):
  472. return
  473. if is_method and isinstance(klass, astroid.Class):
  474. confidence = INFERENCE if has_known_bases(klass) else INFERENCE_FAILURE
  475. else:
  476. confidence = HIGH
  477. authorized_rgx = self.config.dummy_variables_rgx
  478. called_overridden = False
  479. argnames = node.argnames()
  480. global_names = set()
  481. nonlocal_names = set()
  482. for global_stmt in node.nodes_of_class(astroid.Global):
  483. global_names.update(set(global_stmt.names))
  484. for nonlocal_stmt in node.nodes_of_class(astroid.Nonlocal):
  485. nonlocal_names.update(set(nonlocal_stmt.names))
  486. for name, stmts in six.iteritems(not_consumed):
  487. # ignore some special names specified by user configuration
  488. if authorized_rgx.match(name):
  489. continue
  490. # ignore names imported by the global statement
  491. # FIXME: should only ignore them if it's assigned latter
  492. stmt = stmts[0]
  493. if isinstance(stmt, astroid.Global):
  494. continue
  495. if isinstance(stmt, (astroid.Import, astroid.From)):
  496. # Detect imports, assigned to global statements.
  497. if global_names:
  498. skip = False
  499. for import_name, import_alias in stmt.names:
  500. # If the import uses an alias, check only that.
  501. # Otherwise, check only the import name.
  502. if import_alias:
  503. if import_alias in global_names:
  504. skip = True
  505. break
  506. elif import_name in global_names:
  507. skip = True
  508. break
  509. if skip:
  510. continue
  511. # care about functions with unknown argument (builtins)
  512. if name in argnames:
  513. if is_method:
  514. # don't warn for the first argument of a (non static) method
  515. if node.type != 'staticmethod' and name == argnames[0]:
  516. continue
  517. # don't warn for argument of an overridden method
  518. if not called_overridden:
  519. overridden = overridden_method(klass, node.name)
  520. called_overridden = True
  521. if overridden is not None and name in overridden.argnames():
  522. continue
  523. if node.name in PYMETHODS and node.name not in ('__init__', '__new__'):
  524. continue
  525. # don't check callback arguments
  526. if any(node.name.startswith(cb) or node.name.endswith(cb)
  527. for cb in self.config.callbacks):
  528. continue
  529. self.add_message('unused-argument', args=name, node=stmt,
  530. confidence=confidence)
  531. else:
  532. if stmt.parent and isinstance(stmt.parent, astroid.Assign):
  533. if name in nonlocal_names:
  534. continue
  535. self.add_message('unused-variable', args=name, node=stmt)
  536. @check_messages('global-variable-undefined', 'global-variable-not-assigned', 'global-statement',
  537. 'global-at-module-level', 'redefined-builtin')
  538. def visit_global(self, node):
  539. """check names imported exists in the global scope"""
  540. frame = node.frame()
  541. if isinstance(frame, astroid.Module):
  542. self.add_message('global-at-module-level', node=node)
  543. return
  544. module = frame.root()
  545. default_message = True
  546. for name in node.names:
  547. try:
  548. assign_nodes = module.getattr(name)
  549. except astroid.NotFoundError:
  550. # unassigned global, skip
  551. assign_nodes = []
  552. for anode in assign_nodes:
  553. if anode.parent is None:
  554. # node returned for builtin attribute such as __file__,
  555. # __doc__, etc...
  556. continue
  557. if anode.frame() is frame:
  558. # same scope level assignment
  559. break
  560. else:
  561. if not _find_frame_imports(name, frame):
  562. self.add_message('global-variable-not-assigned',
  563. args=name, node=node)
  564. default_message = False
  565. if not assign_nodes:
  566. continue
  567. for anode in assign_nodes:
  568. if anode.parent is None:
  569. self.add_message('redefined-builtin', args=name, node=node)
  570. break
  571. if anode.frame() is module:
  572. # module level assignment
  573. break
  574. else:
  575. # global undefined at the module scope
  576. self.add_message('global-variable-undefined', args=name, node=node)
  577. default_message = False
  578. if default_message:
  579. self.add_message('global-statement', node=node)
  580. def _check_late_binding_closure(self, node, assignment_node):
  581. def _is_direct_lambda_call():
  582. return (isinstance(node_scope.parent, astroid.CallFunc)
  583. and node_scope.parent.func is node_scope)
  584. node_scope = node.scope()
  585. if not isinstance(node_scope, (astroid.Lambda, astroid.Function)):
  586. return
  587. if isinstance(node.parent, astroid.Arguments):
  588. return
  589. if isinstance(assignment_node, astroid.Comprehension):
  590. if assignment_node.parent.parent_of(node.scope()):
  591. self.add_message('cell-var-from-loop', node=node, args=node.name)
  592. else:
  593. assign_scope = assignment_node.scope()
  594. maybe_for = assignment_node
  595. while not isinstance(maybe_for, astroid.For):
  596. if maybe_for is assign_scope:
  597. break
  598. maybe_for = maybe_for.parent
  599. else:
  600. if (maybe_for.parent_of(node_scope)
  601. and not _is_direct_lambda_call()
  602. and not isinstance(node_scope.statement(), astroid.Return)):
  603. self.add_message('cell-var-from-loop', node=node, args=node.name)
  604. def _loopvar_name(self, node, name):
  605. # filter variables according to node's scope
  606. # XXX used to filter parents but don't remember why, and removing this
  607. # fixes a W0631 false positive reported by Paul Hachmann on 2008/12 on
  608. # python-projects (added to func_use_for_or_listcomp_var test)
  609. #astmts = [stmt for stmt in node.lookup(name)[1]
  610. # if hasattr(stmt, 'ass_type')] and
  611. # not stmt.statement().parent_of(node)]
  612. if not self.linter.is_message_enabled('undefined-loop-variable'):
  613. return
  614. astmts = [stmt for stmt in node.lookup(name)[1]
  615. if hasattr(stmt, 'ass_type')]
  616. # filter variables according their respective scope test is_statement
  617. # and parent to avoid #74747. This is not a total fix, which would
  618. # introduce a mechanism similar to special attribute lookup in
  619. # modules. Also, in order to get correct inference in this case, the
  620. # scope lookup rules would need to be changed to return the initial
  621. # assignment (which does not exist in code per se) as well as any later
  622. # modifications.
  623. if not astmts or (astmts[0].is_statement or astmts[0].parent) \
  624. and astmts[0].statement().parent_of(node):
  625. _astmts = []
  626. else:
  627. _astmts = astmts[:1]
  628. for i, stmt in enumerate(astmts[1:]):
  629. if (astmts[i].statement().parent_of(stmt)
  630. and not in_for_else_branch(astmts[i].statement(), stmt)):
  631. continue
  632. _astmts.append(stmt)
  633. astmts = _astmts
  634. if len(astmts) == 1:
  635. ass = astmts[0].ass_type()
  636. if isinstance(ass, (astroid.For, astroid.Comprehension, astroid.GenExpr)) \
  637. and not ass.statement() is node.statement():
  638. self.add_message('undefined-loop-variable', args=name, node=node)
  639. @check_messages('redefine-in-handler')
  640. def visit_excepthandler(self, node):
  641. for name in get_all_elements(node.name):
  642. clobbering, args = clobber_in_except(name)
  643. if clobbering:
  644. self.add_message('redefine-in-handler', args=args, node=name)
  645. def visit_assname(self, node):
  646. if isinstance(node.ass_type(), astroid.AugAssign):
  647. self.visit_name(node)
  648. def visit_delname(self, node):
  649. self.visit_name(node)
  650. @check_messages(*(MSGS.keys()))
  651. def visit_name(self, node):
  652. """check that a name is defined if the current scope and doesn't
  653. redefine a built-in
  654. """
  655. stmt = node.statement()
  656. if stmt.fromlineno is None:
  657. # name node from a astroid built from live code, skip
  658. assert not stmt.root().file.endswith('.py')
  659. return
  660. name = node.name
  661. frame = stmt.scope()
  662. # if the name node is used as a function default argument's value or as
  663. # a decorator, then start from the parent frame of the function instead
  664. # of the function frame - and thus open an inner class scope
  665. if (is_func_default(node) or is_func_decorator(node)
  666. or is_ancestor_name(frame, node)):
  667. start_index = len(self._to_consume) - 2
  668. else:
  669. start_index = len(self._to_consume) - 1
  670. # iterates through parent scopes, from the inner to the outer
  671. base_scope_type = self._to_consume[start_index][-1]
  672. for i in range(start_index, -1, -1):
  673. to_consume, consumed, scope_type = self._to_consume[i]
  674. # if the current scope is a class scope but it's not the inner
  675. # scope, ignore it. This prevents to access this scope instead of
  676. # the globals one in function members when there are some common
  677. # names. The only exception is when the starting scope is a
  678. # comprehension and its direct outer scope is a class
  679. if scope_type == 'class' and i != start_index and not (
  680. base_scope_type == 'comprehension' and i == start_index-1):
  681. # Detect if we are in a local class scope, as an assignment.
  682. # For example, the following is fair game.
  683. #
  684. # class A:
  685. # b = 1
  686. # c = lambda b=b: b * b
  687. #
  688. # class B:
  689. # tp = 1
  690. # def func(self, arg: tp):
  691. # ...
  692. in_annotation = (
  693. PY3K and isinstance(frame, astroid.Function)
  694. and node.statement() is frame and
  695. (node in frame.args.annotations
  696. or node is frame.args.varargannotation
  697. or node is frame.args.kwargannotation))
  698. if in_annotation:
  699. frame_locals = frame.parent.scope().locals
  700. else:
  701. frame_locals = frame.locals
  702. if not ((isinstance(frame, astroid.Class) or in_annotation)
  703. and name in frame_locals):
  704. continue
  705. # the name has already been consumed, only check it's not a loop
  706. # variable used outside the loop
  707. if name in consumed:
  708. defnode = assign_parent(consumed[name][0])
  709. self._check_late_binding_closure(node, defnode)
  710. self._loopvar_name(node, name)
  711. break
  712. # mark the name as consumed if it's defined in this scope
  713. # (i.e. no KeyError is raised by "to_consume[name]")
  714. try:
  715. consumed[name] = to_consume[name]
  716. except KeyError:
  717. continue
  718. # checks for use before assignment
  719. defnode = assign_parent(to_consume[name][0])
  720. if defnode is not None:
  721. self._check_late_binding_closure(node, defnode)
  722. defstmt = defnode.statement()
  723. defframe = defstmt.frame()
  724. maybee0601 = True
  725. if not frame is defframe:
  726. maybee0601 = _detect_global_scope(node, frame, defframe)
  727. elif defframe.parent is None:
  728. # we are at the module level, check the name is not
  729. # defined in builtins
  730. if name in defframe.scope_attrs or builtin_lookup(name)[1]:
  731. maybee0601 = False
  732. else:
  733. # we are in a local scope, check the name is not
  734. # defined in global or builtin scope
  735. if defframe.root().lookup(name)[1]:
  736. maybee0601 = False
  737. else:
  738. # check if we have a nonlocal
  739. if name in defframe.locals:
  740. maybee0601 = not any(isinstance(child, astroid.Nonlocal)
  741. and name in child.names
  742. for child in defframe.get_children())
  743. # Handle a couple of class scoping issues.
  744. annotation_return = False
  745. # The class reuses itself in the class scope.
  746. recursive_klass = (frame is defframe and
  747. defframe.parent_of(node) and
  748. isinstance(defframe, astroid.Class) and
  749. node.name == defframe.name)
  750. if (self._to_consume[-1][-1] == 'lambda' and
  751. isinstance(frame, astroid.Class)
  752. and name in frame.locals):
  753. maybee0601 = True
  754. elif (isinstance(defframe, astroid.Class) and
  755. isinstance(frame, astroid.Function)):
  756. # Special rule for function return annotations,
  757. # which uses the same name as the class where
  758. # the function lives.
  759. if (PY3K and node is frame.returns and
  760. defframe.parent_of(frame.returns)):
  761. maybee0601 = annotation_return = True
  762. if (maybee0601 and defframe.name in defframe.locals and
  763. defframe.locals[name][0].lineno < frame.lineno):
  764. # Detect class assignments with the same
  765. # name as the class. In this case, no warning
  766. # should be raised.
  767. maybee0601 = False
  768. elif recursive_klass:
  769. maybee0601 = True
  770. else:
  771. maybee0601 = maybee0601 and stmt.fromlineno <= defstmt.fromlineno
  772. if (maybee0601
  773. and not is_defined_before(node)
  774. and not are_exclusive(stmt, defstmt, ('NameError',
  775. 'Exception',
  776. 'BaseException'))):
  777. if recursive_klass or (defstmt is stmt and
  778. isinstance(node, (astroid.DelName,
  779. astroid.AssName))):
  780. self.add_message('undefined-variable', args=name, node=node)
  781. elif annotation_return:
  782. self.add_message('undefined-variable', args=name, node=node)
  783. elif self._to_consume[-1][-1] != 'lambda':
  784. # E0601 may *not* occurs in lambda scope.
  785. self.add_message('used-before-assignment', args=name, node=node)
  786. elif self._to_consume[-1][-1] == 'lambda':
  787. # E0601 can occur in class-level scope in lambdas, as in
  788. # the following example:
  789. # class A:
  790. # x = lambda attr: f + attr
  791. # f = 42
  792. if isinstance(frame, astroid.Class) and name in frame.locals:
  793. if isinstance(node.parent, astroid.Arguments):
  794. # Doing the following is fine:
  795. # class A:
  796. # x = 42
  797. # y = lambda attr=x: attr
  798. if stmt.fromlineno <= defstmt.fromlineno:
  799. self.add_message('used-before-assignment',
  800. args=name, node=node)
  801. else:
  802. self.add_message('undefined-variable',
  803. args=name, node=node)
  804. if isinstance(node, astroid.AssName): # Aug AssName
  805. del consumed[name]
  806. else:
  807. del to_consume[name]
  808. # check it's not a loop variable used outside the loop
  809. self._loopvar_name(node, name)
  810. break
  811. else:
  812. # we have not found the name, if it isn't a builtin, that's an
  813. # undefined name !
  814. if not (name in astroid.Module.scope_attrs or is_builtin(name)
  815. or name in self.config.additional_builtins):
  816. self.add_message('undefined-variable', args=name, node=node)
  817. @check_messages('no-name-in-module')
  818. def visit_import(self, node):
  819. """check modules attribute accesses"""
  820. for name, _ in node.names:
  821. parts = name.split('.')
  822. try:
  823. module = next(node.infer_name_module(parts[0]))
  824. except astroid.ResolveError:
  825. continue
  826. self._check_module_attrs(node, module, parts[1:])
  827. @check_messages('no-name-in-module')
  828. def visit_from(self, node):
  829. """check modules attribute accesses"""
  830. name_parts = node.modname.split('.')
  831. level = getattr(node, 'level', None)
  832. try:
  833. module = node.root().import_module(name_parts[0], level=level)
  834. except Exception: # pylint: disable=broad-except
  835. return
  836. module = self._check_module_attrs(node, module, name_parts[1:])
  837. if not module:
  838. return
  839. for name, _ in node.names:
  840. if name == '*':
  841. continue
  842. self._check_module_attrs(node, module, name.split('.'))
  843. @check_messages('unbalanced-tuple-unpacking', 'unpacking-non-sequence')
  844. def visit_assign(self, node):
  845. """Check unbalanced tuple unpacking for assignments
  846. and unpacking non-sequences.
  847. """
  848. if not isinstance(node.targets[0], (astroid.Tuple, astroid.List)):
  849. return
  850. targets = node.targets[0].itered()
  851. try:
  852. for infered in node.value.infer():
  853. self._check_unpacking(infered, node, targets)
  854. except astroid.InferenceError:
  855. return
  856. def _check_unpacking(self, infered, node, targets):
  857. """ Check for unbalanced tuple unpacking
  858. and unpacking non sequences.
  859. """
  860. if infered is astroid.YES:
  861. return
  862. if (isinstance(infered.parent, astroid.Arguments) and
  863. isinstance(node.value, astroid.Name) and
  864. node.value.name == infered.parent.vararg):
  865. # Variable-length argument, we can't determine the length.
  866. return
  867. if isinstance(infered, (astroid.Tuple, astroid.List)):
  868. # attempt to check unpacking is properly balanced
  869. values = infered.itered()
  870. if len(targets) != len(values):
  871. # Check if we have starred nodes.
  872. if any(isinstance(target, astroid.Starred)
  873. for target in targets):
  874. return
  875. self.add_message('unbalanced-tuple-unpacking', node=node,
  876. args=(_get_unpacking_extra_info(node, infered),
  877. len(targets),
  878. len(values)))
  879. # attempt to check unpacking may be possible (ie RHS is iterable)
  880. elif isinstance(infered, astroid.Instance):
  881. for meth in ('__iter__', '__getitem__'):
  882. try:
  883. infered.getattr(meth)
  884. break
  885. except astroid.NotFoundError:
  886. continue
  887. else:
  888. self.add_message('unpacking-non-sequence', node=node,
  889. args=(_get_unpacking_extra_info(node, infered),))
  890. else:
  891. self.add_message('unpacking-non-sequence', node=node,
  892. args=(_get_unpacking_extra_info(node, infered),))
  893. def _check_module_attrs(self, node, module, module_names):
  894. """check that module_names (list of string) are accessible through the
  895. given module
  896. if the latest access name corresponds to a module, return it
  897. """
  898. assert isinstance(module, astroid.Module), module
  899. ignored_modules = get_global_option(self, 'ignored-modules',
  900. default=[])
  901. while module_names:
  902. name = module_names.pop(0)
  903. if name == '__dict__':
  904. module = None
  905. break
  906. try:
  907. module = next(module.getattr(name)[0].infer())
  908. if module is astroid.YES:
  909. return None
  910. except astroid.NotFoundError:
  911. if module.name in ignored_modules:
  912. return None
  913. self.add_message('no-name-in-module',
  914. args=(name, module.name), node=node)
  915. return None
  916. except astroid.InferenceError:
  917. return None
  918. if module_names:
  919. # FIXME: other message if name is not the latest part of
  920. # module_names ?
  921. modname = module and module.name or '__dict__'
  922. self.add_message('no-name-in-module', node=node,
  923. args=('.'.join(module_names), modname))
  924. return None
  925. if isinstance(module, astroid.Module):
  926. return module
  927. return None
  928. class VariablesChecker3k(VariablesChecker):
  929. '''Modified variables checker for 3k'''
  930. # listcomp have now also their scope
  931. def visit_listcomp(self, node):
  932. """visit dictcomp: update consumption analysis variable
  933. """
  934. self._to_consume.append((copy(node.locals), {}, 'comprehension'))
  935. def leave_listcomp(self, _):
  936. """leave dictcomp: update consumption analysis variable
  937. """
  938. # do not check for not used locals here
  939. self._to_consume.pop()
  940. def leave_module(self, node):
  941. """ Update consumption analysis variable
  942. for metaclasses.
  943. """
  944. module_locals = self._to_consume[0][0]
  945. module_imports = self._to_consume[0][1]
  946. consumed = {}
  947. for klass in node.nodes_of_class(astroid.Class):
  948. found = metaclass = name = None
  949. if not klass._metaclass:
  950. # Skip if this class doesn't use
  951. # explictly a metaclass, but inherits it from ancestors
  952. continue
  953. metaclass = klass.metaclass()
  954. # Look the name in the already found locals.
  955. # If it's not found there, look in the module locals
  956. # and in the imported modules.
  957. if isinstance(klass._metaclass, astroid.Name):
  958. name = klass._metaclass.name
  959. elif metaclass:
  960. # if it uses a `metaclass=module.Class`
  961. name = metaclass.root().name
  962. if name:
  963. found = consumed.setdefault(
  964. name, module_locals.get(name, module_imports.get(name)))
  965. if found is None and not metaclass:
  966. name = None
  967. if isinstance(klass._metaclass, astroid.Name):
  968. name = klass._metaclass.name
  969. elif isinstance(klass._metaclass, astroid.Getattr):
  970. name = klass._metaclass.as_string()
  971. if name is not None:
  972. if not (name in astroid.Module.scope_attrs or
  973. is_builtin(name) or
  974. name in self.config.additional_builtins or
  975. name in node.locals):
  976. self.add_message('undefined-variable',
  977. node=klass,
  978. args=(name, ))
  979. # Pop the consumed items, in order to
  980. # avoid having unused-import false positives
  981. for name in consumed:
  982. module_locals.pop(name, None)
  983. super(VariablesChecker3k, self).leave_module(node)
  984. if sys.version_info >= (3, 0):
  985. VariablesChecker = VariablesChecker3k
  986. def register(linter):
  987. """required method to auto register this checker"""
  988. linter.register_checker(VariablesChecker(linter))