summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bases.py67
-rw-r--r--mixins.py151
-rw-r--r--node_classes.py238
-rw-r--r--nodes.py8
-rw-r--r--scoped_nodes.py176
5 files changed, 344 insertions, 296 deletions
diff --git a/bases.py b/bases.py
index e78b4b45..fa2bf119 100644
--- a/bases.py
+++ b/bases.py
@@ -11,8 +11,15 @@
# 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.
-"""
-Module containing the node classes; it is only used for avoiding circular imports
+
+"""This module contains base classes and functions for the nodes and some inference
+utils.
+
+:author: Sylvain Thenault
+:copyright: 2003-2010 LOGILAB S.A. (Paris, FRANCE)
+:contact: http://www.logilab.fr/ -- mailto:python-projects@logilab.org
+:copyright: 2003-2010 Sylvain Thenault
+:contact: mailto:thenault@gmail.com
"""
from __future__ import generators
@@ -580,59 +587,3 @@ def _repr_tree(node, result, indent='', _done=None, ids=False):
_repr_tree(value, result, indent, _done, ids)
-
-
-# some small MixIns for extending the node classes #######################
-
-# /!\ We cannot build a StmtNode(NodeNG) class since modifying "__bases__"
-# in "nodes.py" has to work *both* for old-style and new-style classes,
-# but we need the StmtMixIn for scoped nodes
-
-class StmtMixIn(BaseClass):
- """StmtMixIn used only for a adding a few attributes"""
- is_statement = True
-
- def replace(self, child, newchild):
- sequence = self.child_sequence(child)
- newchild.parent = self
- child.parent = None
- sequence[sequence.index(child)] = newchild
-
- def next_sibling(self):
- """return the next sibling statement"""
- stmts = self.parent.child_sequence(self)
- index = stmts.index(self)
- try:
- return stmts[index +1]
- except IndexError:
- pass
-
- def previous_sibling(self):
- """return the previous sibling statement"""
- stmts = self.parent.child_sequence(self)
- index = stmts.index(self)
- if index >= 1:
- return stmts[index -1]
-
-
-class BlockRangeMixIn(BaseClass):
- """override block range """
- def set_line_info(self, lastchild):
- self.fromlineno = self.lineno
- self.tolineno = lastchild.tolineno
- self.blockstart_tolineno = self._blockstart_toline()
-
- def _elsed_block_range(self, lineno, orelse, last=None):
- """handle block line numbers range for try/finally, for, if and while
- statements
- """
- if lineno == self.fromlineno:
- return lineno, lineno
- if orelse:
- if lineno >= orelse[0].fromlineno:
- return lineno, orelse[-1].tolineno
- return lineno, orelse[0].fromlineno - 1
- return lineno, last or self.tolineno
-
-
-
diff --git a/mixins.py b/mixins.py
new file mode 100644
index 00000000..bed4a447
--- /dev/null
+++ b/mixins.py
@@ -0,0 +1,151 @@
+# 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.
+"""This module contains some mixins for the different nodes.
+
+:author: Sylvain Thenault
+:copyright: 2003-2010 LOGILAB S.A. (Paris, FRANCE)
+:contact: http://www.logilab.fr/ -- mailto:python-projects@logilab.org
+:copyright: 2003-2010 Sylvain Thenault
+:contact: mailto:thenault@gmail.com
+"""
+
+from logilab.astng import (ASTNGBuildingException, InferenceError,
+ NotFoundError)
+from logilab.astng.bases import BaseClass
+
+# /!\ We cannot build a StmtNode(NodeNG) class since modifying "__bases__"
+# in "nodes.py" has to work *both* for old-style and new-style classes,
+# but we need the StmtMixIn for scoped nodes
+
+class StmtMixIn(BaseClass):
+ """StmtMixIn used only for a adding a few attributes"""
+ is_statement = True
+
+ def replace(self, child, newchild):
+ sequence = self.child_sequence(child)
+ newchild.parent = self
+ child.parent = None
+ sequence[sequence.index(child)] = newchild
+
+ def next_sibling(self):
+ """return the next sibling statement"""
+ stmts = self.parent.child_sequence(self)
+ index = stmts.index(self)
+ try:
+ return stmts[index +1]
+ except IndexError:
+ pass
+
+ def previous_sibling(self):
+ """return the previous sibling statement"""
+ stmts = self.parent.child_sequence(self)
+ index = stmts.index(self)
+ if index >= 1:
+ return stmts[index -1]
+
+
+class BlockRangeMixIn(BaseClass):
+ """override block range """
+ def set_line_info(self, lastchild):
+ self.fromlineno = self.lineno
+ self.tolineno = lastchild.tolineno
+ self.blockstart_tolineno = self._blockstart_toline()
+
+ def _elsed_block_range(self, lineno, orelse, last=None):
+ """handle block line numbers range for try/finally, for, if and while
+ statements
+ """
+ if lineno == self.fromlineno:
+ return lineno, lineno
+ if orelse:
+ if lineno >= orelse[0].fromlineno:
+ return lineno, orelse[-1].tolineno
+ return lineno, orelse[0].fromlineno - 1
+ return lineno, last or self.tolineno
+
+class FilterStmtsMixin(object):
+ """Mixin for statement filtering and assignment type"""
+
+ def _get_filtered_stmts(self, _, node, _stmts, mystmt):
+ """method used in _filter_stmts to get statemtents and trigger break"""
+ if self.statement() is mystmt:
+ # original node's statement is the assignment, only keep
+ # current node (gen exp, list comp)
+ return [node], True
+ return _stmts, False
+
+ def ass_type(self):
+ return self
+
+
+class AssignTypeMixin(object):
+
+ def ass_type(self):
+ return self
+
+ def _get_filtered_stmts(self, lookup_node, node, _stmts, mystmt):
+ """method used in filter_stmts"""
+ if self is mystmt:
+ return _stmts, True
+ if self.statement() is mystmt:
+ # original node's statement is the assignment, only keep
+ # current node (gen exp, list comp)
+ return [node], True
+ return _stmts, False
+
+
+class ParentAssignTypeMixin(AssignTypeMixin):
+
+ def ass_type(self):
+ return self.parent.ass_type()
+
+
+
+class FromImportMixIn(BaseClass, FilterStmtsMixin):
+ """MixIn for From and Import Nodes"""
+
+ def _infer_name(self, frame, name):
+ return name
+
+ def do_import_module(node, modname):
+ """return the ast for a module whose name is <modname> imported by <node>
+ """
+ # handle special case where we are on a package node importing a module
+ # using the same name as the package, which may end in an infinite loop
+ # on relative imports
+ # XXX: no more needed ?
+ mymodule = node.root()
+ level = getattr(node, 'level', None) # Import as no level
+ if mymodule.absolute_modname(modname, level) == mymodule.name:
+ # FIXME: I don't know what to do here...
+ raise InferenceError('module importing itself: %s' % modname)
+ try:
+ return mymodule.import_module(modname, level=level)
+ except (ASTNGBuildingException, SyntaxError):
+ raise InferenceError(modname)
+
+ def real_name(self, asname):
+ """get name from 'as' name"""
+ for index in range(len(self.names)):
+ name, _asname = self.names[index]
+ if name == '*':
+ return asname
+ if not _asname:
+ name = name.split('.', 1)[0]
+ _asname = name
+ if asname == _asname:
+ return name
+ raise NotFoundError(asname)
+
+
+
diff --git a/node_classes.py b/node_classes.py
index 98b4ea76..c49acf28 100644
--- a/node_classes.py
+++ b/node_classes.py
@@ -1,14 +1,34 @@
+# -*- coding: utf-8 -*-
+# 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.
+"""
+Module for some node classes. More nodes in scoped_nodes.py
+
+:author: Sylvain Thenault
+:copyright: 2003-2010 LOGILAB S.A. (Paris, FRANCE)
+:contact: http://www.logilab.fr/ -- mailto:python-projects@logilab.org
+:copyright: 2003-2010 Sylvain Thenault
+:contact: mailto:thenault@gmail.com
+
+"""
from logilab.common.compat import chain, imap
from logilab.astng import (ASTNGBuildingException, InferenceError,
NotFoundError, NoDefault)
-from logilab.astng.bases import (NodeNG, StmtMixIn, BlockRangeMixIn,
- BaseClass, Instance)
-
-"""
-Module for all nodes (except scoped nodes).
-"""
+from logilab.astng.bases import (NodeNG, BaseClass, Instance, copy_context,
+ _infer_stmts)
+from logilab.astng.mixins import (StmtMixIn, BlockRangeMixIn, FilterStmtsMixin,
+ AssignTypeMixin, ParentAssignTypeMixin, FromImportMixIn)
def unpack_infer(stmt, context=None):
"""return an iterator on nodes inferred by the given statement if the inferred
@@ -75,43 +95,160 @@ def are_exclusive(stmt1, stmt2, exceptions=None):
node = node.parent
return False
-class FilterStmtsMixin(object):
- """Mixin for statement filtering and assignment type"""
- def _get_filtered_stmts(self, _, node, _stmts, mystmt):
- """method used in _filter_stmts to get statemtents and trigger break"""
- if self.statement() is mystmt:
- # original node's statement is the assignment, only keep
- # current node (gen exp, list comp)
- return [node], True
- return _stmts, False
- def ass_type(self):
- return self
-class AssignTypeMixin(object):
+class LookupMixIn(BaseClass):
+ """Mixin looking up a name in the right scope
+ """
- def ass_type(self):
- return self
+ def lookup(self, name):
+ """lookup a variable name
- def _get_filtered_stmts(self, lookup_node, node, _stmts, mystmt):
- """method used in filter_stmts"""
- if self is mystmt:
- return _stmts, True
- if self.statement() is mystmt:
- # original node's statement is the assignment, only keep
- # current node (gen exp, list comp)
- return [node], True
- return _stmts, False
+ return the scope node and the list of assignments associated to the given
+ name according to the scope where it has been found (locals, globals or
+ builtin)
+ The lookup is starting from self's scope. If self is not a frame itself and
+ the name is found in the inner frame locals, statements will be filtered
+ to remove ignorable statements according to self's location
+ """
+ return self.scope().scope_lookup(self, name)
-class ParentAssignTypeMixin(AssignTypeMixin):
+ def ilookup(self, name, context=None):
+ """infered lookup
- def ass_type(self):
- return self.parent.ass_type()
+ return an iterator on infered values of the statements returned by
+ the lookup method
+ """
+ frame, stmts = self.lookup(name)
+ context = copy_context(context)
+ context.lookupname = name
+ return _infer_stmts(stmts, context, frame)
+ def _filter_stmts(self, stmts, frame, offset):
+ """filter statements to remove ignorable statements.
+ If self is not a frame itself and the name is found in the inner
+ frame locals, statements will be filtered to remove ignorable
+ statements according to self's location
+ """
+ # if offset == -1, my actual frame is not the inner frame but its parent
+ #
+ # class A(B): pass
+ #
+ # we need this to resolve B correctly
+ if offset == -1:
+ myframe = self.frame().parent.frame()
+ else:
+ myframe = self.frame()
+ if not myframe is frame or self is frame:
+ return stmts
+ mystmt = self.statement()
+ # line filtering if we are in the same frame
+ #
+ # take care node may be missing lineno information (this is the case for
+ # nodes inserted for living objects)
+ if myframe is frame and mystmt.fromlineno is not None:
+ assert mystmt.fromlineno is not None, mystmt
+ mylineno = mystmt.fromlineno + offset
+ else:
+ # disabling lineno filtering
+ mylineno = 0
+ _stmts = []
+ _stmt_parents = []
+ for node in stmts:
+ stmt = node.statement()
+ # line filtering is on and we have reached our location, break
+ if mylineno > 0 and stmt.fromlineno > mylineno:
+ break
+ assert hasattr(node, 'ass_type'), (node, node.scope(),
+ node.scope().locals)
+ ass_type = node.ass_type()
+
+ if node.has_base(self):
+ break
+
+ _stmts, done = ass_type._get_filtered_stmts(self, node, _stmts, mystmt)
+ if done:
+ break
+
+ optional_assign = isinstance(ass_type, (For, Comprehension))
+ if optional_assign and ass_type.parent_of(self):
+ # we are inside a loop, loop var assigment is hidding previous
+ # assigment
+ _stmts = [node]
+ _stmt_parents = [stmt.parent]
+ continue
+
+ # XXX comment various branches below!!!
+ try:
+ pindex = _stmt_parents.index(stmt.parent)
+ except ValueError:
+ pass
+ else:
+ # we got a parent index, this means the currently visited node
+ # is at the same block level as a previously visited node
+ if _stmts[pindex].ass_type().parent_of(ass_type):
+ # both statements are not at the same block level
+ continue
+ # if currently visited node is following previously considered
+ # assignement and both are not exclusive, we can drop the
+ # previous one. For instance in the following code ::
+ #
+ # if a:
+ # x = 1
+ # else:
+ # x = 2
+ # print x
+ #
+ # we can't remove neither x = 1 nor x = 2 when looking for 'x'
+ # of 'print x'; while in the following ::
+ #
+ # x = 1
+ # x = 2
+ # print x
+ #
+ # we can remove x = 1 when we see x = 2
+ #
+ # moreover, on loop assignment types, assignment won't
+ # necessarily be done if the loop has no iteration, so we don't
+ # want to clear previous assigments if any (hence the test on
+ # optional_assign)
+ if not (optional_assign or are_exclusive(_stmts[pindex], node)):
+ del _stmt_parents[pindex]
+ del _stmts[pindex]
+ if isinstance(node, AssName):
+ if not optional_assign and stmt.parent is mystmt.parent:
+ _stmts = []
+ _stmt_parents = []
+ elif isinstance(node, DelName):
+ _stmts = []
+ _stmt_parents = []
+ continue
+ if not are_exclusive(self, node):
+ _stmts.append(node)
+ _stmt_parents.append(stmt.parent)
+ return _stmts
+
+# Name classes
+
+class AssName(LookupMixIn, ParentAssignTypeMixin, NodeNG):
+ """class representing an AssName node"""
+
+
+class DelName(LookupMixIn, ParentAssignTypeMixin, NodeNG):
+ """class representing a DelName node"""
+
+
+class Name(LookupMixIn, NodeNG):
+ """class representing a Name node"""
+
+
+
+
+##################### node classes ########################################
class Arguments(NodeNG, AssignTypeMixin):
"""class representing an Arguments node"""
@@ -251,7 +388,6 @@ class Comprehension(NodeNG):
def _get_filtered_stmts(self, lookup_node, node, stmts, mystmt):
"""method used in filter_stmts"""
if self is mystmt:
- from logilab.astng.nodes import Name # XXX remove me
if isinstance(lookup_node, (Const, Name)):
return [lookup_node], True
@@ -401,42 +537,6 @@ class For(BlockRangeMixIn, StmtMixIn, AssignTypeMixin, NodeNG):
return self.iter.tolineno
-class FromImportMixIn(BaseClass, FilterStmtsMixin):
- """MixIn for From and Import Nodes"""
-
- def _infer_name(self, frame, name):
- return name
-
- def do_import_module(node, modname):
- """return the ast for a module whose name is <modname> imported by <node>
- """
- # handle special case where we are on a package node importing a module
- # using the same name as the package, which may end in an infinite loop
- # on relative imports
- # XXX: no more needed ?
- mymodule = node.root()
- level = getattr(node, 'level', None) # Import as no level
- if mymodule.absolute_modname(modname, level) == mymodule.name:
- # FIXME: I don't know what to do here...
- raise InferenceError('module importing itself: %s' % modname)
- try:
- return mymodule.import_module(modname, level=level)
- except (ASTNGBuildingException, SyntaxError):
- raise InferenceError(modname)
-
- def real_name(self, asname):
- """get name from 'as' name"""
- for index in range(len(self.names)):
- name, _asname = self.names[index]
- if name == '*':
- return asname
- if not _asname:
- name = name.split('.', 1)[0]
- _asname = name
- if asname == _asname:
- return name
- raise NotFoundError(asname)
-
class From(FromImportMixIn, StmtMixIn, NodeNG):
"""class representing a From node"""
diff --git a/nodes.py b/nodes.py
index 804ec041..b7f43713 100644
--- a/nodes.py
+++ b/nodes.py
@@ -38,13 +38,13 @@ on From and Import :
__docformat__ = "restructuredtext en"
from logilab.astng.node_classes import (Arguments, AssAttr, Assert,
- Assign, AugAssign, Backquote, BinOp, BoolOp, Break, CallFunc, Compare,
- Comprehension, Const, Continue, Decorators, DelAttr, Delete,
+ Assign, AssName, AugAssign, Backquote, BinOp, BoolOp, Break, CallFunc, Compare,
+ Comprehension, Const, Continue, Decorators, DelAttr, DelName, Delete,
Dict, Discard, Ellipsis, EmptyNode, ExceptHandler, Exec, ExtSlice, For,
From, Getattr, Global, If, IfExp, Import, Index, Keyword,
- List, ListComp, Pass, Print, Raise, Return, Slice, Subscript,
+ List, ListComp, Name, Pass, Print, Raise, Return, Slice, Subscript,
TryExcept, TryFinally, Tuple, UnaryOp, While, With, Yield, const_factory )
-from logilab.astng.scoped_nodes import AssName, DelName, Name, Module, GenExpr, Lambda, Function, Class
+from logilab.astng.scoped_nodes import Module, GenExpr, Lambda, Function, Class
# astng fields definition ####################################################
diff --git a/scoped_nodes.py b/scoped_nodes.py
index c6851bad..2b97bcf8 100644
--- a/scoped_nodes.py
+++ b/scoped_nodes.py
@@ -10,18 +10,14 @@
# 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.
-"""This module extends ast "scoped" node, i.e. which are opening a new
-local scope in the language definition : Module, Class, Function (and
+"""This module contains the classes for "scoped" node, i.e. which are opening a
+new local scope in the language definition : Module, Class, Function (and
Lambda and GenExpr to some extends).
-All new methods and attributes added on each class are documented
-below.
-
-
:author: Sylvain Thenault
-:copyright: 2003-2009 LOGILAB S.A. (Paris, FRANCE)
+:copyright: 2003-2010 LOGILAB S.A. (Paris, FRANCE)
:contact: http://www.logilab.fr/ -- mailto:python-projects@logilab.org
-:copyright: 2003-2009 Sylvain Thenault
+:copyright: 2003-2010 Sylvain Thenault
:contact: mailto:thenault@gmail.com
"""
from __future__ import generators
@@ -36,13 +32,12 @@ from logilab.common.decorators import cached
from logilab.astng import MANAGER, NotFoundError, NoDefault, \
ASTNGBuildingException, InferenceError
-from logilab.astng.node_classes import (Const, Comprehension, Dict,
- From, For, Import, List, Pass, Raise, Return, Tuple, Yield, DelAttr,
- are_exclusive, const_factory as cf, unpack_infer, FilterStmtsMixin,
- ParentAssignTypeMixin)
-from logilab.astng.bases import (NodeNG, StmtMixIn, BaseClass, YES,
- InferenceContext, Instance, Generator,
- UnboundMethod, BoundMethod, _infer_stmts, copy_context)
+from logilab.astng.node_classes import (Const, DelName, DelAttr,
+ Dict, From, List, Name, Pass, Raise, Return, Tuple, Yield,
+ are_exclusive, LookupMixIn, const_factory as cf, unpack_infer)
+from logilab.astng.bases import (NodeNG, BaseClass, YES, InferenceContext, Instance,
+ Generator, UnboundMethod, BoundMethod, _infer_stmts, copy_context)
+from logilab.astng.mixins import (StmtMixIn, FilterStmtsMixin)
from logilab.astng.nodes_as_string import as_string
@@ -78,143 +73,6 @@ def std_special_attributes(self, name, add_locals=True):
raise NotFoundError(name)
-# MixIns -----------------------------------------------------
-
-
-
-class LookupMixIn(BaseClass):
- """Mixin looking up a name in the right scope
- """
-
- def lookup(self, name):
- """lookup a variable name
-
- return the scope node and the list of assignments associated to the given
- name according to the scope where it has been found (locals, globals or
- builtin)
-
- The lookup is starting from self's scope. If self is not a frame itself and
- the name is found in the inner frame locals, statements will be filtered
- to remove ignorable statements according to self's location
- """
- return self.scope().scope_lookup(self, name)
-
- def ilookup(self, name, context=None):
- """infered lookup
-
- return an iterator on infered values of the statements returned by
- the lookup method
- """
- frame, stmts = self.lookup(name)
- context = copy_context(context)
- context.lookupname = name
- return _infer_stmts(stmts, context, frame)
-
- def _filter_stmts(self, stmts, frame, offset):
- """filter statements to remove ignorable statements.
-
- If self is not a frame itself and the name is found in the inner
- frame locals, statements will be filtered to remove ignorable
- statements according to self's location
- """
- # if offset == -1, my actual frame is not the inner frame but its parent
- #
- # class A(B): pass
- #
- # we need this to resolve B correctly
- if offset == -1:
- myframe = self.frame().parent.frame()
- else:
- myframe = self.frame()
- if not myframe is frame or self is frame:
- return stmts
- mystmt = self.statement()
- # line filtering if we are in the same frame
- #
- # take care node may be missing lineno information (this is the case for
- # nodes inserted for living objects)
- if myframe is frame and mystmt.fromlineno is not None:
- assert mystmt.fromlineno is not None, mystmt
- mylineno = mystmt.fromlineno + offset
- else:
- # disabling lineno filtering
- mylineno = 0
- _stmts = []
- _stmt_parents = []
- for node in stmts:
- stmt = node.statement()
- # line filtering is on and we have reached our location, break
- if mylineno > 0 and stmt.fromlineno > mylineno:
- break
- assert hasattr(node, 'ass_type'), (node, node.scope(),
- node.scope().locals)
- ass_type = node.ass_type()
-
- if node.has_base(self):
- break
-
- _stmts, done = ass_type._get_filtered_stmts(self, node, _stmts, mystmt)
- if done:
- break
-
- optional_assign = isinstance(ass_type, (For, Comprehension))
- if optional_assign and ass_type.parent_of(self):
- # we are inside a loop, loop var assigment is hidding previous
- # assigment
- _stmts = [node]
- _stmt_parents = [stmt.parent]
- continue
-
- # XXX comment various branches below!!!
- try:
- pindex = _stmt_parents.index(stmt.parent)
- except ValueError:
- pass
- else:
- # we got a parent index, this means the currently visited node
- # is at the same block level as a previously visited node
- if _stmts[pindex].ass_type().parent_of(ass_type):
- # both statements are not at the same block level
- continue
- # if currently visited node is following previously considered
- # assignement and both are not exclusive, we can drop the
- # previous one. For instance in the following code ::
- #
- # if a:
- # x = 1
- # else:
- # x = 2
- # print x
- #
- # we can't remove neither x = 1 nor x = 2 when looking for 'x'
- # of 'print x'; while in the following ::
- #
- # x = 1
- # x = 2
- # print x
- #
- # we can remove x = 1 when we see x = 2
- #
- # moreover, on loop assignment types, assignment won't
- # necessarily be done if the loop has no iteration, so we don't
- # want to clear previous assigments if any (hence the test on
- # optional_assign)
- if not (optional_assign or are_exclusive(_stmts[pindex], node)):
- del _stmt_parents[pindex]
- del _stmts[pindex]
- if isinstance(node, AssName):
- if not optional_assign and stmt.parent is mystmt.parent:
- _stmts = []
- _stmt_parents = []
- elif isinstance(node, DelName):
- _stmts = []
- _stmt_parents = []
- continue
- if not are_exclusive(self, node):
- _stmts.append(node)
- _stmt_parents.append(stmt.parent)
- return _stmts
-
def builtin_lookup(name):
"""lookup a name into the builtin module
@@ -232,6 +90,7 @@ def builtin_lookup(name):
return builtinastng, stmts
+# TODO move this Mixin to mixins.py; problem: 'Function' in _scope_lookup
class LocalsDictNodeNG(LookupMixIn, NodeNG):
""" this class provides locals handling common to Module, Function
and Class nodes, including a dict like interface for direct access
@@ -350,19 +209,6 @@ class LocalsDictNodeNG(LookupMixIn, NodeNG):
__contains__ = has_key
-# Name classses
-
-class AssName(LookupMixIn, ParentAssignTypeMixin, NodeNG):
- """class representing an AssName node"""
-
-
-class DelName(LookupMixIn, ParentAssignTypeMixin, NodeNG):
- """class representing a DelName node"""
-
-
-class Name(LookupMixIn, NodeNG):
- """class representing a Name node"""
-
# Module #####################################################################