@@ -658,11 +658,11 @@ def ignore(self, node):
658
658
ASYNCWITH = ASYNCWITHITEM = RAISE = TRYFINALLY = ASSERT = EXEC = \
659
659
EXPR = ASSIGN = handleChildren
660
660
661
- CONTINUE = BREAK = PASS = ignore
661
+ PASS = ignore
662
662
663
663
# "expr" type nodes
664
664
BOOLOP = BINOP = UNARYOP = IFEXP = DICT = SET = \
665
- COMPARE = CALL = REPR = ATTRIBUTE = SUBSCRIPT = LIST = TUPLE = \
665
+ COMPARE = CALL = REPR = ATTRIBUTE = SUBSCRIPT = \
666
666
STARRED = NAMECONSTANT = handleChildren
667
667
668
668
NUM = STR = BYTES = ELLIPSIS = ignore
@@ -748,8 +748,33 @@ def NAME(self, node):
748
748
# arguments, but these aren't dispatched through here
749
749
raise RuntimeError ("Got impossible expression context: %r" % (node .ctx ,))
750
750
751
+ def CONTINUE (self , node ):
752
+ # Walk the tree up until we see a loop (OK), a function or class
753
+ # definition (not OK), for 'continue', a finally block (not OK), or
754
+ # the top module scope (not OK)
755
+ n = node
756
+ while hasattr (n , 'parent' ):
757
+ n , n_child = n .parent , n
758
+ if isinstance (n , (ast .While , ast .For )):
759
+ # Doesn't apply unless it's in the loop itself
760
+ if n_child not in n .orelse :
761
+ return
762
+ if isinstance (n , (ast .FunctionDef , ast .ClassDef )):
763
+ break
764
+ # Handle Try/TryFinally difference in Python < and >= 3.3
765
+ if hasattr (n , 'finalbody' ) and isinstance (node , ast .Continue ):
766
+ if n_child in n .finalbody :
767
+ self .report (messages .ContinueInFinally , node )
768
+ return
769
+ if isinstance (node , ast .Continue ):
770
+ self .report (messages .ContinueOutsideLoop , node )
771
+ else : # ast.Break
772
+ self .report (messages .BreakOutsideLoop , node )
773
+
774
+ BREAK = CONTINUE
775
+
751
776
def RETURN (self , node ):
752
- if isinstance (self .scope , ClassScope ):
777
+ if isinstance (self .scope , ( ClassScope , ModuleScope ) ):
753
778
self .report (messages .ReturnOutsideFunction , node )
754
779
return
755
780
@@ -762,6 +787,10 @@ def RETURN(self, node):
762
787
self .handleNode (node .value , node )
763
788
764
789
def YIELD (self , node ):
790
+ if isinstance (self .scope , (ClassScope , ModuleScope )):
791
+ self .report (messages .YieldOutsideFunction , node )
792
+ return
793
+
765
794
self .scope .isGenerator = True
766
795
self .handleNode (node .value , node )
767
796
@@ -886,6 +915,31 @@ def AUGASSIGN(self, node):
886
915
self .handleNode (node .value , node )
887
916
self .handleNode (node .target , node )
888
917
918
+ def TUPLE (self , node ):
919
+ if not PY2 and isinstance (node .ctx , ast .Store ):
920
+ # Python 3 advanced tuple unpacking: a, *b, c = d.
921
+ # Only one starred expression is allowed, and no more than 1<<8
922
+ # assignments are allowed before a stared expression. There is
923
+ # also a limit of 1<<24 expressions after the starred expression,
924
+ # which is impossible to test due to memory restrictions, but we
925
+ # add it here anyway
926
+ has_starred = False
927
+ star_loc = - 1
928
+ for i , n in enumerate (node .elts ):
929
+ if isinstance (n , ast .Starred ):
930
+ if has_starred :
931
+ self .report (messages .TwoStarredExpressions , node )
932
+ # The SyntaxError doesn't distinguish two from more
933
+ # than two.
934
+ break
935
+ has_starred = True
936
+ star_loc = i
937
+ if star_loc >= 1 << 8 or len (node .elts ) - star_loc - 1 >= 1 << 24 :
938
+ self .report (messages .TooManyExpressionsInStarredAssignment , node )
939
+ self .handleChildren (node )
940
+
941
+ LIST = TUPLE
942
+
889
943
def IMPORT (self , node ):
890
944
for alias in node .names :
891
945
name = alias .asname or alias .name
@@ -914,12 +968,15 @@ def IMPORTFROM(self, node):
914
968
def TRY (self , node ):
915
969
handler_names = []
916
970
# List the exception handlers
917
- for handler in node .handlers :
971
+ for i , handler in enumerate ( node .handlers ) :
918
972
if isinstance (handler .type , ast .Tuple ):
919
973
for exc_type in handler .type .elts :
920
974
handler_names .append (getNodeName (exc_type ))
921
975
elif handler .type :
922
976
handler_names .append (getNodeName (handler .type ))
977
+
978
+ if handler .type is None and i < len (node .handlers ) - 1 :
979
+ self .report (messages .DefaultExceptNotLast , handler )
923
980
# Memorize the except handlers and process the body
924
981
self .exceptHandlers .append (handler_names )
925
982
for child in node .body :
0 commit comments