Skip to content

Commit 494166e

Browse files
committed
calling keywords in debugger now runs in main thread, fixes #83
1 parent 39c575d commit 494166e

File tree

1 file changed

+52
-16
lines changed

1 file changed

+52
-16
lines changed

robotcode/debugger/debugger.py

Lines changed: 52 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from pathlib import Path, PurePath
1212
from typing import (
1313
Any,
14+
Callable,
1415
Deque,
1516
Dict,
1617
Generator,
@@ -223,8 +224,6 @@ def __new__(cls, *args: Any, **kwargs: Any) -> Any:
223224
raise RuntimeError(f"Attempt to create a '{cls.__qualname__}' instance outside of instance()")
224225

225226
def __init__(self) -> None:
226-
from robot.running.model import Keyword
227-
228227
self.breakpoints: Dict[pathlib.PurePath, BreakpointsEntry] = {}
229228

230229
self.exception_breakpoints: Set[ExceptionBreakpointsEntry] = set()
@@ -254,10 +253,12 @@ def __init__(self) -> None:
254253
self.attached = False
255254
self.path_mappings: List[PathMapping] = []
256255

257-
self.run_keyword: Optional[Keyword] = None
258-
self.run_keyword_event = threading.Event()
259-
self.run_keyword_event.set()
260-
self.after_run_keyword_event_state: Optional[State] = None
256+
self._keyword_to_evaluate: Optional[Callable[..., Any]] = None
257+
self._evaluated_keyword_result: Any = None
258+
self._evaluate_keyword_event = threading.Event()
259+
self._evaluate_keyword_event.set()
260+
self._after_evaluate_keyword_event = threading.Event()
261+
self._after_evaluate_keyword_event.set()
261262

262263
@property
263264
def debug(self) -> bool:
@@ -604,13 +605,26 @@ def process_end_state(self, status: str, filter_id: Set[str], description: str,
604605
@_logger.call
605606
def wait_for_running(self) -> None:
606607
if self.attached:
607-
with self.condition:
608-
while True:
608+
while True:
609+
with self.condition:
609610
self.condition.wait_for(lambda: self.state in [State.Running, State.Stopped, State.CallKeyword])
610611

611-
if self.state == State.CallKeyword:
612-
continue
613-
break
612+
if self.state == State.CallKeyword:
613+
self._evaluated_keyword_result = None
614+
try:
615+
if self._keyword_to_evaluate is not None:
616+
self._evaluated_keyword_result = self._keyword_to_evaluate()
617+
self._keyword_to_evaluate = None
618+
except (SystemExit, KeyboardInterrupt):
619+
raise
620+
except BaseException as e:
621+
self._evaluated_keyword_result = e
622+
finally:
623+
self._evaluate_keyword_event.set()
624+
self._after_evaluate_keyword_event.wait(60)
625+
626+
continue
627+
break
614628

615629
def start_output_group(self, name: str, attributes: Dict[str, Any], type: Optional[str] = None) -> None:
616630
if self.group_output:
@@ -1225,13 +1239,35 @@ def evaluate(
12251239
variables.append(var)
12261240

12271241
if splitted:
1228-
kw = Keyword(name=splitted[0], args=tuple(splitted[1:]), assign=tuple(variables))
1229-
old_state = self.state
1230-
self.state = State.CallKeyword
12311242

1232-
result = kw.run(evaluate_context)
1243+
def run_kw() -> Any:
1244+
kw = Keyword(name=splitted[0], args=tuple(splitted[1:]), assign=tuple(variables))
1245+
return kw.run(evaluate_context)
1246+
1247+
with self.condition:
1248+
self._keyword_to_evaluate = run_kw
1249+
self._evaluated_keyword_result = None
1250+
1251+
self._evaluate_keyword_event.clear()
1252+
self._after_evaluate_keyword_event.clear()
1253+
1254+
old_state = self.state
1255+
self.state = State.CallKeyword
1256+
self.condition.notify_all()
1257+
1258+
try:
1259+
self._evaluate_keyword_event.wait(60)
1260+
finally:
1261+
result = self._evaluated_keyword_result
1262+
1263+
with self.condition:
1264+
self._keyword_to_evaluate = None
1265+
self._evaluated_keyword_result = None
1266+
1267+
self.state = old_state
1268+
self.condition.notify_all()
12331269

1234-
self.state = old_state
1270+
self._after_evaluate_keyword_event.set()
12351271

12361272
elif self.IS_VARIABLE_RE.match(expression.strip()):
12371273
try:

0 commit comments

Comments
 (0)