[IronPython] Calling Python objects from C#?

Dino Viehland dinov at exchange.microsoft.com
Mon Jan 15 23:00:32 CET 2007


Sorry, I didn't realize we never made that public...

Now that I'm looking at it a little closer I'm surprised how hard it is to get an ICallerContext instance.  I think the easiest way is: module.GetModuleScope(null); (where module is the EngineModule instance in your sample code).  That will return an IModuleScope which implements ICallerContext and that scope should stay in-sync with the module's own scope.



-----Original Message-----
From: users-bounces at lists.ironpython.com [mailto:users-bounces at lists.ironpython.com] On Behalf Of michael_sweeney at agilent.com
Sent: Monday, January 15, 2007 1:25 PM
To: users at lists.ironpython.com
Subject: Re: [IronPython] Calling Python objects from C#?

I think the DefaultContext class is private to the IronPython.Runtime.Calls namespace. I was unable to access it from my applications .dll.

>From the file DefaultContext.cs:

namespace IronPython.Runtime.Calls {
    class DefaultContext : ICallerContext {
        public static DefaultContext Default = new
                      DefaultContext(CallerContextAttributes.None);
        public static DefaultContext DefaultCLS = new
                      DefaultContext(CallerContextAttributes.ShowCls);

This is correct? Or, should the scope be "public class DefaultContext"?

Mike

> -----Original Message-----
> From: users-bounces at lists.ironpython.com [mailto:users-
> bounces at lists.ironpython.com] On Behalf Of Dino Viehland
> Sent: Monday, January 15, 2007 1:08 PM
> To: Discussion of IronPython
> Subject: Re: [IronPython] Calling Python objects from C#?
>
> For the context you should be able to use DefaultContext.Default.  If you
> wanted members from .NET types to show up on types that are used natively
> in Python (e.g. string, int, etc...) you could use
> DefaultContext.DefaultCLS.  If you wanted the lookup to reflect what had
> happened in the module (e.g. whether the user has done import clr or
> import <some .NET namespace>) then you'd want to pass the module instance
> as the context.
>
>
>
> -----Original Message-----
> From: users-bounces at lists.ironpython.com [mailto:users-
> bounces at lists.ironpython.com] On Behalf Of michael_sweeney at agilent.com
> Sent: Monday, January 15, 2007 12:55 PM
> To: users at lists.ironpython.com
> Subject: Re: [IronPython] Calling Python objects from C#?
>
> Thanks Dino,
>
> That is much simpler! Now for get/set of attributes values...
>
> I need an ICallerContext for the Ops.GetAttr() call. Is there a way to get
> this without calling 'object pmodule = module.Import("MyExample");'?
>
>
>         static void Main(string[] args)
>         {
>             PythonEngine engine = new PythonEngine();
>             EngineModule module = engine.CreateModule("MyExample", true);
>
>             try
>             {
>                 engine.ExecuteFile("MyExample.py", module);
>             }
>             catch (Exception ex)
>             {
>                 Console.WriteLine("Failed to execute Example.py file");
>                 Console.WriteLine("Exception: {0}", ex.Message);
>                 return;
>             }
>
>             // Get the Python Class from the module's global list
>             object ptype = module.Globals["MyClass"];
>
>             // Get Module Instance
>             object pmodule = module.Import("MyExample");
>
>             // Create an instance of the object
>             object pobj = Ops.Call(ptype);
>
>             // Call the method - Using Ops.Invoke()
>             object rtnValue = Ops.Invoke(pobj,
>                          SymbolTable.StringToId("DoWork"));
>             Console.WriteLine("DoWork return value = {0}\n", rtnValue);
>
>             // Perform a GetAttr on the object instance
>             object attr = Ops.GetAttr((ICallerContext)pmodule,
>                         pobj, SymbolTable.StringToId("attr"));
>             Console.WriteLine("attr = {0}, type = {}\n", attr);
>
>         }
>
> Thanks in advance...
>
> Mike
>
> > -----Original Message-----
> > From: users-bounces at lists.ironpython.com [mailto:users-
> > bounces at lists.ironpython.com] On Behalf Of Dino Viehland
> > Sent: Monday, January 15, 2007 11:46 AM
> > To: Discussion of IronPython
> > Subject: Re: [IronPython] Calling Python objects from C#?
> >
> > I think the problem is that AllocateObject is equivalent to calling
> > mytype.__new__ which is not quite what you want - you want the
> equivalent
> > of doing mytype () or mytype.__call__()
> >
> > I would change this to:
> >
> >             // Get the Python Class from the module's global list
> >             object ptype = module.Globals["MyClass"];
> >
> >             // Create an instance of the object
> >             object myclass = Ops.Call(ptype);
> >
> > Not only is it more correct it gets rid of the direct dependency on
> > UserType (for example your code wouldn't have worked w/ an old-style
> class
> > or if a user had done MyClass = System.SomeTypeThatHasADoWorkMethod).
> >
> > >From there I think your Ops.Invoke calls should work (although I
> haven't
> > tried to make sure).
> >
> >
> > -----Original Message-----
> > From: users-bounces at lists.ironpython.com [mailto:users-
> > bounces at lists.ironpython.com] On Behalf Of michael_sweeney at agilent.com
> > Sent: Monday, January 15, 2007 9:58 AM
> > To: users at lists.ironpython.com
> > Subject: [IronPython] Calling Python objects from C#?
> >
> > Hi All,
> >
> > My apology if this has been asked before... I have searched for several
> > examples and did not find what I was looking for.
> >
> > My question is what is the best way to interact with Python objects from
> > within C#? I need to call functions, capture the return value and
> get/set
> > attributes from within C#.
> >
> > I have tried several ways and ended up with this example for calling
> > functions, but it generates an exception saying it does not know what
> > "attr" is.
> >
> > Here is my example:
> >
> > File MyExample.py:
> >
> > class MyClass(object):
> >     def __init__(self):
> >         self.attr = 500.0
> >
> >     def DoWork(self):
> >         print "Attr = ", self.attr
> >         return self.attr
> >
> >
> > File Program.cs:
> >
> > using System;
> >
> > using IronPython.Runtime;
> > using IronPython.Runtime.Types;
> > using IronPython.Runtime.Operations;
> > using IronPython.Hosting;
> > using IronPython.Modules;
> >
> > namespace IPyExample
> > {
> >     class Program
> >     {
> >         static void Main(string[] args)
> >         {
> >             PythonEngine engine = new PythonEngine();
> >             EngineModule module = engine.CreateModule("MyExample",
> true);
> >
> >             try
> >             {
> >                 engine.ExecuteFile("MyExample.py", module);
> >             }
> >             catch (Exception ex)
> >             {
> >                 Console.WriteLine("Failed to execute Example.py file");
> >                 Console.WriteLine("Exception: {0}", ex.Message);
> >                 return;
> >             }
> >
> >             // Get the Python Class from the module's global list
> >             UserType ptype = module.Globals["MyClass"] as UserType;
> >
> >             // Create an instance of the object
> >             object myclass = ptype.AllocateObject();
> >
> >             // Call the method - Using Ops.Invoke()
> >             Ops.Invoke(myclass, SymbolTable.StringToId("DoWork"));
> >
> >             // Call the same method - Using UserType.Invoke()
> >             object rtnValue = ptype.Invoke(myclass,
> >                 SymbolTable.StringToId("DoWork"));
> >
> >             Console.WriteLine("DoWork return value = {0}\n", rtnValue);
> >         }
> >     }
> > }
> >
> >
> > Exception:
> >
> > C:\Documents and Settings\sweeneym\My Documents\Visual Studio
> > 2005\Projects\ATF.
> > IP\IPyExample\bin\Debug>IPYExample
> > Attr =
> > Unhandled Exception: System.MissingMemberException: attr
> >    at IronPython.Runtime.Types.UserType.GetAttr(ICallerContext context,
> > Object self, SymbolId name) in C:\Development\Ir
> > onPython-1.1\Src\IronPython\Runtime\Types\UserType.cs:line 370
> >    at IronPython.Runtime.Operations.Ops.GetAttr(ICallerContext context,
> > Object o, SymbolId name) in C:\Development\IronP
> > ython-1.1\Src\IronPython\Runtime\Operations\Ops.cs:line 1644
> >    at DoWork$f1##4(FunctionEnvironment4Dictionary , Object )
> >    at IronPython.Runtime.Calls.CallTarget1.Invoke(Object arg0)
> >    at IronPython.Runtime.Calls.Function1.Call(ICallerContext context,
> > Object arg0) in C:\Development\IronPython-1.1\Src\
> > IronPython\Runtime\Calls\Function.Generated.cs:line 127
> >    at IronPython.Runtime.Calls.Function1.Call(ICallerContext context,
> > Object[] args) in C:\Development\IronPython-1.1\Sr
> > c\IronPython\Runtime\Calls\Function.Generated.cs:line 138
> >    at
> IronPython.Runtime.Calls.PythonFunction.CallInstance(ICallerContext
> > context, Object instance, Object[] args) in C:
> > \Development\IronPython-
> 1.1\Src\IronPython\Runtime\Calls\Function.cs:line
> > 389
> >    at IronPython.Runtime.Calls.Method.Call(ICallerContext context,
> > Object[] args) in C:\Development\IronPython-1.1\Src\I
> > ronPython\Runtime\Calls\Function.cs:line 972
> >    at IronPython.Runtime.Operations.Ops.Call(Object func, Object[] args)
> > in C:\Development\IronPython-1.1\Src\IronPython
> > \Runtime\Operations\Ops.cs:line 1414
> >    at IronPython.Runtime.Types.DynamicType.Invoke(Object target,
> SymbolId
> > name, Object[] args) in C:\Development\IronPyt
> > hon-1.1\Src\IronPython\Runtime\Types\DynamicType.cs:line 1010
> >    at IronPython.Runtime.Operations.Ops.Invoke(Object target, SymbolId
> > name, Object[] args) in C:\Development\IronPython
> > -1.1\Src\IronPython\Runtime\Operations\Ops.cs:line 1760
> >    at IPyExample.Program.Main(String[] args) in C:\Documents and
> > Settings\sweeneym\My Documents\Visual Studio 2005\Proje
> > cts\ATF.IP\IPyExample\Program.cs:line 35
> >
> >
> > ------------------------------------------------------------
> > Michael A. Sweeney        email: michael_sweeney at agilent.com
> > Agilent Technologies      phone: (509) 921-4395
> > MS:3WU-222                fax:   (509) 921-3991
> > 24001 E. Mission Ave.
> > Liberty Lake, WA 99019 USA
> > ------------------------------------------------------------
> >
> > _______________________________________________
> > users mailing list
> > users at lists.ironpython.com
> > http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
> > _______________________________________________
> > users mailing list
> > users at lists.ironpython.com
> > http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
> _______________________________________________
> users mailing list
> users at lists.ironpython.com
> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
> _______________________________________________
> users mailing list
> users at lists.ironpython.com
> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
_______________________________________________
users mailing list
users at lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com



More information about the Ironpython-users mailing list