IronLanguages / ironpython3

Implementation of Python 3.x for .NET Framework that is built on top of the Dynamic Language Runtime.
Apache License 2.0
2.48k stars 287 forks source link

Calling method with an argument of ReadOnlySpan<char> throws ArgumentException #1788

Open Meddington opened 6 months ago

Meddington commented 6 months ago

Description

With the introduction of Span in .NET, more and more methods have arguments of ReadOnlySpan<char> as apposed to string and ReadOnlySpan<bytes> instead of a byte array. Calling methods that have an argument or return type of Span from python results in exceptions being raised. This is becoming a big limitation in IronPython.

.NET Version is 8.0 (also reproduces on earlier versions) IronPython 3.4.1 (latest)

I found this issue talking about the boxing issue with Span, however, I think the cases in which string or a byte array can be converted automatically to Span should be handled. This would solve the issue for most methods, and hopefully get around the boxing issue for these basic cases.

Steps to Reproduce

Run the following python code from IronPython:

import clr
clr.AddReference("System.Security.Cryptography.Algorithms")
from System.Security.Cryptography import RSA

key_pem = """-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzwTp4JKBcB4Xo8XMvwvW
9t1skgssLMv0dflO3Es4Q2iItyeAbuwtV8D/LCaD6L9MKV/3qzAr5lXmld9rh9Z0
XbABS6476TEeMFlbGxHSzil87tQIUTRDyIcXGdvMiKtkkbq5lpMPLnZSsnLk0j/s
Jih8xHM3KpGm6K4s+yWH8plp3div5R4oNIJsNriR1YJmyqwaS4IYmbK/mS5fBO61
6ZedwdN5A5LWUXJqjoY0Z0weRIPgUbTQMKAaEyChyuKO4mfu6em+oD4PJnVwNsjf
ShIMtO5KmHXn0PZPLLf+PwEdQKNwYGF8ZJLoLRH781Zj8vbc53yA54OhpSallJyC
GQIDAQAB
-----END PUBLIC KEY-----"""

rsa = RSA.Create()
rsa.ImportFromPem(key_pem)

Expected behavior:

Code runs without exceptions.

Actual behavior:

Exception calling rsa.ImportFromPem with a signature of public override void ImportFromPem (ReadOnlySpan<char> input);:

ArgumentException with InnerException of TypeLoadException:

GenericArguments[3], 'System.ReadOnlySpan`1[System.Char]', on 'Microsoft.Scripting.Interpreter.FuncCallInstruction`4[T0,T1,T2,TRet]' violates the constraint of type parameter 'TRet'.

TypeLoadException stack trace:

  at System.RuntimeTypeHandle.Instantiate(QCallTypeHandle handle, IntPtr* pInst, Int32 numGenericArgs, ObjectHandleOnStack type)
   at System.RuntimeType.MakeGenericType(Type[] instantiation)

ArgumentException stack trace:

  at System.RuntimeType.ValidateGenericArguments(MemberInfo definition, RuntimeType[] genericArguments, Exception e)
   at System.RuntimeType.MakeGenericType(Type[] instantiation)
   at Microsoft.Scripting.Interpreter.CallInstruction.GetHelperType(MethodInfo info, Type[] arrTypes)
   at Microsoft.Scripting.Interpreter.CallInstruction.SlowCreate(MethodInfo info, ParameterInfo[] pis)
   at Microsoft.Scripting.Interpreter.CallInstruction.Create(MethodInfo info, ParameterInfo[] parameters)
   at Microsoft.Scripting.Interpreter.DynamicInstructionN..ctor(Type delegateType, CallSite site)
   at Microsoft.Scripting.Interpreter.InstructionList.CreateDynamicInstruction(Type delegateType, CallSiteBinder binder)
   at Microsoft.Scripting.Interpreter.LightCompiler.CompileDynamicExpression(Expression expr)
   at Microsoft.Scripting.Interpreter.LightCompiler.CompileMethodCallExpression(Expression expr)
   at Microsoft.Scripting.Interpreter.LightCompiler.CompileAsVoid(Expression expr)
   at Microsoft.Scripting.Interpreter.LightCompiler.CompileBlockStart(BlockExpression node)
   at Microsoft.Scripting.Interpreter.LightCompiler.CompileBlockExpression(Expression expr, Boolean 
[[SNIP]]

Version Information

Windows 10 .NET Version is 8.0 (also reproduces on earlier versions) IronPython 3.4.1 (latest)