Skip to content

Commit 5afe1c2

Browse files
authored
Merge pull request #2417 from jerneju/index-feature
[FIX] Feature Constructor: no fail when no values
2 parents a73dec0 + fe02689 commit 5afe1c2

File tree

2 files changed

+34
-14
lines changed

2 files changed

+34
-14
lines changed

Orange/widgets/data/owfeatureconstructor.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ def setEditorData(self, data, domain):
244244
def editorData(self):
245245
values = self.valuesedit.text()
246246
values = re.split(r"(?<!\\),", values)
247-
values = tuple(v.replace(r"\,", ",").strip() for v in values)
247+
values = tuple(filter(None, [v.replace(r"\,", ",").strip() for v in values]))
248248
return DiscreteDescriptor(
249249
name=self.nameedit.text(),
250250
values=values,
@@ -292,7 +292,7 @@ def data(self, index, role=Qt.DisplayRole):
292292
return super().data(index, role)
293293

294294

295-
class FeatureConstructorSettingsHandler(DomainContextHandler):
295+
class FeatureConstructorHandler(DomainContextHandler):
296296
"""Context handler that filters descriptors"""
297297

298298
def is_valid_item(self, setting, descriptor, attrs, metas):
@@ -326,7 +326,7 @@ class OWFeatureConstructor(OWWidget):
326326

327327
want_main_area = False
328328

329-
settingsHandler = FeatureConstructorSettingsHandler()
329+
settingsHandler = FeatureConstructorHandler()
330330
descriptors = ContextSetting([])
331331
currentIndex = ContextSetting(-1)
332332

@@ -850,7 +850,7 @@ def make_arg(name):
850850
if sys.version_info >= (3, 0):
851851
return ast.arg(arg=name, annotation=None)
852852
else:
853-
return ast.Name(id=arg, ctx=ast.Param(), lineno=1, col_offset=0)
853+
return ast.Name(id=name, ctx=ast.Param(), lineno=1, col_offset=0)
854854

855855
lambda_ = ast.Lambda(
856856
args=ast.arguments(
@@ -902,7 +902,7 @@ def make_arg(name):
902902
"weibullvariate": random.weibullvariate,
903903
"triangular": random.triangular,
904904
"uniform": random.uniform}
905-
)
905+
)
906906

907907

908908
class FeatureFunc:
@@ -930,8 +930,10 @@ def unique(seq):
930930
return unique_el
931931

932932

933-
def main(argv=sys.argv):
933+
def main(argv=None):
934934
from AnyQt.QtWidgets import QApplication
935+
if argv is None:
936+
argv = sys.argv
935937
app = QApplication(list(argv))
936938
argv = app.arguments()
937939
if len(argv) > 1:

Orange/widgets/data/tests/test_owfeatureconstructor.py

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,10 @@
1111
from Orange.widgets.data.owfeatureconstructor import (DiscreteDescriptor,
1212
ContinuousDescriptor,
1313
StringDescriptor,
14-
construct_variables, OWFeatureConstructor)
14+
construct_variables, OWFeatureConstructor,
15+
DiscreteFeatureEditor)
1516

16-
from Orange.widgets.data.owfeatureconstructor import (
17-
freevars, make_lambda, validate_exp
18-
)
17+
from Orange.widgets.data.owfeatureconstructor import freevars, validate_exp
1918

2019
import dill as pickle # Import dill after Orange because patched
2120

@@ -99,11 +98,11 @@ class PicklingTest(unittest.TestCase):
9998
def test_lambdas_pickle(self):
10099
NONLOCAL_CONST = 5
101100

102-
lambda_func = lambda x, LOCAL_CONST=7: \
103-
x * LOCAL_CONST * NONLOCAL_CONST * self.CLASS_CONST * GLOBAL_CONST
101+
lambda_func = lambda x, local_const=7: \
102+
x * local_const * NONLOCAL_CONST * self.CLASS_CONST * GLOBAL_CONST
104103

105-
def nested_func(x, LOCAL_CONST=7):
106-
return x * LOCAL_CONST * NONLOCAL_CONST * self.CLASS_CONST * GLOBAL_CONST
104+
def nested_func(x, local_const=7):
105+
return x * local_const * NONLOCAL_CONST * self.CLASS_CONST * GLOBAL_CONST
107106

108107
self.assertEqual(lambda_func(11),
109108
pickle.loads(pickle.dumps(lambda_func))(11))
@@ -240,3 +239,22 @@ def test_error_invalid_expression(self):
240239
)
241240
self.widget.apply()
242241
self.assertTrue(self.widget.Error.invalid_expressions.is_shown())
242+
243+
def test_discrete_no_values(self):
244+
"""
245+
Should not fail when there are no values set.
246+
GH-2417
247+
"""
248+
data = Table("iris")
249+
self.widget.setData(data)
250+
discreteFeatureEditor = DiscreteFeatureEditor()
251+
252+
discreteFeatureEditor.valuesedit.setText("")
253+
discreteFeatureEditor.nameedit.setText("D1")
254+
discreteFeatureEditor.expressionedit.setText("iris")
255+
self.widget.addFeature(
256+
discreteFeatureEditor.editorData()
257+
)
258+
self.assertFalse(self.widget.Error.more_values_needed.is_shown())
259+
self.widget.apply()
260+
self.assertTrue(self.widget.Error.more_values_needed.is_shown())

0 commit comments

Comments
 (0)