Skip to content

Commit 0a6874e

Browse files
authored
Merge pull request #1587 from VesnaT/owscript
OWPythonScript: Update locals when script is executed
2 parents d848f01 + a2d5605 commit 0a6874e

File tree

3 files changed

+69
-4
lines changed

3 files changed

+69
-4
lines changed

Orange/widgets/data/owpythonscript.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@ def __init__(self, locals=None, parent=None):
138138
def setLocals(self, locals):
139139
self.locals = locals
140140

141+
def updateLocals(self, locals):
142+
self.locals.update(locals)
143+
141144
def interact(self, banner=None):
142145
try:
143146
sys.ps1
@@ -460,8 +463,9 @@ def __init__(self):
460463

461464
self.controlBox.layout().addWidget(w)
462465

463-
gui.auto_commit(self.controlArea, self, "auto_execute", "Execute",
464-
auto_label="Auto Execute")
466+
self.execute_button = gui.auto_commit(
467+
self.controlArea, self, "auto_execute", "Execute",
468+
auto_label="Auto Execute")
465469

466470
self.splitCanvas = QSplitter(Qt.Vertical, self.mainArea)
467471
self.mainArea.layout().addWidget(self.splitCanvas)
@@ -487,7 +491,7 @@ def __init__(self):
487491

488492
self.consoleBox = gui.vBox(self, 'Console')
489493
self.splitCanvas.addWidget(self.consoleBox)
490-
self.console = PythonConsole(self.__dict__, self)
494+
self.console = PythonConsole({}, self)
491495
self.consoleBox.layout().addWidget(self.console)
492496
self.console.document().setDefaultFont(QFont(defaultFont))
493497
self.consoleBox.setAlignment(Qt.AlignBottom)
@@ -636,14 +640,22 @@ def saveScript(self):
636640
f.write(self.text.toPlainText())
637641
f.close()
638642

643+
def initial_locals_state(self):
644+
d = dict([(i.name, getattr(self, i.name, None)) for i in self.inputs])
645+
d.update(dict([(o.name, None) for o in self.outputs]))
646+
return d
647+
639648
def commit(self):
640649
self._script = str(self.text.toPlainText())
650+
lcls = self.initial_locals_state()
651+
lcls["_script"] = str(self.text.toPlainText())
652+
self.console.updateLocals(lcls)
641653
self.console.write("\nRunning script:\n")
642654
self.console.push("exec(_script)")
643655
self.console.new_prompt(sys.ps1)
644656
for out in self.outputs:
645657
signal = out.name
646-
self.send(signal, getattr(self, signal, None))
658+
self.send(signal, self.console.locals.get(signal, None))
647659

648660

649661
if __name__ == "__main__":
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Test methods with long descriptive names can omit docstrings
2+
# pylint: disable=missing-docstring
3+
from Orange.data import Table
4+
from Orange.classification import LogisticRegressionLearner
5+
from Orange.widgets.data.owpythonscript import OWPythonScript
6+
from Orange.widgets.tests.base import WidgetTest
7+
8+
9+
class TestOWPythonScript(WidgetTest):
10+
def setUp(self):
11+
self.widget = self.create_widget(OWPythonScript)
12+
self.iris = Table("iris")
13+
self.learner = LogisticRegressionLearner()
14+
self.model = self.learner(self.iris)
15+
16+
def test_inputs(self):
17+
"""Check widget's inputs"""
18+
for _input, data in (("in_data", self.iris),
19+
("in_learner", self.learner),
20+
("in_classifier", self.model),
21+
("in_object", "object")):
22+
self.assertEqual(getattr(self.widget, _input), None)
23+
self.send_signal(_input, data)
24+
self.assertEqual(getattr(self.widget, _input), data)
25+
self.send_signal(_input, None)
26+
self.assertEqual(getattr(self.widget, _input), None)
27+
28+
def test_outputs(self):
29+
"""Check widget's outputs"""
30+
for _input, _output, data in (
31+
("in_data", "out_data", self.iris),
32+
("in_learner", "out_learner", self.learner),
33+
("in_classifier", "out_data", self.model),
34+
("in_object", "out_object", "object")):
35+
self.widget.text.setPlainText("{} = {}".format(_output, _input))
36+
self.send_signal(_input, data)
37+
self.assertEqual(self.get_output(_output), data)
38+
self.send_signal(_input, None)
39+
self.widget.text.setPlainText("print({})".format(_output))
40+
self.widget.execute_button.button.click()
41+
self.assertEqual(self.get_output(_output), None)
42+
43+
def test_local_variable(self):
44+
"""Check if variable remains in locals after removed from script"""
45+
self.widget.text.setPlainText("temp = 42\nprint(temp)")
46+
self.widget.execute_button.button.click()
47+
self.assertIn("42", self.widget.console.toPlainText())
48+
self.widget.text.setPlainText("print(temp)")
49+
self.widget.execute_button.button.click()
50+
self.assertNotIn("NameError: name 'temp' is not defined",
51+
self.widget.console.toPlainText())

Orange/widgets/tests/test_scatterplot_density.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111

1212
class TestScatterplotDensity(TestCase):
13+
def setUp(self):
14+
np.random.seed(1)
1315

1416
def random_data(self, n_grid, n_colors, n_data):
1517
mx, Mx = 200, 2000

0 commit comments

Comments
 (0)