1
1
import ast
2
2
import io
3
3
from contextlib import redirect_stderr , redirect_stdout
4
+ from logging import getLogger
4
5
from typing import Generator
5
6
6
7
from ..message import Message
7
8
from ..util import ask_execute , print_preview
8
9
10
+ logger = getLogger (__name__ )
9
11
locals_ = {} # type: ignore
10
12
11
13
14
+ def init_python ():
15
+ check_available_packages ()
16
+
17
+
12
18
def execute_python (code : str , ask : bool ) -> Generator [Message , None , None ]:
13
19
"""Executes a python codeblock and returns the output."""
14
20
code = code .strip ()
15
21
if ask :
16
22
print_preview (code , "python" )
17
23
confirm = ask_execute ()
18
24
print ()
25
+ if not confirm :
26
+ # early return
27
+ yield Message ("system" , "Aborted, user chose not to run command." )
28
+ return
19
29
else :
20
30
print ("Skipping confirmation" )
21
31
22
- if ask and not confirm :
23
- # early return
24
- yield Message ("system" , "Aborted, user chose not to run command." )
25
- return
26
-
27
32
# remove blank lines
28
33
code = "\n " .join ([line for line in code .split ("\n " ) if line .strip ()])
29
34
@@ -50,6 +55,21 @@ def execute_python(code: str, ask: bool) -> Generator[Message, None, None]:
50
55
yield Message ("system" , "Executed code block.\n \n " + output )
51
56
52
57
58
+ def check_available_packages ():
59
+ """Checks that essentials like numpy, pandas, matplotlib are available."""
60
+ expected = ["numpy" , "pandas" , "matplotlib" ]
61
+ missing = []
62
+ for package in expected :
63
+ try :
64
+ __import__ (package )
65
+ except ImportError :
66
+ missing .append (package )
67
+ if missing :
68
+ logger .warning (
69
+ f"Missing packages: { ', ' .join (missing )} . Install them with `pip install gptme-python -E datascience`"
70
+ )
71
+
72
+
53
73
def test_execute_python ():
54
74
assert execute_python ("1 + 1" , ask = False ) == ">>> 1 + 1\n 2\n "
55
75
assert execute_python ("a = 2\n a" , ask = False ) == ">>> a = 2\n >>> a\n 2\n "
0 commit comments