@@ -197,6 +197,13 @@ class EngineTerminatedError(EngineError):
197197 """The engine process exited unexpectedly."""
198198
199199
200+ class AnalysisComplete (Exception ):
201+ """
202+ Raised when analysis is complete, all information has been consumed, but
203+ further information was requested.
204+ """
205+
206+
200207ConfigValue = Union [str , int , bool , None ]
201208ConfigMapping = Mapping [str , ConfigValue ]
202209
@@ -2081,32 +2088,43 @@ async def wait(self) -> None:
20812088 """Waits until the analysis is complete (or stopped)."""
20822089 await self ._finished
20832090
2084- def __aiter__ (self ) -> "AnalysisResult" :
2085- return self
2086-
2087- async def next (self ) -> Optional [InfoDict ]:
2091+ async def get (self ) -> Optional [InfoDict ]:
20882092 """
20892093 Waits for the next dictionary of information from the engine and
2090- returns it. Returns ``None`` if the analysis has been stopped and
2091- all information has been consumed.
2094+ returns it.
20922095
20932096 It might be more convenient to use ``async for info in analysis: ...``.
2094- """
2095- async for info in self :
2096- return info
2097- return None
20982097
2099- async def __anext__ (self ) -> InfoDict :
2098+ :raises: :exc:`chess.engine.AnalysisComplete` if the analysis is
2099+ complete (or has been stopped) and all information has been
2100+ consumed. Use :func:`~chess.engine.AnalysisResult.next()` if you
2101+ prefer to get ``None`` instead of an exception.
2102+ """
21002103 if self ._seen_kork :
2101- raise StopAsyncIteration
2104+ raise AnalysisComplete ()
21022105
21032106 info = await self ._queue .get ()
21042107 if info is KORK :
21052108 self ._seen_kork = True
21062109 await self ._finished
2107- raise StopAsyncIteration
2110+ raise AnalysisComplete ()
21082111
2109- return typing .cast (InfoDict , info )
2112+ return info
2113+
2114+ async def next (self ) -> Optional [InfoDict ]:
2115+ try :
2116+ return await self .get ()
2117+ except AnalysisComplete :
2118+ return None
2119+
2120+ def __aiter__ (self ) -> "AnalysisResult" :
2121+ return self
2122+
2123+ async def __anext__ (self ) -> InfoDict :
2124+ try :
2125+ return await self .get ()
2126+ except AnalysisComplete :
2127+ raise StopAsyncIteration
21102128
21112129 def __enter__ (self ) -> "AnalysisResult" :
21122130 return self
@@ -2364,6 +2382,11 @@ def wait(self) -> None:
23642382 future = asyncio .run_coroutine_threadsafe (self .inner .wait (), self .simple_engine .protocol .loop )
23652383 return future .result ()
23662384
2385+ def get (self ) -> Optional [InfoDict ]:
2386+ with self .simple_engine ._not_shut_down ():
2387+ future = asyncio .run_coroutine_threadsafe (self .inner .get (), self .simple_engine .protocol .loop )
2388+ return future .result ()
2389+
23672390 def next (self ) -> Optional [InfoDict ]:
23682391 with self .simple_engine ._not_shut_down ():
23692392 future = asyncio .run_coroutine_threadsafe (self .inner .next (), self .simple_engine .protocol .loop )
0 commit comments