[IronPython] TryGetMember is called for methods instead of TryInvokeMember

Dino Viehland dinov at microsoft.com
Wed Jun 23 01:16:01 CEST 2010


Calling TryGetMember is actually the correct thing to do.  Different languages have different semantics for when you do “a.Foo();”  Some languages turn this into an InvokeMember while other languages separate this out into a get and invoke.  In Python we separate this out into a get and invoke but you could also get this behavior in C# by doing:

dynamic x = a.Foo;
x();

Which should also work.  So you really need to support both GetMember and InvokeMember.  The result of the GetMember is usually something which binds the instance to the member and then when it does whatever InvokeMember would have done.

I believe the part about updating to the latest assemblies in the thread was about using the assemblies compiled for .NET 4.0 instead of the assemblies compiled for .NET 2.0 SP1+ which don’t work w/ dynamic in .NET 4.0.

From: users-bounces at lists.ironpython.com [mailto:users-bounces at lists.ironpython.com] On Behalf Of Marcus Carvalho
Sent: Tuesday, June 22, 2010 10:55 AM
To: users at lists.ironpython.com
Subject: [IronPython] TryGetMember is called for methods instead of TryInvokeMember

I have an application that passes a DynamicObject to an IronPython script. The class works perfectly in C# but when a method is invoked inside a IronPython script the TryGetMember is called instead of TryInvokeMember and if I try to return a value through TryGetMember I get an exception saying that the member is not callable.

I found a user with similar problem (http://social.msdn.microsoft.com/Forums/en/dlr/thread/0556e593-2360-43b8-97e5-201c3c3ce1c5). He said that dowloading the latest release solved the problem. I have downloaded the latest source code release (70538), compiled it to .NET 4.0, but I still having the issue.

Here is a slightly modified code I get from the post, that does not work for me:


using
System;

using
System.Collections.Generic;

using
System.Linq;

using
System.Text;

using
IronPython.Hosting;

using
IronPython.Runtime;

using
Microsoft.Scripting;

using
Microsoft.Scripting.Hosting;

using
System.Dynamic;

 

 

 

namespace
TestDynamicInvokeFromPython

{
class Program

{
static void Main(string[] args)

{
dynamic myDynamicObject = new MyDynamicObject();
//first tey calling this object from C#, it should call Foo() and they try to call MissingMethod();
Console.WriteLine("C# Test...");
try

{

myDynamicObject.Foo();

System.
Console.WriteLine("Method Result: " + myDynamicObject.MissingMethod());

}
catch (Exception ex)

{
Console.WriteLine("Got C# exception: " + ex.Message);

}

 
ScriptEngine pythonEngine = Python.CreateEngine();
ScriptScope scriptScope = pythonEngine.CreateScope();
string pythonScript = SetPythonScript();
ScriptSource script = pythonEngine.CreateScriptSourceFromString(pythonScript, SourceCodeKind.Statements);

scriptScope.SetVariable(
"myDynamicObject", myDynamicObject);
//Now do the same thing from python, I expect to get the same behaviour as from C# (but I don't)
Console.WriteLine("\r\nScript Test...");
try

{

script.Execute(scriptScope);

}
catch (Exception ex)

{
Console.WriteLine("Got script exception: " + ex.Message);

}

 
Console.ReadKey();

}
static string SetPythonScript()

{
string s = "";

s +=
"import clr" + "\r\n";

s +=
"clr.AddReference('mscorlib')" + "\r\n";

s +=
"myDynamicObject.Foo();" + "\r\n";

s +=
"myDynamicObject.MissingMethod();" + "\r\n";
return s;

}

}

 
public class MyDynamicObject : DynamicObject

{
public void Foo()

{
Console.WriteLine("Foo() Called");

}
public override DynamicMetaObject GetMetaObject(System.Linq.Expressions.Expression parameter)

{
Console.WriteLine("GetMetaObject() Called");
return base.GetMetaObject(parameter);

}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)

{
if (binder.Name == "MissingMethod")

{

result =
"Method Found";
return true;

}
else

{

result =
null;
return false;

}

}
public override bool TryGetMember(GetMemberBinder binder, out object result)

{
Console.WriteLine("TryGetMember() Called");
return base.TryGetMember(binder, out result);

}
//#region AllOtherOverridees
// ...
//#endregion //AllOtherOverridees

}

}

 

Marcus Carvalho 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/ironpython-users/attachments/20100622/7142b005/attachment.html>


More information about the Ironpython-users mailing list