robotcode-repl 2.8.0.dev677__py3-none-any.whl → 2.9.0.dev68__py3-none-any.whl
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.
- robotcode/repl/__version__.py +1 -1
- robotcode/repl/base_interpreter.py +7 -1
- robotcode/repl/cli.py +43 -2
- robotcode/repl/console_interpreter.py +21 -2
- robotcode/repl/doc_cli.py +4 -0
- robotcode/repl/prompt_toolkit_interpreter.py +2 -0
- {robotcode_repl-2.8.0.dev677.dist-info → robotcode_repl-2.9.0.dev68.dist-info}/METADATA +2 -2
- {robotcode_repl-2.8.0.dev677.dist-info → robotcode_repl-2.9.0.dev68.dist-info}/RECORD +10 -10
- {robotcode_repl-2.8.0.dev677.dist-info → robotcode_repl-2.9.0.dev68.dist-info}/WHEEL +1 -1
- {robotcode_repl-2.8.0.dev677.dist-info → robotcode_repl-2.9.0.dev68.dist-info}/entry_points.txt +0 -0
robotcode/repl/__version__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "2.
|
|
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.
|
|
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
|
robotcode/repl/cli.py
CHANGED
|
@@ -10,7 +10,7 @@ from robotcode.plugin._agent_detection import is_running_in_ai_agent
|
|
|
10
10
|
from robotcode.plugin.click_helper.aliases import AliasedCommand
|
|
11
11
|
from robotcode.plugin.click_helper.types import add_options
|
|
12
12
|
from robotcode.plugin.click_helper.wrappable import wrappable
|
|
13
|
-
from robotcode.runner.cli.robot import ROBOT_OPTIONS, ROBOT_VERSION_OPTIONS
|
|
13
|
+
from robotcode.runner.cli.robot import ROBOT_OPTIONS, ROBOT_VERSION_OPTIONS, load_robot_profile
|
|
14
14
|
|
|
15
15
|
from .__version__ import __version__
|
|
16
16
|
from ._backends import BACKEND_CHOICES
|
|
@@ -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,
|
|
@@ -456,6 +483,9 @@ def repl(
|
|
|
456
483
|
if files:
|
|
457
484
|
files = tuple(f.absolute() for f in files)
|
|
458
485
|
|
|
486
|
+
# Before the interpreter is created, so that the session runs under the `wrapper`.
|
|
487
|
+
load_robot_profile(app, tuple(str(f) for f in files))
|
|
488
|
+
|
|
459
489
|
# The shell starts with the debugger *detached* — a failing keyword prints
|
|
460
490
|
# its error and you stay at the prompt — unless a pause trigger was given
|
|
461
491
|
# (then attach so `--break …` just works) or `--debugger-attached` forces it.
|
|
@@ -477,6 +507,7 @@ def repl(
|
|
|
477
507
|
inspect=inspect,
|
|
478
508
|
no_history=no_history,
|
|
479
509
|
backend=backend,
|
|
510
|
+
show_prompt=_resolve_show_prompt(show_prompt),
|
|
480
511
|
)
|
|
481
512
|
# Only `repl` fails its session test on unhandled failures — not `robot-debug`,
|
|
482
513
|
# which builds its interpreter the same way.
|
|
@@ -559,6 +590,9 @@ def robot_debug(
|
|
|
559
590
|
Takes the same arguments as `robotcode robot`, but pauses at breakpoints so
|
|
560
591
|
you can inspect and step through the run at a debug prompt.
|
|
561
592
|
"""
|
|
593
|
+
# Before the interpreter and the debugger are created, so that the run runs under the `wrapper`.
|
|
594
|
+
load_robot_profile(app, robot_options_and_args)
|
|
595
|
+
|
|
562
596
|
# Debugging a real run: the debugger is attached by default (the point of the
|
|
563
597
|
# command), breaking on the first uncaught failure unless turned off. Only an
|
|
564
598
|
# explicit `--no-debugger-attached` detaches it (then it runs like `robot`).
|
|
@@ -566,8 +600,15 @@ def robot_debug(
|
|
|
566
600
|
|
|
567
601
|
backend = _resolve_backend(plain, backend)
|
|
568
602
|
|
|
603
|
+
# A run stops at `(rdb) `, which always shows; `robot-debug` has no option for `>>> `.
|
|
569
604
|
interpreter = _pick_interpreter(
|
|
570
|
-
app=app,
|
|
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(),
|
|
571
612
|
)
|
|
572
613
|
controller = _attach_debugger(
|
|
573
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.
|
|
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
|
|
960
|
+
if self.show_prompt:
|
|
942
961
|
prompt = ">>> " if not lines else "... "
|
|
943
962
|
|
|
944
963
|
prefill = compute_indent(lines) if lines else ""
|
robotcode/repl/doc_cli.py
CHANGED
|
@@ -88,6 +88,8 @@ class KeywordEntry:
|
|
|
88
88
|
short_doc: str
|
|
89
89
|
tags: List[str]
|
|
90
90
|
doc: str
|
|
91
|
+
source: str
|
|
92
|
+
lineno: int
|
|
91
93
|
|
|
92
94
|
|
|
93
95
|
@dataclass
|
|
@@ -394,6 +396,8 @@ def _keyword_entries(library: LibraryDoc, page: str, keywords: List[KeywordDoc])
|
|
|
394
396
|
short_doc=_one_line(kw.format_text(getshortdoc(kw.doc))),
|
|
395
397
|
tags=list(kw.tags),
|
|
396
398
|
doc=kw.format_text(kw.doc),
|
|
399
|
+
source=kw.source or "",
|
|
400
|
+
lineno=kw.line_no,
|
|
397
401
|
)
|
|
398
402
|
for kw in keywords
|
|
399
403
|
]
|
|
@@ -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,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: robotcode-repl
|
|
3
|
-
Version: 2.
|
|
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.
|
|
30
|
+
Requires-Dist: robotcode-runner==2.9.0-dev.68
|
|
31
31
|
Description-Content-Type: text/markdown
|
|
32
32
|
|
|
33
33
|
# robotcode-repl
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
robotcode/repl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
robotcode/repl/__version__.py,sha256=
|
|
2
|
+
robotcode/repl/__version__.py,sha256=VKDQl3EnWjlaGGS16iOqZ2LLnLORneHG-g4VFPliDAk,29
|
|
3
3
|
robotcode/repl/_backends.py,sha256=s7PV-HBhnAvwjn2le0cbOJ5hwLb4MjahUo6KWtRC3lc,110
|
|
4
4
|
robotcode/repl/_indent.py,sha256=jwFKaHNvTWYpUwIWHu6JHoaCz7ljOxneR5sBrKcAjpI,3303
|
|
5
5
|
robotcode/repl/_keyword_lookup.py,sha256=c8InMUDGKsw4wYmiqJzBr9GGxPC-59sRZHI0C-GWjFA,7748
|
|
6
6
|
robotcode/repl/_progress.py,sha256=BaSbDGOy5UOXvD855Kd-lDrYbqPrYIWRVs507vJznK4,2586
|
|
7
7
|
robotcode/repl/_session_export.py,sha256=sTSkLEMoSxNQOsII3xfDY8h-nV-mrem-4h6Iug7VQv4,2841
|
|
8
|
-
robotcode/repl/base_interpreter.py,sha256=
|
|
9
|
-
robotcode/repl/cli.py,sha256=
|
|
10
|
-
robotcode/repl/console_interpreter.py,sha256=
|
|
11
|
-
robotcode/repl/doc_cli.py,sha256=
|
|
8
|
+
robotcode/repl/base_interpreter.py,sha256=ep1xqH5QCtkn2U2P77IJQCk_Q5TTBsYOcRjGC5hV5cY,30176
|
|
9
|
+
robotcode/repl/cli.py,sha256=1o8_p0I8bCPsnhI_QoHXWr9U6t9Mj11PrI1E3XG2e1c,23706
|
|
10
|
+
robotcode/repl/console_interpreter.py,sha256=K8GP7nR_L0o7LpV456OZsRFHym7xH5CyK3NkeD9UvHc,88757
|
|
11
|
+
robotcode/repl/doc_cli.py,sha256=lJ1KrS-oxqW32XyRSFiyhSrtKVvzA7TuMclMuZRYIrE,23221
|
|
12
12
|
robotcode/repl/hooks.py,sha256=huqeT18sHWxG2dQNCGmgQUkb11CzVQkOoDgrDAy9hqg,238
|
|
13
|
-
robotcode/repl/prompt_toolkit_interpreter.py,sha256=
|
|
13
|
+
robotcode/repl/prompt_toolkit_interpreter.py,sha256=fq0uRsWucGhjKwGekUShz4r4Vt0nvbeAa-phLvI6WNw,13416
|
|
14
14
|
robotcode/repl/py.typed,sha256=bWew9mHgMy8LqMu7RuqQXFXLBxh2CRx0dUbSx-3wE48,27
|
|
15
15
|
robotcode/repl/run.py,sha256=IWeiGZm56vkLn-hykP-_mWLrdpDciNyMk33_dT-6EJA,5327
|
|
16
16
|
robotcode/repl/Repl/__init__.py,sha256=-j2WxY3MzdLfsMvpa2wMs6WVF_eeJygdshtMN50r67U,43
|
|
@@ -24,7 +24,7 @@ robotcode/repl/_pt/components.py,sha256=kuYVXJc4bFJq4b3-JtAtBYymvS7ssSwlKDldWYFG
|
|
|
24
24
|
robotcode/repl/_pt/doc_viewer.py,sha256=iazNOQEvRygPSUyqKH2qOYShzdYqd7vufZcxPziJx8Q,71648
|
|
25
25
|
robotcode/repl/_pt/history.py,sha256=Rvbdu4LtbYk9dPgYJY7D1JpfyT1SETUdNmtevxo21H4,1591
|
|
26
26
|
robotcode/repl/_pt/lexer.py,sha256=YXtDMWQXPIocwceMXFlvULWyGXCDmqeAtTer_Ecuvwk,13925
|
|
27
|
-
robotcode_repl-2.
|
|
28
|
-
robotcode_repl-2.
|
|
29
|
-
robotcode_repl-2.
|
|
30
|
-
robotcode_repl-2.
|
|
27
|
+
robotcode_repl-2.9.0.dev68.dist-info/METADATA,sha256=LsjjHtQEfaFbqU5N4pG91dDZiUm2BqaGyEJ1mYFrJ24,2833
|
|
28
|
+
robotcode_repl-2.9.0.dev68.dist-info/WHEEL,sha256=2iZrJkDIkeDh0k9SikKMqFuRP-ua6mb4Ir1AsER4BEw,87
|
|
29
|
+
robotcode_repl-2.9.0.dev68.dist-info/entry_points.txt,sha256=lI4idVOEmSWxmmioejg-_QvHXTLySK6ZxJ13R_v8ykU,40
|
|
30
|
+
robotcode_repl-2.9.0.dev68.dist-info/RECORD,,
|
{robotcode_repl-2.8.0.dev677.dist-info → robotcode_repl-2.9.0.dev68.dist-info}/entry_points.txt
RENAMED
|
File without changes
|