robotcode-repl 2.6.2__py3-none-any.whl → 2.8.0.dev548__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/Repl/repl.py +10 -1
- robotcode/repl/__version__.py +1 -1
- robotcode/repl/_debug/controller.py +47 -5
- robotcode/repl/_debug/types.py +6 -3
- robotcode/repl/_indent.py +8 -1
- robotcode/repl/_pt/components.py +2 -1
- robotcode/repl/_pt/doc_viewer.py +457 -84
- robotcode/repl/_pt/lexer.py +4 -1
- robotcode/repl/base_interpreter.py +281 -13
- robotcode/repl/cli.py +70 -13
- robotcode/repl/console_interpreter.py +356 -111
- robotcode/repl/doc_cli.py +651 -0
- robotcode/repl/hooks.py +2 -1
- robotcode/repl/prompt_toolkit_interpreter.py +35 -2
- robotcode/repl/run.py +51 -8
- {robotcode_repl-2.6.2.dist-info → robotcode_repl-2.8.0.dev548.dist-info}/METADATA +4 -3
- robotcode_repl-2.8.0.dev548.dist-info/RECORD +30 -0
- {robotcode_repl-2.6.2.dist-info → robotcode_repl-2.8.0.dev548.dist-info}/WHEEL +1 -1
- robotcode_repl-2.6.2.dist-info/RECORD +0 -29
- {robotcode_repl-2.6.2.dist-info → robotcode_repl-2.8.0.dev548.dist-info}/entry_points.txt +0 -0
|
@@ -28,6 +28,7 @@ from prompt_toolkit.history import History, InMemoryHistory
|
|
|
28
28
|
from robot import result, running
|
|
29
29
|
|
|
30
30
|
from robotcode.plugin import Application
|
|
31
|
+
from robotcode.robot.utils.markdown_docs import REFERENCE_KEYWORD, LinkResolver
|
|
31
32
|
|
|
32
33
|
from ._pt.components import (
|
|
33
34
|
_DEFAULT_STYLE,
|
|
@@ -121,12 +122,32 @@ class PromptToolkitConsoleInterpreter(ConsoleInterpreter):
|
|
|
121
122
|
return self._session.prompt(prompt, default=prefill, completer=completer)
|
|
122
123
|
return self._session.prompt(prompt, default=prefill)
|
|
123
124
|
|
|
125
|
+
def _end_read(self) -> None:
|
|
126
|
+
loop = self._session.app.loop
|
|
127
|
+
if loop is None:
|
|
128
|
+
# No event loop runs the prompt (yet, or any more).
|
|
129
|
+
super()._end_read()
|
|
130
|
+
return
|
|
131
|
+
# The signal handler can run inside a callback of the prompt's event loop, which
|
|
132
|
+
# would only report an error raised there; so the prompt ends through the loop.
|
|
133
|
+
loop.call_soon_threadsafe(self._end_prompt)
|
|
134
|
+
|
|
135
|
+
def _end_prompt(self) -> None:
|
|
136
|
+
app = self._session.app
|
|
137
|
+
if app.future is not None and not app.future.done():
|
|
138
|
+
app.exit(exception=EOFError())
|
|
139
|
+
|
|
140
|
+
def _report_interrupt(self, prompt: str) -> None:
|
|
141
|
+
# An aborted prompt has already ended its line.
|
|
142
|
+
del prompt
|
|
143
|
+
self._echo("KeyboardInterrupt")
|
|
144
|
+
|
|
124
145
|
def make_completer(
|
|
125
146
|
self, command_names: List[str], context_provider: Callable[[], Tuple[Any, Any]]
|
|
126
147
|
) -> Optional[Any]:
|
|
127
148
|
return _RobotCompleter(command_names=command_names, context_provider=context_provider)
|
|
128
149
|
|
|
129
|
-
def show_doc(self, title: str, markdown: str, *, scroll_to: Optional[str] = None) -> None:
|
|
150
|
+
def show_doc(self, title: str, markdown: str, *, scroll_to: Optional[str] = None, outline: bool = False) -> None:
|
|
130
151
|
"""Display ``markdown`` in the fullscreen doc viewer.
|
|
131
152
|
|
|
132
153
|
Blocks until the user closes the viewer (Esc / q / Enter). The
|
|
@@ -135,8 +156,9 @@ class PromptToolkitConsoleInterpreter(ConsoleInterpreter):
|
|
|
135
156
|
untouched. Safe to call from inside a dot-command handler that
|
|
136
157
|
runs between two `read_line` invocations. ``scroll_to`` opens the
|
|
137
158
|
viewer scrolled to the first rendered line containing that text.
|
|
159
|
+
``outline`` gives the page of a library a sidebar with its headings.
|
|
138
160
|
"""
|
|
139
|
-
self._doc_viewer.run(title, markdown, scroll_to=scroll_to)
|
|
161
|
+
self._doc_viewer.run(title, markdown, scroll_to=scroll_to, outline=outline)
|
|
140
162
|
|
|
141
163
|
def _keyword_list_entry(self, owner_name: str, kw_name: str) -> str:
|
|
142
164
|
"""Render a `.kw` list entry as a link into the keyword's page.
|
|
@@ -148,6 +170,17 @@ class PromptToolkitConsoleInterpreter(ConsoleInterpreter):
|
|
|
148
170
|
"""
|
|
149
171
|
return f"- [{kw_name}](kw:{quote(f'{owner_name}.{kw_name}')})"
|
|
150
172
|
|
|
173
|
+
def _keyword_link_resolver(self, owner_name: str) -> Optional[LinkResolver]:
|
|
174
|
+
"""References to other keywords of the same owner open that
|
|
175
|
+
keyword's page, like the entries of the `.kw` list."""
|
|
176
|
+
|
|
177
|
+
def resolve(kind: str, name: str) -> Optional[str]:
|
|
178
|
+
if kind == REFERENCE_KEYWORD:
|
|
179
|
+
return f"kw:{quote(f'{owner_name}.{name}')}"
|
|
180
|
+
return None
|
|
181
|
+
|
|
182
|
+
return resolve
|
|
183
|
+
|
|
151
184
|
def _resolve_doc_link(self, target: str) -> Optional[Tuple[str, str]]:
|
|
152
185
|
"""Resolve a `kw:<owner.keyword>` doc-viewer link to a keyword
|
|
153
186
|
page; returns ``None`` for any other target so the viewer falls
|
robotcode/repl/run.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import io
|
|
2
2
|
import sys
|
|
3
|
+
from dataclasses import dataclass
|
|
3
4
|
from pathlib import Path
|
|
4
5
|
from typing import Optional, Tuple
|
|
5
6
|
|
|
@@ -25,6 +26,36 @@ RobotCode REPL
|
|
|
25
26
|
repl
|
|
26
27
|
"""
|
|
27
28
|
|
|
29
|
+
# Options from robot.toml, `args`, argument files or ROBOT_OPTIONS that are meant for real
|
|
30
|
+
# suites. Applied to REPL_SUITE they deselect or skip its only test, so the REPL never
|
|
31
|
+
# starts, or turn the session into a dry run in which nothing typed is executed. The
|
|
32
|
+
# other skip options are dropped along with them.
|
|
33
|
+
_IGNORED_ROBOT_OPTIONS = (
|
|
34
|
+
"include",
|
|
35
|
+
"exclude",
|
|
36
|
+
"suite",
|
|
37
|
+
"test",
|
|
38
|
+
"task",
|
|
39
|
+
"rerunfailed",
|
|
40
|
+
"rerunfailedsuites",
|
|
41
|
+
"dryrun",
|
|
42
|
+
"settag",
|
|
43
|
+
"skip",
|
|
44
|
+
"skiponfailure",
|
|
45
|
+
"skipteardownonexit",
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@dataclass
|
|
50
|
+
class ReplResult:
|
|
51
|
+
"""How a REPL session ended."""
|
|
52
|
+
|
|
53
|
+
# Robot Framework's return code for the session test: 1 when it failed, 0 when it
|
|
54
|
+
# passed or when `statusrc` is switched off.
|
|
55
|
+
return_code: int
|
|
56
|
+
# The code given to `.exit`/`.quit`, None without one.
|
|
57
|
+
exit_code: Optional[int]
|
|
58
|
+
|
|
28
59
|
|
|
29
60
|
def run_repl(
|
|
30
61
|
interpreter: BaseInterpreter,
|
|
@@ -39,7 +70,8 @@ def run_repl(
|
|
|
39
70
|
xunit: Optional[str] = None,
|
|
40
71
|
source: Optional[Path] = None,
|
|
41
72
|
files: Tuple[Path, ...] = (),
|
|
42
|
-
|
|
73
|
+
statusrc: Optional[bool] = None,
|
|
74
|
+
) -> ReplResult:
|
|
43
75
|
robot_options_and_args: Tuple[str, ...] = ()
|
|
44
76
|
|
|
45
77
|
if files:
|
|
@@ -53,16 +85,18 @@ def run_repl(
|
|
|
53
85
|
robot_options_and_args += ("--pythonpath", pypath)
|
|
54
86
|
if outputdir:
|
|
55
87
|
robot_options_and_args += ("--outputdir", outputdir)
|
|
88
|
+
# Parsed after the configured options, so Robot's "last one wins" lets it override them.
|
|
89
|
+
if statusrc is not None:
|
|
90
|
+
robot_options_and_args += ("--statusrc" if statusrc else "--nostatusrc",)
|
|
56
91
|
|
|
57
92
|
root_folder, _profile, cmd_options = handle_robot_options(app, (*robot_options_and_args, *(str(f) for f in files)))
|
|
58
93
|
|
|
59
|
-
|
|
60
|
-
|
|
94
|
+
# Resolved before `app.chdir`, so a relative `--source` is relative to where the
|
|
95
|
+
# REPL was started (like FILES), not to the project root.
|
|
96
|
+
source = normalized_path(source if source is not None else Path.cwd() / "__repl_internal__.robot")
|
|
61
97
|
|
|
62
98
|
with app.chdir(root_folder) as orig_folder:
|
|
63
99
|
try:
|
|
64
|
-
curdir = normalized_path(source).parent if source is not None else Path.cwd()
|
|
65
|
-
|
|
66
100
|
options, _ = RobotFrameworkEx(
|
|
67
101
|
app,
|
|
68
102
|
["."],
|
|
@@ -71,7 +105,12 @@ def run_repl(
|
|
|
71
105
|
orig_folder=orig_folder,
|
|
72
106
|
).parse_arguments((*cmd_options, *robot_options_and_args))
|
|
73
107
|
|
|
74
|
-
|
|
108
|
+
# Every key is dropped, but only options that are actually set (not e.g. `--nodryrun`) are reported.
|
|
109
|
+
ignored = [key for key in _IGNORED_ROBOT_OPTIONS if options.pop(key, None)]
|
|
110
|
+
if ignored:
|
|
111
|
+
app.verbose(f"Ignoring robot options in the REPL: {', '.join(ignored)}")
|
|
112
|
+
|
|
113
|
+
interpreter.source = source
|
|
75
114
|
|
|
76
115
|
settings = RobotSettings(
|
|
77
116
|
options,
|
|
@@ -92,8 +131,9 @@ def run_repl(
|
|
|
92
131
|
sys.path = settings.pythonpath + sys.path
|
|
93
132
|
|
|
94
133
|
with io.StringIO(REPL_SUITE) as suite_io:
|
|
95
|
-
model = get_model(suite_io, curdir=str(
|
|
96
|
-
|
|
134
|
+
model = get_model(suite_io, curdir=str(source.parent).replace("\\", "\\\\"))
|
|
135
|
+
# RF < 6.1 expects a `str` suite source; RF 6.1+ converts it to a `Path` itself.
|
|
136
|
+
model.source = str(source)
|
|
97
137
|
|
|
98
138
|
suite = TestSuite.from_model(model)
|
|
99
139
|
suite.configure(**settings.suite_config)
|
|
@@ -109,3 +149,6 @@ def run_repl(
|
|
|
109
149
|
except DataError as err:
|
|
110
150
|
app.error(str(err))
|
|
111
151
|
app.exit(DATA_ERROR)
|
|
152
|
+
|
|
153
|
+
# The prompt loop runs inside `suite.run`, so a code given to `.exit` is known by now.
|
|
154
|
+
return ReplResult(result.return_code, interpreter.exit_code)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: robotcode-repl
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.8.0-dev.548
|
|
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
|
|
@@ -20,13 +20,14 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
21
|
Classifier: Programming Language :: Python :: 3.13
|
|
22
22
|
Classifier: Programming Language :: Python :: 3.14
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
23
24
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
24
25
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
25
26
|
Classifier: Topic :: Utilities
|
|
26
27
|
Classifier: Typing :: Typed
|
|
27
28
|
Requires-Python: >=3.10
|
|
28
29
|
Requires-Dist: prompt-toolkit!=3.0.52
|
|
29
|
-
Requires-Dist: robotcode-runner==2.
|
|
30
|
+
Requires-Dist: robotcode-runner==2.8.0-dev.548
|
|
30
31
|
Description-Content-Type: text/markdown
|
|
31
32
|
|
|
32
33
|
# robotcode-repl
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
robotcode/repl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
robotcode/repl/__version__.py,sha256=4qGR5Sg7VszfoERVpnszHJ_tsWJ0G_bUZdheH0_dqx4,30
|
|
3
|
+
robotcode/repl/_backends.py,sha256=s7PV-HBhnAvwjn2le0cbOJ5hwLb4MjahUo6KWtRC3lc,110
|
|
4
|
+
robotcode/repl/_indent.py,sha256=jwFKaHNvTWYpUwIWHu6JHoaCz7ljOxneR5sBrKcAjpI,3303
|
|
5
|
+
robotcode/repl/_keyword_lookup.py,sha256=c8InMUDGKsw4wYmiqJzBr9GGxPC-59sRZHI0C-GWjFA,7748
|
|
6
|
+
robotcode/repl/_progress.py,sha256=BaSbDGOy5UOXvD855Kd-lDrYbqPrYIWRVs507vJznK4,2586
|
|
7
|
+
robotcode/repl/_session_export.py,sha256=sTSkLEMoSxNQOsII3xfDY8h-nV-mrem-4h6Iug7VQv4,2841
|
|
8
|
+
robotcode/repl/base_interpreter.py,sha256=haLDzqVqrgs7uqmAGVjma8W8j110GcLA0KZlv0QHKxI,29856
|
|
9
|
+
robotcode/repl/cli.py,sha256=jt0fvcQqZ40wX7GwfPawGDAd53BFCggsKSnydZYsHvc,22029
|
|
10
|
+
robotcode/repl/console_interpreter.py,sha256=4PwPwsE3D6ZE8qYe0ZRc58gTuf3GWQQa7Hh5hqs7hJw,87781
|
|
11
|
+
robotcode/repl/doc_cli.py,sha256=24ZzA37cOt21wPzggx1fi_K2_GCpBekA6xiAp5_WRE0,23122
|
|
12
|
+
robotcode/repl/hooks.py,sha256=huqeT18sHWxG2dQNCGmgQUkb11CzVQkOoDgrDAy9hqg,238
|
|
13
|
+
robotcode/repl/prompt_toolkit_interpreter.py,sha256=0xbh71AMbuJt8nyIRVv0gEfIhnRrmO7ZVNKVss5yfNw,13344
|
|
14
|
+
robotcode/repl/py.typed,sha256=bWew9mHgMy8LqMu7RuqQXFXLBxh2CRx0dUbSx-3wE48,27
|
|
15
|
+
robotcode/repl/run.py,sha256=IWeiGZm56vkLn-hykP-_mWLrdpDciNyMk33_dT-6EJA,5327
|
|
16
|
+
robotcode/repl/Repl/__init__.py,sha256=-j2WxY3MzdLfsMvpa2wMs6WVF_eeJygdshtMN50r67U,43
|
|
17
|
+
robotcode/repl/Repl/repl.py,sha256=k3vCeg9z_4cb2dgZ4YKHl4TD599gumVkQMImAzGl20Y,1628
|
|
18
|
+
robotcode/repl/_debug/__init__.py,sha256=uQNyC3pdlpJZI3FRKzcp9BYEz1QtfBR--gsgKNomxrQ,908
|
|
19
|
+
robotcode/repl/_debug/controller.py,sha256=D5lxDqrVmjRG4bAF9_5561TIQ9MzlvOphIBVW8DzhOU,33221
|
|
20
|
+
robotcode/repl/_debug/types.py,sha256=3Vbecx44pruY0fXptEowKr_tYhljXSb6Sbr81YS22Mk,4597
|
|
21
|
+
robotcode/repl/_pt/__init__.py,sha256=k1bJgYbKwp5ScYO8fSx0BVy8XW9Aw_8o0jTOWQTQdX8,411
|
|
22
|
+
robotcode/repl/_pt/completion.py,sha256=BJD6sASKu1EfW0QPNKIDRc9O-8ttErXvxvnFb10lAxk,23318
|
|
23
|
+
robotcode/repl/_pt/components.py,sha256=kuYVXJc4bFJq4b3-JtAtBYymvS7ssSwlKDldWYFGMuA,20152
|
|
24
|
+
robotcode/repl/_pt/doc_viewer.py,sha256=iazNOQEvRygPSUyqKH2qOYShzdYqd7vufZcxPziJx8Q,71648
|
|
25
|
+
robotcode/repl/_pt/history.py,sha256=Rvbdu4LtbYk9dPgYJY7D1JpfyT1SETUdNmtevxo21H4,1591
|
|
26
|
+
robotcode/repl/_pt/lexer.py,sha256=YXtDMWQXPIocwceMXFlvULWyGXCDmqeAtTer_Ecuvwk,13925
|
|
27
|
+
robotcode_repl-2.8.0.dev548.dist-info/METADATA,sha256=tIi2Mhdf0HfnLnCvUOt5LQwp_vcblkLrW1fEqG_Fatc,2835
|
|
28
|
+
robotcode_repl-2.8.0.dev548.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
|
|
29
|
+
robotcode_repl-2.8.0.dev548.dist-info/entry_points.txt,sha256=lI4idVOEmSWxmmioejg-_QvHXTLySK6ZxJ13R_v8ykU,40
|
|
30
|
+
robotcode_repl-2.8.0.dev548.dist-info/RECORD,,
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
robotcode/repl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
robotcode/repl/__version__.py,sha256=53Sii4w6BIWn-1RhaTyqUO46gDe4nDCRQDAcpsWFH24,22
|
|
3
|
-
robotcode/repl/_backends.py,sha256=s7PV-HBhnAvwjn2le0cbOJ5hwLb4MjahUo6KWtRC3lc,110
|
|
4
|
-
robotcode/repl/_indent.py,sha256=0v0RYe8nWpfNZpCEQanVOuotA7WZJtfg5KFuybq18I0,3014
|
|
5
|
-
robotcode/repl/_keyword_lookup.py,sha256=c8InMUDGKsw4wYmiqJzBr9GGxPC-59sRZHI0C-GWjFA,7748
|
|
6
|
-
robotcode/repl/_progress.py,sha256=BaSbDGOy5UOXvD855Kd-lDrYbqPrYIWRVs507vJznK4,2586
|
|
7
|
-
robotcode/repl/_session_export.py,sha256=sTSkLEMoSxNQOsII3xfDY8h-nV-mrem-4h6Iug7VQv4,2841
|
|
8
|
-
robotcode/repl/base_interpreter.py,sha256=TZGHfoXgUATlFhQdpFS48DFO21oZrUxqosGJhMV8jnI,17786
|
|
9
|
-
robotcode/repl/cli.py,sha256=A6QwuTYyOfTkQf1U6dWgd-pEY5_69deURaYa4AA59dU,19418
|
|
10
|
-
robotcode/repl/console_interpreter.py,sha256=c88N5U7FNXCTwexj79iiAZ8Rq_o1TI7sEPmi1d92fZg,75687
|
|
11
|
-
robotcode/repl/hooks.py,sha256=FyaV18JRJqAls3Sox8J3uRQFV59HDO92EdN6cQEEgPo,208
|
|
12
|
-
robotcode/repl/prompt_toolkit_interpreter.py,sha256=iZnsS0hwbxxS_RFh799x1Ide0tvAghEI25R7JF8lC4E,11939
|
|
13
|
-
robotcode/repl/py.typed,sha256=bWew9mHgMy8LqMu7RuqQXFXLBxh2CRx0dUbSx-3wE48,27
|
|
14
|
-
robotcode/repl/run.py,sha256=ISAU_m5nGwVQqBnjLCy30oBbIvtYQsU-aknkSJODPGw,3581
|
|
15
|
-
robotcode/repl/Repl/__init__.py,sha256=-j2WxY3MzdLfsMvpa2wMs6WVF_eeJygdshtMN50r67U,43
|
|
16
|
-
robotcode/repl/Repl/repl.py,sha256=-uYIceM5OQ2uvkc4WUBJ1SjQjT3avusoeSBVx9UnUGg,1129
|
|
17
|
-
robotcode/repl/_debug/__init__.py,sha256=uQNyC3pdlpJZI3FRKzcp9BYEz1QtfBR--gsgKNomxrQ,908
|
|
18
|
-
robotcode/repl/_debug/controller.py,sha256=DOs3MM1AVxui0g5I1WdNA4nwGgeUdOhtfQogRE-4KC0,31263
|
|
19
|
-
robotcode/repl/_debug/types.py,sha256=9bj3oi99wI3KsWNm7xs9GrxizaOw8WKDd7CCxrqxhAs,4363
|
|
20
|
-
robotcode/repl/_pt/__init__.py,sha256=k1bJgYbKwp5ScYO8fSx0BVy8XW9Aw_8o0jTOWQTQdX8,411
|
|
21
|
-
robotcode/repl/_pt/completion.py,sha256=BJD6sASKu1EfW0QPNKIDRc9O-8ttErXvxvnFb10lAxk,23318
|
|
22
|
-
robotcode/repl/_pt/components.py,sha256=hMZl9K82gc1ONNUa0kuTCzyHeMyiqs0FG0aBSd3-Q-c,20094
|
|
23
|
-
robotcode/repl/_pt/doc_viewer.py,sha256=_WAkJP8U3eslj2aWrNaOknLyYzdpKUsWeWuVC3PB6Y0,55635
|
|
24
|
-
robotcode/repl/_pt/history.py,sha256=Rvbdu4LtbYk9dPgYJY7D1JpfyT1SETUdNmtevxo21H4,1591
|
|
25
|
-
robotcode/repl/_pt/lexer.py,sha256=EIPGOkUaQie0PGa3lym0-s3CHHvLZiIxvz5sJNo3jdQ,13725
|
|
26
|
-
robotcode_repl-2.6.2.dist-info/METADATA,sha256=RSThPSpI0PZIHMFNjl8hYkFtMYIO9vkNVHB4pICOGyg,2768
|
|
27
|
-
robotcode_repl-2.6.2.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
|
|
28
|
-
robotcode_repl-2.6.2.dist-info/entry_points.txt,sha256=lI4idVOEmSWxmmioejg-_QvHXTLySK6ZxJ13R_v8ykU,40
|
|
29
|
-
robotcode_repl-2.6.2.dist-info/RECORD,,
|
|
File without changes
|