Skip to content

Commit

Permalink
signals: Support extending of Inputs/Outputs classes
Browse files Browse the repository at this point in the history
  • Loading branch information
astaric committed Jul 26, 2017
1 parent 20ffdf5 commit dc48d5c
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 12 deletions.
4 changes: 2 additions & 2 deletions Orange/widgets/model/owlinearregression.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ class OWLinearRegression(OWBaseLearner):

LEARNER = LinearRegressionLearner

class Outputs:
coefficients = Output("Coefficients", Table, explicit=True)
class Outputs(OWBaseLearner.Outputs):
coefficients = Output("Coefficients", Table)

#: Types
REGULARIZATION_TYPES = ["No regularization", "Ridge regression (L2)",
Expand Down
6 changes: 3 additions & 3 deletions Orange/widgets/model/owlogisticregression.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from Orange.classification.logistic_regression import LogisticRegressionLearner
from Orange.widgets import settings, gui
from Orange.widgets.utils.owlearnerwidget import OWBaseLearner
from Orange.widgets.widget import Output
from Orange.widgets.utils.signals import Output


class OWLogisticRegression(OWBaseLearner):
Expand All @@ -22,8 +22,8 @@ class OWLogisticRegression(OWBaseLearner):

LEARNER = LogisticRegressionLearner

class Outputs:
coefficients = Output("Coefficients", Table, explicit=True)
class Outputs(OWBaseLearner.Outputs):
coefficients = Output("Coefficients", Table)

penalty_type = settings.Setting(1)
C_index = settings.Setting(61)
Expand Down
20 changes: 13 additions & 7 deletions Orange/widgets/utils/signals.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import copy
import inspect
import itertools

from Orange.canvas.registry.description import InputSignal, OutputSignal
Expand Down Expand Up @@ -145,6 +146,12 @@ def send(self, value, id=None):
signal_manager.send(self.widget, self.name, value, id)


def _get_members(obj, member_type):
def is_member_type(member):
return isinstance(member, member_type)
return inspect.getmembers(obj, is_member_type)


class WidgetSignalsMixin:
"""Mixin for managing widget's input and output signals"""
class Inputs:
Expand All @@ -158,9 +165,8 @@ def __init__(self):

def _bind_outputs(self):
bound_cls = self.Outputs()
for name, signal in self.Outputs.__dict__.items():
if isinstance(signal, Output):
bound_cls.__dict__[name] = signal.bound_signal(self)
for name, signal in _get_members(bound_cls, Output):
setattr(bound_cls, name, signal.bound_signal(self))
setattr(self, "Outputs", bound_cls)

def send(self, signalName, value, id=None):
Expand Down Expand Up @@ -210,8 +216,9 @@ def signal_from_args(args, signal_type):

@classmethod
def _check_input_handlers(cls):
unbound = [signal.name for signal in cls.Inputs.__dict__.values()
if isinstance(signal, Input) and not signal.handler]
unbound = [signal.name
for _, signal in _get_members(cls.Inputs, Input)
if not signal.handler]
if unbound:
raise ValueError("unbound signal(s) in {}: {}".
format(cls.__name__, ", ".join(unbound)))
Expand Down Expand Up @@ -242,8 +249,7 @@ def get_signals(cls, direction):
return old_style

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


Expand Down

0 comments on commit dc48d5c

Please sign in to comment.