+def _polymorphic_method(func):
+ @functools.wraps(func)
+ def wrapper(a, b):
+ if isinstance(b, Expression):
+ return func(a, b)
+ if isinstance(b, numbers.Rational):
+ b = constant(b)
+ return func(a, b)
+ return NotImplemented
+ return wrapper
+
+def _polymorphic_operator(func):
+ # A polymorphic operator should call a polymorphic method, hence we just
+ # have to test the left operand.
+ @functools.wraps(func)
+ def wrapper(a, b):
+ if isinstance(a, numbers.Rational):
+ a = constant(a)
+ return func(a, b)
+ elif isinstance(a, Expression):
+ return func(a, b)
+ raise TypeError('arguments must be linear expressions')
+ return wrapper
+
+