Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception when importing a C++/CLI assembly using "operator -" #2261

Open
maxun opened this issue Oct 7, 2023 · 2 comments
Open

Exception when importing a C++/CLI assembly using "operator -" #2261

maxun opened this issue Oct 7, 2023 · 2 comments
Labels

Comments

@maxun
Copy link

maxun commented Oct 7, 2023

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 win32
Type "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 Operator
Traceback (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_module
System.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();
		}
	};
}

See Operator.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.

@filmor
Copy link
Member

filmor commented Oct 7, 2023

I'll have a look. Especially for edge cases like these, PRs are appreciated. I don't have an MSVC build setup available right now.

@filmor filmor added the bug label Oct 7, 2023
@maxun
Copy link
Author

maxun commented Oct 7, 2023

Here is the assembly so you do not need to recompile it with MSVC:

Operator.zip

I am not sure about the purpose of this IsReverse function but adding a trivial check should fix this bug.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants