Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions Orange/widgets/utils/signals.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import copy
import itertools

from Orange.canvas.registry.description import InputSignal, OutputSignal

# increasing counter for ensuring the order of Input/Output definitions
# is preserved when going through the unordered class namespace of
# WidgetSignalsMixin.Inputs/Outputs.
_counter = itertools.count()


class _Signal:
@staticmethod
Expand Down Expand Up @@ -61,6 +67,7 @@ def __init__(self, name, type, id=None, doc=None, replaces=None, *,
multiple=False, default=False, explicit=False):
flags = self.get_flags(multiple, default, explicit, False)
super().__init__(name, type, "", flags, id, doc, replaces or [])
self._seq_id = next(_counter)

def __call__(self, method):
"""
Expand Down Expand Up @@ -118,6 +125,7 @@ def __init__(self, name, type, id=None, doc=None, replaces=None, *,
flags = self.get_flags(False, default, explicit, dynamic)
super().__init__(name, type, flags, id, doc, replaces or [])
self.widget = None
self._seq_id = next(_counter)

def bound_signal(self, widget):
"""
Expand Down Expand Up @@ -234,8 +242,9 @@ def get_signals(cls, direction):
return old_style

signal_class = getattr(cls, direction.title())
return [signal for signal in signal_class.__dict__.values()
if isinstance(signal, _Signal)]
signals = [signal for signal in signal_class.__dict__.values()
if isinstance(signal, _Signal)]
return list(sorted(signals, key=lambda s: s._seq_id))


class AttributeList(list):
Expand Down
23 changes: 22 additions & 1 deletion Orange/widgets/utils/tests/test_signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
Single, Multiple, Default, NonDefault, Explicit, Dynamic, InputSignal, \
OutputSignal
from Orange.widgets.tests.base import GuiTest
from Orange.widgets.utils.signals import _Signal, Input, Output
from Orange.widgets.utils.signals import _Signal, Input, Output, \
WidgetSignalsMixin
from Orange.widgets.widget import OWWidget


Expand Down Expand Up @@ -186,6 +187,26 @@ def foo(self):
self.assertIsInstance(output, OutputSignal)
self.assertEqual(output.name, "another name")

def test_get_signals_order(self):
class TestWidget(WidgetSignalsMixin):
class Inputs:
input_1 = Input("1", int)
input_2 = Input("2", int)
input_3 = Input("3", int)
input_a = Input("a", object)

class Outputs:
output_1 = Output("1", int)
output_2 = Output("2", int)
output_3 = Output("3", int)
output_a = Output("a", object)

inputs = TestWidget.get_signals("inputs")
self.assertTrue(all(isinstance(s, Input) for s in inputs))
self.assertSequenceEqual([s.name for s in inputs], list("123a"))
outputs = TestWidget.get_signals("outputs")
self.assertTrue(all(isinstance(s, Output) for s in outputs))
self.assertSequenceEqual([s.name for s in outputs], list("123a"))

if __name__ == "__main__":
unittest.main()