ironpython2
ironpython2 copied to clipboard
Referencing multiple assemblies can trigger TypeError when calling an extension method
Running the following in .NET (Core):
import clr
clr.AddReference("System.Core")
clr.AddReference("System.Linq")
import System.Linq
clr.ImportExtensions(System.Linq)
range(1,10).ElementAt(5)
leads to the following TypeError:
TypeError: Multiple targets could match: ElementAt(IEnumerable[Int32], Int32), ElementAt(IEnumerable[Int32], Int32)
Reported by @Simon900225 on gitter.
Interestingly, it works fine in ipy3.
Sorry, false alarm , I see label "core" now.
It seems that on .NET Core, Enumerable
extensions are exported by System.Core.dll
, and by System.Linq.dll
. Therefore there are two identical ambiguous targets, each one comes from a different assembly. The above example works on .NET Core if one of the DLL references is removed. It also keeps working on .NET Framework if the reference to System.Linq
(but not System.Core
) is removed.
I am not sure what should be a desired behaviour here; should overloads from one DLL hide extension methods of matching signature defined in another DLL? Any order of priority?
My initial reaction to the issue is that if the user was loading two different versions of an assembly I would just say fix your code. But in this case they're loading System.Core
which is just a facade assembly that's type-forwarding Enumerable
to the System.Linq
assembly so it's actually the same type? Feels like we should be able to avoid the ambiguity in this case.
@slozier I think I agree with you: if two or more assemblies export extension methods with the same signature, then it is a legitimate "ambiguous call" case and the error message is warranted (I wish it were more informative, though). However, if it just a case of a simple type forwarding, then ImportExtensions
should avoid importing from the same type twice.
A sidenote is that it worked up until 2.7.9 and then stopped working from 2.7.10 and forward.
@Simon900225 Were you using 2.7.9 with .NET Core?
Yes, with .NET 6. But I guess that it's running with help of the "compatibility layer" then as 2.7.9 is not built with .NET core as a target.
Ok, 2.7.9 has a .NET Core 2.1 target so I assume .NET 6 will use those assemblies. I'll have to see what changed between 2.7.9 and 2.7.10.
Looks like it started failing on https://github.com/IronLanguages/ironpython2/pull/619 (which makes sense).
Similar issue hitting slightly different code paths:
import clr
clr.AddReference("System.Core")
import System.Linq
clr.ImportExtensions(System.Linq)
clr.ImportExtensions(System.Linq.Enumerable)
range(1,10).ElementAt(5)
In this case the 2nd ImportExtensions
is loading the System.Linq
assembly (because that's the assembly of the forwarded type) and we then get the same failure.
Looks like test_cliclass.test_extension_methods
is hitting this issue.