Description
Environment
- Pythonnet version: 3.0.5
- Python version: 3.10
- Operating System: Windows 11
- .NET Runtime: .NET Framework 4.7.2
Details
I have a C# object that I pass into python, and I am trying to implement some python builtins on the C# class. This works fine for some methods, like __repr__() or __dir__(), but runs into issues with __getattribute__. This is an issue as I would like to implement __getattr__ or __getattribute__ for the purposes of customizing attribute access in python for some of my .NET types. https://docs.python.org/3/reference/datamodel.html#object.__getattribute__
I have created a demo C# console application to demonstrate my problem:
MyClass.cs:
namespace pythonnet_demo
{
internal class MyClass
{
public object __repr__()
{
return "Test repr!";
}
public object __getattribute__(string name)
{
return "__getattribute__ works!";
}
}
}
Program.cs:
using Python.Runtime;
using System.IO;
namespace pythonnet_demo
{
internal class Program
{
static void Main(string[] args)
{
string pythonHome = @"C:\dev\python";
Runtime.PythonDLL = Path.Combine(pythonHome, "python310.dll");
PythonEngine.PythonHome = pythonHome;
PythonEngine.Initialize();
MyClass obj = new MyClass();
using (Py.GIL())
{
PyModule _scope = Py.CreateScope("__main__");
_scope.Set("obj", obj);
//Test repr, works as expected, "Test repr!" printed to console
_scope.Exec("print(repr(obj))");
//Test __getattribute__, throws exception, 'AttributeError', no attribute X
_scope.Exec("print(obj.X)");
}
}
}
}
As noted in the above comments, the __repr__() method from MyClass.cs runs properly from python, but not the __getattribute__ method.
If I create a script.py file and just run it normally via python I do get the expected result.
class MyClassPy:
def __repr__(self):
return "Test repr!"
def __getattribute__(self, name):
return "__getattribute__ works!"
obj = MyClassPy()
print(repr(obj))
print(obj.X)
The above script prints to the console as expected when run (output below), unlike C# where only the repr method is executed.
Test repr!
__getattribute__ works!
Why doesn't this work from C#? Am I missing something?
Note: I have tried changing the parameters, eg using object name
instead of string name
in MyClass.cs, same result.