-
Notifications
You must be signed in to change notification settings - Fork 6
/
exec_code.py
81 lines (72 loc) · 1.79 KB
/
exec_code.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import sys
from io import StringIO
from nepattern import AnyString
from arclet.alconna import Alconna, Args, Arparma, Metadata, Option
alc = Alconna(
"exec",
Args.code(AnyString, multiple=True, completion=lambda: "print(1+1)", seps="\n"),
Option("--pure-text"),
Option("--no-output"),
Option("--out", Args.name(str, "res")),
Metadata("exec python code", example="exec\\nprint(1+1)"),
)
alc.shortcut(
"echo",
{"command": "exec --pure-text\nprint('{*}')"},
)
alc.shortcut(
r"sin(\d+)",
{"command": "exec --pure-text\nimport math\nprint(math.sin({0}*math.pi/180))"},
)
def exec_code(result: Arparma):
if result.find("pure-text"):
codes = list(result.code)
else:
codes = str(result.origin).split("\n")[1:]
output = result.query[str]("out.name", "res")
if not codes:
return ""
lcs = {}
_stdout = StringIO()
_to = sys.stdout
sys.stdout = _stdout
try:
exec(
"def rc(__out: str):\n "
+ " ".join(_code + "\n" for _code in codes)
+ " return locals().get(__out)",
{**globals(), **locals()},
lcs,
)
code_res = lcs["rc"](output)
sys.stdout = _to
if result.find("no-output"):
return ""
if code_res is not None:
return f"{output}: {code_res}"
_out = _stdout.getvalue()
return f"output: {_out}"
except Exception as e:
sys.stdout = _to
return str(e)
finally:
sys.stdout = _to
print(exec_code(alc.parse("echo 1234")))
print(exec_code(alc.parse("sin30")))
print(
exec_code(
alc.parse(
"""\
exec
print(
exec_code(
alc.parse(
"exec\\n"
"import sys;print(sys.version)"
)
)
)
"""
)
)
)