Hi Denis, Thanks for your fast response. Sounds completely reasonable to me. And this has not been too much of an issue for me. I got rid of the abstract base class simply by providing an “empty” implementation and using a non-abstract base class. No need for meta classes any more. This way, I got rid of error messages. Great! Unfortunately, there seem to be an issue when calling a virtual method inside the C# implementation. Even when overriding this virtual method in Python, it’s still the base class’ implementation which is called. See the new simple base class defined in C#: namespace PythonBaseClass { using System; public class Door { public virtual void Open() { if (!IsOpen()) Toggle(); } public virtual void Close() { if (IsOpen()) Toggle(); } public virtual bool IsOpen() { Console.WriteLine("Door.IsOpen()"); return false; } public virtual void Toggle() { Console.WriteLine("Door.Toggle()"); } } } The consuming Python code now looks like this: import clr from PythonBaseClass import Door class StringDoor(Door): def __init__(self): self.status = "closed" def IsOpen(self): print "StringDoor.IsOpen()" return self.status == "open" def Toggle(self): print "StringDoor.Toggle()" if self.status == "open": self.status = "closed" else: self.status = "open" But the output does not look like expected: Python 2.7.12 (v2.7.12:d33e0cf91556, Jun 27 2016, 15:19:22) [MSC v.1500 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information.
from PythonInheritedClass import StringDoor d = StringDoor() d.status 'closed' d.Open() Door.IsOpen() Door.Toggle() d.status 'closed'
From my understanding, the output should rather read “StringDoor.<something>()” instead of “Door.<something>()”. Obviously, only the base implementation is called but the overridden methods are ignored. Also a limitation of inheriting C# classes in pythonnet? BR, Henning From: PythonDotNet [mailto:pythondotnet-bounces+hmoeller=comprion.com@python.org] On Behalf Of Denis Akhiyarov Sent: Donnerstag, 22. September 2016 19:38 To: A list for users and developers of Python for .NET <pythondotnet@python.org> Subject: Re: [Python.NET] Inheriting from abstract .NET class You are not a "Python n00b" based on metaclass usage! My recommendation is to keep simple integration layer between CPython and .NET, hence metaclasses were/are not supported. But contributions are welcome! Although I expect this to be a tremendous undertaking based on reviewing multiple sources. Note that metaclass is a very different low-level concept from higher-level abstract classes in .NET, hence direct mapping (e.g. `.register()` ) is not feasible. Thanks, Denis On Thu, Sep 22, 2016 at 10:04 AM, Henning Moeller <HMoeller@comprion.com<mailto:HMoeller@comprion.com>> wrote: Hello out there, I’m trying to inherit from an abstract .NET base class in Python (2.7). I’m a Python n00b but from what I understood… Here’s what I managed to do in Python only and which works fine: [File: room.py] ------- import abc class Room(object): def __init__(self, door): self.door = door def open(self): self.door.open() def close(self): self.door.close() def is_open(self): return self.door.is_open() 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: [File: PythonAbstractBaseClass.dll] ------- 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: [File: room2.py] ------- import clr import abc from PythonAbstractBaseClass import Door class Room(object): def __init__(self, door): self.door = door def open(self): self.door.open() def close(self): self.door.close() def is_open(self): return self.door.is_open() 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 is missing feature? Thanks in advance, Henning _________________________________________________ Python.NET mailing list - PythonDotNet@python.org<mailto:PythonDotNet@python.org> https://mail.python.org/mailman/listinfo/pythondotnet