Skip to content

Commit 81b40d6

Browse files
authored
Merge pull request #3101 from robertcv/fix_editdomain
[FIX] EditDomain: Editing TimeVariable broke formatting
2 parents e1dafe3 + b3102b2 commit 81b40d6

File tree

4 files changed

+86
-8
lines changed

4 files changed

+86
-8
lines changed

Orange/data/tests/test_variable.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,12 @@ def test_repr_value(self):
417417
var = TimeVariable('time')
418418
self.assertEqual(var.repr_val(Value(var, 416.3)), '416.3')
419419

420+
def test_have_date_have_time_in_construct(self):
421+
"""Test if have_time and have_date is correctly set"""
422+
var = TimeVariable('time', have_date=1)
423+
self.assertTrue(var.have_date)
424+
self.assertFalse(var.have_time)
425+
420426

421427
PickleContinuousVariable = create_pickling_tests(
422428
"PickleContinuousVariable",

Orange/data/variable.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -931,10 +931,10 @@ class TimeVariable(ContinuousVariable):
931931
utc_offset = None
932932
timezone = timezone.utc
933933

934-
def __init__(self, *args, **kwargs):
934+
def __init__(self, *args, have_date=0, have_time=0, **kwargs):
935935
super().__init__(*args, **kwargs)
936-
self.have_date = 0
937-
self.have_time = 0
936+
self.have_date = have_date
937+
self.have_time = have_time
938938

939939
def copy(self, compute_value=None):
940940
copy = super().copy(compute_value=compute_value)

Orange/widgets/data/oweditdomain.py

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,13 @@ def variable_description(var, skip_attributes=False):
5555
var.name,
5656
(("values", tuple(var.values)),),
5757
attributes)
58+
elif var.is_time:
59+
return (var_type.__module__,
60+
var_type.__name__,
61+
var.name,
62+
(("have_date", var.have_date),
63+
("have_time", var.have_time)),
64+
attributes)
5865
else:
5966
return (var_type.__module__,
6067
var_type.__name__,
@@ -68,14 +75,14 @@ def variable_from_description(description, compute_value=None):
6875
:func:`variable_description`).
6976
7077
"""
71-
module, type_name, name, kwargs, attrs = description
78+
module, type_name, name, args, attrs = description
7279
try:
7380
constructor = get_qualified(module, type_name)
7481
except (ImportError, AttributeError):
7582
raise ValueError("Invalid descriptor type '{}.{}"
7683
"".format(module, type_name))
7784

78-
var = constructor(name, compute_value=compute_value, **dict(list(kwargs)))
85+
var = constructor(name, compute_value=compute_value, **dict(list(args)))
7986
var.attributes.update(attrs)
8087
return var
8188

@@ -364,6 +371,31 @@ class ContinuousVariableEditor(VariableEditor):
364371
pass
365372

366373

374+
class TimeVariableEditor(VariableEditor):
375+
"""An editor widget for editing a Time variable.
376+
377+
Extends the :class:`VariableEditor` to enable editing of
378+
time variables.
379+
380+
"""
381+
def get_data(self):
382+
"""Retrieve the modified variable"""
383+
name = str(self.name_edit.text()).strip()
384+
labels = self.labels_model.get_dict()
385+
386+
# Is the variable actually changed.
387+
if self.var is not None and not self.is_same():
388+
var = type(self.var)(name)
389+
var.attributes.update(labels)
390+
var.have_date = self.var.have_date
391+
var.have_time = self.var.have_time
392+
self.var = var
393+
else:
394+
var = self.var
395+
396+
return var
397+
398+
367399
class OWEditDomain(widget.OWWidget):
368400
name = "Edit Domain"
369401
description = "Rename features and their values."
@@ -413,6 +445,7 @@ def __init__(self):
413445

414446
self.editor_stack.addWidget(DiscreteVariableEditor())
415447
self.editor_stack.addWidget(ContinuousVariableEditor())
448+
self.editor_stack.addWidget(TimeVariableEditor())
416449
self.editor_stack.addWidget(VariableEditor())
417450

418451
box.layout().addWidget(self.editor_stack)
@@ -508,9 +541,12 @@ def open_editor(self, index):
508541

509542
var = self.domain_model[index]
510543

511-
editor_index = 2
544+
editor_index = 3
512545
if var.is_discrete:
513546
editor_index = 0
547+
# TimeVariable is also continuous, first check if time
548+
elif var.is_time:
549+
editor_index = 2
514550
elif var.is_continuous:
515551
editor_index = 1
516552
editor = self.editor_stack.widget(editor_index)

Orange/widgets/data/tests/test_oweditdomain.py

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77
from AnyQt.QtCore import QModelIndex, Qt
88

99
from Orange.data import ContinuousVariable, DiscreteVariable, \
10-
StringVariable, Table, Domain
10+
StringVariable, TimeVariable, Table, Domain
1111
from Orange.widgets.data.oweditdomain import EditDomainReport, OWEditDomain, \
12-
ContinuousVariableEditor, DiscreteVariableEditor, VariableEditor
12+
ContinuousVariableEditor, DiscreteVariableEditor, VariableEditor, \
13+
TimeVariableEditor
1314
from Orange.widgets.data.owcolor import OWColor, ColorRole
1415
from Orange.widgets.tests.base import WidgetTest, GuiTest
1516

@@ -169,6 +170,20 @@ def test_duplicate_names(self):
169170
output = self.get_output(self.widget.Outputs.data)
170171
self.assertIsInstance(output, Table)
171172

173+
def test_time_variable_preservation(self):
174+
"""Test if time variables preserve format specific attributes"""
175+
table = Table("cyber-security-breaches")
176+
self.send_signal(self.widget.Inputs.data, table)
177+
output = self.get_output(self.widget.Outputs.data)
178+
self.assertEqual(str(table[0, 4]), str(output[0, 4]))
179+
180+
editor = self.widget.editor_stack.findChild(TimeVariableEditor)
181+
editor.name_edit.setText("Date")
182+
editor.commit()
183+
self.widget.commit()
184+
output = self.get_output(self.widget.Outputs.data)
185+
self.assertEqual(str(table[0, 4]), str(output[0, 4]))
186+
172187

173188
class TestEditors(GuiTest):
174189
def test_variable_editor(self):
@@ -221,3 +236,24 @@ def test_discrete_editor(self):
221236
self.assertEqual(w.name_edit.text(), "")
222237
self.assertEqual(w.labels_model.get_dict(), {})
223238
self.assertIs(w.get_data(), None)
239+
240+
def test_time_editor(self):
241+
w = TimeVariableEditor()
242+
self.assertIs(w.get_data(), None)
243+
244+
v = TimeVariable("T", have_date=1)
245+
v.attributes.update({"A": 1, "B": "b"})
246+
w.set_data(v)
247+
248+
self.assertEqual(w.name_edit.text(), v.name)
249+
self.assertEqual(w.labels_model.get_dict(), v.attributes)
250+
self.assertTrue(w.is_same())
251+
252+
var = w.get_data()
253+
self.assertTrue(var.have_date)
254+
self.assertFalse(var.have_time)
255+
256+
w.set_data(None)
257+
self.assertEqual(w.name_edit.text(), "")
258+
self.assertEqual(w.labels_model.get_dict(), {})
259+
self.assertIs(w.get_data(), None)

0 commit comments

Comments
 (0)