Coverage for src/lib3to6/fixers_fstring.py : 93%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# This file is part of the lib3to6 project
2# https://github.com/mbarkhau/lib3to6
3#
4# Copyright (c) 2019-2021 Manuel Barkhau (mbarkhau@gmail.com) - MIT License
5# SPDX-License-Identifier: MIT
7import ast
8import typing as typ
10from . import common
11from . import fixer_base as fb
14class FStringToStrFormatFixer(fb.TransformerFixerBase):
16 version_info = common.VersionInfo(apply_since="2.6", apply_until="3.5")
18 def _formatted_value_str(
19 self, fmt_val_node: ast.FormattedValue, arg_nodes: typ.List[ast.expr]
20 ) -> str:
21 arg_index = len(arg_nodes)
22 arg_nodes.append(fmt_val_node.value)
24 format_spec_node = fmt_val_node.format_spec
25 if format_spec_node is None:
26 format_spec = ""
27 elif not isinstance(format_spec_node, ast.JoinedStr):
28 raise common.FixerError("Unexpected Node Type", format_spec_node)
29 else:
30 format_spec = ":" + self._joined_str_str(format_spec_node, arg_nodes)
32 return "{" + str(arg_index) + format_spec + "}"
34 def _joined_str_str(self, joined_str_node: ast.JoinedStr, arg_nodes: typ.List[ast.expr]) -> str:
35 fmt_str = ""
36 for val in joined_str_node.values:
37 if isinstance(val, ast.Str):
38 fmt_str += val.s
39 elif isinstance(val, ast.FormattedValue):
40 fmt_str += self._formatted_value_str(val, arg_nodes)
41 else:
42 raise common.FixerError("Unexpected Node Type", val)
43 return fmt_str
45 def visit_JoinedStr(self, node: ast.JoinedStr) -> ast.Call:
46 arg_nodes: typ.List[ast.expr] = []
48 fmt_str = self._joined_str_str(node, arg_nodes)
49 format_attr_node = ast.Attribute(value=ast.Str(s=fmt_str), attr="format", ctx=ast.Load())
50 return ast.Call(func=format_attr_node, args=arg_nodes, keywords=[])