@@ -1160,6 +1160,22 @@ def imports_on_separate_lines(logical_line):
11601160 yield found , "E401 multiple imports on one line"
11611161
11621162
1163+ _STRING_PREFIXES = frozenset (('u' , 'U' , 'b' , 'B' , 'r' , 'R' ))
1164+
1165+
1166+ def _is_string_literal (line ):
1167+ if line :
1168+ first_char = line [0 ]
1169+ if first_char in _STRING_PREFIXES :
1170+ first_char = line [1 ]
1171+ return first_char == '"' or first_char == "'"
1172+ return False
1173+
1174+
1175+ _ALLOWED_KEYWORDS_IN_IMPORTS = (
1176+ 'try' , 'except' , 'else' , 'finally' , 'with' , 'if' , 'elif' )
1177+
1178+
11631179@register_check
11641180def module_imports_on_top_of_file (
11651181 logical_line , indent_level , checker_state , noqa ):
@@ -1178,41 +1194,32 @@ def module_imports_on_top_of_file(
11781194
11791195 Okay: if x:\n import os
11801196 """ # noqa
1181- def is_string_literal (line ):
1182- if line [0 ] in 'uUbB' :
1183- line = line [1 :]
1184- if line and line [0 ] in 'rR' :
1185- line = line [1 :]
1186- return line and (line [0 ] == '"' or line [0 ] == "'" )
1187-
1188- allowed_keywords = (
1189- 'try' , 'except' , 'else' , 'finally' , 'with' , 'if' , 'elif' )
11901197
11911198 if indent_level : # Allow imports in conditional statement/function
11921199 return
11931200 if not logical_line : # Allow empty lines or comments
11941201 return
11951202 if noqa :
11961203 return
1197- line = logical_line
1198- if line .startswith ('import ' ) or line .startswith ('from ' ):
1204+ if logical_line .startswith (('import ' , 'from ' )):
11991205 if checker_state .get ('seen_non_imports' , False ):
12001206 yield 0 , "E402 module level import not at top of file"
1201- elif re .match (DUNDER_REGEX , line ):
1202- return
1203- elif any (line .startswith (kw ) for kw in allowed_keywords ):
1204- # Allow certain keywords intermixed with imports in order to
1205- # support conditional or filtered importing
1206- return
1207- elif is_string_literal (line ):
1208- # The first literal is a docstring, allow it. Otherwise, report
1209- # error.
1210- if checker_state .get ('seen_docstring' , False ):
1211- checker_state ['seen_non_imports' ] = True
1207+ elif not checker_state .get ('seen_non_imports' , False ):
1208+ if DUNDER_REGEX .match (logical_line ):
1209+ return
1210+ elif logical_line .startswith (_ALLOWED_KEYWORDS_IN_IMPORTS ):
1211+ # Allow certain keywords intermixed with imports in order to
1212+ # support conditional or filtered importing
1213+ return
1214+ elif _is_string_literal (logical_line ):
1215+ # The first literal is a docstring, allow it. Otherwise,
1216+ # report error.
1217+ if checker_state .get ('seen_docstring' , False ):
1218+ checker_state ['seen_non_imports' ] = True
1219+ else :
1220+ checker_state ['seen_docstring' ] = True
12121221 else :
1213- checker_state ['seen_docstring' ] = True
1214- else :
1215- checker_state ['seen_non_imports' ] = True
1222+ checker_state ['seen_non_imports' ] = True
12161223
12171224
12181225@register_check
0 commit comments