@@ -70,101 +70,101 @@ def import_statement(
7070
7171def line (content : str , line_separator : str , config : Config = DEFAULT_CONFIG ) -> str :
7272 """Returns a line wrapped to the specified line-length, if possible."""
73- # A ``from ... import *`` statement cannot use parenthesis-based wrapping
74- # because the wildcard ``*`` has no valid continuation in that mode.
75- # Use a backslash continuation instead so the statement is split across
76- # lines while remaining valid Python.
73+ if len (content ) <= config .line_length :
74+ return content
75+
76+ wrap_mode = config .multi_line_output
77+ if wrap_mode is Modes .NOQA :
78+ if "# NOQA" not in content :
79+ return f"{ content } { config .comment_prefix } NOQA"
80+ return content
81+
82+ line_without_comment = content
83+ comment = None
84+ if "#" in content :
85+ line_without_comment , comment = content .split ("#" , 1 )
86+
87+ # A ``from ... import *`` / ``from ... cimport *`` statement cannot use
88+ # parenthesis-based wrapping because the wildcard ``*`` has no valid
89+ # continuation in that mode. Use a backslash continuation instead so the
90+ # statement is split across lines while remaining valid Python.
7791 # See https://github.com/PyCQA/isort/issues/2267
78- bare = content .split ("#" , 1 )[0 ].rstrip ()
79- if bare .startswith ("from " ) and bare .endswith (" import *" ):
80- if len (content ) <= config .line_length :
81- return content
82- line_without_comment , _ , comment = content .partition ("#" )
83- prefix = line_without_comment .rstrip ()
92+ if line_without_comment .rstrip ().endswith ("*" ):
93+ prefix , keyword , _ = line_without_comment .rstrip ().rsplit (" " , 2 )
8494 comment_suffix = f" #{ comment } " if comment else ""
85- module_path = prefix [: - len (" import *" )]
86- return f"{ module_path } import \\ { line_separator } { config .indent } *{ comment_suffix } "
87- wrap_mode = config .multi_line_output
88- if len (content ) > config .line_length and wrap_mode != Modes .NOQA :
89- line_without_comment = content
90- comment = None
91- if "#" in content :
92- line_without_comment , comment = content .split ("#" , 1 )
93- for splitter in ("import " , "cimport " , "." , "as " ):
94- exp = r"\b" + re .escape (splitter ) + r"\b"
95- if re .search (exp , line_without_comment ) and not line_without_comment .strip ().startswith (
96- splitter
97- ):
98- line_parts = re .split (exp , line_without_comment )
99- _is_vertical_mode = wrap_mode in (
100- Modes .VERTICAL_HANGING_INDENT ,
101- Modes .VERTICAL_GRID_GROUPED ,
95+ return f"{ prefix } { keyword } \\ { line_separator } { config .indent } *{ comment_suffix } "
96+
97+ for splitter in ("import " , "cimport " , "." , "as " ):
98+ exp = r"\b" + re .escape (splitter ) + r"\b"
99+ if re .search (exp , line_without_comment ) and not line_without_comment .strip ().startswith (
100+ splitter
101+ ):
102+ line_parts = re .split (exp , line_without_comment )
103+ _is_vertical_mode = wrap_mode in (
104+ Modes .VERTICAL_HANGING_INDENT ,
105+ Modes .VERTICAL_GRID_GROUPED ,
106+ )
107+ # Determine whether the comment should be hoisted to the opening
108+ # parenthesis line rather than embedded in the import line.
109+ # This happens for noqa comments (when use_parentheses is True)
110+ # and for all comments in vertical hanging modes (when
111+ # use_parentheses is False), so that multi_line_output=3/5 is
112+ # respected even without an explicit use_parentheses=True setting.
113+ _hoist_comment_to_paren = comment and (
114+ (config .use_parentheses and "noqa" in comment )
115+ or (_is_vertical_mode and not config .use_parentheses )
116+ )
117+ if comment and not _hoist_comment_to_paren :
118+ _comma_maybe = (
119+ ","
120+ if (
121+ config .include_trailing_comma
122+ and config .use_parentheses
123+ and not line_without_comment .rstrip ().endswith ("," )
124+ )
125+ else ""
102126 )
103- # Determine whether the comment should be hoisted to the opening
104- # parenthesis line rather than embedded in the import line.
105- # This happens for noqa comments (when use_parentheses is True)
106- # and for all comments in vertical hanging modes (when
107- # use_parentheses is False), so that multi_line_output=3/5 is
108- # respected even without an explicit use_parentheses=True setting.
109- _hoist_comment_to_paren = comment and (
110- (config .use_parentheses and "noqa" in comment )
111- or (_is_vertical_mode and not config .use_parentheses )
127+ line_parts [- 1 ] = (
128+ f"{ line_parts [- 1 ].strip ()} { _comma_maybe } { config .comment_prefix } { comment } "
112129 )
113- if comment and not _hoist_comment_to_paren :
114- _comma_maybe = (
115- ","
116- if (
117- config .include_trailing_comma
118- and config .use_parentheses
119- and not line_without_comment .rstrip ().endswith ("," )
120- )
121- else ""
122- )
123- line_parts [- 1 ] = (
124- f"{ line_parts [- 1 ].strip ()} { _comma_maybe } { config .comment_prefix } { comment } "
125- )
126- next_line = []
127- while (len (content ) + 2 ) > (
128- config .wrap_length or config .line_length
129- ) and line_parts :
130- next_line .append (line_parts .pop ())
131- content = splitter .join (line_parts )
132- if not content :
133- content = next_line .pop ()
130+ next_line = []
131+ while (len (content ) + 2 ) > (config .wrap_length or config .line_length ) and line_parts :
132+ next_line .append (line_parts .pop ())
133+ content = splitter .join (line_parts )
134+ if not content :
135+ content = next_line .pop ()
134136
135- cont_line = _wrap_line (
136- config .indent + splitter .join (next_line ).lstrip (),
137- line_separator ,
138- config ,
139- )
140- if config .use_parentheses or _is_vertical_mode :
141- if splitter == "as " :
142- output = f"{ content } { splitter } { cont_line .lstrip ()} "
143- else :
144- _comma = "," if config .include_trailing_comma and not comment else ""
137+ cont_line = _wrap_line (
138+ config .indent + splitter .join (next_line ).lstrip (),
139+ line_separator ,
140+ config ,
141+ )
142+ if config .use_parentheses or _is_vertical_mode :
143+ if splitter == "as " :
144+ output = f"{ content } { splitter } { cont_line .lstrip ()} "
145+ else :
146+ _comma = "," if config .include_trailing_comma and not comment else ""
145147
146- if _is_vertical_mode :
147- _separator = line_separator
148- else :
149- _separator = ""
150- noqa_comment = ""
151- if _hoist_comment_to_paren :
152- noqa_comment = f"{ config .comment_prefix } { comment } "
153- cont_line = cont_line .rstrip ()
154- _comma = "," if config .include_trailing_comma else ""
155- output = (
156- f"{ content } { splitter } ({ noqa_comment } "
157- f"{ line_separator } { cont_line } { _comma } { _separator } )"
158- )
159- lines = output .split (line_separator )
160- if config .comment_prefix in lines [- 1 ] and lines [- 1 ].endswith (")" ):
161- content , comment = lines [- 1 ].split (config .comment_prefix , 1 )
162- lines [- 1 ] = content + ")" + config .comment_prefix + comment [:- 1 ]
163- output = line_separator .join (lines )
164- return output
165- return f"{ content } { splitter } \\ { line_separator } { cont_line } "
166- elif len (content ) > config .line_length and wrap_mode == Modes .NOQA and "# NOQA" not in content :
167- return f"{ content } { config .comment_prefix } NOQA"
148+ if _is_vertical_mode :
149+ _separator = line_separator
150+ else :
151+ _separator = ""
152+ noqa_comment = ""
153+ if _hoist_comment_to_paren :
154+ noqa_comment = f"{ config .comment_prefix } { comment } "
155+ cont_line = cont_line .rstrip ()
156+ _comma = "," if config .include_trailing_comma else ""
157+ output = (
158+ f"{ content } { splitter } ({ noqa_comment } "
159+ f"{ line_separator } { cont_line } { _comma } { _separator } )"
160+ )
161+ lines = output .split (line_separator )
162+ if config .comment_prefix in lines [- 1 ] and lines [- 1 ].endswith (")" ):
163+ content , comment = lines [- 1 ].split (config .comment_prefix , 1 )
164+ lines [- 1 ] = content + ")" + config .comment_prefix + comment [:- 1 ]
165+ output = line_separator .join (lines )
166+ return output
167+ return f"{ content } { splitter } \\ { line_separator } { cont_line } "
168168
169169 return content
170170
0 commit comments