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. 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. 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.
Ideas? Enlightenment?

Thanks

Here's the code:

import clr
clr.AddReference("System.Core")
import System
from System import Linq

clr.ImportExtensions(Linq)

class Product(object):
    def __init__(self, cat, id, qtyOnHand ):
        self.Cat = cat
        self.ID = id
        self.QtyOnHand = qtyOnHand
        self.Q = self.QtyOnHand

def runit():
    products = [Product(prod[0], prod[1], prod[2]) for prod in
('DrillRod', 'DR123', 45), ('Flange', 'F423', 12), ('Gizmo', 'G9872', 214), ('Sprocket', 'S534', 42)]

# pd = products.Where(lambda prod: prod.Q < 40).Select(lambda prod: (prod.Cat, prod.ID) ) # blows: "Type System.Collections.Generic.IEnumerable`1[TSource] contains generic parameters"

# pd = products.Where(lambda prod: prod.Q < 40).AsEnumerable().Select(lambda prod: (prod.Cat, prod.ID) )
    #blows, same exception

    pd = products.Where(lambda prod: prod.Q < 40)               #ok
for prod in pd: print prod.Cat, prod.ID, prod.Q #==> Flange F423 12

# pd2 = pd.Select(lambda prod: (prod.Cat, prod.ID) ) #blows, same exception - note source (pd) is not a list at this point - it's a ...+WhereEnumerator... object

    pd2 = products.Select(lambda prod: (prod.Cat, prod.ID) )    #ok
for prod in pd2: print "Cat: {0}, ID: {1}".format(prod[0], prod[1]) #==> Cat: DrillRod, ID: DR123 ...

pd2 = list(pd).Select(lambda prod: (prod.Cat, prod.ID) ) #ok Wrapping it in a list for prod in pd2: print "Cat: {0}, ID: {1}".format(prod[0], prod[1]) #==> Cat: Flange, ID: F423

# pd = products.Where(lambda prod: prod.Q < 30).ToList() #blows, same exception

    pd = list( products.Where(lambda prod: prod.Q < 30) )       #ok
for prod in pd2: print "Cat: {0}, ID: {1}".format(prod[0], prod[1]) #==> Cat: Flange, ID: F423

    # ok
pd = list( products.Where(lambda prod: prod.Q < 40) ).Select(lambda prod: "Cat: {0}, ID: {1}, Qty: {2}".format(prod.Cat, prod.ID, prod.Q))
    for prod in pd: print prod      #==> Cat: Flange, ID: F423, Qty: 12

    # ok
    pd = ( list(products.Where(lambda prod: prod.Q < 40))
.Select(lambda prod: "Cat: {0}, ID: {1}, Qty: {2}".format(prod.Cat, prod.ID, prod.Q)) )
    for prod in pd: print prod      #==> Cat: Flange, ID: F423, Qty: 12

if __name__ == "__main__":
    runit()
-------------------------------------------------------------------------------------------------------------------------

Here's the barf:

System.ArgumentException was unhandled by user code
Message=Type System.Collections.Generic.IEnumerable`1[TSource] contains generic parameters
  Source=System.Core
  StackTrace:
       at System.Dynamic.Utils.TypeUtils.ValidateType(Type type)
at System.Linq.Expressions.Expression.Convert(Expression expression, Type type, MethodInfo method) at Microsoft.Scripting.Ast.Utils.Convert(Expression expression, Type type) at IronPython.Runtime.Binding.MetaBuiltinFunction.GetInstance(Expression instance, Type testType) at IronPython.Runtime.Binding.MetaBuiltinFunction.MakeSelfCall(DynamicMetaObjectBinder call, Expression codeContext, DynamicMetaObject[] args) at IronPython.Runtime.Binding.MetaBuiltinFunction.InvokeWorker(DynamicMetaObjectBinder call, Expression codeContext, DynamicMetaObject[] args) at IronPython.Runtime.Binding.MetaBuiltinFunction.Invoke(PythonInvokeBinder pythonInvoke, Expression codeContext, DynamicMetaObject target, DynamicMetaObject[] args) at IronPython.Runtime.Binding.PythonInvokeBinder.BindWorker(DynamicMetaObject context, DynamicMetaObject target, DynamicMetaObject[] args) at IronPython.Runtime.Binding.PythonInvokeBinder.Bind(DynamicMetaObject target, DynamicMetaObject[] args) at Microsoft.Scripting.Utils.DynamicUtils.GenericInterpretedBinder`1.Bind(DynamicMetaObjectBinder binder, Int32 compilationThreshold, Object[] args) at Microsoft.Scripting.Utils.DynamicUtils.LightBind[T](DynamicMetaObjectBinder binder, Object[] args, Int32 compilationThreshold) at IronPython.Runtime.Types.BuiltinFunction.IronPython.Runtime.Binding.IFastInvokable.MakeInvokeBinding[T](CallSite`1 site, PythonInvokeBinder binder, CodeContext state, Object[] args) at IronPython.Runtime.Binding.PythonInvokeBinder.BindDelegate[T](CallSite`1 site, Object[] args) at System.Runtime.CompilerServices.CallSiteBinder.BindCore[T](CallSite`1 site, Object[] args) at System.Dynamic.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2) at Test_CLR_ImportExtensions$2.runit$80(PythonFunction $function) in C:\IPy27_Projects\IPy_LINQ1\IPy_LINQ1\Test_CLR_ImportExtensions.py:line 131 at IronPython.Runtime.PythonFunction.FunctionCaller.Call0(CallSite site, CodeContext context, Object func) at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1) at __main__$1.__main__(FunctionCode $functionCode) in C:\IPy27_Projects\IPy_LINQ1\IPy_LINQ1\Main.py:line 21
       at IronPython.Compiler.RuntimeScriptCode.InvokeTarget(Scope scope)
       at IronPython.Compiler.RuntimeScriptCode.Run(Scope scope)
at IronPython.Hosting.PythonCommandLine.RunFileWorker(String fileName)
       at IronPython.Hosting.PythonCommandLine.RunFile(String fileName)
  InnerException:  (nothing after this)






_______________________________________________
Users mailing list
Users@lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com

Reply via email to