I’m trying to inherit from an abstract .NET base class in Python (2.7) using Python.NET (2.1.0). I’m a Python n00b but from what I understood…
Here’s what I managed to do in Python only and which works fine:
import abc
class Door(object):
    __metaclass__ = abc.ABCMeta
    def open(self):
        if not self.is_open():
            self.toggle()
    def close(self):
        if self.is_open():
            self.toggle()
    @abc.abstractmethod
    def is_open(self):
        pass
    @abc.abstractmethod
    def toggle(self):
        pass
class StringDoor(Door):
    def __init__(self):
        self.status = "closed"
    def is_open(self):
        return self.status == "open"
    def toggle(self):
        if self.status == "open":
            self.status = "closed"
        else:
            self.status = "open"
class BooleanDoor(Door):
    def __init__(self):
        self.status = True
    def is_open(self):
        return self.status
    def toggle(self):
        self.status = not (self.status)
Door.register(StringDoor)
Door.register(BooleanDoor)
Now, all I did was to replace the abstract base class Door by a C# representation:
namespace PythonAbstractBaseClass
{
    public abstract class Door
    {
        public virtual void Open()
        {
            if (!IsOpen())
                Toggle();
        }
        public virtual void Close()
        {
            if (IsOpen())
                Toggle();
        }
        public abstract bool IsOpen();
        public abstract void Toggle();
    }
}
Removing Door from the Python part and importing it from the .NET assembly instead, I end up with this:
import clr
import abc
from PythonAbstractBaseClass import Door
class StringDoor(Door):
    def __init__(self):
        self.status = "closed"
    def is_open(self):
        return self.status == "open"
    def toggle(self):
        if self.status == "open":
            self.status = "closed"
        else:
            self.status = "open"
class BooleanDoor(Door):
    def __init__(self):
        self.status = True
    def is_open(self):
        return self.status
    def toggle(self):
        self.status = not (self.status)
Door.register(StringDoor)
Door.register(BooleanDoor)
But this fails with the following error message:
    Door.register(StringDoor)
AttributeError: type object 'Door' has no attribute 'register'
From what I understood about abc.ABCMeta, this metaclass contributes the register() method. It seems that abstract C# classes do not come with the same metaclass. They instead come with metaclass CLR Metatype which obviously does not provide register().
But if I drop the call to register(), on instantiating one of the derived classes, I receive the error message
    sdoor = StringDoor()
TypeError: cannot instantiate abstract class
Is there a way to inherit from an abstract .NET class or is this a missing feature?
Thanks in advance,
Henning
 
     
     
    