My software does lots of reflection on "plugin" types. Simply inheriting from a specific type is enough in C#, but when I use python.net I also have to define __namespace__. Since my users generally have the namespace being ., there is no logic reason for them to have to do this.
I can see which part of the code causes this:
// from MetaType.cs:133 (git: 7247da55c174be1b733e5f9fc4e1c356f6c42dc4)if(clsDict.HasKey("__assembly__")||clsDict.HasKey("__namespace__")){returnTypeManager.CreateSubType(name,base_type,clsDict);}
I am wonder if we could broaden the cases where TypeManager.CreateSubType is used. For example in cases where the super class is a type created with CreateSubType, or just any .NET class in general. Maybe it could also be if the super class implements a specific interface.
_TODO_
Add a way to not have to specify namespace in the class in order for reflection to work.
The logic reason is that classes with __namespace__ are .NET classes as well as Python classes, and classes without it are just Python classes. This is by design.
@lostmsu The point is that it could be enough that the base class is a .NET class. Since we control the __new__ in this case anyhow, this wouldn't be a huge change (a breaking one, yes, but I think the new behaviour might be less surprising).
Maybe I can add that if the base class is abstract, inheriting from it without namespace causes a an exception during construction: "Python.Runtime.PythonException: cannot instantiate abstract class". A similar issue happens with interfaces.
Also the python object seems to loose all memory of its type once it gets converted back into an C# object, casting it to its base type.
@rmadsen-ks Hi can I ask if you find any workaround for the problem? I’m having the exact same problem of inheriting from an abstract base class then converting back into C# loses all info. GetType.GetFields() won’t work at all and I’m honestly stuck right now. I wonder if #433 can help.
Hi @phuongdtvd, this sounded like a design decision to me, so I made a fork which does some of these things a bit differently. I don't think #433 makes a huge difference here.
@rmadsen-ks Could you create a PR from your branch? I personally don't see (right now) a problem with always making classes derived from .NET classes also .NET classes themselves (with a way to shut that off). We could make this behaviour configurable (something like Runtime.Configure("<feature-name>", true)), to keep it compatible without bumping the major version.
Hi @filmor, sure, but I have a bunch of features on that fork, some more or less experimental. In total, it is not that many changes. I'll clean it up a bit and setup a PR.
Turning previously non-.NET types defined in Python as derived from .NET types into .NET types would be a breaking change. As 3.0 is released, this is problematic.
Activity
lostmsu commented on Apr 27, 2022
The logic reason is that classes with __namespace__ are .NET classes as well as Python classes, and classes without it are just Python classes. This is by design.
filmor commented on Apr 27, 2022
@lostmsu The point is that it could be enough that the base class is a .NET class. Since we control the __new__ in this case anyhow, this wouldn't be a huge change (a breaking one, yes, but I think the new behaviour might be less surprising).
lostmsu commented on Apr 27, 2022
@filmor are you suggesting all new derived classes to be .NET classes by default? What would be the way to turn that off?
rmadsen-ks commented on Apr 29, 2022
Maybe I can add that if the base class is abstract, inheriting from it without namespace causes a an exception during construction: "Python.Runtime.PythonException: cannot instantiate abstract class". A similar issue happens with interfaces.
Also the python object seems to loose all memory of its type once it gets converted back into an C# object, casting it to its base type.
Both these issues could be fixed by this change.
phuongdtvd commented on Nov 17, 2022
@rmadsen-ks Hi can I ask if you find any workaround for the problem? I’m having the exact same problem of inheriting from an abstract base class then converting back into C# loses all info. GetType.GetFields() won’t work at all and I’m honestly stuck right now. I wonder if #433 can help.
rmadsen-ks commented on Nov 18, 2022
Hi @phuongdtvd, this sounded like a design decision to me, so I made a fork which does some of these things a bit differently. I don't think #433 makes a huge difference here.
filmor commented on Nov 18, 2022
@rmadsen-ks Could you create a PR from your branch? I personally don't see (right now) a problem with always making classes derived from .NET classes also .NET classes themselves (with a way to shut that off). We could make this behaviour configurable (something like Runtime.Configure("<feature-name>", true)), to keep it compatible without bumping the major version.
rmadsen-ks commented on Nov 18, 2022
Hi @filmor, sure, but I have a bunch of features on that fork, some more or less experimental. In total, it is not that many changes. I'll clean it up a bit and setup a PR.
rmadsen-ks commented on Nov 18, 2022
@filmor, I have added PR #2019. Those are the majority of changes in my fork.
lostmsu commented on Nov 29, 2022
Turning previously non-.NET types defined in Python as derived from .NET types into .NET types would be a breaking change. As 3.0 is released, this is problematic.
filmor commented on Nov 29, 2022
@lostmsu I lined out how we could do it anyhow, via a runtime/startup feature flag mechanism. No magic required.