| Index: third_party/logilab/astng/bases.py
 | 
| diff --git a/third_party/logilab/astroid/bases.py b/third_party/logilab/astng/bases.py
 | 
| similarity index 83%
 | 
| rename from third_party/logilab/astroid/bases.py
 | 
| rename to third_party/logilab/astng/bases.py
 | 
| index 37e613b8241494ccfd319b17ae3024453b69f00d..92f12aad7d34df630263a7c5ad8b22393b0b6d60 100644
 | 
| --- a/third_party/logilab/astroid/bases.py
 | 
| +++ b/third_party/logilab/astng/bases.py
 | 
| @@ -1,43 +1,43 @@
 | 
| -# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 | 
| +# -*- coding: utf-8 -*-
 | 
| +# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 | 
|  # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 | 
| +# copyright 2003-2010 Sylvain Thenault, all rights reserved.
 | 
| +# contact mailto:thenault@gmail.com
 | 
|  #
 | 
| -# This file is part of astroid.
 | 
| +# This file is part of logilab-astng.
 | 
|  #
 | 
| -# astroid is free software: you can redistribute it and/or modify it
 | 
| +# logilab-astng is free software: you can redistribute it and/or modify it
 | 
|  # under the terms of the GNU Lesser General Public License as published by the
 | 
|  # Free Software Foundation, either version 2.1 of the License, or (at your
 | 
|  # option) any later version.
 | 
|  #
 | 
| -# astroid is distributed in the hope that it will be useful, but
 | 
| +# logilab-astng 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 Lesser General Public License
 | 
|  # for more details.
 | 
|  #
 | 
|  # You should have received a copy of the GNU Lesser General Public License along
 | 
| -# with astroid. If not, see <http://www.gnu.org/licenses/>.
 | 
| +# with logilab-astng. If not, see <http://www.gnu.org/licenses/>.
 | 
|  """This module contains base classes and functions for the nodes and some
 | 
|  inference utils.
 | 
|  """
 | 
|  
 | 
|  __docformat__ = "restructuredtext en"
 | 
|  
 | 
| -import sys
 | 
|  from contextlib import contextmanager
 | 
|  
 | 
| -from astroid.exceptions import (InferenceError, AstroidError, NotFoundError,
 | 
| -                                UnresolvableName, UseInferenceDefault)
 | 
| +from logilab.common.compat import builtins
 | 
|  
 | 
| +from logilab.astng import BUILTINS_MODULE
 | 
| +from logilab.astng.exceptions import InferenceError, ASTNGError, \
 | 
| +                                       NotFoundError, UnresolvableName
 | 
| +from logilab.astng.as_string import as_string
 | 
|  
 | 
| -if sys.version_info >= (3, 0):
 | 
| -    BUILTINS = 'builtins'
 | 
| -else:
 | 
| -    BUILTINS = '__builtin__'
 | 
| -
 | 
| +BUILTINS_NAME = builtins.__name__
 | 
|  
 | 
|  class Proxy(object):
 | 
|      """a simple proxy object"""
 | 
| -
 | 
| -    _proxied = None # proxied object may be set by class or by instance
 | 
| +    _proxied = None
 | 
|  
 | 
|      def __init__(self, proxied=None):
 | 
|          if proxied is not None:
 | 
| @@ -72,7 +72,7 @@ class InferenceContext(object):
 | 
|          name = self.lookupname
 | 
|          if (node, name) in self.path:
 | 
|              raise StopIteration()
 | 
| -        self.path.add((node, name))
 | 
| +        self.path.add( (node, name) )
 | 
|  
 | 
|      def clone(self):
 | 
|          # XXX copy lookupname/callcontext ?
 | 
| @@ -131,8 +131,6 @@ class _Yes(object):
 | 
|      def __repr__(self):
 | 
|          return 'YES'
 | 
|      def __getattribute__(self, name):
 | 
| -        if name == 'next':
 | 
| -            raise AttributeError('next method should not be called')
 | 
|          if name.startswith('__') and name.endswith('__'):
 | 
|              # to avoid inspection pb
 | 
|              return super(_Yes, self).__getattribute__(name)
 | 
| @@ -171,9 +169,6 @@ class Instance(Proxy):
 | 
|      def igetattr(self, name, context=None):
 | 
|          """inferred getattr"""
 | 
|          try:
 | 
| -            # avoid recursively inferring the same attr on the same class
 | 
| -            if context:
 | 
| -                context.push((self._proxied, name))
 | 
|              # XXX frame should be self._proxied, or not ?
 | 
|              get_attr = self.getattr(name, context, lookupclass=False)
 | 
|              return _infer_stmts(self._wrap_attr(get_attr, context), context,
 | 
| @@ -191,7 +186,7 @@ class Instance(Proxy):
 | 
|          """wrap bound methods of attrs in a InstanceMethod proxies"""
 | 
|          for attr in attrs:
 | 
|              if isinstance(attr, UnboundMethod):
 | 
| -                if BUILTINS + '.property' in attr.decoratornames():
 | 
| +                if BUILTINS_NAME + '.property' in attr.decoratornames():
 | 
|                      for infered in attr.infer_call_result(self, context):
 | 
|                          yield infered
 | 
|                  else:
 | 
| @@ -203,8 +198,6 @@ class Instance(Proxy):
 | 
|          """infer what a class instance is returning when called"""
 | 
|          infered = False
 | 
|          for node in self._proxied.igetattr('__call__', context):
 | 
| -            if node is YES:
 | 
| -                continue
 | 
|              for res in node.infer_call_result(caller, context):
 | 
|                  infered = True
 | 
|                  yield res
 | 
| @@ -258,15 +251,14 @@ class UnboundMethod(Proxy):
 | 
|          # If we're unbound method __new__ of builtin object, the result is an
 | 
|          # instance of the class given as first argument.
 | 
|          if (self._proxied.name == '__new__' and
 | 
| -                self._proxied.parent.frame().qname() == '%s.object' % BUILTINS):
 | 
| -            infer = caller.args[0].infer() if caller.args else []
 | 
| -            return ((x is YES and x or Instance(x)) for x in infer)
 | 
| +                self._proxied.parent.frame().qname() == '%s.object' % BUILTINS_MODULE):
 | 
| +            return (x is YES and x or Instance(x) for x in caller.args[0].infer())
 | 
|          return self._proxied.infer_call_result(caller, context)
 | 
|  
 | 
|  
 | 
|  class BoundMethod(UnboundMethod):
 | 
|      """a special node representing a method bound to an instance"""
 | 
| -    def __init__(self, proxy, bound):
 | 
| +    def __init__(self,  proxy, bound):
 | 
|          UnboundMethod.__init__(self, proxy)
 | 
|          self.bound = bound
 | 
|  
 | 
| @@ -280,15 +272,12 @@ class BoundMethod(UnboundMethod):
 | 
|  
 | 
|  
 | 
|  class Generator(Instance):
 | 
| -    """a special node representing a generator.
 | 
| -
 | 
| -    Proxied class is set once for all in raw_building.
 | 
| -    """
 | 
| +    """a special node representing a generator"""
 | 
|      def callable(self):
 | 
| -        return False
 | 
| +        return True
 | 
|  
 | 
|      def pytype(self):
 | 
| -        return '%s.generator' % BUILTINS
 | 
| +        return '%s.generator' % BUILTINS_MODULE
 | 
|  
 | 
|      def display_type(self):
 | 
|          return 'Generator'
 | 
| @@ -345,7 +334,7 @@ def raise_if_nothing_infered(func):
 | 
|  # Node  ######################################################################
 | 
|  
 | 
|  class NodeNG(object):
 | 
| -    """Base Class for all Astroid node classes.
 | 
| +    """Base Class for all ASTNG node classes.
 | 
|  
 | 
|      It represents a node of the new abstract syntax tree.
 | 
|      """
 | 
| @@ -360,24 +349,7 @@ class NodeNG(object):
 | 
|      # parent node in the tree
 | 
|      parent = None
 | 
|      # attributes containing child node(s) redefined in most concrete classes:
 | 
| -    _astroid_fields = ()
 | 
| -    # instance specific inference function infer(node, context)
 | 
| -    _explicit_inference = None
 | 
| -
 | 
| -    def infer(self, context=None, **kwargs):
 | 
| -        """main interface to the interface system, return a generator on infered
 | 
| -        values.
 | 
| -
 | 
| -        If the instance has some explicit inference function set, it will be
 | 
| -        called instead of the default interface.
 | 
| -        """
 | 
| -        if self._explicit_inference is not None:
 | 
| -            # explicit_inference is not bound, give it self explicitly
 | 
| -            try:
 | 
| -                return self._explicit_inference(self, context, **kwargs)
 | 
| -            except UseInferenceDefault:
 | 
| -                pass
 | 
| -        return self._infer(context, **kwargs)
 | 
| +    _astng_fields = ()
 | 
|  
 | 
|      def _repr_name(self):
 | 
|          """return self.name or self.attrname or '' for nice representation"""
 | 
| @@ -387,19 +359,20 @@ class NodeNG(object):
 | 
|          return '%s(%s)' % (self.__class__.__name__, self._repr_name())
 | 
|  
 | 
|      def __repr__(self):
 | 
| -        return '<%s(%s) l.%s [%s] at 0x%x>' % (self.__class__.__name__,
 | 
| -                                               self._repr_name(),
 | 
| -                                               self.fromlineno,
 | 
| -                                               self.root().name,
 | 
| -                                               id(self))
 | 
| +        return '<%s(%s) l.%s [%s] at Ox%x>' % (self.__class__.__name__,
 | 
| +                                           self._repr_name(),
 | 
| +                                           self.fromlineno,
 | 
| +                                           self.root().name,
 | 
| +                                           id(self))
 | 
|  
 | 
|  
 | 
|      def accept(self, visitor):
 | 
| +        klass = self.__class__.__name__
 | 
|          func = getattr(visitor, "visit_" + self.__class__.__name__.lower())
 | 
|          return func(self)
 | 
|  
 | 
|      def get_children(self):
 | 
| -        for field in self._astroid_fields:
 | 
| +        for field in self._astng_fields:
 | 
|              attr = getattr(self, field)
 | 
|              if attr is None:
 | 
|                  continue
 | 
| @@ -411,7 +384,7 @@ class NodeNG(object):
 | 
|  
 | 
|      def last_child(self):
 | 
|          """an optimized version of list(get_children())[-1]"""
 | 
| -        for field in self._astroid_fields[::-1]:
 | 
| +        for field in self._astng_fields[::-1]:
 | 
|              attr = getattr(self, field)
 | 
|              if not attr: # None or empty listy / tuple
 | 
|                  continue
 | 
| @@ -455,7 +428,7 @@ class NodeNG(object):
 | 
|  
 | 
|      def child_sequence(self, child):
 | 
|          """search for the right sequence where the child lies in"""
 | 
| -        for field in self._astroid_fields:
 | 
| +        for field in self._astng_fields:
 | 
|              node_or_sequence = getattr(self, field)
 | 
|              if node_or_sequence is child:
 | 
|                  return [node_or_sequence]
 | 
| @@ -463,20 +436,20 @@ class NodeNG(object):
 | 
|              if isinstance(node_or_sequence, (tuple, list)) and child in node_or_sequence:
 | 
|                  return node_or_sequence
 | 
|          else:
 | 
| -            msg = 'Could not find %s in %s\'s children'
 | 
| -            raise AstroidError(msg % (repr(child), repr(self)))
 | 
| +            msg = 'Could not found %s in %s\'s children'
 | 
| +            raise ASTNGError(msg % (repr(child), repr(self)))
 | 
|  
 | 
|      def locate_child(self, child):
 | 
|          """return a 2-uple (child attribute name, sequence or node)"""
 | 
| -        for field in self._astroid_fields:
 | 
| +        for field in self._astng_fields:
 | 
|              node_or_sequence = getattr(self, field)
 | 
|              # /!\ compiler.ast Nodes have an __iter__ walking over child nodes
 | 
|              if child is node_or_sequence:
 | 
|                  return field, child
 | 
|              if isinstance(node_or_sequence, (tuple, list)) and child in node_or_sequence:
 | 
|                  return field, node_or_sequence
 | 
| -        msg = 'Could not find %s in %s\'s children'
 | 
| -        raise AstroidError(msg % (repr(child), repr(self)))
 | 
| +        msg = 'Could not found %s in %s\'s children'
 | 
| +        raise ASTNGError(msg % (repr(child), repr(self)))
 | 
|      # FIXME : should we merge child_sequence and locate_child ? locate_child
 | 
|      # is only used in are_exclusive, child_sequence one time in pylint.
 | 
|  
 | 
| @@ -565,7 +538,7 @@ class NodeNG(object):
 | 
|          # overridden for From, Import, Global, TryExcept and Arguments
 | 
|          return None
 | 
|  
 | 
| -    def _infer(self, context=None):
 | 
| +    def infer(self, context=None):
 | 
|          """we don't know how to resolve a statement by default"""
 | 
|          # this method is overridden by most concrete classes
 | 
|          raise InferenceError(self.__class__.__name__)
 | 
| @@ -588,12 +561,15 @@ class NodeNG(object):
 | 
|          return False
 | 
|  
 | 
|      def as_string(self):
 | 
| -        from astroid.as_string import to_code
 | 
| -        return to_code(self)
 | 
| +        return as_string(self)
 | 
|  
 | 
|      def repr_tree(self, ids=False):
 | 
| -        from astroid.as_string import dump
 | 
| -        return dump(self)
 | 
| +        """print a nice astng tree representation.
 | 
| +
 | 
| +        :param ids: if true, we also print the ids (usefull for debugging)"""
 | 
| +        result = []
 | 
| +        _repr_tree(self, result, ids=ids)
 | 
| +        return "\n".join(result)
 | 
|  
 | 
|  
 | 
|  class Statement(NodeNG):
 | 
| @@ -615,3 +591,39 @@ class Statement(NodeNG):
 | 
|          index = stmts.index(self)
 | 
|          if index >= 1:
 | 
|              return stmts[index -1]
 | 
| +
 | 
| +INDENT = "    "
 | 
| +
 | 
| +def _repr_tree(node, result, indent='', _done=None, ids=False):
 | 
| +    """built a tree representation of a node as a list of lines"""
 | 
| +    if _done is None:
 | 
| +        _done = set()
 | 
| +    if not hasattr(node, '_astng_fields'): # not a astng node
 | 
| +        return
 | 
| +    if node in _done:
 | 
| +        result.append( indent + 'loop in tree: %s' % node )
 | 
| +        return
 | 
| +    _done.add(node)
 | 
| +    node_str = str(node)
 | 
| +    if ids:
 | 
| +        node_str += '  . \t%x' % id(node)
 | 
| +    result.append( indent + node_str )
 | 
| +    indent += INDENT
 | 
| +    for field in node._astng_fields:
 | 
| +        value = getattr(node, field)
 | 
| +        if isinstance(value, (list, tuple) ):
 | 
| +            result.append(  indent + field + " = [" )
 | 
| +            for child in value:
 | 
| +                if isinstance(child, (list, tuple) ):
 | 
| +                    # special case for Dict # FIXME
 | 
| +                    _repr_tree(child[0], result, indent, _done, ids)
 | 
| +                    _repr_tree(child[1], result, indent, _done, ids)
 | 
| +                    result.append(indent + ',')
 | 
| +                else:
 | 
| +                    _repr_tree(child, result, indent, _done, ids)
 | 
| +            result.append(  indent + "]" )
 | 
| +        else:
 | 
| +            result.append(  indent + field + " = " )
 | 
| +            _repr_tree(value, result, indent, _done, ids)
 | 
| +
 | 
| +
 | 
| 
 |