mirror of
https://fuchsia.googlesource.com/third_party/github.com/pylint-dev/pylint
synced 2024-09-21 16:19:21 +00:00
4becf6f9e5
forget the past.
145 lines
5.2 KiB
Python
145 lines
5.2 KiB
Python
# pylint: disable-msg=W0611
|
|
#
|
|
# Copyright (c) 2003-2005 LOGILAB S.A. (Paris, FRANCE).
|
|
# http://www.logilab.fr/ -- mailto:contact@logilab.fr
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify it under
|
|
# the terms of the GNU General Public License as published by the Free Software
|
|
# Foundation; either version 2 of the License, or (at your option) any later
|
|
# version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful, but WITHOUT
|
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License along with
|
|
# this program; if not, write to the Free Software Foundation, Inc.,
|
|
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
"""some functions that may be usefull for various checkers
|
|
"""
|
|
|
|
__revision__ = '$Id: utils.py,v 1.16 2006-03-03 09:25:34 syt Exp $'
|
|
|
|
from logilab import astng
|
|
from logilab.astng.utils import are_exclusive
|
|
try:
|
|
# python >= 2.4
|
|
COMP_NODE_TYPES = (astng.ListComp, astng.GenExpr)
|
|
FOR_NODE_TYPES = (astng.For, astng.ListCompFor, astng.GenExprFor)
|
|
except AttributeError:
|
|
COMP_NODE_TYPES = astng.ListComp
|
|
FOR_NODE_TYPES = (astng.For, astng.ListCompFor)
|
|
|
|
def is_error(node):
|
|
"""return true if the function does nothing but raising an exception"""
|
|
for child_node in node.code.getChildNodes():
|
|
if isinstance(child_node, astng.Raise):
|
|
return True
|
|
return False
|
|
|
|
def is_empty(node):
|
|
"""return true if the given node does nothing but 'pass'"""
|
|
for child_node in node.getChildNodes():
|
|
if isinstance(child_node, astng.Pass):
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
builtins = __builtins__.copy()
|
|
SPECIAL_BUILTINS = ('__builtins__',) # '__path__', '__file__')
|
|
|
|
def is_builtin(name): # was is_native_builtin
|
|
"""return true if <name> could be considered as a builtin defined by python
|
|
"""
|
|
if builtins.has_key(name):
|
|
return True
|
|
if name in SPECIAL_BUILTINS:
|
|
return True
|
|
return False
|
|
|
|
def is_defined_before(var_node, comp_node_types=COMP_NODE_TYPES):
|
|
"""return True if the variable node is defined by a parent node (list
|
|
or generator comprehension, lambda) or in a previous sibling node
|
|
one the same line (statement_defining ; statement_using)
|
|
"""
|
|
varname = var_node.name
|
|
_node = var_node.parent
|
|
while _node:
|
|
if isinstance(_node, comp_node_types):
|
|
for ass_node in _node.nodes_of_class(astng.AssName):
|
|
if ass_node.name == varname:
|
|
return True
|
|
elif isinstance(_node, astng.For):
|
|
for ass_node in _node.assign.nodes_of_class(astng.AssName):
|
|
if ass_node.name == varname:
|
|
return True
|
|
elif isinstance(_node, (astng.Lambda, astng.Function)):
|
|
if varname in _node.argnames:
|
|
return True
|
|
if getattr(_node, 'name', None) == varname:
|
|
return True
|
|
break
|
|
_node = _node.parent
|
|
# possibly multiple statements on the same line using semi colon separator
|
|
stmt = var_node.statement()
|
|
_node = stmt.previous_sibling()
|
|
lineno = stmt.lineno
|
|
while _node and _node.lineno == lineno:
|
|
for ass_node in _node.nodes_of_class(astng.AssName):
|
|
if ass_node.name == varname:
|
|
return True
|
|
for imp_node in _node.nodes_of_class( (astng.From, astng.Import)):
|
|
if varname in [name[1] or name[0] for name in imp_node.names]:
|
|
return True
|
|
_node = _node.previous_sibling()
|
|
return False
|
|
|
|
def is_func_default(node):
|
|
"""return true if the name is used in function default argument's value
|
|
"""
|
|
parent = node.parent
|
|
if parent is None:
|
|
return 0
|
|
if isinstance(parent, astng.Function) and parent.defaults and \
|
|
node in parent.defaults:
|
|
return 1
|
|
return is_func_default(parent)
|
|
|
|
def is_ancestor_name(frame, node):
|
|
"""return True if `frame` is a astng.Class node with `node` in the
|
|
subtree of its bases attribute
|
|
"""
|
|
try:
|
|
bases = frame.bases
|
|
except AttributeError:
|
|
return False
|
|
for base in bases:
|
|
if node in base.nodes_of_class(astng.Name):
|
|
return True
|
|
return False
|
|
|
|
def assign_parent(node):
|
|
"""return the higher parent which is not an AssName, AssTuple or AssList
|
|
node
|
|
"""
|
|
while node and isinstance(node, (astng.AssName,
|
|
astng.AssTuple,
|
|
astng.AssList)):
|
|
node = node.parent
|
|
return node
|
|
|
|
def overrides_an_abstract_method(class_node, name):
|
|
"""return True if pnode is a parent of node"""
|
|
for ancestor in class_node.ancestors():
|
|
if name in ancestor and isinstance(ancestor[name], astng.Function) and \
|
|
ancestor[name].is_abstract(pass_is_abstract=False):
|
|
return True
|
|
return False
|
|
|
|
def overrides_a_method(class_node, name):
|
|
"""return True if <name> is a method overriden from an ancestor"""
|
|
for ancestor in class_node.ancestors():
|
|
if name in ancestor and isinstance(ancestor[name], astng.Function):
|
|
return True
|
|
return False
|