- Notifications
You must be signed in to change notification settings - Fork749
Open
Labels
Description
Environment
- Pythonnet version: >= 3.0.0 ( version < 3.0.0 are ok)
- Python version: 3.9, 3.10, 3.11, 3.12...
- Operating System: Windows x64
- .NET Runtime: 4.6.2 .net framework
Details
Importing a .net assembly written in C++/CLI using a very specific way to define an operator result in an exception:
Python 3.11.4 | packaged by Anaconda, Inc. | (main, Jul 5 2023, 13:47:18) [MSC v.1916 64 bit (AMD64)] on win32Type "help", "copyright", "credits" or "license" for more information.>>> import clr>>> clr.AddReference(r"C:\Users\laure\source\repos\Operator\x64\Release\Operator.dll")<System.Reflection.RuntimeAssembly object at 0x0000029709E3D680>>>> import OperatorTraceback (most recent call last): File "<stdin>", line 1, in <module> File "<frozen importlib._bootstrap>", line 1176, in _find_and_load File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 676, in _load_unlocked File "<frozen importlib._bootstrap>", line 573, in module_from_spec File "<string>", line 15, in create_moduleSystem.IndexOutOfRangeException: Index was outside the bounds of the array. at Python.Runtime.OperatorMethod.IsReverse(MethodBase method) at Python.Runtime.OperatorMethod.FilterMethods(MethodBase[] methods, MethodBase[]& forwardMethods, MethodBase[]& reverseMethods) at Python.Runtime.ClassManager.GetClassInfo(Type type, ClassBase impl) at Python.Runtime.ClassManager.InitClassBase(Type type, ClassBase impl, ReflectedClrType pyType) at Python.Runtime.ReflectedClrType.GetOrCreate(Type type) at Python.Runtime.ModuleObject.GetAttribute(String name, Boolean guess) at Python.Runtime.ModuleObject.LoadNames() at Python.Runtime.ImportHook.Import(String modname) at Python.Runtime.CLRModule._load_clr_module(PyObject spec)
This can be reproduce with the minimal code (C++/CLI):
namespace Operator{public ref class Matrix{public:Matrix^ operator - (){return gcnew Matrix();}};}
SeeOperator.zip
Investigation
It seems there is two way to define the operator- in C++/CLI:
Matrix^ operator - ()
And
static Matrix^ operator - (Matrix^ m)
There is no issue when using the second form. Actually in C# only the equivalent of the second form is possible. It explains why this bug is very uncommon.
Source of the exception
The code in pythonnet code triggering this exception (src/runtime/Types/OperatorMethod.cs)
public static bool IsReverse(MethodBase method) { Type primaryType = method.IsOpsHelper() ? method.DeclaringType.GetGenericArguments()[0] : method.DeclaringType; Type leftOperandType = method.GetParameters()[0].ParameterType; return leftOperandType != primaryType; }
The exception is thrown because GetGenericArguments return an empty list.