We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Bug: expired matcher 在删除前依然会运行
**描述问题：**

超出有效期的事件响应器在删除前仍然会运行一次

**期望的结果**

超出有效期的事件响应器不被运行

**环境信息：**

 - OS: Any
 - Python Version: Any
 - Nonebot Version: 2.0.0a6
Bug: expired matcher 在删除前依然会运行
**描述问题：**

超出有效期的事件响应器在删除前仍然会运行一次

**期望的结果**

超出有效期的事件响应器不被运行

**环境信息：**

 - OS: Any
 - Python Version: Any
 - Nonebot Version: 2.0.0a6

--- 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/message.py`
Content:
```
1 """
2 事件处理
3 ========
4 
5 NoneBot 内部处理并按优先级分发事件给所有事件响应器，提供了多个插槽以进行事件的预处理等。
6 """
7 
8 import asyncio
9 from datetime import datetime
10 
11 from nonebot.log import logger
12 from nonebot.rule import TrieRule
13 from nonebot.utils import escape_tag
14 from nonebot.matcher import matchers, Matcher
15 from nonebot.typing import Set, Type, Union, Optional, Iterable, NoReturn, Bot, Event
16 from nonebot.exception import IgnoredException, StopPropagation
17 from nonebot.typing import EventPreProcessor, RunPreProcessor, EventPostProcessor, RunPostProcessor
18 
19 _event_preprocessors: Set[EventPreProcessor] = set()
20 _event_postprocessors: Set[EventPostProcessor] = set()
21 _run_preprocessors: Set[RunPreProcessor] = set()
22 _run_postprocessors: Set[RunPostProcessor] = set()
23 
24 
25 def event_preprocessor(func: EventPreProcessor) -> EventPreProcessor:
26     """
27     :说明:
28       事件预处理。装饰一个函数，使它在每次接收到事件并分发给各响应器之前执行。
29     :参数:
30       事件预处理函数接收三个参数。
31 
32       * ``bot: Bot``: Bot 对象
33       * ``event: Event``: Event 对象
34       * ``state: dict``: 当前 State
35     """
36     _event_preprocessors.add(func)
37     return func
38 
39 
40 def event_postprocessor(func: EventPostProcessor) -> EventPostProcessor:
41     """
42     :说明:
43       事件后处理。装饰一个函数，使它在每次接收到事件并分发给各响应器之后执行。
44     :参数:
45       事件后处理函数接收三个参数。
46 
47       * ``bot: Bot``: Bot 对象
48       * ``event: Event``: Event 对象
49       * ``state: dict``: 当前事件运行前 State
50     """
51     _event_postprocessors.add(func)
52     return func
53 
54 
55 def run_preprocessor(func: RunPreProcessor) -> RunPreProcessor:
56     """
57     :说明:
58       运行预处理。装饰一个函数，使它在每次事件响应器运行前执行。
59     :参数:
60       运行预处理函数接收四个参数。
61 
62       * ``matcher: Matcher``: 当前要运行的事件响应器
63       * ``bot: Bot``: Bot 对象
64       * ``event: Event``: Event 对象
65       * ``state: dict``: 当前 State
66     """
67     _run_preprocessors.add(func)
68     return func
69 
70 
71 def run_postprocessor(func: RunPostProcessor) -> RunPostProcessor:
72     """
73     :说明:
74       运行后处理。装饰一个函数，使它在每次事件响应器运行后执行。
75     :参数:
76       运行后处理函数接收五个参数。
77 
78       * ``matcher: Matcher``: 运行完毕的事件响应器
79       * ``exception: Optional[Exception]``: 事件响应器运行错误（如果存在）
80       * ``bot: Bot``: Bot 对象
81       * ``event: Event``: Event 对象
82       * ``state: dict``: 当前 State
83     """
84     _run_postprocessors.add(func)
85     return func
86 
87 
88 async def _check_matcher(priority: int, bot: Bot, event: Event,
89                          state: dict) -> Iterable[Type[Matcher]]:
90     current_matchers = matchers[priority].copy()
91 
92     async def _check(Matcher: Type[Matcher], bot: Bot, event: Event,
93                      state: dict) -> Optional[Type[Matcher]]:
94         try:
95             if await Matcher.check_perm(
96                     bot, event) and await Matcher.check_rule(bot, event, state):
97                 return Matcher
98         except Exception as e:
99             logger.opt(colors=True, exception=e).error(
100                 f"<r><bg #f8bbd0>Rule check failed for {Matcher}.</bg #f8bbd0></r>"
101             )
102         return None
103 
104     async def _check_expire(Matcher: Type[Matcher]) -> Optional[Type[Matcher]]:
105         if Matcher.temp or (Matcher.expire_time and
106                             datetime.now() > Matcher.expire_time):
107             return Matcher
108         return None
109 
110     checking_tasks = [
111         _check(Matcher, bot, event, state) for Matcher in current_matchers
112     ]
113     checking_expire_tasks = [
114         _check_expire(Matcher) for Matcher in current_matchers
115     ]
116     results = await asyncio.gather(*checking_tasks, return_exceptions=True)
117     expired = await asyncio.gather(*checking_expire_tasks)
118     for expired_matcher in filter(lambda x: x and x in results, expired):
119         try:
120             matchers[priority].remove(expired_matcher)
121         except Exception:
122             pass
123     return filter(lambda x: x, results)
124 
125 
126 async def _run_matcher(Matcher: Type[Matcher], bot: Bot, event: Event,
127                        state: dict) -> Union[None, NoReturn]:
128     logger.info(f"Event will be handled by {Matcher}")
129 
130     matcher = Matcher()
131 
132     coros = list(
133         map(lambda x: x(matcher, bot, event, state), _run_preprocessors))
134     if coros:
135         try:
136             await asyncio.gather(*coros)
137         except IgnoredException:
138             logger.opt(colors=True).info(
139                 f"Matcher {matcher} running is <b>cancelled</b>")
140             return
141         except Exception as e:
142             logger.opt(colors=True, exception=e).error(
143                 "<r><bg #f8bbd0>Error when running RunPreProcessors. "
144                 "Running cancelled!</bg #f8bbd0></r>")
145             return
146 
147     exception = None
148 
149     try:
150         logger.debug(f"Running matcher {matcher}")
151         await matcher.run(bot, event, state)
152     except StopPropagation as e:
153         exception = e
154     except Exception as e:
155         logger.opt(colors=True, exception=e).error(
156             f"<r><bg #f8bbd0>Running matcher {matcher} failed.</bg #f8bbd0></r>"
157         )
158         exception = e
159 
160     coros = list(
161         map(lambda x: x(matcher, exception, bot, event, state),
162             _run_postprocessors))
163     if coros:
164         try:
165             await asyncio.gather(*coros)
166         except Exception as e:
167             logger.opt(colors=True, exception=e).error(
168                 "<r><bg #f8bbd0>Error when running RunPostProcessors</bg #f8bbd0></r>"
169             )
170 
171     if matcher.block or isinstance(exception, StopPropagation):
172         raise StopPropagation
173 
174 
175 async def handle_event(bot: Bot, event: Event):
176     """
177     :说明:
178        处理一个事件。调用该函数以实现分发事件。
179     :参数:
180       * ``bot: Bot``: Bot 对象
181       * ``event: Event``: Event 对象
182     :示例:
183 
184     .. code-block:: python
185 
186         import asyncio
187         asyncio.create_task(handle_event(bot, event))
188     """
189     show_log = True
190     log_msg = f"<m>{bot.type.upper()} </m>| {event.self_id} [{event.name}]: "
191     if event.type == "message":
192         log_msg += f"Message {event.id} from "
193         log_msg += str(event.user_id)
194         if event.detail_type == "group":
195             log_msg += f"@[群:{event.group_id}]:"
196 
197         log_msg += ' "' + "".join(
198             map(
199                 lambda x: escape_tag(str(x))
200                 if x.type == "text" else f"<le>{escape_tag(str(x))}</le>",
201                 event.message)) + '"'  # type: ignore
202     elif event.type == "notice":
203         log_msg += f"Notice {event.raw_event}"
204     elif event.type == "request":
205         log_msg += f"Request {event.raw_event}"
206     elif event.type == "meta_event":
207         # log_msg += f"MetaEvent {event.detail_type}"
208         show_log = False
209     if show_log:
210         logger.opt(colors=True).info(log_msg)
211 
212     state = {}
213     coros = list(map(lambda x: x(bot, event, state), _event_preprocessors))
214     if coros:
215         try:
216             logger.debug("Running PreProcessors...")
217             await asyncio.gather(*coros)
218         except IgnoredException:
219             logger.opt(
220                 colors=True).info(f"Event {event.name} is <b>ignored</b>")
221             return
222         except Exception as e:
223             logger.opt(colors=True, exception=e).error(
224                 "<r><bg #f8bbd0>Error when running EventPreProcessors. "
225                 "Event ignored!</bg #f8bbd0></r>")
226             return
227 
228     # Trie Match
229     _, _ = TrieRule.get_value(bot, event, state)
230 
231     break_flag = False
232     for priority in sorted(matchers.keys()):
233         if break_flag:
234             break
235 
236         if show_log:
237             logger.debug(f"Checking for matchers in priority {priority}...")
238 
239         run_matchers = await _check_matcher(priority, bot, event, state)
240 
241         pending_tasks = [
242             _run_matcher(matcher, bot, event, state.copy())
243             for matcher in run_matchers
244         ]
245 
246         results = await asyncio.gather(*pending_tasks, return_exceptions=True)
247 
248         for result in results:
249             if isinstance(result, StopPropagation):
250                 if not break_flag:
251                     break_flag = True
252                     logger.debug("Stop event propagation")
253 
254     coros = list(map(lambda x: x(bot, event, state), _event_postprocessors))
255     if coros:
256         try:
257             logger.debug("Running PostProcessors...")
258             await asyncio.gather(*coros)
259         except Exception as e:
260             logger.opt(colors=True, exception=e).error(
261                 "<r><bg #f8bbd0>Error when running EventPostProcessors</bg #f8bbd0></r>"
262             )
263
```
--- 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/message.py b/nonebot/message.py
--- a/nonebot/message.py
+++ b/nonebot/message.py
@@ -92,8 +92,9 @@
     async def _check(Matcher: Type[Matcher], bot: Bot, event: Event,
                      state: dict) -> Optional[Type[Matcher]]:
         try:
-            if await Matcher.check_perm(
-                    bot, event) and await Matcher.check_rule(bot, event, state):
+            if (Matcher.expire_time and datetime.now() <= Matcher.expire_time
+               ) and await Matcher.check_perm(
+                   bot, event) and await Matcher.check_rule(bot, event, state):
                 return Matcher
         except Exception as e:
             logger.opt(colors=True, exception=e).error(

{"golden_diff": "diff --git a/nonebot/message.py b/nonebot/message.py\n--- a/nonebot/message.py\n+++ b/nonebot/message.py\n@@ -92,8 +92,9 @@\n     async def _check(Matcher: Type[Matcher], bot: Bot, event: Event,\n                      state: dict) -> Optional[Type[Matcher]]:\n         try:\n-            if await Matcher.check_perm(\n-                    bot, event) and await Matcher.check_rule(bot, event, state):\n+            if (Matcher.expire_time and datetime.now() <= Matcher.expire_time\n+               ) and await Matcher.check_perm(\n+                   bot, event) and await Matcher.check_rule(bot, event, state):\n                 return Matcher\n         except Exception as e:\n             logger.opt(colors=True, exception=e).error(\n", "issue": "Bug: expired matcher \u5728\u5220\u9664\u524d\u4f9d\u7136\u4f1a\u8fd0\u884c\n**\u63cf\u8ff0\u95ee\u9898\uff1a**\r\n\r\n\u8d85\u51fa\u6709\u6548\u671f\u7684\u4e8b\u4ef6\u54cd\u5e94\u5668\u5728\u5220\u9664\u524d\u4ecd\u7136\u4f1a\u8fd0\u884c\u4e00\u6b21\r\n\r\n**\u671f\u671b\u7684\u7ed3\u679c**\r\n\r\n\u8d85\u51fa\u6709\u6548\u671f\u7684\u4e8b\u4ef6\u54cd\u5e94\u5668\u4e0d\u88ab\u8fd0\u884c\r\n\r\n**\u73af\u5883\u4fe1\u606f\uff1a**\r\n\r\n - OS: Any\r\n - Python Version: Any\r\n - Nonebot Version: 2.0.0a6\nBug: expired matcher \u5728\u5220\u9664\u524d\u4f9d\u7136\u4f1a\u8fd0\u884c\n**\u63cf\u8ff0\u95ee\u9898\uff1a**\r\n\r\n\u8d85\u51fa\u6709\u6548\u671f\u7684\u4e8b\u4ef6\u54cd\u5e94\u5668\u5728\u5220\u9664\u524d\u4ecd\u7136\u4f1a\u8fd0\u884c\u4e00\u6b21\r\n\r\n**\u671f\u671b\u7684\u7ed3\u679c**\r\n\r\n\u8d85\u51fa\u6709\u6548\u671f\u7684\u4e8b\u4ef6\u54cd\u5e94\u5668\u4e0d\u88ab\u8fd0\u884c\r\n\r\n**\u73af\u5883\u4fe1\u606f\uff1a**\r\n\r\n - OS: Any\r\n - Python Version: Any\r\n - Nonebot Version: 2.0.0a6\n", "before_files": [{"content": "\"\"\"\n\u4e8b\u4ef6\u5904\u7406\n========\n\nNoneBot \u5185\u90e8\u5904\u7406\u5e76\u6309\u4f18\u5148\u7ea7\u5206\u53d1\u4e8b\u4ef6\u7ed9\u6240\u6709\u4e8b\u4ef6\u54cd\u5e94\u5668\uff0c\u63d0\u4f9b\u4e86\u591a\u4e2a\u63d2\u69fd\u4ee5\u8fdb\u884c\u4e8b\u4ef6\u7684\u9884\u5904\u7406\u7b49\u3002\n\"\"\"\n\nimport asyncio\nfrom datetime import datetime\n\nfrom nonebot.log import logger\nfrom nonebot.rule import TrieRule\nfrom nonebot.utils import escape_tag\nfrom nonebot.matcher import matchers, Matcher\nfrom nonebot.typing import Set, Type, Union, Optional, Iterable, NoReturn, Bot, Event\nfrom nonebot.exception import IgnoredException, StopPropagation\nfrom nonebot.typing import EventPreProcessor, RunPreProcessor, EventPostProcessor, RunPostProcessor\n\n_event_preprocessors: Set[EventPreProcessor] = set()\n_event_postprocessors: Set[EventPostProcessor] = set()\n_run_preprocessors: Set[RunPreProcessor] = set()\n_run_postprocessors: Set[RunPostProcessor] = set()\n\n\ndef event_preprocessor(func: EventPreProcessor) -> EventPreProcessor:\n    \"\"\"\n    :\u8bf4\u660e:\n      \u4e8b\u4ef6\u9884\u5904\u7406\u3002\u88c5\u9970\u4e00\u4e2a\u51fd\u6570\uff0c\u4f7f\u5b83\u5728\u6bcf\u6b21\u63a5\u6536\u5230\u4e8b\u4ef6\u5e76\u5206\u53d1\u7ed9\u5404\u54cd\u5e94\u5668\u4e4b\u524d\u6267\u884c\u3002\n    :\u53c2\u6570:\n      \u4e8b\u4ef6\u9884\u5904\u7406\u51fd\u6570\u63a5\u6536\u4e09\u4e2a\u53c2\u6570\u3002\n\n      * ``bot: Bot``: Bot \u5bf9\u8c61\n      * ``event: Event``: Event \u5bf9\u8c61\n      * ``state: dict``: \u5f53\u524d State\n    \"\"\"\n    _event_preprocessors.add(func)\n    return func\n\n\ndef event_postprocessor(func: EventPostProcessor) -> EventPostProcessor:\n    \"\"\"\n    :\u8bf4\u660e:\n      \u4e8b\u4ef6\u540e\u5904\u7406\u3002\u88c5\u9970\u4e00\u4e2a\u51fd\u6570\uff0c\u4f7f\u5b83\u5728\u6bcf\u6b21\u63a5\u6536\u5230\u4e8b\u4ef6\u5e76\u5206\u53d1\u7ed9\u5404\u54cd\u5e94\u5668\u4e4b\u540e\u6267\u884c\u3002\n    :\u53c2\u6570:\n      \u4e8b\u4ef6\u540e\u5904\u7406\u51fd\u6570\u63a5\u6536\u4e09\u4e2a\u53c2\u6570\u3002\n\n      * ``bot: Bot``: Bot \u5bf9\u8c61\n      * ``event: Event``: Event \u5bf9\u8c61\n      * ``state: dict``: \u5f53\u524d\u4e8b\u4ef6\u8fd0\u884c\u524d State\n    \"\"\"\n    _event_postprocessors.add(func)\n    return func\n\n\ndef run_preprocessor(func: RunPreProcessor) -> RunPreProcessor:\n    \"\"\"\n    :\u8bf4\u660e:\n      \u8fd0\u884c\u9884\u5904\u7406\u3002\u88c5\u9970\u4e00\u4e2a\u51fd\u6570\uff0c\u4f7f\u5b83\u5728\u6bcf\u6b21\u4e8b\u4ef6\u54cd\u5e94\u5668\u8fd0\u884c\u524d\u6267\u884c\u3002\n    :\u53c2\u6570:\n      \u8fd0\u884c\u9884\u5904\u7406\u51fd\u6570\u63a5\u6536\u56db\u4e2a\u53c2\u6570\u3002\n\n      * ``matcher: Matcher``: \u5f53\u524d\u8981\u8fd0\u884c\u7684\u4e8b\u4ef6\u54cd\u5e94\u5668\n      * ``bot: Bot``: Bot \u5bf9\u8c61\n      * ``event: Event``: Event \u5bf9\u8c61\n      * ``state: dict``: \u5f53\u524d State\n    \"\"\"\n    _run_preprocessors.add(func)\n    return func\n\n\ndef run_postprocessor(func: RunPostProcessor) -> RunPostProcessor:\n    \"\"\"\n    :\u8bf4\u660e:\n      \u8fd0\u884c\u540e\u5904\u7406\u3002\u88c5\u9970\u4e00\u4e2a\u51fd\u6570\uff0c\u4f7f\u5b83\u5728\u6bcf\u6b21\u4e8b\u4ef6\u54cd\u5e94\u5668\u8fd0\u884c\u540e\u6267\u884c\u3002\n    :\u53c2\u6570:\n      \u8fd0\u884c\u540e\u5904\u7406\u51fd\u6570\u63a5\u6536\u4e94\u4e2a\u53c2\u6570\u3002\n\n      * ``matcher: Matcher``: \u8fd0\u884c\u5b8c\u6bd5\u7684\u4e8b\u4ef6\u54cd\u5e94\u5668\n      * ``exception: Optional[Exception]``: \u4e8b\u4ef6\u54cd\u5e94\u5668\u8fd0\u884c\u9519\u8bef\uff08\u5982\u679c\u5b58\u5728\uff09\n      * ``bot: Bot``: Bot \u5bf9\u8c61\n      * ``event: Event``: Event \u5bf9\u8c61\n      * ``state: dict``: \u5f53\u524d State\n    \"\"\"\n    _run_postprocessors.add(func)\n    return func\n\n\nasync def _check_matcher(priority: int, bot: Bot, event: Event,\n                         state: dict) -> Iterable[Type[Matcher]]:\n    current_matchers = matchers[priority].copy()\n\n    async def _check(Matcher: Type[Matcher], bot: Bot, event: Event,\n                     state: dict) -> Optional[Type[Matcher]]:\n        try:\n            if await Matcher.check_perm(\n                    bot, event) and await Matcher.check_rule(bot, event, state):\n                return Matcher\n        except Exception as e:\n            logger.opt(colors=True, exception=e).error(\n                f\"<r><bg #f8bbd0>Rule check failed for {Matcher}.</bg #f8bbd0></r>\"\n            )\n        return None\n\n    async def _check_expire(Matcher: Type[Matcher]) -> Optional[Type[Matcher]]:\n        if Matcher.temp or (Matcher.expire_time and\n                            datetime.now() > Matcher.expire_time):\n            return Matcher\n        return None\n\n    checking_tasks = [\n        _check(Matcher, bot, event, state) for Matcher in current_matchers\n    ]\n    checking_expire_tasks = [\n        _check_expire(Matcher) for Matcher in current_matchers\n    ]\n    results = await asyncio.gather(*checking_tasks, return_exceptions=True)\n    expired = await asyncio.gather(*checking_expire_tasks)\n    for expired_matcher in filter(lambda x: x and x in results, expired):\n        try:\n            matchers[priority].remove(expired_matcher)\n        except Exception:\n            pass\n    return filter(lambda x: x, results)\n\n\nasync def _run_matcher(Matcher: Type[Matcher], bot: Bot, event: Event,\n                       state: dict) -> Union[None, NoReturn]:\n    logger.info(f\"Event will be handled by {Matcher}\")\n\n    matcher = Matcher()\n\n    coros = list(\n        map(lambda x: x(matcher, bot, event, state), _run_preprocessors))\n    if coros:\n        try:\n            await asyncio.gather(*coros)\n        except IgnoredException:\n            logger.opt(colors=True).info(\n                f\"Matcher {matcher} running is <b>cancelled</b>\")\n            return\n        except Exception as e:\n            logger.opt(colors=True, exception=e).error(\n                \"<r><bg #f8bbd0>Error when running RunPreProcessors. \"\n                \"Running cancelled!</bg #f8bbd0></r>\")\n            return\n\n    exception = None\n\n    try:\n        logger.debug(f\"Running matcher {matcher}\")\n        await matcher.run(bot, event, state)\n    except StopPropagation as e:\n        exception = e\n    except Exception as e:\n        logger.opt(colors=True, exception=e).error(\n            f\"<r><bg #f8bbd0>Running matcher {matcher} failed.</bg #f8bbd0></r>\"\n        )\n        exception = e\n\n    coros = list(\n        map(lambda x: x(matcher, exception, bot, event, state),\n            _run_postprocessors))\n    if coros:\n        try:\n            await asyncio.gather(*coros)\n        except Exception as e:\n            logger.opt(colors=True, exception=e).error(\n                \"<r><bg #f8bbd0>Error when running RunPostProcessors</bg #f8bbd0></r>\"\n            )\n\n    if matcher.block or isinstance(exception, StopPropagation):\n        raise StopPropagation\n\n\nasync def handle_event(bot: Bot, event: Event):\n    \"\"\"\n    :\u8bf4\u660e:\n       \u5904\u7406\u4e00\u4e2a\u4e8b\u4ef6\u3002\u8c03\u7528\u8be5\u51fd\u6570\u4ee5\u5b9e\u73b0\u5206\u53d1\u4e8b\u4ef6\u3002\n    :\u53c2\u6570:\n      * ``bot: Bot``: Bot \u5bf9\u8c61\n      * ``event: Event``: Event \u5bf9\u8c61\n    :\u793a\u4f8b:\n\n    .. code-block:: python\n\n        import asyncio\n        asyncio.create_task(handle_event(bot, event))\n    \"\"\"\n    show_log = True\n    log_msg = f\"<m>{bot.type.upper()} </m>| {event.self_id} [{event.name}]: \"\n    if event.type == \"message\":\n        log_msg += f\"Message {event.id} from \"\n        log_msg += str(event.user_id)\n        if event.detail_type == \"group\":\n            log_msg += f\"@[\u7fa4:{event.group_id}]:\"\n\n        log_msg += ' \"' + \"\".join(\n            map(\n                lambda x: escape_tag(str(x))\n                if x.type == \"text\" else f\"<le>{escape_tag(str(x))}</le>\",\n                event.message)) + '\"'  # type: ignore\n    elif event.type == \"notice\":\n        log_msg += f\"Notice {event.raw_event}\"\n    elif event.type == \"request\":\n        log_msg += f\"Request {event.raw_event}\"\n    elif event.type == \"meta_event\":\n        # log_msg += f\"MetaEvent {event.detail_type}\"\n        show_log = False\n    if show_log:\n        logger.opt(colors=True).info(log_msg)\n\n    state = {}\n    coros = list(map(lambda x: x(bot, event, state), _event_preprocessors))\n    if coros:\n        try:\n            logger.debug(\"Running PreProcessors...\")\n            await asyncio.gather(*coros)\n        except IgnoredException:\n            logger.opt(\n                colors=True).info(f\"Event {event.name} is <b>ignored</b>\")\n            return\n        except Exception as e:\n            logger.opt(colors=True, exception=e).error(\n                \"<r><bg #f8bbd0>Error when running EventPreProcessors. \"\n                \"Event ignored!</bg #f8bbd0></r>\")\n            return\n\n    # Trie Match\n    _, _ = TrieRule.get_value(bot, event, state)\n\n    break_flag = False\n    for priority in sorted(matchers.keys()):\n        if break_flag:\n            break\n\n        if show_log:\n            logger.debug(f\"Checking for matchers in priority {priority}...\")\n\n        run_matchers = await _check_matcher(priority, bot, event, state)\n\n        pending_tasks = [\n            _run_matcher(matcher, bot, event, state.copy())\n            for matcher in run_matchers\n        ]\n\n        results = await asyncio.gather(*pending_tasks, return_exceptions=True)\n\n        for result in results:\n            if isinstance(result, StopPropagation):\n                if not break_flag:\n                    break_flag = True\n                    logger.debug(\"Stop event propagation\")\n\n    coros = list(map(lambda x: x(bot, event, state), _event_postprocessors))\n    if coros:\n        try:\n            logger.debug(\"Running PostProcessors...\")\n            await asyncio.gather(*coros)\n        except Exception as e:\n            logger.opt(colors=True, exception=e).error(\n                \"<r><bg #f8bbd0>Error when running EventPostProcessors</bg #f8bbd0></r>\"\n            )\n", "path": "nonebot/message.py"}], "after_files": [{"content": "\"\"\"\n\u4e8b\u4ef6\u5904\u7406\n========\n\nNoneBot \u5185\u90e8\u5904\u7406\u5e76\u6309\u4f18\u5148\u7ea7\u5206\u53d1\u4e8b\u4ef6\u7ed9\u6240\u6709\u4e8b\u4ef6\u54cd\u5e94\u5668\uff0c\u63d0\u4f9b\u4e86\u591a\u4e2a\u63d2\u69fd\u4ee5\u8fdb\u884c\u4e8b\u4ef6\u7684\u9884\u5904\u7406\u7b49\u3002\n\"\"\"\n\nimport asyncio\nfrom datetime import datetime\n\nfrom nonebot.log import logger\nfrom nonebot.rule import TrieRule\nfrom nonebot.utils import escape_tag\nfrom nonebot.matcher import matchers, Matcher\nfrom nonebot.typing import Set, Type, Union, Optional, Iterable, NoReturn, Bot, Event\nfrom nonebot.exception import IgnoredException, StopPropagation\nfrom nonebot.typing import EventPreProcessor, RunPreProcessor, EventPostProcessor, RunPostProcessor\n\n_event_preprocessors: Set[EventPreProcessor] = set()\n_event_postprocessors: Set[EventPostProcessor] = set()\n_run_preprocessors: Set[RunPreProcessor] = set()\n_run_postprocessors: Set[RunPostProcessor] = set()\n\n\ndef event_preprocessor(func: EventPreProcessor) -> EventPreProcessor:\n    \"\"\"\n    :\u8bf4\u660e:\n      \u4e8b\u4ef6\u9884\u5904\u7406\u3002\u88c5\u9970\u4e00\u4e2a\u51fd\u6570\uff0c\u4f7f\u5b83\u5728\u6bcf\u6b21\u63a5\u6536\u5230\u4e8b\u4ef6\u5e76\u5206\u53d1\u7ed9\u5404\u54cd\u5e94\u5668\u4e4b\u524d\u6267\u884c\u3002\n    :\u53c2\u6570:\n      \u4e8b\u4ef6\u9884\u5904\u7406\u51fd\u6570\u63a5\u6536\u4e09\u4e2a\u53c2\u6570\u3002\n\n      * ``bot: Bot``: Bot \u5bf9\u8c61\n      * ``event: Event``: Event \u5bf9\u8c61\n      * ``state: dict``: \u5f53\u524d State\n    \"\"\"\n    _event_preprocessors.add(func)\n    return func\n\n\ndef event_postprocessor(func: EventPostProcessor) -> EventPostProcessor:\n    \"\"\"\n    :\u8bf4\u660e:\n      \u4e8b\u4ef6\u540e\u5904\u7406\u3002\u88c5\u9970\u4e00\u4e2a\u51fd\u6570\uff0c\u4f7f\u5b83\u5728\u6bcf\u6b21\u63a5\u6536\u5230\u4e8b\u4ef6\u5e76\u5206\u53d1\u7ed9\u5404\u54cd\u5e94\u5668\u4e4b\u540e\u6267\u884c\u3002\n    :\u53c2\u6570:\n      \u4e8b\u4ef6\u540e\u5904\u7406\u51fd\u6570\u63a5\u6536\u4e09\u4e2a\u53c2\u6570\u3002\n\n      * ``bot: Bot``: Bot \u5bf9\u8c61\n      * ``event: Event``: Event \u5bf9\u8c61\n      * ``state: dict``: \u5f53\u524d\u4e8b\u4ef6\u8fd0\u884c\u524d State\n    \"\"\"\n    _event_postprocessors.add(func)\n    return func\n\n\ndef run_preprocessor(func: RunPreProcessor) -> RunPreProcessor:\n    \"\"\"\n    :\u8bf4\u660e:\n      \u8fd0\u884c\u9884\u5904\u7406\u3002\u88c5\u9970\u4e00\u4e2a\u51fd\u6570\uff0c\u4f7f\u5b83\u5728\u6bcf\u6b21\u4e8b\u4ef6\u54cd\u5e94\u5668\u8fd0\u884c\u524d\u6267\u884c\u3002\n    :\u53c2\u6570:\n      \u8fd0\u884c\u9884\u5904\u7406\u51fd\u6570\u63a5\u6536\u56db\u4e2a\u53c2\u6570\u3002\n\n      * ``matcher: Matcher``: \u5f53\u524d\u8981\u8fd0\u884c\u7684\u4e8b\u4ef6\u54cd\u5e94\u5668\n      * ``bot: Bot``: Bot \u5bf9\u8c61\n      * ``event: Event``: Event \u5bf9\u8c61\n      * ``state: dict``: \u5f53\u524d State\n    \"\"\"\n    _run_preprocessors.add(func)\n    return func\n\n\ndef run_postprocessor(func: RunPostProcessor) -> RunPostProcessor:\n    \"\"\"\n    :\u8bf4\u660e:\n      \u8fd0\u884c\u540e\u5904\u7406\u3002\u88c5\u9970\u4e00\u4e2a\u51fd\u6570\uff0c\u4f7f\u5b83\u5728\u6bcf\u6b21\u4e8b\u4ef6\u54cd\u5e94\u5668\u8fd0\u884c\u540e\u6267\u884c\u3002\n    :\u53c2\u6570:\n      \u8fd0\u884c\u540e\u5904\u7406\u51fd\u6570\u63a5\u6536\u4e94\u4e2a\u53c2\u6570\u3002\n\n      * ``matcher: Matcher``: \u8fd0\u884c\u5b8c\u6bd5\u7684\u4e8b\u4ef6\u54cd\u5e94\u5668\n      * ``exception: Optional[Exception]``: \u4e8b\u4ef6\u54cd\u5e94\u5668\u8fd0\u884c\u9519\u8bef\uff08\u5982\u679c\u5b58\u5728\uff09\n      * ``bot: Bot``: Bot \u5bf9\u8c61\n      * ``event: Event``: Event \u5bf9\u8c61\n      * ``state: dict``: \u5f53\u524d State\n    \"\"\"\n    _run_postprocessors.add(func)\n    return func\n\n\nasync def _check_matcher(priority: int, bot: Bot, event: Event,\n                         state: dict) -> Iterable[Type[Matcher]]:\n    current_matchers = matchers[priority].copy()\n\n    async def _check(Matcher: Type[Matcher], bot: Bot, event: Event,\n                     state: dict) -> Optional[Type[Matcher]]:\n        try:\n            if (Matcher.expire_time and datetime.now() <= Matcher.expire_time\n               ) and await Matcher.check_perm(\n                   bot, event) and await Matcher.check_rule(bot, event, state):\n                return Matcher\n        except Exception as e:\n            logger.opt(colors=True, exception=e).error(\n                f\"<r><bg #f8bbd0>Rule check failed for {Matcher}.</bg #f8bbd0></r>\"\n            )\n        return None\n\n    async def _check_expire(Matcher: Type[Matcher]) -> Optional[Type[Matcher]]:\n        if Matcher.temp or (Matcher.expire_time and\n                            datetime.now() > Matcher.expire_time):\n            return Matcher\n        return None\n\n    checking_tasks = [\n        _check(Matcher, bot, event, state) for Matcher in current_matchers\n    ]\n    checking_expire_tasks = [\n        _check_expire(Matcher) for Matcher in current_matchers\n    ]\n    results = await asyncio.gather(*checking_tasks, return_exceptions=True)\n    expired = await asyncio.gather(*checking_expire_tasks)\n    for expired_matcher in filter(lambda x: x and x in results, expired):\n        try:\n            matchers[priority].remove(expired_matcher)\n        except Exception:\n            pass\n    return filter(lambda x: x, results)\n\n\nasync def _run_matcher(Matcher: Type[Matcher], bot: Bot, event: Event,\n                       state: dict) -> Union[None, NoReturn]:\n    logger.info(f\"Event will be handled by {Matcher}\")\n\n    matcher = Matcher()\n\n    coros = list(\n        map(lambda x: x(matcher, bot, event, state), _run_preprocessors))\n    if coros:\n        try:\n            await asyncio.gather(*coros)\n        except IgnoredException:\n            logger.opt(colors=True).info(\n                f\"Matcher {matcher} running is <b>cancelled</b>\")\n            return\n        except Exception as e:\n            logger.opt(colors=True, exception=e).error(\n                \"<r><bg #f8bbd0>Error when running RunPreProcessors. \"\n                \"Running cancelled!</bg #f8bbd0></r>\")\n            return\n\n    exception = None\n\n    try:\n        logger.debug(f\"Running matcher {matcher}\")\n        await matcher.run(bot, event, state)\n    except StopPropagation as e:\n        exception = e\n    except Exception as e:\n        logger.opt(colors=True, exception=e).error(\n            f\"<r><bg #f8bbd0>Running matcher {matcher} failed.</bg #f8bbd0></r>\"\n        )\n        exception = e\n\n    coros = list(\n        map(lambda x: x(matcher, exception, bot, event, state),\n            _run_postprocessors))\n    if coros:\n        try:\n            await asyncio.gather(*coros)\n        except Exception as e:\n            logger.opt(colors=True, exception=e).error(\n                \"<r><bg #f8bbd0>Error when running RunPostProcessors</bg #f8bbd0></r>\"\n            )\n\n    if matcher.block or isinstance(exception, StopPropagation):\n        raise StopPropagation\n\n\nasync def handle_event(bot: Bot, event: Event):\n    \"\"\"\n    :\u8bf4\u660e:\n       \u5904\u7406\u4e00\u4e2a\u4e8b\u4ef6\u3002\u8c03\u7528\u8be5\u51fd\u6570\u4ee5\u5b9e\u73b0\u5206\u53d1\u4e8b\u4ef6\u3002\n    :\u53c2\u6570:\n      * ``bot: Bot``: Bot \u5bf9\u8c61\n      * ``event: Event``: Event \u5bf9\u8c61\n    :\u793a\u4f8b:\n\n    .. code-block:: python\n\n        import asyncio\n        asyncio.create_task(handle_event(bot, event))\n    \"\"\"\n    show_log = True\n    log_msg = f\"<m>{bot.type.upper()} </m>| {event.self_id} [{event.name}]: \"\n    if event.type == \"message\":\n        log_msg += f\"Message {event.id} from \"\n        log_msg += str(event.user_id)\n        if event.detail_type == \"group\":\n            log_msg += f\"@[\u7fa4:{event.group_id}]:\"\n\n        log_msg += ' \"' + \"\".join(\n            map(\n                lambda x: escape_tag(str(x))\n                if x.type == \"text\" else f\"<le>{escape_tag(str(x))}</le>\",\n                event.message)) + '\"'  # type: ignore\n    elif event.type == \"notice\":\n        log_msg += f\"Notice {event.raw_event}\"\n    elif event.type == \"request\":\n        log_msg += f\"Request {event.raw_event}\"\n    elif event.type == \"meta_event\":\n        # log_msg += f\"MetaEvent {event.detail_type}\"\n        show_log = False\n    if show_log:\n        logger.opt(colors=True).info(log_msg)\n\n    state = {}\n    coros = list(map(lambda x: x(bot, event, state), _event_preprocessors))\n    if coros:\n        try:\n            logger.debug(\"Running PreProcessors...\")\n            await asyncio.gather(*coros)\n        except IgnoredException:\n            logger.opt(\n                colors=True).info(f\"Event {event.name} is <b>ignored</b>\")\n            return\n        except Exception as e:\n            logger.opt(colors=True, exception=e).error(\n                \"<r><bg #f8bbd0>Error when running EventPreProcessors. \"\n                \"Event ignored!</bg #f8bbd0></r>\")\n            return\n\n    # Trie Match\n    _, _ = TrieRule.get_value(bot, event, state)\n\n    break_flag = False\n    for priority in sorted(matchers.keys()):\n        if break_flag:\n            break\n\n        if show_log:\n            logger.debug(f\"Checking for matchers in priority {priority}...\")\n\n        run_matchers = await _check_matcher(priority, bot, event, state)\n\n        pending_tasks = [\n            _run_matcher(matcher, bot, event, state.copy())\n            for matcher in run_matchers\n        ]\n\n        results = await asyncio.gather(*pending_tasks, return_exceptions=True)\n\n        for result in results:\n            if isinstance(result, StopPropagation):\n                if not break_flag:\n                    break_flag = True\n                    logger.debug(\"Stop event propagation\")\n\n    coros = list(map(lambda x: x(bot, event, state), _event_postprocessors))\n    if coros:\n        try:\n            logger.debug(\"Running PostProcessors...\")\n            await asyncio.gather(*coros)\n        except Exception as e:\n            logger.opt(colors=True, exception=e).error(\n                \"<r><bg #f8bbd0>Error when running EventPostProcessors</bg #f8bbd0></r>\"\n            )\n", "path": "nonebot/message.py"}]}