from black.numerics import normalize_numeric_literal
from black.strings import get_string_prefix, fix_docstring
from black.strings import normalize_string_prefix, normalize_string_quotes
-from black.trans import Transformer, CannotTransform, StringMerger
-from black.trans import StringSplitter, StringParenWrapper, StringParenStripper
-from black.mode import Mode
-from black.mode import Feature
+from black.trans import Transformer, CannotTransform, StringMerger, StringSplitter
+from black.trans import StringParenWrapper, StringParenStripper, hug_power_op
+from black.mode import Mode, Feature, Preview
from blib2to3.pytree import Node, Leaf
from blib2to3.pgen2 import token
in ways that will no longer stringify to valid Python code on the tree.
"""
- def __init__(self, mode: Mode, remove_u_prefix: bool = False) -> None:
+ def __init__(self, mode: Mode) -> None:
self.mode = mode
- self.remove_u_prefix = remove_u_prefix
self.current_line: Line
self.__post_init__()
normalize_prefix(node, inside_brackets=any_open_brackets)
if self.mode.string_normalization and node.type == token.STRING:
- node.value = normalize_string_prefix(
- node.value, remove_u_prefix=self.remove_u_prefix
- )
+ node.value = normalize_string_prefix(node.value)
node.value = normalize_string_quotes(node.value)
if node.type == token.NUMBER:
normalize_numeric_literal(node)
if is_docstring(leaf) and "\\\n" not in leaf.value:
# We're ignoring docstrings with backslash newline escapes because changing
# indentation of those changes the AST representation of the code.
- docstring = normalize_string_prefix(leaf.value, self.remove_u_prefix)
+ docstring = normalize_string_prefix(leaf.value)
prefix = get_string_prefix(docstring)
docstring = docstring[len(prefix) :] # Remove the prefix
quote_char = docstring[0]
and not (line.inside_brackets and line.contains_standalone_comments())
):
# Only apply basic string preprocessing, since lines shouldn't be split here.
- if mode.experimental_string_processing:
+ if Preview.string_processing in mode:
transformers = [string_merge, string_paren_strip]
else:
transformers = []
# via type ... https://github.com/mypyc/mypyc/issues/884
rhs = type("rhs", (), {"__call__": _rhs})()
- if mode.experimental_string_processing:
+ if Preview.string_processing in mode:
if line.inside_brackets:
transformers = [
string_merge,
transformers = [delimiter_split, standalone_comment_split, rhs]
else:
transformers = [rhs]
+ # It's always safe to attempt hugging of power operations and pretty much every line
+ # could match.
+ transformers.append(hug_power_op)
for transform in transformers:
# We are accumulating lines in `result` because we might want to abort
# "import from" nodes store parentheses directly as part of
# the statement
if is_lpar_token(child):
+ assert is_rpar_token(node.children[-1])
# make parentheses invisible
child.value = ""
- node.children[-1].value = "" # type: ignore
+ node.children[-1].value = ""
elif child.type != token.STAR:
# insert invisible parentheses
node.insert_child(index, Leaf(token.LPAR, ""))
if (
prev
and prev.type == token.COMMA
+ and leaf.opening_bracket is not None
and not is_one_tuple_between(
leaf.opening_bracket, leaf, line.leaves
)
if (
prev
and prev.type == token.COMMA
+ and leaf.opening_bracket is not None
and not is_one_tuple_between(leaf.opening_bracket, leaf, line.leaves)
):
# Never omit bracket pairs with trailing commas.