<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
  </head>
  <body text="#000000" bgcolor="#ffffff">
    Hi all - I've been experimenting with with the new extension method
    import facility and so far it is working well, more or less as I
    expected, except that I'm getting an error message when I try to
    chain Linq method calls. I don't know whether this should be
    considered a bug or not. It seems the dynamic code cannot pass the
    intermediate enumerable (iterator/generator?) object between method
    calls. I have to wrap it in a list(...) call for it to work. And I
    would have thought .ToList() would work, but it blows too. <br>
    I don't know enough about the internals to judge whether it's even
    possible for the DLR to do this. The exception seems to be coming
    from DLR code.<br>
    Would be nice if the chained syntax could be made to work, tho. But
    even as it is, it still allows much cleaner code style than my
    homebrew module did.<br>
    Ideas? Enlightenment?<br>
    <br>
    Thanks<br>
    <br>
    Here's the code:<br>
    <br>
    import clr<br>
    clr.AddReference("System.Core")<br>
    import System<br>
    from System import Linq<br>
    <br>
    clr.<font color="#3333ff">ImportExtensions</font>(Linq) <br>
    <br>
    class Product(object):<br>
    &nbsp;&nbsp;&nbsp; def __init__(self, cat, id, qtyOnHand ):<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.Cat = cat<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.ID = id<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.QtyOnHand = qtyOnHand<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.Q = self.QtyOnHand<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
    def runit():<br>
    &nbsp;&nbsp;&nbsp; products = [Product(prod[0], prod[1], prod[2]) for prod in <br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ('DrillRod', 'DR123', 45), ('Flange', 'F423', 12), ('Gizmo',
    'G9872', 214), ('Sprocket', 'S534', 42)]<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
    &nbsp;&nbsp;&nbsp; # pd = products.Where(lambda prod: prod.Q &lt; 40).Select(lambda
    prod: (prod.Cat, prod.ID) ) <br>
    &nbsp;&nbsp;&nbsp; # <font color="#ff0000">blows</font>: "<font color="#ff0000">Type
      System.Collections.Generic.IEnumerable`1[TSource] contains generic
      parameters</font>"<br>
    &nbsp;&nbsp;&nbsp; <br>
    &nbsp;&nbsp;&nbsp; # pd = products.Where(lambda prod: prod.Q &lt;
    40).AsEnumerable().Select(lambda prod: (prod.Cat, prod.ID) ) <br>
    &nbsp;&nbsp;&nbsp; #blows, same exception<br>
    &nbsp;&nbsp;&nbsp; <br>
    &nbsp;&nbsp;&nbsp; pd = <font color="#3333ff">products</font>.Where(lambda prod:
    prod.Q &lt; 40)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #ok<br>
    &nbsp;&nbsp;&nbsp; for prod in pd: print prod.Cat, prod.ID, prod.Q&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
    &nbsp;&nbsp;&nbsp; &nbsp; #==&gt; Flange F423 12<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
    &nbsp;&nbsp;&nbsp; # pd2 = <font color="#3333ff">pd</font>.Select(lambda prod:
    (prod.Cat, prod.ID) )&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #blows, same exception - note source
    (pd) is not a list at this point - it's a ...+WhereEnumerator...
    object<br>
    &nbsp;&nbsp;&nbsp; <br>
    &nbsp;&nbsp;&nbsp; pd2 = <font color="#3333ff">products</font>.Select(lambda prod:
    (prod.Cat, prod.ID) )&nbsp;&nbsp;&nbsp; #ok<br>
    &nbsp;&nbsp;&nbsp; for prod in pd2: print "Cat: {0}, ID: {1}".format(prod[0],
    prod[1]) &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; #==&gt; Cat: DrillRod, ID: DR123 ...<br>
    &nbsp;&nbsp;&nbsp; <br>
    &nbsp;&nbsp;&nbsp; pd2 = list(<font color="#3333ff">pd</font>).Select(lambda prod:
    (prod.Cat, prod.ID) )&nbsp;&nbsp;&nbsp; #ok&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Wrapping it in a list<br>
    &nbsp;&nbsp;&nbsp; for prod in pd2: print "Cat: {0}, ID: {1}".format(prod[0],
    prod[1]) &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; #==&gt; Cat: Flange, ID: F423<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
    &nbsp;&nbsp;&nbsp; # pd = <font color="#3333ff">products</font>.Where(lambda prod:
    prod.Q &lt; 30).<font color="#cc33cc">ToList</font>()&nbsp;&nbsp;&nbsp; #blows,
    same exception<br>
    <br>
    &nbsp;&nbsp;&nbsp; pd = list( <font color="#3333ff">products</font>.Where(lambda
    prod: prod.Q &lt; 30) )&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #ok<br>
    &nbsp;&nbsp;&nbsp; for prod in pd2: print "Cat: {0}, ID: {1}".format(prod[0],
    prod[1])&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; #==&gt; Cat: Flange, ID: F423<br>
    <br>
    &nbsp;&nbsp;&nbsp; # ok<br>
    &nbsp;&nbsp;&nbsp; pd = list( <font color="#3333ff">products</font>.Where(lambda
    prod: prod.Q &lt; 40) ).Select(lambda prod: "Cat: {0}, ID: {1}, Qty:
    {2}".format(prod.Cat, prod.ID, prod.Q))<br>
    &nbsp;&nbsp;&nbsp; for prod in pd: print prod&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #==&gt; Cat: Flange, ID: F423,
    Qty: 12<br>
    &nbsp;&nbsp;&nbsp; <br>
    &nbsp;&nbsp;&nbsp; # ok<br>
    &nbsp;&nbsp;&nbsp; pd = ( list(<font color="#3333ff">products</font>.Where(lambda
    prod: prod.Q &lt; 40))<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Select(lambda prod: "Cat: {0}, ID: {1}, Qty:
    {2}".format(prod.Cat, prod.ID, prod.Q)) )<br>
    &nbsp;&nbsp;&nbsp; for prod in pd: print prod&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #==&gt; Cat: Flange, ID: F423,
    Qty: 12<br>
    <br>
    if __name__ == "__main__":<br>
    &nbsp;&nbsp;&nbsp; runit()<br>
-------------------------------------------------------------------------------------------------------------------------<br>
    <br>
    Here's the barf:<br>
    <br>
    System.ArgumentException was unhandled by user code<br>
    &nbsp; Message=Type System.Collections.Generic.IEnumerable`1[TSource]
    contains generic parameters<br>
    &nbsp; Source=System.Core<br>
    &nbsp; StackTrace:<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at System.Dynamic.Utils.TypeUtils.ValidateType(Type type)<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at System.Linq.Expressions.Expression.Convert(Expression
    expression, Type type, MethodInfo method)<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at Microsoft.Scripting.Ast.Utils.Convert(Expression
    expression, Type type)<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at
    IronPython.Runtime.Binding.MetaBuiltinFunction.GetInstance(Expression
    instance, Type testType)<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at
    IronPython.Runtime.Binding.MetaBuiltinFunction.MakeSelfCall(DynamicMetaObjectBinder
    call, Expression codeContext, DynamicMetaObject[] args)<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at
    IronPython.Runtime.Binding.MetaBuiltinFunction.InvokeWorker(DynamicMetaObjectBinder
    call, Expression codeContext, DynamicMetaObject[] args)<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at
    IronPython.Runtime.Binding.MetaBuiltinFunction.Invoke(PythonInvokeBinder
    pythonInvoke, Expression codeContext, DynamicMetaObject target,
    DynamicMetaObject[] args)<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at
    IronPython.Runtime.Binding.PythonInvokeBinder.BindWorker(DynamicMetaObject
    context, DynamicMetaObject target, DynamicMetaObject[] args)<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at
    IronPython.Runtime.Binding.PythonInvokeBinder.Bind(DynamicMetaObject
    target, DynamicMetaObject[] args)<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at
    Microsoft.Scripting.Utils.DynamicUtils.GenericInterpretedBinder`1.Bind(DynamicMetaObjectBinder
    binder, Int32 compilationThreshold, Object[] args)<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at
    Microsoft.Scripting.Utils.DynamicUtils.LightBind[T](DynamicMetaObjectBinder
    binder, Object[] args, Int32 compilationThreshold)<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at
    IronPython.Runtime.Types.BuiltinFunction.IronPython.Runtime.Binding.IFastInvokable.MakeInvokeBinding[T](CallSite`1
    site, PythonInvokeBinder binder, CodeContext state, Object[] args)<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at
    IronPython.Runtime.Binding.PythonInvokeBinder.BindDelegate[T](CallSite`1
    site, Object[] args)<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at
    System.Runtime.CompilerServices.CallSiteBinder.BindCore[T](CallSite`1
    site, Object[] args)<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at
    System.Dynamic.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet](CallSite
    site, T0 arg0, T1 arg1, T2 arg2)<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at Test_CLR_ImportExtensions$2.runit$80(PythonFunction
    $function) in
    C:\IPy27_Projects\IPy_LINQ1\IPy_LINQ1\Test_CLR_ImportExtensions.py:line
    131<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at
    IronPython.Runtime.PythonFunction.FunctionCaller.Call0(CallSite
    site, CodeContext context, Object func)<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at
    System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite
    site, T0 arg0, T1 arg1)<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at __main__$1.__main__(FunctionCode $functionCode) in
    C:\IPy27_Projects\IPy_LINQ1\IPy_LINQ1\Main.py:line 21<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at IronPython.Compiler.RuntimeScriptCode.InvokeTarget(Scope
    scope)<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at IronPython.Compiler.RuntimeScriptCode.Run(Scope scope)<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at IronPython.Hosting.PythonCommandLine.RunFileWorker(String
    fileName)<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at IronPython.Hosting.PythonCommandLine.RunFile(String
    fileName)<br>
    &nbsp; InnerException:&nbsp; (nothing after this)<br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
  </body>
</html>