22
33import asyncio
44from concurrent .futures import ProcessPoolExecutor
5- from contextlib import AbstractAsyncContextManager , asynccontextmanager
5+ from contextlib import asynccontextmanager
66from pathlib import Path
77from typing import TYPE_CHECKING
88
99import watchfiles
1010from starlette .websockets import WebSocket
1111
1212if TYPE_CHECKING :
13- import os
14- from collections .abc import Callable , Sequence
13+ from collections .abc import AsyncGenerator , Sequence
14+ from os import PathLike
15+ from typing import Protocol
1516
1617 from starlette .types import Receive , Scope , Send
1718
1819 from sphinx_autobuild .filter import IgnoreFilter
1920
21+ class ChangeCallback (Protocol ):
22+ def __call__ (self , * , changed_paths : Sequence [Path ]) -> None : ...
23+
2024
2125class RebuildServer :
2226 def __init__ (
2327 self ,
24- paths : list [os . PathLike [str ]],
28+ paths : list [PathLike [str ]],
2529 ignore_filter : IgnoreFilter ,
26- change_callback : Callable [[ Sequence [ Path ]], None ] ,
30+ change_callback : ChangeCallback ,
2731 ) -> None :
2832 self .paths = [Path (path ).resolve (strict = True ) for path in paths ]
2933 self .ignore = ignore_filter
@@ -32,7 +36,7 @@ def __init__(
3236 self .should_exit = asyncio .Event ()
3337
3438 @asynccontextmanager
35- async def lifespan (self , _app ) -> AbstractAsyncContextManager [None ]:
39+ async def lifespan (self , _app ) -> AsyncGenerator [None ]:
3640 task = asyncio .create_task (self .main ())
3741 yield
3842 self .should_exit .set ()
0 commit comments