Newer
Older
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
# This file is part of the mantidqt package
#
# Copyright (C) 2017 mantidproject
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from __future__ import (absolute_import, unicode_literals)
# std imports
# local imports
from mantidqt.utils.async import AsyncTask
class PythonCodeExecution(object):
"""Provides the ability to execute arbitrary
strings of Python code. It supports
reporting progress updates in asynchronous execution
"""
def execute_async(self, code_str, user_globals,
user_locals, success_cb=None, error_cb=None,
progress_cb=None):
"""
Execute the given code string on a separate thread. This function
returns as soon as the new thread starts
:param code_str: A string containing code to execute
:param user_globals: A mutable mapping type to store global variables
:param user_locals: A mutable mapping type to store local variables
:param success_cb: A callback of the form f() called on success
:param error_cb: A callback of the form f(exc) called on error,
:param progress_cb: A callback for progress updates
providing the exception generated
:returns: The created async task
"""
# AsyncTask's callbacks have a slightly different form
if success_cb:
def on_success(_): success_cb()
else:
def on_success(_): pass
if error_cb:
def on_error(task_result): error_cb(task_result.exception)
else:
def on_error(_): pass
t = AsyncTask(self.execute, args=(code_str, user_globals, user_locals),
success_cb=on_success, error_cb=on_error)
t.start()
return t
def execute(self, code_str, user_globals,
user_locals):
"""Execute the given code on the calling thread
within the provided context. All exceptions are caught
and stored with the returned result
:param code_str: A string containing code to execute
:param user_globals: A mutable mapping type to store global variables
:param user_locals: A mutable mapping type to store local variables
:raises: Any error that the code generates
"""
exec(code_str, user_globals, user_locals)