@@ -1134,20 +1134,60 @@ def attr_matches(self, text):
11341134 # we simple attribute matching with normal identifiers.
11351135 _ATTR_MATCH_RE = re .compile (r"(.+)\.(\w*)$" )
11361136
1137+ def _strip_code_before_operator (self , code : str ) -> str :
1138+ operators = ["=" , "==" , "!=" , ">=" , "<=" , ">" , "<" ]
1139+ o_parens = {"(" , "[" , "{" }
1140+ c_parens = {")" , "]" , "}" }
1141+
1142+ # Dry-run tokenize to catch errors
1143+ try :
1144+ _ = list (tokenize .generate_tokens (iter (code .splitlines ()).__next__ ))
1145+ except tokenize .TokenError :
1146+ # Try trimming the expression and retrying
1147+ trimmed_code = self ._trim_expr (code )
1148+ try :
1149+ _ = list (
1150+ tokenize .generate_tokens (iter (trimmed_code .splitlines ()).__next__ )
1151+ )
1152+ code = trimmed_code
1153+ except tokenize .TokenError :
1154+ return code
1155+
1156+ tokens = _parse_tokens (code )
1157+ encountered_operator = False
1158+ after_operator = []
1159+ nesting_level = 0
1160+
1161+ for t in tokens :
1162+ if t .type == tokenize .OP :
1163+ if t .string in o_parens :
1164+ nesting_level += 1
1165+ elif t .string in c_parens :
1166+ nesting_level -= 1
1167+ elif t .string in operators and nesting_level == 0 :
1168+ encountered_operator = True
1169+ after_operator = []
1170+ continue
1171+
1172+ if encountered_operator :
1173+ after_operator .append (t .string )
1174+
1175+ if encountered_operator :
1176+ return "" .join (after_operator )
1177+ else :
1178+ return code
1179+
11371180 def _attr_matches (
11381181 self , text : str , include_prefix : bool = True
11391182 ) -> tuple [Sequence [str ], str ]:
11401183 m2 = self ._ATTR_MATCH_RE .match (text )
11411184 if not m2 :
11421185 return [], ""
11431186 expr , attr = m2 .group (1 , 2 )
1144-
1145- operators = ["=" , "==" , "!=" , ">=" , "<=" , ">" , "<" ]
1146- # Split by the operator and take the right side
1147- if not (expr .startswith ("(" ) and expr .endswith (")" )):
1148- for op in operators :
1149- if op in expr :
1150- expr = expr .split (op )[- 1 ]
1187+ try :
1188+ expr = self ._strip_code_before_operator (expr )
1189+ except tokenize .TokenError :
1190+ pass
11511191
11521192 obj = self ._evaluate_expr (expr )
11531193
0 commit comments