2222# Allowed
2323f_single_chained_attr = "f'{attr1.attr2}'"
2424f_variable_lookup = "f'smth {value}'"
25+ f_multi_variable_lookup = "f'smth {value1} {value2} {value3}'"
2526f_dict_lookup_str_key = 'f\' smth {dict_value["key"]}\' '
2627f_list_index_lookup = "f'smth {list_value[0]}'"
2728f_function_empty_args = "f'smth {user.get_full_name()}'"
3334f_function_with_single_arg = "f'smth {func(arg)}'"
3435f_function_with_three_args = "f'{func(arg1, arg2, arg3)}'"
3536f_method_with_three_args = "f'{obj.method(arg1, arg2, arg3)}'"
37+ f_assign = "f'{value=}'"
38+ f_assign_attr = "f'{value.attr=}'"
39+ f_assign_call = "f'{value()=}'"
40+
41+ # Allowed format specifiers
42+ f_format_aligned = "f'{value:<5}'"
43+ f_format_str = "f'{value!s}'"
44+ f_format_repr = "f'{value!r}'"
45+ f_format_code = "f'{value!a}'"
46+ f_format_hex_lower_short = "f'{value:x}'"
47+ f_format_hex_upper_short = "f'{value:X}'"
48+ f_format_hex_lower_long = "f'{value:#x}'"
49+ f_format_hex_upper_long = "f'{value:#X}'"
50+ f_format_char = "f'{value:c}'"
51+ f_format_rounded = "f'{value:.123456f}'"
52+ f_format_scientific = "f'{value:.456789e}'"
53+ f_format_var_single = "f'{value:{fmt}}'"
54+ f_format_var_single2 = "f'{value1:{fmt1}} {value2:{fmt2}}'"
55+ f_format_var_single_index = "f'{value:{fmt[0]}}'"
56+ f_format_var_single_call = "f'{value:{fmt()}}'"
57+ f_format_convertions = "f'{value1!r} {value2!s} {value3!a}'"
58+ f_format_assign = "f'{value=:<8}'"
59+ f_format_assign_conversion = "f'{value=!r}'"
60+ f_format_assign_attr = "f'{value.attr=:.456e}'"
61+ f_format_assign_var_single = "f'{value=:{fmt}}'"
62+ f_format_assign_var_single2 = "f'{value1=:{fmt1}} {value2=:{fmt2}}'"
3663
3764# Disallowed
3865f_string = "f'x + y = {2 + 2}'"
5380f_single_chained_functions = "f'{f1().f2()}'"
5481f_function_with_four_args = "f'{func(arg1, arg2, arg3, arg4)}'"
5582f_method_with_four_args = "f'{obj.meth(arg1, arg2, arg3, arg4)}-post'"
83+ f_nested_string = 'f\' {f"{value}"}\' '
84+ # Disallowed format specifiers
85+ f_format_var_multi = "f'pre {value:{fmt1}{fmt2}}'"
86+ f_format_var_chain = "f'{value:{fmt.attr.attr}}'"
87+ f_format_var_before1 = "f'{value:{fmt}10}'"
88+ f_format_var_before2 = "f'{value:{fmt}.4f}'"
89+ f_format_var_after1 = "f'{value:_{fmt}}'"
90+ f_format_var_after2 = "f'{value:_^{fmt}}'"
91+ f_format_var_between1 = "f'{value:_{fmt}10}'"
92+ f_format_var_between2 = "f'{value:.{precision}f}'"
93+ f_format_var_around = "f'{value:{fmt1}^{fmt2}}'"
94+ f_format_str_const = "f'{value!s:10}'"
95+ f_format_repr_const = "f'{value!r:10}'"
96+ f_format_code_const = "f'{value!a:10}'"
97+ f_format_str_var = "f'{value!s:{fmt}}'"
98+ f_format_repr_var = "f'{value!r:{fmt}}'"
99+ f_format_code_var = "f'{value!a:{fmt}}'"
100+ f_format_hex_lower_short_const = "f'{value:10x}'"
101+ f_format_hex_upper_short_const = "f'{value:10X}'"
102+ f_format_hex_lower_long_const = "f'{value:#10x}'"
103+ f_format_hex_upper_long_const = "f'{value:#10X}'"
104+ f_format_char_const = "f'{value:10c}'"
105+ f_format_round_const = "f'{value:10.4f}'"
106+ f_format_scientific_const = "f'{value:10.7e}'"
107+ f_format_useless1 = "f'{value:_}'"
108+ f_format_useless2 = "f'{value:_<}'"
109+ f_format_assign_const = "f'{value=:_^8.2f}'"
110+ f_format_assign_conversion_const = "f'{value=!r:_>11}'"
111+ f_format_assign_var_chain = "f'{value=:{fmt.attr.attr}}'"
112+ f_format_assign_var_multi = "f'{value=:{fmt1}{fmt2}}'"
56113
57114# regression 1921
58115f_string_comma_format = 'f"Count={count:,}"'
@@ -103,6 +160,37 @@ def test_string_normal(
103160 f_calling_returned_function ,
104161 f_single_chained_functions ,
105162 f_function_with_four_args ,
163+ f_method_with_four_args ,
164+ f_nested_string ,
165+ # format specifiers
166+ f_format_var_multi ,
167+ f_format_var_chain ,
168+ f_format_var_before1 ,
169+ f_format_var_before2 ,
170+ f_format_var_after1 ,
171+ f_format_var_after2 ,
172+ f_format_var_between1 ,
173+ f_format_var_between2 ,
174+ f_format_var_around ,
175+ f_format_str_const ,
176+ f_format_repr_const ,
177+ f_format_code_const ,
178+ f_format_str_var ,
179+ f_format_repr_var ,
180+ f_format_code_var ,
181+ f_format_hex_lower_short_const ,
182+ f_format_hex_upper_short_const ,
183+ f_format_hex_lower_long_const ,
184+ f_format_hex_upper_long_const ,
185+ f_format_char_const ,
186+ f_format_round_const ,
187+ f_format_scientific_const ,
188+ f_format_useless1 ,
189+ f_format_useless2 ,
190+ f_format_assign_const ,
191+ f_format_assign_conversion_const ,
192+ f_format_assign_var_chain ,
193+ f_format_assign_var_multi ,
106194 ],
107195)
108196def test_complex_f_string (assert_errors , parse_ast_tree , code , default_options ):
@@ -125,6 +213,7 @@ def test_complex_f_string(assert_errors, parse_ast_tree, code, default_options):
125213 f_function_empty_args ,
126214 f_list_index_lookup ,
127215 f_variable_lookup ,
216+ f_multi_variable_lookup ,
128217 f_single_chained_attr ,
129218 f_attr_on_function ,
130219 f_true_index ,
@@ -135,6 +224,31 @@ def test_complex_f_string(assert_errors, parse_ast_tree, code, default_options):
135224 f_function_with_single_arg ,
136225 f_function_with_three_args ,
137226 f_method_with_three_args ,
227+ f_assign ,
228+ f_assign_attr ,
229+ f_assign_call ,
230+ # format specifiers
231+ f_format_aligned ,
232+ f_format_str ,
233+ f_format_repr ,
234+ f_format_code ,
235+ f_format_hex_lower_short ,
236+ f_format_hex_upper_short ,
237+ f_format_hex_lower_long ,
238+ f_format_hex_upper_long ,
239+ f_format_char ,
240+ f_format_rounded ,
241+ f_format_scientific ,
242+ f_format_var_single ,
243+ f_format_var_single2 ,
244+ f_format_var_single_index ,
245+ f_format_var_single_call ,
246+ f_format_convertions ,
247+ f_format_assign ,
248+ f_format_assign_conversion ,
249+ f_format_assign_attr ,
250+ f_format_assign_var_single ,
251+ f_format_assign_var_single2 ,
138252 ],
139253)
140254def test_simple_f_string (assert_errors , parse_ast_tree , code , default_options ):
0 commit comments