py-adtools 0.1.3__py3-none-any.whl → 0.1.5__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.
Potentially problematic release.
This version of py-adtools might be problematic. Click here for more details.
- adtools/evaluator.py +15 -14
- adtools/evaluator_pool.py +8 -8
- {py_adtools-0.1.3.dist-info → py_adtools-0.1.5.dist-info}/METADATA +1 -1
- py_adtools-0.1.5.dist-info/RECORD +10 -0
- py_adtools-0.1.3.dist-info/RECORD +0 -10
- {py_adtools-0.1.3.dist-info → py_adtools-0.1.5.dist-info}/WHEEL +0 -0
- {py_adtools-0.1.3.dist-info → py_adtools-0.1.5.dist-info}/licenses/LICENSE +0 -0
- {py_adtools-0.1.3.dist-info → py_adtools-0.1.5.dist-info}/top_level.txt +0 -0
adtools/evaluator.py
CHANGED
|
@@ -12,6 +12,7 @@ from abc import ABC, abstractmethod
|
|
|
12
12
|
from queue import Empty
|
|
13
13
|
from typing import Any, Literal, Dict, Callable, List
|
|
14
14
|
import psutil
|
|
15
|
+
import traceback
|
|
15
16
|
|
|
16
17
|
from .py_code import PyProgram
|
|
17
18
|
|
|
@@ -35,9 +36,9 @@ class PyEvaluator(ABC):
|
|
|
35
36
|
debug_mode: Debug mode.
|
|
36
37
|
join_timeout_seconds: Timeout in seconds to wait for the process to finish. Kill the process if timeout.
|
|
37
38
|
"""
|
|
38
|
-
self.
|
|
39
|
-
self.
|
|
40
|
-
self.
|
|
39
|
+
self.debug_mode = debug_mode
|
|
40
|
+
self.exec_code = exec_code
|
|
41
|
+
self.join_timeout_seconds = join_timeout_seconds
|
|
41
42
|
|
|
42
43
|
@abstractmethod
|
|
43
44
|
def evaluate_program(
|
|
@@ -73,13 +74,13 @@ class PyEvaluator(ABC):
|
|
|
73
74
|
children_processes = []
|
|
74
75
|
# Terminate parent process
|
|
75
76
|
process.terminate()
|
|
76
|
-
process.join(timeout=self.
|
|
77
|
+
process.join(timeout=self.join_timeout_seconds)
|
|
77
78
|
if process.is_alive():
|
|
78
79
|
process.kill()
|
|
79
80
|
process.join()
|
|
80
81
|
# Kill all children processes
|
|
81
82
|
for child in children_processes:
|
|
82
|
-
if self.
|
|
83
|
+
if self.debug_mode:
|
|
83
84
|
print(f"Killing process {process.pid}'s children process {child.pid}")
|
|
84
85
|
child.terminate()
|
|
85
86
|
|
|
@@ -97,7 +98,7 @@ class PyEvaluator(ABC):
|
|
|
97
98
|
class_names = [c.name for c in program.classes]
|
|
98
99
|
|
|
99
100
|
# Execute the code and get callable instances
|
|
100
|
-
if self.
|
|
101
|
+
if self.exec_code:
|
|
101
102
|
all_globals_namespace = {}
|
|
102
103
|
# Execute the program, map func/var/class to global namespace
|
|
103
104
|
exec(str(program), all_globals_namespace)
|
|
@@ -123,8 +124,8 @@ class PyEvaluator(ABC):
|
|
|
123
124
|
)
|
|
124
125
|
return res
|
|
125
126
|
except Exception as e:
|
|
126
|
-
if self.
|
|
127
|
-
print(
|
|
127
|
+
if self.debug_mode:
|
|
128
|
+
print(traceback.format_exc())
|
|
128
129
|
return None
|
|
129
130
|
|
|
130
131
|
def _evaluate_in_safe_process(
|
|
@@ -148,7 +149,7 @@ class PyEvaluator(ABC):
|
|
|
148
149
|
self,
|
|
149
150
|
program: str | PyProgram,
|
|
150
151
|
timeout_seconds: int | float = None,
|
|
151
|
-
redirect_to_devnull: bool =
|
|
152
|
+
redirect_to_devnull: bool = False,
|
|
152
153
|
multiprocessing_start_method: Literal['default', 'auto', 'fork', 'spawn'] = 'auto',
|
|
153
154
|
**kwargs
|
|
154
155
|
):
|
|
@@ -188,14 +189,14 @@ class PyEvaluator(ABC):
|
|
|
188
189
|
# After getting the result, terminate/kill the process
|
|
189
190
|
self._kill_process_and_its_children(process)
|
|
190
191
|
except Empty: # The queue is empty indicates a timeout
|
|
191
|
-
if self.
|
|
192
|
+
if self.debug_mode:
|
|
192
193
|
print(f'DEBUG: the evaluation time exceeds {timeout_seconds}s.')
|
|
193
194
|
# Terminate/kill all processes if timeout happens
|
|
194
195
|
self._kill_process_and_its_children(process)
|
|
195
196
|
result = None
|
|
196
197
|
except Exception as e:
|
|
197
|
-
if self.
|
|
198
|
-
print(f'DEBUG: evaluation failed with exception:\n{
|
|
198
|
+
if self.debug_mode:
|
|
199
|
+
print(f'DEBUG: evaluation failed with exception:\n{traceback.format_exc()}')
|
|
199
200
|
# Terminate/kill all processes if meet exceptions
|
|
200
201
|
self._kill_process_and_its_children(process)
|
|
201
202
|
result = None
|
|
@@ -206,6 +207,6 @@ class PyEvaluator(ABC):
|
|
|
206
207
|
self._kill_process_and_its_children(process)
|
|
207
208
|
return result
|
|
208
209
|
except Exception as e:
|
|
209
|
-
if self.
|
|
210
|
-
print(
|
|
210
|
+
if self.debug_mode:
|
|
211
|
+
print(traceback.format_exc())
|
|
211
212
|
return None
|
adtools/evaluator_pool.py
CHANGED
|
@@ -26,12 +26,12 @@ class EvaluatorExecutorPool:
|
|
|
26
26
|
max_workers: The maximum number of workers.
|
|
27
27
|
pool_type: Type of the executor pool.
|
|
28
28
|
"""
|
|
29
|
-
self.
|
|
30
|
-
self.
|
|
29
|
+
self.evaluator = evaluator
|
|
30
|
+
self.max_workers = max_workers
|
|
31
31
|
if pool_type == 'thread':
|
|
32
|
-
self.
|
|
32
|
+
self.pool = ThreadPoolExecutor(max_workers=self.max_workers)
|
|
33
33
|
else:
|
|
34
|
-
self.
|
|
34
|
+
self.pool = ProcessPoolExecutor(max_workers=self.max_workers)
|
|
35
35
|
|
|
36
36
|
def evaluate(self, program: str | PyProgram, return_time=True, **kwargs):
|
|
37
37
|
"""Evaluate program.
|
|
@@ -40,7 +40,7 @@ class EvaluatorExecutorPool:
|
|
|
40
40
|
**kwargs: additional keyword arguments to pass to 'evaluate_program'.
|
|
41
41
|
"""
|
|
42
42
|
start_time = time.time()
|
|
43
|
-
future = self.
|
|
43
|
+
future = self.pool.submit(self.evaluator.evaluate, program, **kwargs)
|
|
44
44
|
res = future.result()
|
|
45
45
|
duration = time.time() - start_time
|
|
46
46
|
if return_time:
|
|
@@ -52,7 +52,7 @@ class EvaluatorExecutorPool:
|
|
|
52
52
|
self,
|
|
53
53
|
program: str | PyProgram,
|
|
54
54
|
timeout_seconds: Optional[float],
|
|
55
|
-
redirect_to_devnull: bool =
|
|
55
|
+
redirect_to_devnull: bool = False,
|
|
56
56
|
multiprocessing_start_method: Literal['default', 'auto', 'fork', 'spawn'] = 'auto',
|
|
57
57
|
return_time=True,
|
|
58
58
|
**kwargs
|
|
@@ -66,8 +66,8 @@ class EvaluatorExecutorPool:
|
|
|
66
66
|
**kwargs: additional keyword arguments to pass to 'evaluate_program'.
|
|
67
67
|
"""
|
|
68
68
|
start_time = time.time()
|
|
69
|
-
future = self.
|
|
70
|
-
self.
|
|
69
|
+
future = self.pool.submit(
|
|
70
|
+
self.evaluator.secure_evaluate,
|
|
71
71
|
program,
|
|
72
72
|
timeout_seconds,
|
|
73
73
|
redirect_to_devnull,
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
adtools/__init__.py,sha256=kbxntZFeCcURiIypNOdMWyeKPdlzRsWOB-K7z6HNCsc,150
|
|
2
|
+
adtools/evaluator.py,sha256=weA6zR1WyUE3f5pt7wQYF1ukmkA-e2kDLaogbDmG_Ig,9154
|
|
3
|
+
adtools/evaluator_pool.py,sha256=v_NZibN4VI3STVUZt6ARdyoB4Z061xAefZlH8lkWsjE,2972
|
|
4
|
+
adtools/lm_base.py,sha256=fXltOlJpxy_b4ByX7nSIGXcMnH71W81tuzLsRtq_7JE,15709
|
|
5
|
+
adtools/py_code.py,sha256=FZfkp-IZ4zpOjrWe6svKNJsQhVANaTTkE0l0mc4aMW8,14277
|
|
6
|
+
py_adtools-0.1.5.dist-info/licenses/LICENSE,sha256=E5GGyecx3y5h2gcEGQloF-rDY9wbaef5IHjRsvtFbt8,1065
|
|
7
|
+
py_adtools-0.1.5.dist-info/METADATA,sha256=iR6GXsszQb8aFq8SQiXFWU_dUTTJ83MyhtEUfDEK93g,6364
|
|
8
|
+
py_adtools-0.1.5.dist-info/WHEEL,sha256=lTU6B6eIfYoiQJTZNc-fyaR6BpL6ehTzU3xGYxn2n8k,91
|
|
9
|
+
py_adtools-0.1.5.dist-info/top_level.txt,sha256=X2kKzmJFDAKR2FWCij5pfMG9pVVjVUomyl4e-1VLXIk,8
|
|
10
|
+
py_adtools-0.1.5.dist-info/RECORD,,
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
adtools/__init__.py,sha256=kbxntZFeCcURiIypNOdMWyeKPdlzRsWOB-K7z6HNCsc,150
|
|
2
|
-
adtools/evaluator.py,sha256=YAvnN1w7gIMNMnRGQAxU3hriVjEkJYQTph_ADwL_x2A,9083
|
|
3
|
-
adtools/evaluator_pool.py,sha256=GdvZu7KpJi79bP6l7A3sXu0voNh9YUfh07GPAk_qVeI,2981
|
|
4
|
-
adtools/lm_base.py,sha256=fXltOlJpxy_b4ByX7nSIGXcMnH71W81tuzLsRtq_7JE,15709
|
|
5
|
-
adtools/py_code.py,sha256=FZfkp-IZ4zpOjrWe6svKNJsQhVANaTTkE0l0mc4aMW8,14277
|
|
6
|
-
py_adtools-0.1.3.dist-info/licenses/LICENSE,sha256=E5GGyecx3y5h2gcEGQloF-rDY9wbaef5IHjRsvtFbt8,1065
|
|
7
|
-
py_adtools-0.1.3.dist-info/METADATA,sha256=jiotXGFPphm27xC-RZnwefjkSZcvwOwr_7TbY3LRfHM,6364
|
|
8
|
-
py_adtools-0.1.3.dist-info/WHEEL,sha256=lTU6B6eIfYoiQJTZNc-fyaR6BpL6ehTzU3xGYxn2n8k,91
|
|
9
|
-
py_adtools-0.1.3.dist-info/top_level.txt,sha256=X2kKzmJFDAKR2FWCij5pfMG9pVVjVUomyl4e-1VLXIk,8
|
|
10
|
-
py_adtools-0.1.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|