You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Inheriting and extending Python classes in C# #862
I am trying to let a user of my library inherit a Python class, and override some of its behavior. Simply declaring a class with the same set of methods, and calling ToPython on it somewhat works thanks to Python's duck typing.
Problem is that approach fails to pass isinstance and obj is Class tests in the 3rd-party Python code.
If there's no existing way to deal with it, I'd be happy to implement the necessary machinery, if somebody would give some directions on where to start.
@filmor is it possible to use MetaType to represent my C# class as being derived from a specific Python type? Or do I have to simply go with __instancecheck__?
Can MetaType be used for A (C#) derives from B (C#) deriving from C (Python)?
obj is Class is an "old" way of doing isinstance(obj, Class). I am not sure if they have the same semantics.
And I want to define a derived class in C# like this:
classDerived{...}accept(newDerived().ToPython());
Problem is, according to my understanding from SO, I have to override __instancecheck__ in Base.__class__ for it to recognize my instance of Derived to be an instance of Base. But I can't! I can only change what is in Derived.
Is there a different way to tell Python, that Derived is actually "derived" from Base?
Activity
filmor commentedon May 15, 2019
I'm not sure what you mean by
obj is Classhere, butisinstancecan indeed be overridden, and we do so already: https://github.com/pythonnet/pythonnet/blob/master/src/runtime/metatype.cs#L259In metatype, we register
__instancecheck__(the one I linked) and__subclasscheck__for this purpose, you can try to extend them for your use case.lostmsu commentedon May 15, 2019
@filmor is it possible to use
MetaTypeto represent my C# class as being derived from a specific Python type? Or do I have to simply go with__instancecheck__?Can
MetaTypebe used forA(C#) derives fromB(C#) deriving fromC(Python)?obj is Classis an "old" way of doingisinstance(obj, Class). I am not sure if they have the same semantics.filmor commentedon May 15, 2019
obj is Classis not the old way of doingisinstance, it's an entirely different thing (checking thatobjandClassare the exact same objects).The issue here is that
Bdoes not derive from the Python class. In__instancecheck__we solve this by checking whether the object we are looking at is of our metaclass (https://github.com/pythonnet/pythonnet/blob/master/src/runtime/metatype.cs#L287) and if that's the case, checking if it's "assignable from" (https://github.com/pythonnet/pythonnet/blob/master/src/runtime/metatype.cs#L300).What you could do is introducing an attribute that is checked in
DoInstanceCheck:Alternatively, you could try to override
__instancecheck__directly on your (base) class.lostmsu commentedon May 15, 2019
@filmor thanks for your help. I will try that approach tomorrow.
Also, excuse my lack of knowledge about Python. Using Python.NET is actually the way I am trying to avoid it as much as possible :)
lostmsu commentedon May 16, 2019
@filmor looked at some docs about
isinstanceand its relationship to__instancecheck__, and can't figure how to apply it to my problem.Suppose I have this 3rd party code (so I can't modify it):
And I want to define a derived class in C# like this:
Problem is, according to my understanding from SO, I have to override
__instancecheck__inBase.__class__for it to recognize my instance ofDerivedto be an instance ofBase. But I can't! I can only change what is inDerived.Is there a different way to tell Python, that
Derivedis actually "derived" fromBase?lostmsu commentedon May 16, 2019
@filmor I looked at the Python source code, and this check eventually goes down to walking MRO in
PyType_IsSubtype: https://hg.python.org/cpython/file/v3.5.3/Objects/typeobject.c#l1345allow substituting base types for CLR types (as seen from Python)
allow substituting base types for CLR types (as seen from Python)
allow substituting base types for CLR types (as seen from Python)
allow substituting base types for CLR types (as seen from Python)
allow substituting base types for CLR types (as seen from Python)
allow substituting base types for CLR types (as seen from Python)
allow substituting base types for CLR types (as seen from Python)
allow substituting base types for CLR types (as seen from Python)