Tipragot
628be439b8
Cela permet de ne pas avoir de problèmes de compatibilité car python est dans le git.
377 lines
13 KiB
Python
377 lines
13 KiB
Python
"""Defines all wrap modes that can be used when outputting formatted imports"""
|
|
import enum
|
|
from inspect import signature
|
|
from typing import Any, Callable, Dict, List
|
|
|
|
import isort.comments
|
|
|
|
_wrap_modes: Dict[str, Callable[..., str]] = {}
|
|
|
|
|
|
def from_string(value: str) -> "WrapModes":
|
|
return getattr(WrapModes, str(value), None) or WrapModes(int(value))
|
|
|
|
|
|
def formatter_from_string(name: str) -> Callable[..., str]:
|
|
return _wrap_modes.get(name.upper(), grid)
|
|
|
|
|
|
def _wrap_mode_interface(
|
|
statement: str,
|
|
imports: List[str],
|
|
white_space: str,
|
|
indent: str,
|
|
line_length: int,
|
|
comments: List[str],
|
|
line_separator: str,
|
|
comment_prefix: str,
|
|
include_trailing_comma: bool,
|
|
remove_comments: bool,
|
|
) -> str:
|
|
"""Defines the common interface used by all wrap mode functions"""
|
|
return ""
|
|
|
|
|
|
def _wrap_mode(function: Callable[..., str]) -> Callable[..., str]:
|
|
"""Registers an individual wrap mode. Function name and order are significant and used for
|
|
creating enum.
|
|
"""
|
|
_wrap_modes[function.__name__.upper()] = function
|
|
function.__signature__ = signature(_wrap_mode_interface) # type: ignore
|
|
function.__annotations__ = _wrap_mode_interface.__annotations__
|
|
return function
|
|
|
|
|
|
@_wrap_mode
|
|
def grid(**interface: Any) -> str:
|
|
if not interface["imports"]:
|
|
return ""
|
|
|
|
interface["statement"] += "(" + interface["imports"].pop(0)
|
|
while interface["imports"]:
|
|
next_import = interface["imports"].pop(0)
|
|
next_statement = isort.comments.add_to_line(
|
|
interface["comments"],
|
|
interface["statement"] + ", " + next_import,
|
|
removed=interface["remove_comments"],
|
|
comment_prefix=interface["comment_prefix"],
|
|
)
|
|
if (
|
|
len(next_statement.split(interface["line_separator"])[-1]) + 1
|
|
> interface["line_length"]
|
|
):
|
|
lines = [f"{interface['white_space']}{next_import.split(' ')[0]}"]
|
|
for part in next_import.split(" ")[1:]:
|
|
new_line = f"{lines[-1]} {part}"
|
|
if len(new_line) + 1 > interface["line_length"]:
|
|
lines.append(f"{interface['white_space']}{part}")
|
|
else:
|
|
lines[-1] = new_line
|
|
next_import = interface["line_separator"].join(lines)
|
|
interface["statement"] = (
|
|
isort.comments.add_to_line(
|
|
interface["comments"],
|
|
f"{interface['statement']},",
|
|
removed=interface["remove_comments"],
|
|
comment_prefix=interface["comment_prefix"],
|
|
)
|
|
+ f"{interface['line_separator']}{next_import}"
|
|
)
|
|
interface["comments"] = []
|
|
else:
|
|
interface["statement"] += ", " + next_import
|
|
return f"{interface['statement']}{',' if interface['include_trailing_comma'] else ''})"
|
|
|
|
|
|
@_wrap_mode
|
|
def vertical(**interface: Any) -> str:
|
|
if not interface["imports"]:
|
|
return ""
|
|
|
|
first_import = (
|
|
isort.comments.add_to_line(
|
|
interface["comments"],
|
|
interface["imports"].pop(0) + ",",
|
|
removed=interface["remove_comments"],
|
|
comment_prefix=interface["comment_prefix"],
|
|
)
|
|
+ interface["line_separator"]
|
|
+ interface["white_space"]
|
|
)
|
|
|
|
_imports = ("," + interface["line_separator"] + interface["white_space"]).join(
|
|
interface["imports"]
|
|
)
|
|
_comma_maybe = "," if interface["include_trailing_comma"] else ""
|
|
return f"{interface['statement']}({first_import}{_imports}{_comma_maybe})"
|
|
|
|
|
|
def _hanging_indent_end_line(line: str) -> str:
|
|
if not line.endswith(" "):
|
|
line += " "
|
|
return line + "\\"
|
|
|
|
|
|
@_wrap_mode
|
|
def hanging_indent(**interface: Any) -> str:
|
|
if not interface["imports"]:
|
|
return ""
|
|
|
|
line_length_limit = interface["line_length"] - 3
|
|
|
|
next_import = interface["imports"].pop(0)
|
|
next_statement = interface["statement"] + next_import
|
|
# Check for first import
|
|
if len(next_statement) > line_length_limit:
|
|
next_statement = (
|
|
_hanging_indent_end_line(interface["statement"])
|
|
+ interface["line_separator"]
|
|
+ interface["indent"]
|
|
+ next_import
|
|
)
|
|
|
|
interface["statement"] = next_statement
|
|
while interface["imports"]:
|
|
next_import = interface["imports"].pop(0)
|
|
next_statement = interface["statement"] + ", " + next_import
|
|
if len(next_statement.split(interface["line_separator"])[-1]) > line_length_limit:
|
|
next_statement = (
|
|
_hanging_indent_end_line(interface["statement"] + ",")
|
|
+ f"{interface['line_separator']}{interface['indent']}{next_import}"
|
|
)
|
|
interface["statement"] = next_statement
|
|
|
|
interface[
|
|
"statement"
|
|
] = f"{interface['statement']}{',' if interface['include_trailing_comma'] else ''}"
|
|
if interface["comments"]:
|
|
statement_with_comments = isort.comments.add_to_line(
|
|
interface["comments"],
|
|
interface["statement"],
|
|
removed=interface["remove_comments"],
|
|
comment_prefix=interface["comment_prefix"],
|
|
)
|
|
if len(statement_with_comments.split(interface["line_separator"])[-1]) <= (
|
|
line_length_limit + 2
|
|
):
|
|
return statement_with_comments
|
|
return (
|
|
_hanging_indent_end_line(interface["statement"])
|
|
+ str(interface["line_separator"])
|
|
+ isort.comments.add_to_line(
|
|
interface["comments"],
|
|
interface["indent"],
|
|
removed=interface["remove_comments"],
|
|
comment_prefix=interface["comment_prefix"].lstrip(),
|
|
)
|
|
)
|
|
return str(interface["statement"])
|
|
|
|
|
|
@_wrap_mode
|
|
def vertical_hanging_indent(**interface: Any) -> str:
|
|
_line_with_comments = isort.comments.add_to_line(
|
|
interface["comments"],
|
|
"",
|
|
removed=interface["remove_comments"],
|
|
comment_prefix=interface["comment_prefix"],
|
|
)
|
|
_imports = ("," + interface["line_separator"] + interface["indent"]).join(interface["imports"])
|
|
_comma_maybe = "," if interface["include_trailing_comma"] else ""
|
|
return (
|
|
f"{interface['statement']}({_line_with_comments}{interface['line_separator']}"
|
|
f"{interface['indent']}{_imports}{_comma_maybe}{interface['line_separator']})"
|
|
)
|
|
|
|
|
|
def _vertical_grid_common(need_trailing_char: bool, **interface: Any) -> str:
|
|
if not interface["imports"]:
|
|
return ""
|
|
|
|
interface["statement"] += (
|
|
isort.comments.add_to_line(
|
|
interface["comments"],
|
|
"(",
|
|
removed=interface["remove_comments"],
|
|
comment_prefix=interface["comment_prefix"],
|
|
)
|
|
+ interface["line_separator"]
|
|
+ interface["indent"]
|
|
+ interface["imports"].pop(0)
|
|
)
|
|
while interface["imports"]:
|
|
next_import = interface["imports"].pop(0)
|
|
next_statement = f"{interface['statement']}, {next_import}"
|
|
current_line_length = len(next_statement.split(interface["line_separator"])[-1])
|
|
if interface["imports"] or interface["include_trailing_comma"]:
|
|
# We need to account for a comma after this import.
|
|
current_line_length += 1
|
|
if not interface["imports"] and need_trailing_char:
|
|
# We need to account for a closing ) we're going to add.
|
|
current_line_length += 1
|
|
if current_line_length > interface["line_length"]:
|
|
next_statement = (
|
|
f"{interface['statement']},{interface['line_separator']}"
|
|
f"{interface['indent']}{next_import}"
|
|
)
|
|
interface["statement"] = next_statement
|
|
if interface["include_trailing_comma"]:
|
|
interface["statement"] += ","
|
|
return str(interface["statement"])
|
|
|
|
|
|
@_wrap_mode
|
|
def vertical_grid(**interface: Any) -> str:
|
|
return _vertical_grid_common(need_trailing_char=True, **interface) + ")"
|
|
|
|
|
|
@_wrap_mode
|
|
def vertical_grid_grouped(**interface: Any) -> str:
|
|
return (
|
|
_vertical_grid_common(need_trailing_char=False, **interface)
|
|
+ str(interface["line_separator"])
|
|
+ ")"
|
|
)
|
|
|
|
|
|
@_wrap_mode
|
|
def vertical_grid_grouped_no_comma(**interface: Any) -> str:
|
|
# This is a deprecated alias for vertical_grid_grouped above. This function
|
|
# needs to exist for backwards compatibility but should never get called.
|
|
raise NotImplementedError
|
|
|
|
|
|
@_wrap_mode
|
|
def noqa(**interface: Any) -> str:
|
|
_imports = ", ".join(interface["imports"])
|
|
retval = f"{interface['statement']}{_imports}"
|
|
comment_str = " ".join(interface["comments"])
|
|
if interface["comments"]:
|
|
if (
|
|
len(retval) + len(interface["comment_prefix"]) + 1 + len(comment_str)
|
|
<= interface["line_length"]
|
|
):
|
|
return f"{retval}{interface['comment_prefix']} {comment_str}"
|
|
if "NOQA" in interface["comments"]:
|
|
return f"{retval}{interface['comment_prefix']} {comment_str}"
|
|
return f"{retval}{interface['comment_prefix']} NOQA {comment_str}"
|
|
|
|
if len(retval) <= interface["line_length"]:
|
|
return retval
|
|
return f"{retval}{interface['comment_prefix']} NOQA"
|
|
|
|
|
|
@_wrap_mode
|
|
def vertical_hanging_indent_bracket(**interface: Any) -> str:
|
|
if not interface["imports"]:
|
|
return ""
|
|
statement = vertical_hanging_indent(**interface)
|
|
return f'{statement[:-1]}{interface["indent"]})'
|
|
|
|
|
|
@_wrap_mode
|
|
def vertical_prefix_from_module_import(**interface: Any) -> str:
|
|
if not interface["imports"]:
|
|
return ""
|
|
|
|
prefix_statement = interface["statement"]
|
|
output_statement = prefix_statement + interface["imports"].pop(0)
|
|
comments = interface["comments"]
|
|
|
|
statement = output_statement
|
|
statement_with_comments = ""
|
|
for next_import in interface["imports"]:
|
|
statement = statement + ", " + next_import
|
|
statement_with_comments = isort.comments.add_to_line(
|
|
comments,
|
|
statement,
|
|
removed=interface["remove_comments"],
|
|
comment_prefix=interface["comment_prefix"],
|
|
)
|
|
if (
|
|
len(statement_with_comments.split(interface["line_separator"])[-1]) + 1
|
|
> interface["line_length"]
|
|
):
|
|
statement = (
|
|
isort.comments.add_to_line(
|
|
comments,
|
|
output_statement,
|
|
removed=interface["remove_comments"],
|
|
comment_prefix=interface["comment_prefix"],
|
|
)
|
|
+ f"{interface['line_separator']}{prefix_statement}{next_import}"
|
|
)
|
|
comments = []
|
|
output_statement = statement
|
|
|
|
if comments and statement_with_comments:
|
|
output_statement = statement_with_comments
|
|
return str(output_statement)
|
|
|
|
|
|
@_wrap_mode
|
|
def hanging_indent_with_parentheses(**interface: Any) -> str:
|
|
if not interface["imports"]:
|
|
return ""
|
|
|
|
line_length_limit = interface["line_length"] - 1
|
|
|
|
interface["statement"] += "("
|
|
next_import = interface["imports"].pop(0)
|
|
next_statement = interface["statement"] + next_import
|
|
# Check for first import
|
|
if len(next_statement) > line_length_limit:
|
|
next_statement = (
|
|
isort.comments.add_to_line(
|
|
interface["comments"],
|
|
interface["statement"],
|
|
removed=interface["remove_comments"],
|
|
comment_prefix=interface["comment_prefix"],
|
|
)
|
|
+ f"{interface['line_separator']}{interface['indent']}{next_import}"
|
|
)
|
|
interface["comments"] = []
|
|
interface["statement"] = next_statement
|
|
while interface["imports"]:
|
|
next_import = interface["imports"].pop(0)
|
|
if (
|
|
not interface["line_separator"] in interface["statement"]
|
|
and "#" in interface["statement"]
|
|
): # pragma: no cover # TODO: fix, this is because of test run inconsistency.
|
|
line, comments = interface["statement"].split("#", 1)
|
|
next_statement = (
|
|
f"{line.rstrip()}, {next_import}{interface['comment_prefix']}{comments}"
|
|
)
|
|
else:
|
|
next_statement = isort.comments.add_to_line(
|
|
interface["comments"],
|
|
interface["statement"] + ", " + next_import,
|
|
removed=interface["remove_comments"],
|
|
comment_prefix=interface["comment_prefix"],
|
|
)
|
|
current_line = next_statement.split(interface["line_separator"])[-1]
|
|
if len(current_line) > line_length_limit:
|
|
next_statement = (
|
|
isort.comments.add_to_line(
|
|
interface["comments"],
|
|
interface["statement"] + ",",
|
|
removed=interface["remove_comments"],
|
|
comment_prefix=interface["comment_prefix"],
|
|
)
|
|
+ f"{interface['line_separator']}{interface['indent']}{next_import}"
|
|
)
|
|
interface["comments"] = []
|
|
interface["statement"] = next_statement
|
|
return f"{interface['statement']}{',' if interface['include_trailing_comma'] else ''})"
|
|
|
|
|
|
@_wrap_mode
|
|
def backslash_grid(**interface: Any) -> str:
|
|
interface["indent"] = interface["white_space"][:-1]
|
|
return hanging_indent(**interface)
|
|
|
|
|
|
WrapModes = enum.Enum( # type: ignore
|
|
"WrapModes", {wrap_mode: index for index, wrap_mode in enumerate(_wrap_modes.keys())}
|
|
)
|