@@ -1638,6 +1638,8 @@ class StringParenWrapper(BaseStringSplitter, CustomSplitMapMixin):
16381638 * The line is a dictionary key assignment where some valid key is being
16391639 assigned the value of some string.
16401640 OR
1641+ * The line is an lambda expression and the value is a string.
1642+ OR
16411643 * The line starts with an "atom" string that prefers to be wrapped in
16421644 parens. It's preferred to be wrapped when the string is surrounded by
16431645 commas (or is the first/last child).
@@ -1683,7 +1685,7 @@ def do_splitter_match(self, line: Line) -> TMatchResult:
16831685 or self ._else_match (LL )
16841686 or self ._assert_match (LL )
16851687 or self ._assign_match (LL )
1686- or self ._dict_match (LL )
1688+ or self ._dict_or_lambda_match (LL )
16871689 or self ._prefer_paren_wrap_match (LL )
16881690 )
16891691
@@ -1841,22 +1843,23 @@ def _assign_match(LL: List[Leaf]) -> Optional[int]:
18411843 return None
18421844
18431845 @staticmethod
1844- def _dict_match (LL : List [Leaf ]) -> Optional [int ]:
1846+ def _dict_or_lambda_match (LL : List [Leaf ]) -> Optional [int ]:
18451847 """
18461848 Returns:
18471849 string_idx such that @LL[string_idx] is equal to our target (i.e.
18481850 matched) string, if this line matches the dictionary key assignment
1849- statement requirements listed in the 'Requirements' section of this
1850- classes' docstring.
1851+ statement or lambda expression requirements listed in the
1852+ 'Requirements' section of this classes' docstring.
18511853 OR
18521854 None, otherwise.
18531855 """
1854- # If this line is apart of a dictionary key assignment...
1855- if syms .dictsetmaker in [parent_type (LL [0 ]), parent_type (LL [0 ].parent )]:
1856+ # If this line is a part of a dictionary key assignment or lambda expression...
1857+ parent_types = [parent_type (LL [0 ]), parent_type (LL [0 ].parent )]
1858+ if syms .dictsetmaker in parent_types or syms .lambdef in parent_types :
18561859 is_valid_index = is_valid_index_factory (LL )
18571860
18581861 for i , leaf in enumerate (LL ):
1859- # We MUST find a colon...
1862+ # We MUST find a colon, it can either be dict's or lambda's colon ...
18601863 if leaf .type == token .COLON :
18611864 idx = i + 2 if is_empty_par (LL [i + 1 ]) else i + 1
18621865
@@ -1951,6 +1954,25 @@ def do_transform(self, line: Line, string_idx: int) -> Iterator[TResult[Line]]:
19511954 f" (left_leaves={ left_leaves } , right_leaves={ right_leaves } )"
19521955 )
19531956 old_rpar_leaf = right_leaves .pop ()
1957+ elif right_leaves and right_leaves [- 1 ].type == token .RPAR :
1958+ # Special case for lambda expressions as dict's value, e.g.:
1959+ # my_dict = {
1960+ # "key": lambda x: f"formatted: {x},
1961+ # }
1962+ # After wrapping the dict's value with parentheses, the string is
1963+ # followed by a RPAR but its opening bracket is lambda's, not
1964+ # the string's:
1965+ # "key": (lambda x: f"formatted: {x}),
1966+ opening_bracket = right_leaves [- 1 ].opening_bracket
1967+ if opening_bracket is not None and opening_bracket in left_leaves :
1968+ index = left_leaves .index (opening_bracket )
1969+ if (
1970+ index > 0
1971+ and index < len (left_leaves ) - 1
1972+ and left_leaves [index - 1 ].type == token .COLON
1973+ and left_leaves [index + 1 ].value == "lambda"
1974+ ):
1975+ right_leaves .pop ()
19541976
19551977 append_leaves (string_line , line , right_leaves )
19561978
0 commit comments