135
135
LAMBDA_REGEX = re .compile (r'\blambda\b' )
136
136
HUNK_REGEX = re .compile (r'^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@.*$' )
137
137
STARTSWITH_DEF_REGEX = re .compile (r'^(async\s+def|def)\b' )
138
+ STARTSWITH_GENERIC_REGEX = re .compile (r'^(async\s+def|def|class|type)\s+\w+\[' )
138
139
STARTSWITH_TOP_LEVEL_REGEX = re .compile (r'^(async\s+def\s+|def\s+|class\s+|@)' )
139
140
STARTSWITH_INDENT_STATEMENT_REGEX = re .compile (
140
141
r'^\s*({})\b' .format ('|' .join (s .replace (' ' , r'\s+' ) for s in (
@@ -1019,12 +1020,13 @@ def whitespace_around_named_parameter_equals(logical_line, tokens):
1019
1020
E251: return magic(r = real, i = imag)
1020
1021
E252: def complex(real, image: float=0.0):
1021
1022
"""
1022
- parens = 0
1023
+ paren_stack = []
1023
1024
no_space = False
1024
1025
require_space = False
1025
1026
prev_end = None
1026
1027
annotated_func_arg = False
1027
1028
in_def = bool (STARTSWITH_DEF_REGEX .match (logical_line ))
1029
+ in_generic = bool (STARTSWITH_GENERIC_REGEX .match (logical_line ))
1028
1030
1029
1031
message = "E251 unexpected spaces around keyword / parameter equals"
1030
1032
missing_message = "E252 missing whitespace around parameter equals"
@@ -1042,23 +1044,31 @@ def whitespace_around_named_parameter_equals(logical_line, tokens):
1042
1044
yield (prev_end , missing_message )
1043
1045
if token_type == tokenize .OP :
1044
1046
if text in '([' :
1045
- parens += 1
1046
- elif text in ')]' :
1047
- parens -= 1
1048
- elif in_def and text == ':' and parens == 1 :
1047
+ paren_stack .append (text )
1048
+ elif text in ')]' and paren_stack :
1049
+ paren_stack .pop ()
1050
+ elif (
1051
+ text == ':' and (
1052
+ # def f(arg: tp = default): ...
1053
+ (in_def and paren_stack == ['(' ]) or
1054
+ # def f[T: tp = default](): ...
1055
+ # class C[T: tp = default](): ...
1056
+ (in_generic and paren_stack == ['[' ])
1057
+ )
1058
+ ):
1049
1059
annotated_func_arg = True
1050
- elif parens == 1 and text == ',' :
1060
+ elif len ( paren_stack ) == 1 and text == ',' :
1051
1061
annotated_func_arg = False
1052
- elif parens and text == '=' :
1053
- if annotated_func_arg and parens == 1 :
1062
+ elif paren_stack and text == '=' :
1063
+ if annotated_func_arg and len ( paren_stack ) == 1 :
1054
1064
require_space = True
1055
1065
if start == prev_end :
1056
1066
yield (prev_end , missing_message )
1057
1067
else :
1058
1068
no_space = True
1059
1069
if start != prev_end :
1060
1070
yield (prev_end , message )
1061
- if not parens :
1071
+ if not paren_stack :
1062
1072
annotated_func_arg = False
1063
1073
1064
1074
prev_end = end
0 commit comments