We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Bug: Message.template format 问题
**描述问题：**

无法使用format

**如何复现？**

```py
from nonebot.adapters.onebot.v11 import Message
file_list = [
    "file:///file1.image",
    "file:///file2.image",
    ...
]
text = "img1:  {:image} img2: {:image} ..."

msg = Message.template(text).format(*file_list)
```


**期望的结果**

`msg` 为可以直接发送的 包含文字和图片的消息

**环境信息：**

 - OS: Linux CentOS8
 - Python Version: 3.9
 - Nonebot Version: 2.0.0-beta.1


**截图或日志**
```log
Traceback (most recent call last):
  File "/data/nb-test/test/re_test.py", line 23, in <module>
    msg = Message.template(text).format(*file_list)
  File "/root/.cache/pypoetry/virtualenvs/nb-test-NOSw4fD6-py3.9/lib/python3.9/site-packages/nonebot/adapters/_template.py", line 80, in format
    msg += self.vformat(self.template, args, kwargs)
  File "/root/.cache/pypoetry/virtualenvs/nb-test-NOSw4fD6-py3.9/lib/python3.9/site-packages/nonebot/adapters/_template.py", line 94, in vformat
    result, _ = self._vformat(format_string, args, kwargs, used_args, 2)
  File "/root/.cache/pypoetry/virtualenvs/nb-test-NOSw4fD6-py3.9/lib/python3.9/site-packages/nonebot/adapters/_template.py", line 165, in _vformat
    formatted_text = self.format_field(obj, str(format_control))
  File "/root/.cache/pypoetry/virtualenvs/nb-test-NOSw4fD6-py3.9/lib/python3.9/site-packages/nonebot/adapters/_template.py", line 181, in format_field
    super().format_field(value, format_spec)
  File "/root/miniconda3/lib/python3.9/string.py", line 235, in format_field
    return format(value, format_spec)
ValueError: Invalid format specifier
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `nonebot/internal/adapter/template.py`
Content:
```
1 import inspect
2 import functools
3 from string import Formatter
4 from typing import (
5     TYPE_CHECKING,
6     Any,
7     Set,
8     Dict,
9     List,
10     Type,
11     Tuple,
12     Union,
13     Generic,
14     Mapping,
15     TypeVar,
16     Callable,
17     Optional,
18     Sequence,
19     cast,
20     overload,
21 )
22 
23 if TYPE_CHECKING:
24     from .message import Message, MessageSegment
25 
26 TM = TypeVar("TM", bound="Message")
27 TF = TypeVar("TF", str, "Message")
28 
29 FormatSpecFunc = Callable[[Any], str]
30 FormatSpecFunc_T = TypeVar("FormatSpecFunc_T", bound=FormatSpecFunc)
31 
32 
33 class MessageTemplate(Formatter, Generic[TF]):
34     """消息模板格式化实现类。
35 
36     参数:
37         template: 模板
38         factory: 消息构造类型，默认为 `str`
39     """
40 
41     @overload
42     def __init__(
43         self: "MessageTemplate[str]", template: str, factory: Type[str] = str
44     ) -> None:
45         ...
46 
47     @overload
48     def __init__(
49         self: "MessageTemplate[TM]", template: Union[str, TM], factory: Type[TM]
50     ) -> None:
51         ...
52 
53     def __init__(self, template, factory=str) -> None:
54         self.template: TF = template
55         self.factory: Type[TF] = factory
56         self.format_specs: Dict[str, FormatSpecFunc] = {}
57 
58     def add_format_spec(
59         self, spec: FormatSpecFunc_T, name: Optional[str] = None
60     ) -> FormatSpecFunc_T:
61         name = name or spec.__name__
62         if name in self.format_specs:
63             raise ValueError(f"Format spec {name} already exists!")
64         self.format_specs[name] = spec
65         return spec
66 
67     def format(self, *args: Any, **kwargs: Any) -> TF:
68         """根据模板和参数生成消息对象"""
69         msg = self.factory()
70         if isinstance(self.template, str):
71             msg += self.vformat(self.template, args, kwargs)
72         elif isinstance(self.template, self.factory):
73             template = cast("Message[MessageSegment]", self.template)
74             for seg in template:
75                 msg += self.vformat(str(seg), args, kwargs) if seg.is_text() else seg
76         else:
77             raise TypeError("template must be a string or instance of Message!")
78 
79         return msg  # type:ignore
80 
81     def vformat(
82         self, format_string: str, args: Sequence[Any], kwargs: Mapping[str, Any]
83     ) -> TF:
84         used_args = set()
85         result, _ = self._vformat(format_string, args, kwargs, used_args, 2)
86         self.check_unused_args(list(used_args), args, kwargs)
87         return result
88 
89     def _vformat(
90         self,
91         format_string: str,
92         args: Sequence[Any],
93         kwargs: Mapping[str, Any],
94         used_args: Set[Union[int, str]],
95         recursion_depth: int,
96         auto_arg_index: int = 0,
97     ) -> Tuple[TF, int]:
98         if recursion_depth < 0:
99             raise ValueError("Max string recursion exceeded")
100 
101         results: List[Any] = []
102 
103         for (literal_text, field_name, format_spec, conversion) in self.parse(
104             format_string
105         ):
106 
107             # output the literal text
108             if literal_text:
109                 results.append(literal_text)
110 
111             # if there's a field, output it
112             if field_name is not None:
113                 # this is some markup, find the object and do
114                 #  the formatting
115 
116                 # handle arg indexing when empty field_names are given.
117                 if field_name == "":
118                     if auto_arg_index is False:
119                         raise ValueError(
120                             "cannot switch from manual field specification to "
121                             "automatic field numbering"
122                         )
123                     field_name = str(auto_arg_index)
124                     auto_arg_index += 1
125                 elif field_name.isdigit():
126                     if auto_arg_index:
127                         raise ValueError(
128                             "cannot switch from manual field specification to "
129                             "automatic field numbering"
130                         )
131                     # disable auto arg incrementing, if it gets
132                     # used later on, then an exception will be raised
133                     auto_arg_index = False
134 
135                 # given the field_name, find the object it references
136                 #  and the argument it came from
137                 obj, arg_used = self.get_field(field_name, args, kwargs)
138                 used_args.add(arg_used)
139 
140                 assert format_spec is not None
141 
142                 # do any conversion on the resulting object
143                 obj = self.convert_field(obj, conversion) if conversion else obj
144 
145                 # expand the format spec, if needed
146                 format_control, auto_arg_index = self._vformat(
147                     format_spec,
148                     args,
149                     kwargs,
150                     used_args,
151                     recursion_depth - 1,
152                     auto_arg_index,
153                 )
154 
155                 # format the object and append to the result
156                 formatted_text = self.format_field(obj, str(format_control))
157                 results.append(formatted_text)
158 
159         return (
160             self.factory(functools.reduce(self._add, results or [""])),
161             auto_arg_index,
162         )
163 
164     def format_field(self, value: Any, format_spec: str) -> Any:
165         formatter: Optional[FormatSpecFunc] = self.format_specs.get(format_spec)
166         if formatter is None and not issubclass(self.factory, str):
167             segment_class: Type["MessageSegment"] = self.factory.get_segment_class()
168             method = getattr(segment_class, format_spec, None)
169             if inspect.ismethod(method):
170                 formatter = getattr(segment_class, format_spec)
171         return (
172             super().format_field(value, format_spec)
173             if formatter is None
174             else formatter(value)
175         )
176 
177     def _add(self, a: Any, b: Any) -> Any:
178         try:
179             return a + b
180         except TypeError:
181             return a + str(b)
182
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/nonebot/internal/adapter/template.py b/nonebot/internal/adapter/template.py
--- a/nonebot/internal/adapter/template.py
+++ b/nonebot/internal/adapter/template.py
@@ -1,4 +1,3 @@
-import inspect
 import functools
 from string import Formatter
 from typing import (
@@ -35,7 +34,7 @@
 
     参数:
         template: 模板
-        factory: 消息构造类型，默认为 `str`
+        factory: 消息类型工厂，默认为 `str`
     """
 
     @overload
@@ -64,8 +63,15 @@
         self.format_specs[name] = spec
         return spec
 
-    def format(self, *args: Any, **kwargs: Any) -> TF:
-        """根据模板和参数生成消息对象"""
+    def format(self, *args, **kwargs):
+        """根据传入参数和模板生成消息对象"""
+        return self._format(args, kwargs)
+
+    def format_map(self, mapping: Mapping[str, Any]) -> TF:
+        """根据传入字典和模板生成消息对象, 在传入字段名不是有效标识符时有用"""
+        return self._format([], mapping)
+
+    def _format(self, args: Sequence[Any], kwargs: Mapping[str, Any]) -> TF:
         msg = self.factory()
         if isinstance(self.template, str):
             msg += self.vformat(self.template, args, kwargs)
@@ -166,7 +172,7 @@
         if formatter is None and not issubclass(self.factory, str):
             segment_class: Type["MessageSegment"] = self.factory.get_segment_class()
             method = getattr(segment_class, format_spec, None)
-            if inspect.ismethod(method):
+            if callable(method) and not cast(str, method.__name__).startswith("_"):
                 formatter = getattr(segment_class, format_spec)
         return (
             super().format_field(value, format_spec)

{"golden_diff": "diff --git a/nonebot/internal/adapter/template.py b/nonebot/internal/adapter/template.py\n--- a/nonebot/internal/adapter/template.py\n+++ b/nonebot/internal/adapter/template.py\n@@ -1,4 +1,3 @@\n-import inspect\n import functools\n from string import Formatter\n from typing import (\n@@ -35,7 +34,7 @@\n \n     \u53c2\u6570:\n         template: \u6a21\u677f\n-        factory: \u6d88\u606f\u6784\u9020\u7c7b\u578b\uff0c\u9ed8\u8ba4\u4e3a `str`\n+        factory: \u6d88\u606f\u7c7b\u578b\u5de5\u5382\uff0c\u9ed8\u8ba4\u4e3a `str`\n     \"\"\"\n \n     @overload\n@@ -64,8 +63,15 @@\n         self.format_specs[name] = spec\n         return spec\n \n-    def format(self, *args: Any, **kwargs: Any) -> TF:\n-        \"\"\"\u6839\u636e\u6a21\u677f\u548c\u53c2\u6570\u751f\u6210\u6d88\u606f\u5bf9\u8c61\"\"\"\n+    def format(self, *args, **kwargs):\n+        \"\"\"\u6839\u636e\u4f20\u5165\u53c2\u6570\u548c\u6a21\u677f\u751f\u6210\u6d88\u606f\u5bf9\u8c61\"\"\"\n+        return self._format(args, kwargs)\n+\n+    def format_map(self, mapping: Mapping[str, Any]) -> TF:\n+        \"\"\"\u6839\u636e\u4f20\u5165\u5b57\u5178\u548c\u6a21\u677f\u751f\u6210\u6d88\u606f\u5bf9\u8c61, \u5728\u4f20\u5165\u5b57\u6bb5\u540d\u4e0d\u662f\u6709\u6548\u6807\u8bc6\u7b26\u65f6\u6709\u7528\"\"\"\n+        return self._format([], mapping)\n+\n+    def _format(self, args: Sequence[Any], kwargs: Mapping[str, Any]) -> TF:\n         msg = self.factory()\n         if isinstance(self.template, str):\n             msg += self.vformat(self.template, args, kwargs)\n@@ -166,7 +172,7 @@\n         if formatter is None and not issubclass(self.factory, str):\n             segment_class: Type[\"MessageSegment\"] = self.factory.get_segment_class()\n             method = getattr(segment_class, format_spec, None)\n-            if inspect.ismethod(method):\n+            if callable(method) and not cast(str, method.__name__).startswith(\"_\"):\n                 formatter = getattr(segment_class, format_spec)\n         return (\n             super().format_field(value, format_spec)\n", "issue": "Bug: Message.template format \u95ee\u9898\n**\u63cf\u8ff0\u95ee\u9898\uff1a**\r\n\r\n\u65e0\u6cd5\u4f7f\u7528format\r\n\r\n**\u5982\u4f55\u590d\u73b0\uff1f**\r\n\r\n```py\r\nfrom nonebot.adapters.onebot.v11 import Message\r\nfile_list = [\r\n    \"file:///file1.image\",\r\n    \"file:///file2.image\",\r\n    ...\r\n]\r\ntext = \"img1:  {:image} img2: {:image} ...\"\r\n\r\nmsg = Message.template(text).format(*file_list)\r\n```\r\n\r\n\r\n**\u671f\u671b\u7684\u7ed3\u679c**\r\n\r\n`msg` \u4e3a\u53ef\u4ee5\u76f4\u63a5\u53d1\u9001\u7684 \u5305\u542b\u6587\u5b57\u548c\u56fe\u7247\u7684\u6d88\u606f\r\n\r\n**\u73af\u5883\u4fe1\u606f\uff1a**\r\n\r\n - OS: Linux CentOS8\r\n - Python Version: 3.9\r\n - Nonebot Version: 2.0.0-beta.1\r\n\r\n\r\n**\u622a\u56fe\u6216\u65e5\u5fd7**\r\n```log\r\nTraceback (most recent call last):\r\n  File \"/data/nb-test/test/re_test.py\", line 23, in <module>\r\n    msg = Message.template(text).format(*file_list)\r\n  File \"/root/.cache/pypoetry/virtualenvs/nb-test-NOSw4fD6-py3.9/lib/python3.9/site-packages/nonebot/adapters/_template.py\", line 80, in format\r\n    msg += self.vformat(self.template, args, kwargs)\r\n  File \"/root/.cache/pypoetry/virtualenvs/nb-test-NOSw4fD6-py3.9/lib/python3.9/site-packages/nonebot/adapters/_template.py\", line 94, in vformat\r\n    result, _ = self._vformat(format_string, args, kwargs, used_args, 2)\r\n  File \"/root/.cache/pypoetry/virtualenvs/nb-test-NOSw4fD6-py3.9/lib/python3.9/site-packages/nonebot/adapters/_template.py\", line 165, in _vformat\r\n    formatted_text = self.format_field(obj, str(format_control))\r\n  File \"/root/.cache/pypoetry/virtualenvs/nb-test-NOSw4fD6-py3.9/lib/python3.9/site-packages/nonebot/adapters/_template.py\", line 181, in format_field\r\n    super().format_field(value, format_spec)\r\n  File \"/root/miniconda3/lib/python3.9/string.py\", line 235, in format_field\r\n    return format(value, format_spec)\r\nValueError: Invalid format specifier\r\n```\n", "before_files": [{"content": "import inspect\nimport functools\nfrom string import Formatter\nfrom typing import (\n    TYPE_CHECKING,\n    Any,\n    Set,\n    Dict,\n    List,\n    Type,\n    Tuple,\n    Union,\n    Generic,\n    Mapping,\n    TypeVar,\n    Callable,\n    Optional,\n    Sequence,\n    cast,\n    overload,\n)\n\nif TYPE_CHECKING:\n    from .message import Message, MessageSegment\n\nTM = TypeVar(\"TM\", bound=\"Message\")\nTF = TypeVar(\"TF\", str, \"Message\")\n\nFormatSpecFunc = Callable[[Any], str]\nFormatSpecFunc_T = TypeVar(\"FormatSpecFunc_T\", bound=FormatSpecFunc)\n\n\nclass MessageTemplate(Formatter, Generic[TF]):\n    \"\"\"\u6d88\u606f\u6a21\u677f\u683c\u5f0f\u5316\u5b9e\u73b0\u7c7b\u3002\n\n    \u53c2\u6570:\n        template: \u6a21\u677f\n        factory: \u6d88\u606f\u6784\u9020\u7c7b\u578b\uff0c\u9ed8\u8ba4\u4e3a `str`\n    \"\"\"\n\n    @overload\n    def __init__(\n        self: \"MessageTemplate[str]\", template: str, factory: Type[str] = str\n    ) -> None:\n        ...\n\n    @overload\n    def __init__(\n        self: \"MessageTemplate[TM]\", template: Union[str, TM], factory: Type[TM]\n    ) -> None:\n        ...\n\n    def __init__(self, template, factory=str) -> None:\n        self.template: TF = template\n        self.factory: Type[TF] = factory\n        self.format_specs: Dict[str, FormatSpecFunc] = {}\n\n    def add_format_spec(\n        self, spec: FormatSpecFunc_T, name: Optional[str] = None\n    ) -> FormatSpecFunc_T:\n        name = name or spec.__name__\n        if name in self.format_specs:\n            raise ValueError(f\"Format spec {name} already exists!\")\n        self.format_specs[name] = spec\n        return spec\n\n    def format(self, *args: Any, **kwargs: Any) -> TF:\n        \"\"\"\u6839\u636e\u6a21\u677f\u548c\u53c2\u6570\u751f\u6210\u6d88\u606f\u5bf9\u8c61\"\"\"\n        msg = self.factory()\n        if isinstance(self.template, str):\n            msg += self.vformat(self.template, args, kwargs)\n        elif isinstance(self.template, self.factory):\n            template = cast(\"Message[MessageSegment]\", self.template)\n            for seg in template:\n                msg += self.vformat(str(seg), args, kwargs) if seg.is_text() else seg\n        else:\n            raise TypeError(\"template must be a string or instance of Message!\")\n\n        return msg  # type:ignore\n\n    def vformat(\n        self, format_string: str, args: Sequence[Any], kwargs: Mapping[str, Any]\n    ) -> TF:\n        used_args = set()\n        result, _ = self._vformat(format_string, args, kwargs, used_args, 2)\n        self.check_unused_args(list(used_args), args, kwargs)\n        return result\n\n    def _vformat(\n        self,\n        format_string: str,\n        args: Sequence[Any],\n        kwargs: Mapping[str, Any],\n        used_args: Set[Union[int, str]],\n        recursion_depth: int,\n        auto_arg_index: int = 0,\n    ) -> Tuple[TF, int]:\n        if recursion_depth < 0:\n            raise ValueError(\"Max string recursion exceeded\")\n\n        results: List[Any] = []\n\n        for (literal_text, field_name, format_spec, conversion) in self.parse(\n            format_string\n        ):\n\n            # output the literal text\n            if literal_text:\n                results.append(literal_text)\n\n            # if there's a field, output it\n            if field_name is not None:\n                # this is some markup, find the object and do\n                #  the formatting\n\n                # handle arg indexing when empty field_names are given.\n                if field_name == \"\":\n                    if auto_arg_index is False:\n                        raise ValueError(\n                            \"cannot switch from manual field specification to \"\n                            \"automatic field numbering\"\n                        )\n                    field_name = str(auto_arg_index)\n                    auto_arg_index += 1\n                elif field_name.isdigit():\n                    if auto_arg_index:\n                        raise ValueError(\n                            \"cannot switch from manual field specification to \"\n                            \"automatic field numbering\"\n                        )\n                    # disable auto arg incrementing, if it gets\n                    # used later on, then an exception will be raised\n                    auto_arg_index = False\n\n                # given the field_name, find the object it references\n                #  and the argument it came from\n                obj, arg_used = self.get_field(field_name, args, kwargs)\n                used_args.add(arg_used)\n\n                assert format_spec is not None\n\n                # do any conversion on the resulting object\n                obj = self.convert_field(obj, conversion) if conversion else obj\n\n                # expand the format spec, if needed\n                format_control, auto_arg_index = self._vformat(\n                    format_spec,\n                    args,\n                    kwargs,\n                    used_args,\n                    recursion_depth - 1,\n                    auto_arg_index,\n                )\n\n                # format the object and append to the result\n                formatted_text = self.format_field(obj, str(format_control))\n                results.append(formatted_text)\n\n        return (\n            self.factory(functools.reduce(self._add, results or [\"\"])),\n            auto_arg_index,\n        )\n\n    def format_field(self, value: Any, format_spec: str) -> Any:\n        formatter: Optional[FormatSpecFunc] = self.format_specs.get(format_spec)\n        if formatter is None and not issubclass(self.factory, str):\n            segment_class: Type[\"MessageSegment\"] = self.factory.get_segment_class()\n            method = getattr(segment_class, format_spec, None)\n            if inspect.ismethod(method):\n                formatter = getattr(segment_class, format_spec)\n        return (\n            super().format_field(value, format_spec)\n            if formatter is None\n            else formatter(value)\n        )\n\n    def _add(self, a: Any, b: Any) -> Any:\n        try:\n            return a + b\n        except TypeError:\n            return a + str(b)\n", "path": "nonebot/internal/adapter/template.py"}], "after_files": [{"content": "import functools\nfrom string import Formatter\nfrom typing import (\n    TYPE_CHECKING,\n    Any,\n    Set,\n    Dict,\n    List,\n    Type,\n    Tuple,\n    Union,\n    Generic,\n    Mapping,\n    TypeVar,\n    Callable,\n    Optional,\n    Sequence,\n    cast,\n    overload,\n)\n\nif TYPE_CHECKING:\n    from .message import Message, MessageSegment\n\nTM = TypeVar(\"TM\", bound=\"Message\")\nTF = TypeVar(\"TF\", str, \"Message\")\n\nFormatSpecFunc = Callable[[Any], str]\nFormatSpecFunc_T = TypeVar(\"FormatSpecFunc_T\", bound=FormatSpecFunc)\n\n\nclass MessageTemplate(Formatter, Generic[TF]):\n    \"\"\"\u6d88\u606f\u6a21\u677f\u683c\u5f0f\u5316\u5b9e\u73b0\u7c7b\u3002\n\n    \u53c2\u6570:\n        template: \u6a21\u677f\n        factory: \u6d88\u606f\u7c7b\u578b\u5de5\u5382\uff0c\u9ed8\u8ba4\u4e3a `str`\n    \"\"\"\n\n    @overload\n    def __init__(\n        self: \"MessageTemplate[str]\", template: str, factory: Type[str] = str\n    ) -> None:\n        ...\n\n    @overload\n    def __init__(\n        self: \"MessageTemplate[TM]\", template: Union[str, TM], factory: Type[TM]\n    ) -> None:\n        ...\n\n    def __init__(self, template, factory=str) -> None:\n        self.template: TF = template\n        self.factory: Type[TF] = factory\n        self.format_specs: Dict[str, FormatSpecFunc] = {}\n\n    def add_format_spec(\n        self, spec: FormatSpecFunc_T, name: Optional[str] = None\n    ) -> FormatSpecFunc_T:\n        name = name or spec.__name__\n        if name in self.format_specs:\n            raise ValueError(f\"Format spec {name} already exists!\")\n        self.format_specs[name] = spec\n        return spec\n\n    def format(self, *args, **kwargs):\n        \"\"\"\u6839\u636e\u4f20\u5165\u53c2\u6570\u548c\u6a21\u677f\u751f\u6210\u6d88\u606f\u5bf9\u8c61\"\"\"\n        return self._format(args, kwargs)\n\n    def format_map(self, mapping: Mapping[str, Any]) -> TF:\n        \"\"\"\u6839\u636e\u4f20\u5165\u5b57\u5178\u548c\u6a21\u677f\u751f\u6210\u6d88\u606f\u5bf9\u8c61, \u5728\u4f20\u5165\u5b57\u6bb5\u540d\u4e0d\u662f\u6709\u6548\u6807\u8bc6\u7b26\u65f6\u6709\u7528\"\"\"\n        return self._format([], mapping)\n\n    def _format(self, args: Sequence[Any], kwargs: Mapping[str, Any]) -> TF:\n        msg = self.factory()\n        if isinstance(self.template, str):\n            msg += self.vformat(self.template, args, kwargs)\n        elif isinstance(self.template, self.factory):\n            template = cast(\"Message[MessageSegment]\", self.template)\n            for seg in template:\n                msg += self.vformat(str(seg), args, kwargs) if seg.is_text() else seg\n        else:\n            raise TypeError(\"template must be a string or instance of Message!\")\n\n        return msg  # type:ignore\n\n    def vformat(\n        self, format_string: str, args: Sequence[Any], kwargs: Mapping[str, Any]\n    ) -> TF:\n        used_args = set()\n        result, _ = self._vformat(format_string, args, kwargs, used_args, 2)\n        self.check_unused_args(list(used_args), args, kwargs)\n        return result\n\n    def _vformat(\n        self,\n        format_string: str,\n        args: Sequence[Any],\n        kwargs: Mapping[str, Any],\n        used_args: Set[Union[int, str]],\n        recursion_depth: int,\n        auto_arg_index: int = 0,\n    ) -> Tuple[TF, int]:\n        if recursion_depth < 0:\n            raise ValueError(\"Max string recursion exceeded\")\n\n        results: List[Any] = []\n\n        for (literal_text, field_name, format_spec, conversion) in self.parse(\n            format_string\n        ):\n\n            # output the literal text\n            if literal_text:\n                results.append(literal_text)\n\n            # if there's a field, output it\n            if field_name is not None:\n                # this is some markup, find the object and do\n                #  the formatting\n\n                # handle arg indexing when empty field_names are given.\n                if field_name == \"\":\n                    if auto_arg_index is False:\n                        raise ValueError(\n                            \"cannot switch from manual field specification to \"\n                            \"automatic field numbering\"\n                        )\n                    field_name = str(auto_arg_index)\n                    auto_arg_index += 1\n                elif field_name.isdigit():\n                    if auto_arg_index:\n                        raise ValueError(\n                            \"cannot switch from manual field specification to \"\n                            \"automatic field numbering\"\n                        )\n                    # disable auto arg incrementing, if it gets\n                    # used later on, then an exception will be raised\n                    auto_arg_index = False\n\n                # given the field_name, find the object it references\n                #  and the argument it came from\n                obj, arg_used = self.get_field(field_name, args, kwargs)\n                used_args.add(arg_used)\n\n                assert format_spec is not None\n\n                # do any conversion on the resulting object\n                obj = self.convert_field(obj, conversion) if conversion else obj\n\n                # expand the format spec, if needed\n                format_control, auto_arg_index = self._vformat(\n                    format_spec,\n                    args,\n                    kwargs,\n                    used_args,\n                    recursion_depth - 1,\n                    auto_arg_index,\n                )\n\n                # format the object and append to the result\n                formatted_text = self.format_field(obj, str(format_control))\n                results.append(formatted_text)\n\n        return (\n            self.factory(functools.reduce(self._add, results or [\"\"])),\n            auto_arg_index,\n        )\n\n    def format_field(self, value: Any, format_spec: str) -> Any:\n        formatter: Optional[FormatSpecFunc] = self.format_specs.get(format_spec)\n        if formatter is None and not issubclass(self.factory, str):\n            segment_class: Type[\"MessageSegment\"] = self.factory.get_segment_class()\n            method = getattr(segment_class, format_spec, None)\n            if callable(method) and not cast(str, method.__name__).startswith(\"_\"):\n                formatter = getattr(segment_class, format_spec)\n        return (\n            super().format_field(value, format_spec)\n            if formatter is None\n            else formatter(value)\n        )\n\n    def _add(self, a: Any, b: Any) -> Any:\n        try:\n            return a + b\n        except TypeError:\n            return a + str(b)\n", "path": "nonebot/internal/adapter/template.py"}]}