Skip to content

Commit

Permalink
Add AnalysisResult.would_block() (fixes #889)
Browse files Browse the repository at this point in the history
  • Loading branch information
niklasf committed Jun 8, 2022
1 parent 34d74f9 commit 7c44637
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 0 deletions.
21 changes: 21 additions & 0 deletions chess/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -2601,6 +2601,19 @@ async def get(self) -> InfoDict:

return info

def would_block(self) -> bool:
"""
Checks if calling :func:`~chess.engine.AnalysisResult.get()`,
calling :func:`~chess.engine.AnalysisResult.next()`,
calling :func:`~chess.engine.AnalysisResult.wait()`, or advancing the
iterator one step would require waiting for the engine.
All of these functions would return immediately information is pending
(queue is not :func:`empty <chess.engine.AnalysisResult.empty()>`)
or if the search is finished.
"""
return not self._seen_kork and self._queue.empty()

def empty(self) -> bool:
"""
Checks if all information has been consumed.
Expand Down Expand Up @@ -2891,6 +2904,14 @@ def wait(self) -> BestMove:
future = asyncio.run_coroutine_threadsafe(self.inner.wait(), self.simple_engine.protocol.loop)
return future.result()

def would_block(self) -> bool:
async def _would_block() -> bool:
return self.inner.would_block()

with self.simple_engine._not_shut_down():
future = asyncio.run_coroutine_threadsafe(_would_block(), self.simple_engine.protocol.loop)
return future.result()

def empty(self) -> bool:
async def _empty() -> bool:
return self.inner.empty()
Expand Down
6 changes: 6 additions & 0 deletions test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2986,7 +2986,10 @@ def test_sf_analysis(self):
for info in analysis:
if "score" in info and info["score"].white() >= chess.engine.Mate(+2):
break

analysis.wait()
self.assertFalse(analysis.would_block())

self.assertEqual(analysis.info["score"].relative, chess.engine.Mate(+2))
self.assertEqual(analysis.multipv[0]["score"].black(), chess.engine.Mate(-2))

Expand All @@ -2997,6 +3000,7 @@ def test_sf_analysis(self):
was_really_empty = False
self.assertEqual(was_really_empty, was_empty)
self.assertTrue(analysis.empty())
self.assertFalse(analysis.would_block())
for info in analysis:
self.fail("all info should have been consumed")

Expand Down Expand Up @@ -3174,8 +3178,10 @@ async def main():
mock.expect("go infinite")
mock.expect("stop", ["bestmove e2e4"])
result = await protocol.analysis(chess.Board())
self.assertTrue(result.would_block())
result.stop()
best = await result.wait()
self.assertFalse(result.would_block())
self.assertEqual(best.move, chess.Move.from_uci("e2e4"))
self.assertTrue(best.ponder is None)
mock.assert_done()
Expand Down

0 comments on commit 7c44637

Please sign in to comment.