diff options
| author | Emile Anclin <emile.anclin@logilab.fr> | 2010-12-14 17:17:35 +0100 |
|---|---|---|
| committer | Emile Anclin <emile.anclin@logilab.fr> | 2010-12-14 17:17:35 +0100 |
| commit | f498037505dfc0d9ebc37a852b2fe38c5935e2c8 (patch) | |
| tree | eb34ef2f84e35f73f3f9d9f192d0122fc03fd5fd | |
| parent | c09dbcf295cb2eb9b2a2c0febf195df9c7cce57a (diff) | |
| download | astroid-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.py | 58 | ||||
| -rw-r--r-- | raw_building.py | 26 | ||||
| -rw-r--r-- | scoped_nodes.py | 3 |
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 |
