Using multiple class interheritance / mixins in Python test-cases

Hi,

I have a instrument class topic, I wanted to adress with either class inheritance or mixins in Python.
What I’d like to achieve is the following.

There are instruments

  • A1, A2, A3, … of parent type A
  • B1, B2, B3, … of parent type B
  • C1, C2, … of parent type C
    with A, B, C derived from OpenTap.ScipInstrument.
    Now, the implementation of C1 is a combination of A1 and B1. With that, I’d like to implement A1, B2, C3 with a shared code base rather than copying things.

I thought about implementing C1 with class inheritance from (ScpiInstrument,A1,B1) but that fails with “PythonException: Multiple inheritance with managed classes cannot be used.”

Second try was to have a Python mixins M1, M2 such that are defined as

  • class M1
  • class M2
  • class A1 (ScpiInstrument,M1)
  • class B1 (ScipiIinstrument,M2)
  • class C1(ScipiInstrument,M1,M2)
    throwing the PythonException: Non .NET type used as super class for meta type. This is not supported.

If M1 is derived from IResource, IInstrument it fails with PythonException: Method ‘xxxx’ in Type ‘M1’ from assembly ‘Python.Runtime.Dynamic’ does not have an implementation’ with different functions xxxx missing depending on the interface parent.

What I found is a statement in Creating Python Classes Derived from C# Class saying, there shall be no inheritance (not sure, if that applies to my scenario).

Can you give an recommendation how my instrument challenge can be addressed?

Thanks.

Best regards,

Gernot

I did some my trials with Python class wrappers. No error, but no instrument showing up in the Editor as well.

Hi @gernot.hueber,

When you make a subclass of a .NET class its quite restricted because it has to adhere to the .NET class constraints.

That means you can only inherit from one class if one of them is a .NET class (e.g ScpiInstrument). Additionally, you can inherit other interfaces, which means you will have to implement those APIs

So class A1 (ScpiInstrument,M1) works if M1 is an interface, but A1 has to implement the methods defined by M1.

if M1 is a class or “mixin” it will not work.

If you want to use a “mixin”, I suggest just using it without inheritance e.g:

class A1(ScpiInstrument):
   def __init__(self):
      super().__init__()
      self.m1 = M1()

   # forward methods manually
   def F1(self):
      return self.m1.F1()

Hi Rolf,

Thanks for your reply and explanation.

Regarding your proposal and example; looks promising and makes a lot of sense to me. That said, I’ll try out immediately. It solves my main issue of implementing functions multiple times, though still the forwarding needs to be implemented per function (and yes, there are a larger number of functions to be forwarded).

Thanks again for this proposal!

BR, Gernot