third_party.pylibs.pylint.src/checkers/utils.py
root 4becf6f9e5 forget the past.
forget the past.
2006-04-26 10:48:09 +00:00

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