diff options
author | Eevee (Alex Munroe) <amunroe@yelp.com> | 2014-07-31 16:32:21 -0700 |
---|---|---|
committer | Eevee (Alex Munroe) <amunroe@yelp.com> | 2014-07-31 16:32:21 -0700 |
commit | 3a090e2819c85abacae5dd244733408cb110e427 (patch) | |
tree | 22afd25a9e0b62afb2c456c8f63fd2b69d597f02 /node_classes.py | |
parent | 58e5e9774ba6a5cb378f2e30eb026489d66922fd (diff) | |
parent | bf919348a823a573ebbb7c435626172ba21b7c3c (diff) | |
download | astroid-git-3a090e2819c85abacae5dd244733408cb110e427.tar.gz |
merged with default
Diffstat (limited to 'node_classes.py')
-rw-r--r-- | node_classes.py | 60 |
1 files changed, 41 insertions, 19 deletions
diff --git a/node_classes.py b/node_classes.py index 45a00ba9..3c765bb4 100644 --- a/node_classes.py +++ b/node_classes.py @@ -24,9 +24,11 @@ from logilab.common.decorators import cachedproperty from astroid.exceptions import NoDefault from astroid.bases import (NodeNG, Statement, Instance, InferenceContext, - _infer_stmts, YES, BUILTINS) -from astroid.mixins import BlockRangeMixIn, AssignTypeMixin, \ - ParentAssignTypeMixin, FromImportMixIn + _infer_stmts, YES, BUILTINS) +from astroid.mixins import (BlockRangeMixIn, AssignTypeMixin, + ParentAssignTypeMixin, FromImportMixIn) + +PY3K = sys.version_info >= (3, 0) def unpack_infer(stmt, context=None): @@ -84,16 +86,16 @@ def are_exclusive(stmt1, stmt2, exceptions=None): # nodes are in exclusive branches if isinstance(node, If) and exceptions is None: if (node.locate_child(previous)[1] - is not node.locate_child(children[node])[1]): + is not node.locate_child(children[node])[1]): return True elif isinstance(node, TryExcept): c2attr, c2node = node.locate_child(previous) c1attr, c1node = node.locate_child(children[node]) if c1node is not c2node: if ((c2attr == 'body' and c1attr == 'handlers' and children[node].catch(exceptions)) or - (c2attr == 'handlers' and c1attr == 'body' and previous.catch(exceptions)) or - (c2attr == 'handlers' and c1attr == 'orelse') or - (c2attr == 'orelse' and c1attr == 'handlers')): + (c2attr == 'handlers' and c1attr == 'body' and previous.catch(exceptions)) or + (c2attr == 'handlers' and c1attr == 'orelse') or + (c2attr == 'orelse' and c1attr == 'handlers')): return True elif c2attr == 'handlers' and c1attr == 'handlers': return previous is not children[node] @@ -110,13 +112,13 @@ class LookupMixIn(object): 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) + 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 + 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) @@ -254,7 +256,26 @@ class Name(LookupMixIn, NodeNG): class Arguments(NodeNG, AssignTypeMixin): """class representing an Arguments node""" - _astroid_fields = ('args', 'defaults', 'kwonlyargs', 'kw_defaults') + if PY3K: + # Python 3.4+ uses a different approach regarding annotations, + # each argument is a new class, _ast.arg, which exposes an + # 'annotation' attribute. In astroid though, arguments are exposed + # as is in the Arguments node and the only way to expose annotations + # is by using something similar with Python 3.3: + # - we expose 'varargannotation' and 'kwargannotation' of annotations + # of varargs and kwargs. + # - we expose 'annotation', a list with annotations for + # for each normal argument. If an argument doesn't have an + # annotation, its value will be None. + + _astroid_fields = ('args', 'defaults', 'kwonlyargs', + 'kw_defaults', 'annotations', + 'varargannotation', 'kwargannotation') + annotations = None + varargannotation = None + kwargannotation = None + else: + _astroid_fields = ('args', 'defaults', 'kwonlyargs', 'kw_defaults') args = None defaults = None kwonlyargs = None @@ -429,7 +450,7 @@ class Compare(NodeNG): class Comprehension(NodeNG): """class representing a Comprehension node""" - _astroid_fields = ('target', 'iter' ,'ifs') + _astroid_fields = ('target', 'iter', 'ifs') target = None iter = None ifs = None @@ -513,7 +534,7 @@ class Dict(NodeNG, Instance): self.items = [] else: self.items = [(const_factory(k), const_factory(v)) - for k,v in items.iteritems()] + for k, v in items.iteritems()] def pytype(self): return '%s.dict' % BUILTINS @@ -539,7 +560,8 @@ class Dict(NodeNG, Instance): for inferedkey in key.infer(context): if inferedkey is YES: continue - if isinstance(inferedkey, Const) and inferedkey.value == lookup_key: + if isinstance(inferedkey, Const) \ + and inferedkey.value == lookup_key: return value # This should raise KeyError, but all call sites only catch # IndexError. Let's leave it like that for now. @@ -614,7 +636,7 @@ class For(BlockRangeMixIn, AssignTypeMixin, Statement): class From(FromImportMixIn, Statement): """class representing a From node""" - def __init__(self, fromname, names, level=0): + def __init__(self, fromname, names, level=0): self.modname = fromname self.names = names self.level = level @@ -818,7 +840,7 @@ class TryFinally(BlockRangeMixIn, Statement): child = self.body[0] # py2.5 try: except: finally: if (isinstance(child, TryExcept) and child.fromlineno == self.fromlineno - and lineno > self.fromlineno and lineno <= child.tolineno): + and lineno > self.fromlineno and lineno <= child.tolineno): return child.block_range(lineno) return self._elsed_block_range(lineno, self.finalbody) |