robotcode-repl 2.9.0.dev51__tar.gz → 2.9.0.dev68__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. {robotcode_repl-2.9.0.dev51 → robotcode_repl-2.9.0.dev68}/PKG-INFO +2 -2
  2. {robotcode_repl-2.9.0.dev51 → robotcode_repl-2.9.0.dev68}/pyproject.toml +1 -1
  3. robotcode_repl-2.9.0.dev68/src/robotcode/repl/__version__.py +1 -0
  4. {robotcode_repl-2.9.0.dev51 → robotcode_repl-2.9.0.dev68}/src/robotcode/repl/base_interpreter.py +7 -1
  5. {robotcode_repl-2.9.0.dev51 → robotcode_repl-2.9.0.dev68}/src/robotcode/repl/cli.py +36 -1
  6. {robotcode_repl-2.9.0.dev51 → robotcode_repl-2.9.0.dev68}/src/robotcode/repl/console_interpreter.py +21 -2
  7. {robotcode_repl-2.9.0.dev51 → robotcode_repl-2.9.0.dev68}/src/robotcode/repl/prompt_toolkit_interpreter.py +2 -0
  8. robotcode_repl-2.9.0.dev51/src/robotcode/repl/__version__.py +0 -1
  9. {robotcode_repl-2.9.0.dev51 → robotcode_repl-2.9.0.dev68}/.gitignore +0 -0
  10. {robotcode_repl-2.9.0.dev51 → robotcode_repl-2.9.0.dev68}/README.md +0 -0
  11. {robotcode_repl-2.9.0.dev51 → robotcode_repl-2.9.0.dev68}/src/robotcode/repl/Repl/__init__.py +0 -0
  12. {robotcode_repl-2.9.0.dev51 → robotcode_repl-2.9.0.dev68}/src/robotcode/repl/Repl/repl.py +0 -0
  13. {robotcode_repl-2.9.0.dev51 → robotcode_repl-2.9.0.dev68}/src/robotcode/repl/__init__.py +0 -0
  14. {robotcode_repl-2.9.0.dev51 → robotcode_repl-2.9.0.dev68}/src/robotcode/repl/_backends.py +0 -0
  15. {robotcode_repl-2.9.0.dev51 → robotcode_repl-2.9.0.dev68}/src/robotcode/repl/_debug/__init__.py +0 -0
  16. {robotcode_repl-2.9.0.dev51 → robotcode_repl-2.9.0.dev68}/src/robotcode/repl/_debug/controller.py +0 -0
  17. {robotcode_repl-2.9.0.dev51 → robotcode_repl-2.9.0.dev68}/src/robotcode/repl/_debug/types.py +0 -0
  18. {robotcode_repl-2.9.0.dev51 → robotcode_repl-2.9.0.dev68}/src/robotcode/repl/_indent.py +0 -0
  19. {robotcode_repl-2.9.0.dev51 → robotcode_repl-2.9.0.dev68}/src/robotcode/repl/_keyword_lookup.py +0 -0
  20. {robotcode_repl-2.9.0.dev51 → robotcode_repl-2.9.0.dev68}/src/robotcode/repl/_progress.py +0 -0
  21. {robotcode_repl-2.9.0.dev51 → robotcode_repl-2.9.0.dev68}/src/robotcode/repl/_pt/__init__.py +0 -0
  22. {robotcode_repl-2.9.0.dev51 → robotcode_repl-2.9.0.dev68}/src/robotcode/repl/_pt/completion.py +0 -0
  23. {robotcode_repl-2.9.0.dev51 → robotcode_repl-2.9.0.dev68}/src/robotcode/repl/_pt/components.py +0 -0
  24. {robotcode_repl-2.9.0.dev51 → robotcode_repl-2.9.0.dev68}/src/robotcode/repl/_pt/doc_viewer.py +0 -0
  25. {robotcode_repl-2.9.0.dev51 → robotcode_repl-2.9.0.dev68}/src/robotcode/repl/_pt/history.py +0 -0
  26. {robotcode_repl-2.9.0.dev51 → robotcode_repl-2.9.0.dev68}/src/robotcode/repl/_pt/lexer.py +0 -0
  27. {robotcode_repl-2.9.0.dev51 → robotcode_repl-2.9.0.dev68}/src/robotcode/repl/_session_export.py +0 -0
  28. {robotcode_repl-2.9.0.dev51 → robotcode_repl-2.9.0.dev68}/src/robotcode/repl/doc_cli.py +0 -0
  29. {robotcode_repl-2.9.0.dev51 → robotcode_repl-2.9.0.dev68}/src/robotcode/repl/hooks.py +0 -0
  30. {robotcode_repl-2.9.0.dev51 → robotcode_repl-2.9.0.dev68}/src/robotcode/repl/py.typed +0 -0
  31. {robotcode_repl-2.9.0.dev51 → robotcode_repl-2.9.0.dev68}/src/robotcode/repl/run.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: robotcode-repl
3
- Version: 2.9.0-dev.51
3
+ Version: 2.9.0-dev.68
4
4
  Summary: RobotCode REPL for Robot Framework
5
5
  Project-URL: Homepage, https://robotcode.io
6
6
  Project-URL: Donate, https://opencollective.com/robotcode
@@ -27,7 +27,7 @@ Classifier: Topic :: Utilities
27
27
  Classifier: Typing :: Typed
28
28
  Requires-Python: >=3.10
29
29
  Requires-Dist: prompt-toolkit!=3.0.52
30
- Requires-Dist: robotcode-runner==2.9.0-dev.51
30
+ Requires-Dist: robotcode-runner==2.9.0-dev.68
31
31
  Description-Content-Type: text/markdown
32
32
 
33
33
  # robotcode-repl
@@ -29,7 +29,7 @@ classifiers = [
29
29
  ]
30
30
  dynamic = ["version"]
31
31
  dependencies = [
32
- "robotcode-runner==2.9.0-dev.51",
32
+ "robotcode-runner==2.9.0-dev.68",
33
33
  "prompt_toolkit!=3.0.52"
34
34
  ]
35
35
 
@@ -0,0 +1 @@
1
+ __version__ = "2.9.0-dev.68"
@@ -597,13 +597,19 @@ class BaseInterpreter(abc.ABC):
597
597
  # Checked after marking the statement: a SIGTERM in between can't be missed.
598
598
  if kw is None or self._termination_requested:
599
599
  break
600
- self.set_last_result(self.run_keyword(kw))
600
+ result = self.run_keyword(kw)
601
+ self.set_last_result(result)
602
+ self.show_result(kw, result)
601
603
  finally:
602
604
  self._running_statement = False
603
605
 
604
606
  def set_last_result(self, result: Any) -> None:
605
607
  self.last_result = result
606
608
 
609
+ def show_result(self, statement: Keyword, result: Any) -> None:
610
+ """Show the result of a statement of the input after it has run. Each interpreter knows how;
611
+ the REPL server returns results through its protocol."""
612
+
607
613
  @abc.abstractmethod
608
614
  def log_message(
609
615
  self, message: str, level: str, html: Union[str, bool] = False, timestamp: Union[datetime, str, None] = None
@@ -28,6 +28,7 @@ def _pick_interpreter(
28
28
  inspect: bool,
29
29
  no_history: bool,
30
30
  backend: str,
31
+ show_prompt: bool,
31
32
  ) -> ConsoleInterpreter:
32
33
  """Construct the interpreter that matches ``backend``.
33
34
 
@@ -43,6 +44,7 @@ def _pick_interpreter(
43
44
  show_keywords=show_keywords,
44
45
  inspect=inspect,
45
46
  no_history=no_history,
47
+ show_prompt=show_prompt,
46
48
  )
47
49
  if backend not in ("auto", "prompt-toolkit"):
48
50
  raise ValueError(f"Unknown backend: {backend!r}. Choose from {BACKEND_CHOICES}.")
@@ -52,6 +54,7 @@ def _pick_interpreter(
52
54
  show_keywords=show_keywords,
53
55
  inspect=inspect,
54
56
  no_history=no_history,
57
+ show_prompt=show_prompt,
55
58
  )
56
59
 
57
60
 
@@ -153,6 +156,20 @@ def _resolve_backend(plain: bool, backend: str) -> str:
153
156
  return backend
154
157
 
155
158
 
159
+ def _resolve_show_prompt(show_prompt: Optional[bool]) -> bool:
160
+ """Whether `repl` shows its `>>> ` / `... ` prompt.
161
+
162
+ Always on an interactive terminal. Otherwise `--show-prompt` / `--no-show-prompt`
163
+ (or `ROBOTCODE_REPL_SHOW_PROMPT`) decides, and without either a recognised AI
164
+ agent gets the prompt: it marks where the output of a statement ends.
165
+ """
166
+ if _is_interactive_stdin():
167
+ return True
168
+ if show_prompt is not None:
169
+ return show_prompt
170
+ return is_running_in_ai_agent()
171
+
172
+
156
173
  def _resolve_attached(
157
174
  debugger_attached: Optional[bool],
158
175
  *,
@@ -302,6 +319,15 @@ SHELL_OPTIONS = [
302
319
  default=False,
303
320
  help="Activate inspection mode. This forces a prompt to appear after the REPL script is executed.",
304
321
  ),
322
+ click.option(
323
+ "--show-prompt/--no-show-prompt",
324
+ default=None,
325
+ envvar="ROBOTCODE_REPL_SHOW_PROMPT",
326
+ help="Show (`--show-prompt`) or hide (`--no-show-prompt`) the `>>>` prompt when the input is not a "
327
+ "terminal, such as piped input. Without either option it shows there only in the session of a "
328
+ "recognised AI agent, where it marks the end of each statement's output. On a terminal the prompt "
329
+ "always shows.",
330
+ ),
305
331
  click.option(
306
332
  "-d",
307
333
  "--outputdir",
@@ -430,6 +456,7 @@ def repl(
430
456
  pythonpath: Tuple[str, ...],
431
457
  show_keywords: bool,
432
458
  inspect: bool,
459
+ show_prompt: Optional[bool],
433
460
  no_history: bool,
434
461
  backend: str,
435
462
  plain: bool,
@@ -480,6 +507,7 @@ def repl(
480
507
  inspect=inspect,
481
508
  no_history=no_history,
482
509
  backend=backend,
510
+ show_prompt=_resolve_show_prompt(show_prompt),
483
511
  )
484
512
  # Only `repl` fails its session test on unhandled failures — not `robot-debug`,
485
513
  # which builds its interpreter the same way.
@@ -572,8 +600,15 @@ def robot_debug(
572
600
 
573
601
  backend = _resolve_backend(plain, backend)
574
602
 
603
+ # A run stops at `(rdb) `, which always shows; `robot-debug` has no option for `>>> `.
575
604
  interpreter = _pick_interpreter(
576
- app=app, files=[], show_keywords=False, inspect=False, no_history=no_history, backend=backend
605
+ app=app,
606
+ files=[],
607
+ show_keywords=False,
608
+ inspect=False,
609
+ no_history=no_history,
610
+ backend=backend,
611
+ show_prompt=_is_interactive_stdin(),
577
612
  )
578
613
  controller = _attach_debugger(
579
614
  interpreter,
@@ -348,6 +348,7 @@ class ConsoleInterpreter(BaseInterpreter):
348
348
  show_keywords: bool = False,
349
349
  inspect: Optional[bool] = False,
350
350
  no_history: bool = False,
351
+ show_prompt: bool = False,
351
352
  ) -> None:
352
353
  del no_history # plain mode has no history file to honour the flag against
353
354
  super().__init__()
@@ -356,6 +357,8 @@ class ConsoleInterpreter(BaseInterpreter):
356
357
  self.files = files
357
358
  self.show_keywords = show_keywords
358
359
  self.inspect = inspect
360
+ # Whether `>>> ` and `... ` show; `robotcode repl` decides it (`_resolve_show_prompt`).
361
+ self.show_prompt = show_prompt
359
362
 
360
363
  self.executed_files: List[Path] = []
361
364
  # REPL inputs that parsed cleanly — `.save` exports them as a
@@ -368,6 +371,8 @@ class ConsoleInterpreter(BaseInterpreter):
368
371
  # runs, then the session ends without reading again — on a terminal, a
369
372
  # read after Ctrl-D waits for more input instead of ending.
370
373
  self._input_ended = False
374
+ # Set while the statements of a script file run: like the body of a test, they show no results.
375
+ self._input_from_file = False
371
376
  # Set while a prompt waits for input: SIGTERM then ends the wait (`_end_waiting`).
372
377
  self._reading = False
373
378
 
@@ -868,7 +873,7 @@ class ConsoleInterpreter(BaseInterpreter):
868
873
  self.set_last_result(self.run_keyword(kw))
869
874
  finally:
870
875
  self.record_failures = record_failures
871
- self._echo(f"=> {_repr.repr(self.last_result)}")
876
+ self._echo_result(test.body[-1], self.last_result)
872
877
 
873
878
  # ------------------------------------------------------------------
874
879
  # Robot integration
@@ -892,6 +897,18 @@ class ConsoleInterpreter(BaseInterpreter):
892
897
  # than crash the REPL.
893
898
  pass
894
899
 
900
+ def show_result(self, statement: Keyword, result: Any) -> None:
901
+ if not self._input_from_file:
902
+ self._echo_result(statement, result)
903
+
904
+ def _echo_result(self, statement: Any, result: Any) -> None:
905
+ """Print the result of `statement` as `=> <value>`, at the `>>>` and the `(rdb)` prompt alike.
906
+ `None` shows nothing, and neither does an assignment: the message that sets the variable
907
+ names the value."""
908
+ if result is None or getattr(statement, "assign", None):
909
+ return
910
+ self._echo(f"=> {_repr.repr(result)}")
911
+
895
912
  def _alias_setting_imports(self, test: "running.TestCase") -> None:
896
913
  """REPL-only: rewrite top-level ``Library`` / ``Resource`` / ``Variables``
897
914
  keyword calls into the BuiltIn ``Import …`` keywords.
@@ -929,8 +946,10 @@ class ConsoleInterpreter(BaseInterpreter):
929
946
  text = file.read_text(encoding="utf-8")
930
947
 
931
948
  # Run like a test body: an invalid statement fails when execution reaches it.
949
+ self._input_from_file = True
932
950
  yield from self._body_to_run(self.parse_input(text))
933
951
  else:
952
+ self._input_from_file = False
934
953
  if self._input_ended:
935
954
  raise EOFError
936
955
 
@@ -938,7 +957,7 @@ class ConsoleInterpreter(BaseInterpreter):
938
957
  last_one = False
939
958
  while True:
940
959
  prompt = ""
941
- if sys.stdin.isatty():
960
+ if self.show_prompt:
942
961
  prompt = ">>> " if not lines else "... "
943
962
 
944
963
  prefill = compute_indent(lines) if lines else ""
@@ -67,6 +67,7 @@ class PromptToolkitConsoleInterpreter(ConsoleInterpreter):
67
67
  show_keywords: bool = False,
68
68
  inspect: Optional[bool] = False,
69
69
  no_history: bool = False,
70
+ show_prompt: bool = False,
70
71
  ) -> None:
71
72
  super().__init__(
72
73
  app=app,
@@ -74,6 +75,7 @@ class PromptToolkitConsoleInterpreter(ConsoleInterpreter):
74
75
  show_keywords=show_keywords,
75
76
  inspect=inspect,
76
77
  no_history=no_history,
78
+ show_prompt=show_prompt,
77
79
  )
78
80
 
79
81
  self._history_store: History
@@ -1 +0,0 @@
1
- __version__ = "2.9.0-dev.51"