Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: third_party/logilab/astroid/node_classes.py

Issue 753543006: pylint: upgrade to 1.4.0 (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/logilab/astroid/modutils.py ('k') | third_party/logilab/astroid/protocols.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved. 1 # copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr 2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
3 # 3 #
4 # This file is part of astroid. 4 # This file is part of astroid.
5 # 5 #
6 # astroid is free software: you can redistribute it and/or modify it 6 # astroid is free software: you can redistribute it and/or modify it
7 # under the terms of the GNU Lesser General Public License as published by the 7 # under the terms of the GNU Lesser General Public License as published by the
8 # Free Software Foundation, either version 2.1 of the License, or (at your 8 # Free Software Foundation, either version 2.1 of the License, or (at your
9 # option) any later version. 9 # option) any later version.
10 # 10 #
11 # astroid is distributed in the hope that it will be useful, but 11 # astroid is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 13 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
14 # for more details. 14 # for more details.
15 # 15 #
16 # You should have received a copy of the GNU Lesser General Public License along 16 # You should have received a copy of the GNU Lesser General Public License along
17 # with astroid. If not, see <http://www.gnu.org/licenses/>. 17 # with astroid. If not, see <http://www.gnu.org/licenses/>.
18 """Module for some node classes. More nodes in scoped_nodes.py 18 """Module for some node classes. More nodes in scoped_nodes.py
19 """ 19 """
20 20
21 import sys 21 import sys
22 22
23 import six
24 from logilab.common.decorators import cachedproperty
25
23 from astroid.exceptions import NoDefault 26 from astroid.exceptions import NoDefault
24 from astroid.bases import (NodeNG, Statement, Instance, InferenceContext, 27 from astroid.bases import (NodeNG, Statement, Instance, InferenceContext,
25 _infer_stmts, YES, BUILTINS) 28 _infer_stmts, YES, BUILTINS)
26 from astroid.mixins import (BlockRangeMixIn, AssignTypeMixin, 29 from astroid.mixins import (BlockRangeMixIn, AssignTypeMixin,
27 ParentAssignTypeMixin, FromImportMixIn) 30 ParentAssignTypeMixin, FromImportMixIn)
28 31
29 PY3K = sys.version_info >= (3, 0) 32 PY3K = sys.version_info >= (3, 0)
30 33
31 34
32 def unpack_infer(stmt, context=None): 35 def unpack_infer(stmt, context=None):
33 """recursively generate nodes inferred by the given statement. 36 """recursively generate nodes inferred by the given statement.
34 If the inferred value is a list or a tuple, recurse on the elements 37 If the inferred value is a list or a tuple, recurse on the elements
35 """ 38 """
36 if isinstance(stmt, (List, Tuple)): 39 if isinstance(stmt, (List, Tuple)):
37 for elt in stmt.elts: 40 for elt in stmt.elts:
38 for infered_elt in unpack_infer(elt, context): 41 for infered_elt in unpack_infer(elt, context):
39 yield infered_elt 42 yield infered_elt
40 return 43 return
41 # if infered is a final node, return it and stop 44 # if infered is a final node, return it and stop
42 infered = stmt.infer(context).next() 45 infered = next(stmt.infer(context))
43 if infered is stmt: 46 if infered is stmt:
44 yield infered 47 yield infered
45 return 48 return
46 # else, infer recursivly, except YES object that should be returned as is 49 # else, infer recursivly, except YES object that should be returned as is
47 for infered in stmt.infer(context): 50 for infered in stmt.infer(context):
48 if infered is YES: 51 if infered is YES:
49 yield infered 52 yield infered
50 else: 53 else:
51 for inf_inf in unpack_infer(infered, context): 54 for inf_inf in unpack_infer(infered, context):
52 yield inf_inf 55 yield inf_inf
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 """ 123 """
121 return self.scope().scope_lookup(self, name) 124 return self.scope().scope_lookup(self, name)
122 125
123 def ilookup(self, name): 126 def ilookup(self, name):
124 """infered lookup 127 """infered lookup
125 128
126 return an iterator on infered values of the statements returned by 129 return an iterator on infered values of the statements returned by
127 the lookup method 130 the lookup method
128 """ 131 """
129 frame, stmts = self.lookup(name) 132 frame, stmts = self.lookup(name)
130 context = InferenceContext() 133 return _infer_stmts(stmts, None, frame)
131 return _infer_stmts(stmts, context, frame)
132 134
133 def _filter_stmts(self, stmts, frame, offset): 135 def _filter_stmts(self, stmts, frame, offset):
134 """filter statements to remove ignorable statements. 136 """filter statements to remove ignorable statements.
135 137
136 If self is not a frame itself and the name is found in the inner 138 If self is not a frame itself and the name is found in the inner
137 frame locals, statements will be filtered to remove ignorable 139 frame locals, statements will be filtered to remove ignorable
138 statements according to self's location 140 statements according to self's location
139 """ 141 """
140 # if offset == -1, my actual frame is not the inner frame but its parent 142 # if offset == -1, my actual frame is not the inner frame but its parent
141 # 143 #
142 # class A(B): pass 144 # class A(B): pass
143 # 145 #
144 # we need this to resolve B correctly 146 # we need this to resolve B correctly
145 if offset == -1: 147 if offset == -1:
146 myframe = self.frame().parent.frame() 148 myframe = self.frame().parent.frame()
147 else: 149 else:
148 myframe = self.frame() 150 myframe = self.frame()
151 # If the frame of this node is the same as the statement
152 # of this node, then the node is part of a class or
153 # a function definition and the frame of this node should be the
154 # the upper frame, not the frame of the definition.
155 # For more information why this is important,
156 # see Pylint issue #295.
157 # For example, for 'b', the statement is the same
158 # as the frame / scope:
159 #
160 # def test(b=1):
161 # ...
162
163 if self.statement() is myframe and myframe.parent:
164 myframe = myframe.parent.frame()
149 if not myframe is frame or self is frame: 165 if not myframe is frame or self is frame:
150 return stmts 166 return stmts
151 mystmt = self.statement() 167 mystmt = self.statement()
152 # line filtering if we are in the same frame 168 # line filtering if we are in the same frame
153 # 169 #
154 # take care node may be missing lineno information (this is the case for 170 # take care node may be missing lineno information (this is the case for
155 # nodes inserted for living objects) 171 # nodes inserted for living objects)
156 if myframe is frame and mystmt.fromlineno is not None: 172 if myframe is frame and mystmt.fromlineno is not None:
157 assert mystmt.fromlineno is not None, mystmt 173 assert mystmt.fromlineno is not None, mystmt
158 mylineno = mystmt.fromlineno + offset 174 mylineno = mystmt.fromlineno + offset
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 298
283 def __init__(self, vararg=None, kwarg=None): 299 def __init__(self, vararg=None, kwarg=None):
284 self.vararg = vararg 300 self.vararg = vararg
285 self.kwarg = kwarg 301 self.kwarg = kwarg
286 302
287 def _infer_name(self, frame, name): 303 def _infer_name(self, frame, name):
288 if self.parent is frame: 304 if self.parent is frame:
289 return name 305 return name
290 return None 306 return None
291 307
308 @cachedproperty
309 def fromlineno(self):
310 lineno = super(Arguments, self).fromlineno
311 return max(lineno, self.parent.fromlineno)
312
292 def format_args(self): 313 def format_args(self):
293 """return arguments formatted as string""" 314 """return arguments formatted as string"""
294 result = [] 315 result = []
295 if self.args: 316 if self.args:
296 result.append(_format_args(self.args, self.defaults)) 317 result.append(_format_args(self.args, self.defaults))
297 if self.vararg: 318 if self.vararg:
298 result.append('*%s' % self.vararg) 319 result.append('*%s' % self.vararg)
299 if self.kwarg: 320 if self.kwarg:
300 result.append('**%s' % self.kwarg) 321 result.append('**%s' % self.kwarg)
301 if self.kwonlyargs: 322 if self.kwonlyargs:
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 return stmts, False 489 return stmts, False
469 490
470 491
471 class Const(NodeNG, Instance): 492 class Const(NodeNG, Instance):
472 """represent a constant node like num, str, bool, None, bytes""" 493 """represent a constant node like num, str, bool, None, bytes"""
473 494
474 def __init__(self, value=None): 495 def __init__(self, value=None):
475 self.value = value 496 self.value = value
476 497
477 def getitem(self, index, context=None): 498 def getitem(self, index, context=None):
478 if isinstance(self.value, basestring): 499 if isinstance(self.value, six.string_types):
479 return Const(self.value[index]) 500 return Const(self.value[index])
480 raise TypeError('%r (value=%s)' % (self, self.value)) 501 raise TypeError('%r (value=%s)' % (self, self.value))
481 502
482 def has_dynamic_getattr(self): 503 def has_dynamic_getattr(self):
483 return False 504 return False
484 505
485 def itered(self): 506 def itered(self):
486 if isinstance(self.value, basestring): 507 if isinstance(self.value, six.string_types):
487 return self.value 508 return self.value
488 raise TypeError() 509 raise TypeError()
489 510
490 def pytype(self): 511 def pytype(self):
491 return self._proxied.qname() 512 return self._proxied.qname()
492 513
493 514
494 class Continue(Statement): 515 class Continue(Statement):
495 """class representing a Continue node""" 516 """class representing a Continue node"""
496 517
(...skipping 24 matching lines...) Expand all
521 542
522 class Dict(NodeNG, Instance): 543 class Dict(NodeNG, Instance):
523 """class representing a Dict node""" 544 """class representing a Dict node"""
524 _astroid_fields = ('items',) 545 _astroid_fields = ('items',)
525 546
526 def __init__(self, items=None): 547 def __init__(self, items=None):
527 if items is None: 548 if items is None:
528 self.items = [] 549 self.items = []
529 else: 550 else:
530 self.items = [(const_factory(k), const_factory(v)) 551 self.items = [(const_factory(k), const_factory(v))
531 for k, v in items.iteritems()] 552 for k, v in items.items()]
532 553
533 def pytype(self): 554 def pytype(self):
534 return '%s.dict' % BUILTINS 555 return '%s.dict' % BUILTINS
535 556
536 def get_children(self): 557 def get_children(self):
537 """get children of a Dict node""" 558 """get children of a Dict node"""
538 # overrides get_children 559 # overrides get_children
539 for key, value in self.items: 560 for key, value in self.items:
540 yield key 561 yield key
541 yield value 562 yield value
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 """class representing an EmptyNode node""" 597 """class representing an EmptyNode node"""
577 598
578 599
579 class ExceptHandler(Statement, AssignTypeMixin): 600 class ExceptHandler(Statement, AssignTypeMixin):
580 """class representing an ExceptHandler node""" 601 """class representing an ExceptHandler node"""
581 _astroid_fields = ('type', 'name', 'body',) 602 _astroid_fields = ('type', 'name', 'body',)
582 type = None 603 type = None
583 name = None 604 name = None
584 body = None 605 body = None
585 606
586 def _blockstart_toline(self): 607 @cachedproperty
608 def blockstart_tolineno(self):
587 if self.name: 609 if self.name:
588 return self.name.tolineno 610 return self.name.tolineno
589 elif self.type: 611 elif self.type:
590 return self.type.tolineno 612 return self.type.tolineno
591 else: 613 else:
592 return self.lineno 614 return self.lineno
593 615
594 def set_line_info(self, lastchild):
595 self.fromlineno = self.lineno
596 self.tolineno = lastchild.tolineno
597 self.blockstart_tolineno = self._blockstart_toline()
598
599 def catch(self, exceptions): 616 def catch(self, exceptions):
600 if self.type is None or exceptions is None: 617 if self.type is None or exceptions is None:
601 return True 618 return True
602 for node in self.type.nodes_of_class(Name): 619 for node in self.type.nodes_of_class(Name):
603 if node.name in exceptions: 620 if node.name in exceptions:
604 return True 621 return True
605 622
606 623
607 class Exec(Statement): 624 class Exec(Statement):
608 """class representing an Exec node""" 625 """class representing an Exec node"""
(...skipping 10 matching lines...) Expand all
619 636
620 class For(BlockRangeMixIn, AssignTypeMixin, Statement): 637 class For(BlockRangeMixIn, AssignTypeMixin, Statement):
621 """class representing a For node""" 638 """class representing a For node"""
622 _astroid_fields = ('target', 'iter', 'body', 'orelse',) 639 _astroid_fields = ('target', 'iter', 'body', 'orelse',)
623 target = None 640 target = None
624 iter = None 641 iter = None
625 body = None 642 body = None
626 orelse = None 643 orelse = None
627 644
628 optional_assign = True 645 optional_assign = True
629 def _blockstart_toline(self): 646 @cachedproperty
647 def blockstart_tolineno(self):
630 return self.iter.tolineno 648 return self.iter.tolineno
631 649
632 650
633 class From(FromImportMixIn, Statement): 651 class From(FromImportMixIn, Statement):
634 """class representing a From node""" 652 """class representing a From node"""
635 653
636 def __init__(self, fromname, names, level=0): 654 def __init__(self, fromname, names, level=0):
637 self.modname = fromname 655 self.modname = fromname
638 self.names = names 656 self.names = names
639 self.level = level 657 self.level = level
(...skipping 14 matching lines...) Expand all
654 return name 672 return name
655 673
656 674
657 class If(BlockRangeMixIn, Statement): 675 class If(BlockRangeMixIn, Statement):
658 """class representing an If node""" 676 """class representing an If node"""
659 _astroid_fields = ('test', 'body', 'orelse') 677 _astroid_fields = ('test', 'body', 'orelse')
660 test = None 678 test = None
661 body = None 679 body = None
662 orelse = None 680 orelse = None
663 681
664 def _blockstart_toline(self): 682 @cachedproperty
683 def blockstart_tolineno(self):
665 return self.test.tolineno 684 return self.test.tolineno
666 685
667 def block_range(self, lineno): 686 def block_range(self, lineno):
668 """handle block line numbers range for if statements""" 687 """handle block line numbers range for if statements"""
669 if lineno == self.body[0].fromlineno: 688 if lineno == self.body[0].fromlineno:
670 return lineno, lineno 689 return lineno, lineno
671 if lineno <= self.body[-1].tolineno: 690 if lineno <= self.body[-1].tolineno:
672 return lineno, self.body[-1].tolineno 691 return lineno, self.body[-1].tolineno
673 return self._elsed_block_range(lineno, self.orelse, 692 return self._elsed_block_range(lineno, self.orelse,
674 self.body[0].fromlineno - 1) 693 self.body[0].fromlineno - 1)
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
805 class TryExcept(BlockRangeMixIn, Statement): 824 class TryExcept(BlockRangeMixIn, Statement):
806 """class representing a TryExcept node""" 825 """class representing a TryExcept node"""
807 _astroid_fields = ('body', 'handlers', 'orelse',) 826 _astroid_fields = ('body', 'handlers', 'orelse',)
808 body = None 827 body = None
809 handlers = None 828 handlers = None
810 orelse = None 829 orelse = None
811 830
812 def _infer_name(self, frame, name): 831 def _infer_name(self, frame, name):
813 return name 832 return name
814 833
815 def _blockstart_toline(self):
816 return self.lineno
817
818 def block_range(self, lineno): 834 def block_range(self, lineno):
819 """handle block line numbers range for try/except statements""" 835 """handle block line numbers range for try/except statements"""
820 last = None 836 last = None
821 for exhandler in self.handlers: 837 for exhandler in self.handlers:
822 if exhandler.type and lineno == exhandler.type.fromlineno: 838 if exhandler.type and lineno == exhandler.type.fromlineno:
823 return lineno, lineno 839 return lineno, lineno
824 if exhandler.body[0].fromlineno <= lineno <= exhandler.body[-1].toli neno: 840 if exhandler.body[0].fromlineno <= lineno <= exhandler.body[-1].toli neno:
825 return lineno, exhandler.body[-1].tolineno 841 return lineno, exhandler.body[-1].tolineno
826 if last is None: 842 if last is None:
827 last = exhandler.body[0].fromlineno - 1 843 last = exhandler.body[0].fromlineno - 1
828 return self._elsed_block_range(lineno, self.orelse, last) 844 return self._elsed_block_range(lineno, self.orelse, last)
829 845
830 846
831 class TryFinally(BlockRangeMixIn, Statement): 847 class TryFinally(BlockRangeMixIn, Statement):
832 """class representing a TryFinally node""" 848 """class representing a TryFinally node"""
833 _astroid_fields = ('body', 'finalbody',) 849 _astroid_fields = ('body', 'finalbody',)
834 body = None 850 body = None
835 finalbody = None 851 finalbody = None
836 852
837 def _blockstart_toline(self):
838 return self.lineno
839
840 def block_range(self, lineno): 853 def block_range(self, lineno):
841 """handle block line numbers range for try/finally statements""" 854 """handle block line numbers range for try/finally statements"""
842 child = self.body[0] 855 child = self.body[0]
843 # py2.5 try: except: finally: 856 # py2.5 try: except: finally:
844 if (isinstance(child, TryExcept) and child.fromlineno == self.fromlineno 857 if (isinstance(child, TryExcept) and child.fromlineno == self.fromlineno
845 and lineno > self.fromlineno and lineno <= child.tolineno): 858 and lineno > self.fromlineno and lineno <= child.tolineno):
846 return child.block_range(lineno) 859 return child.block_range(lineno)
847 return self._elsed_block_range(lineno, self.finalbody) 860 return self._elsed_block_range(lineno, self.finalbody)
848 861
849 862
(...skipping 23 matching lines...) Expand all
873 operand = None 886 operand = None
874 887
875 888
876 class While(BlockRangeMixIn, Statement): 889 class While(BlockRangeMixIn, Statement):
877 """class representing a While node""" 890 """class representing a While node"""
878 _astroid_fields = ('test', 'body', 'orelse',) 891 _astroid_fields = ('test', 'body', 'orelse',)
879 test = None 892 test = None
880 body = None 893 body = None
881 orelse = None 894 orelse = None
882 895
883 def _blockstart_toline(self): 896 @cachedproperty
897 def blockstart_tolineno(self):
884 return self.test.tolineno 898 return self.test.tolineno
885 899
886 def block_range(self, lineno): 900 def block_range(self, lineno):
887 """handle block line numbers range for for and while statements""" 901 """handle block line numbers range for for and while statements"""
888 return self. _elsed_block_range(lineno, self.orelse) 902 return self. _elsed_block_range(lineno, self.orelse)
889 903
890 904
891 class With(BlockRangeMixIn, AssignTypeMixin, Statement): 905 class With(BlockRangeMixIn, AssignTypeMixin, Statement):
892 """class representing a With node""" 906 """class representing a With node"""
893 _astroid_fields = ('items', 'body') 907 _astroid_fields = ('items', 'body')
894 items = None 908 items = None
895 body = None 909 body = None
896 910
897 def _blockstart_toline(self): 911 @cachedproperty
912 def blockstart_tolineno(self):
898 return self.items[-1][0].tolineno 913 return self.items[-1][0].tolineno
899 914
900 def get_children(self): 915 def get_children(self):
901 for expr, var in self.items: 916 for expr, var in self.items:
902 yield expr 917 yield expr
903 if var: 918 if var:
904 yield var 919 yield var
905 for elt in self.body: 920 for elt in self.body:
906 yield elt 921 yield elt
907 922
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
941 # we should rather recall the builder on this value than returning an empty 956 # we should rather recall the builder on this value than returning an empty
942 # node (another option being that const_factory shouldn't be called with som ething 957 # node (another option being that const_factory shouldn't be called with som ething
943 # not in CONST_CLS) 958 # not in CONST_CLS)
944 assert not isinstance(value, NodeNG) 959 assert not isinstance(value, NodeNG)
945 try: 960 try:
946 return CONST_CLS[value.__class__](value) 961 return CONST_CLS[value.__class__](value)
947 except (KeyError, AttributeError): 962 except (KeyError, AttributeError):
948 node = EmptyNode() 963 node = EmptyNode()
949 node.object = value 964 node.object = value
950 return node 965 return node
OLDNEW
« no previous file with comments | « third_party/logilab/astroid/modutils.py ('k') | third_party/logilab/astroid/protocols.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698