summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmile Anclin <emile.anclin@logilab.fr>2010-12-14 17:17:35 +0100
committerEmile Anclin <emile.anclin@logilab.fr>2010-12-14 17:17:35 +0100
commitf498037505dfc0d9ebc37a852b2fe38c5935e2c8 (patch)
treeeb34ef2f84e35f73f3f9d9f192d0122fc03fd5fd
parentc09dbcf295cb2eb9b2a2c0febf195df9c7cce57a (diff)
downloadastroid-git-f498037505dfc0d9ebc37a852b2fe38c5935e2c8.tar.gz
cleanup : do more boot strapping in astng_boot_strapping
* refactor const_factory and add a note in scoped_nodes
-rw-r--r--node_classes.py58
-rw-r--r--raw_building.py26
-rw-r--r--scoped_nodes.py3
3 files changed, 55 insertions, 32 deletions
diff --git a/node_classes.py b/node_classes.py
index a3f68ea8..836ec492 100644
--- a/node_classes.py
+++ b/node_classes.py
@@ -427,7 +427,7 @@ class Comprehension(NodeNG):
class Const(NodeNG, Instance):
- """represent a Str or Num node"""
+ """represent a constant node like num, str, bool, None, bytes"""
def __init__(self, value=None):
self.value = value
@@ -480,7 +480,12 @@ class Delete(Statement, AssignTypeMixin):
class Dict(NodeNG, Instance):
"""class representing a Dict node"""
_astng_fields = ('items',)
- items = None
+
+ def __init__(self, items=None):
+ if items == None:
+ self.items = []
+ else:
+ self.items = items
def pytype(self):
return '__builtin__.dict'
@@ -650,7 +655,12 @@ class Keyword(NodeNG):
class List(NodeNG, Instance, ParentAssignTypeMixin):
"""class representing a List node"""
_astng_fields = ('elts',)
- elts = None
+
+ def __init__(self, elts=None):
+ if elts == None:
+ self.elts = []
+ else:
+ self.elts = elts
def pytype(self):
return '__builtin__.list'
@@ -790,7 +800,12 @@ class TryFinally(BlockRangeMixIn, Statement):
class Tuple(NodeNG, Instance, ParentAssignTypeMixin):
"""class representing a Tuple node"""
_astng_fields = ('elts',)
- elts = None
+
+ def __init__(self, elts=None):
+ if elts == None:
+ self.elts = []
+ else:
+ self.elts = elts
def pytype(self):
return '__builtin__.tuple'
@@ -848,24 +863,27 @@ CONST_CLS = {
list: List,
tuple: Tuple,
dict: Dict,
+ set: Set,
+ type(None): Const,
}
+def _update_const_classes():
+ """update constant classes, so the keys of CONST_CLS can be reused"""
+ klasses = (bool, int, float, complex, str)
+ if sys.version < (3, 0):
+ klasses += (unicode, long)
+ if sys.version >= (2, 6):
+ klassses += (bytes,)
+ for kls in klasses:
+ CONST_CLS[kls] = Const
+_update_const_classes()
+
def const_factory(value):
"""return an astng node for a python value"""
- try:
- # if value is of class list, tuple, dict use specific class, not Const
- cls = CONST_CLS[value.__class__]
- node = cls()
- if isinstance(node, Dict):
- node.items = ()
- else:
- node.elts = ()
- except KeyError:
- # why was value in (None, False, True) not OK?
- assert isinstance(value, (int, long, complex, float, basestring)) or value in (None, False, True)
- node = Const()
- node.value = value
- return node
-
-
+ # /!\ current implementation expects the item / elts nodes for
+ # dict, list, tuples and the constant value for the others.
+ #
+ # some constants (like from gtk._gtk) don't have their class in CONST_CLS,
+ # even though we can "assert isinstance(value, tuple(CONST_CLS))"
+ return CONST_CLS.get(value.__class__, Const)(value)
diff --git a/raw_building.py b/raw_building.py
index 4685d3e4..c798aedf 100644
--- a/raw_building.py
+++ b/raw_building.py
@@ -40,12 +40,15 @@ from os.path import abspath
from inspect import (getargspec, isdatadescriptor, isfunction, ismethod,
ismethoddescriptor, isclass, isbuiltin)
+from logilab.astng.node_classes import CONST_CLS
from logilab.astng.nodes import (Module, Class, Const, const_factory, From,
Function, EmptyNode, Name, Arguments, Dict, List, Set, Tuple)
from logilab.astng.bases import Generator
from logilab.astng.manager import ASTNGManager
MANAGER = ASTNGManager()
+_CONSTANTS = tuple(CONST_CLS) # the keys of CONST_CLS eg python builtin types
+
def _attach_local_node(parent, node, name):
node.name = name # needed by add_local_node
parent.add_local_node(node)
@@ -288,7 +291,7 @@ class InspectBuilder(object):
elif isdatadescriptor(member):
assert isinstance(member, object)
object_build_datadescriptor(node, member, name)
- elif isinstance(member, (int, long, float, str, unicode)) or member is None:
+ elif isinstance(member, _CONSTANTS):
attach_const_node(node, name, member)
else:
# create an empty node so that the name is actually defined
@@ -313,13 +316,16 @@ def astng_boot_strapping():
builder = InspectBuilder()
from logilab.common.compat import builtins
astng_builtin = builder.inspect_build(builtins)
- for cls in (bool, int, long, float, complex, str, unicode):
- _CONST_PROXY[cls] = astng_builtin.getattr(cls.__name__)[0] # XXX
- nonetype = build_class('NoneType')
- nonetype.parent = astng_builtin
- _CONST_PROXY[type(None)] = nonetype
- if sys.version_info >= (2, 6):
- _CONST_PROXY[bytes] = MANAGER.astng_from_class(bytes)
+ for cls, node_cls in CONST_CLS.items():
+ if cls is type(None):
+ proxy = build_class('NoneType')
+ proxy.parent = astng_builtin
+ else:
+ proxy = astng_builtin.getattr(cls.__name__)[0] # XXX
+ if cls in (dict, list, set, tuple):
+ node_cls._proxied = proxy
+ else:
+ _CONST_PROXY[cls] = proxy
astng_boot_strapping()
@@ -330,10 +336,6 @@ def _set_proxied(const):
return _CONST_PROXY[const.value.__class__]
Const._proxied = property(_set_proxied)
-Dict._proxied = MANAGER.astng_from_class(dict)
-List._proxied = MANAGER.astng_from_class(list)
-Set._proxied = MANAGER.astng_from_class(set) # will be needed for py3k
-Tuple._proxied = MANAGER.astng_from_class(tuple)
# FIXME : is it alright that Generator._proxied is not a astng node?
Generator._proxied = MANAGER.infer_astng_from_something(type(a for a in ()))
diff --git a/scoped_nodes.py b/scoped_nodes.py
index 22b9c026..a9656a9d 100644
--- a/scoped_nodes.py
+++ b/scoped_nodes.py
@@ -855,6 +855,9 @@ class Class(Statement, LocalsDictNodeNG, FilterStmtsMixin):
if name in self.special_attributes:
if name == '__module__':
return [cf(self.root().qname())] + values
+ # FIXME : what is expected by passing the list of ancestors to cf:
+ # you can just do [cf(tuple())] + values without breaking any test
+ # this is ticket http://www.logilab.org/ticket/52785
if name == '__bases__':
return [cf(tuple(self.ancestors(recurs=False, context=context)))] + values
# XXX need proper meta class handling + MRO implementation