[IronPython] pickling exceptions and differences between IronPython and cpython
Using the pickle modules from cpython to pickle built in exceptions fails under IronPython because IronPython adds a clsException attribute which pickle can't handle. And example is below. Should this be considered a bug? IronPython 1.0.60712 (Beta) on .NET 2.0.50727.42 Copyright (c) Microsoft Corporation. All rights reserved. >>> import pickle >>> a=[] >>> try: ... a[4] ... except Exception, e: ... pickle.dumps(e) ... Traceback (most recent call last): File , line 0, in ##43 File z:\iptest\pickle.py, line 1386, in dumps File z:\iptest\pickle.py, line 231, in dump File z:\iptest\pickle.py, line 293, in save File z:\iptest\pickle.py, line 739, in save_inst File z:\iptest\pickle.py, line 293, in save File z:\iptest\pickle.py, line 663, in save_dict File z:\iptest\pickle.py, line 677, in _batch_setitems File z:\iptest\pickle.py, line 313, in save TypeError: can't pickle IndexOutOfRangeException instance (non- default __reduce__ needed) >>> pickle.dumps(e.clsException) Traceback (most recent call last): File , line 0, in ##72 File z:\iptest\pickle.py, line 1386, in dumps File z:\iptest\pickle.py, line 231, in dump File z:\iptest\pickle.py, line 313, in save TypeError: can't pickle IndexOutOfRangeException instance (non- default __reduce__ needed) >>> del e.clsException >>> pickle.dumps(e) "(iexceptions\nIndexError\np0\n(dp1\nS'msg'\np2\nS'index out of range: 4'\np3\nsS'args'\np4\n(g3\ntp5\nsb." >>> while in cpython: Python 2.4.2 (#1, Jun 14 2006, 09:51:02) [GCC 4.0.1 (Apple Computer, Inc. build 5247)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import pickle >>> a=[] >>> try: ... a[4] ... except Exception, e: ... pickle.dumps(e) ... "(iexceptions\nIndexError\np0\n(dp1\nS'args'\np2\n(S'list index out of range'\np3\ntp4\nsb." >>> ___ users mailing list users@lists.ironpython.com http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
[IronPython] Need help using IronPython from C#
I'd like to do the equivalent of something like... import RemoteAdmin ls = RemoteAdmin.ConnectToService("localhost","LogViewer") numEntries = ls.GetNumberOfEntries() e = ls.GetEntry(numEntries - 1) entryString = str(e) in C#. So I get as far as PythonEngine e = new PythonEngine(); # The RemoteAdmin module is in an assembly built using IronPython.Hosting.Compiler and then referenced by the C# project ClrModule clr = (ClrModule) e.Import("clr"); clr.AddReference(typeof(RemoteAdmin).Assembly) e.Import("RemoteAdmin"); and then I'm lost. Is there a way to make a delegate from a method that exists in the PythonEngine environment and then call the delegate from C#? I'm aware of the Evaluate and Execute methods of PythonEngine, but I'm looking for a more direct way to call the python methods and access python object attributes, rather than building up strings to pass to Evaluate. Thanks - Jason ___ users mailing list users@lists.ironpython.com http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
Re: [IronPython] Need help using IronPython from C#
On Aug 11, 2006, at 3:53 PM, Dino Viehland wrote: > > > If you really do want to get a delegate to a Python function that > came from a module you might want to look at Ops.GetDelegate. If > you were to create a module, execute its contents, and then get the > method back out by name as an object you could pass the method to > Ops.GetDelegate w/ a delegate type and create a delegate to the raw > Python method that you could call from C#. I think this is closer to what I want. I'm looking for clean way to expose an API written in Python to a C# program. So I can do MyDelegate ConnectToService = (MyDelegate) IronPython.Runtime.Operations.Ops.GetDelegate(e.Evaluate ("RemoteAdmin.ConnectToService"), typeof(MyDelegate)); and then... object ls = ConnectToService("localhost","LogViewer"); but now how do I get to the methods and attributes of ls? > > -Original Message- > From: [EMAIL PROTECTED] [mailto:users- > [EMAIL PROTECTED] On Behalf Of Jason Ferrara > Sent: Friday, August 11, 2006 12:08 PM > To: Discussion of IronPython > Subject: [IronPython] Need help using IronPython from C# > > I'd like to do the equivalent of something like... > > import RemoteAdmin > > ls = RemoteAdmin.ConnectToService("localhost","LogViewer") > numEntries = ls.GetNumberOfEntries() > e = ls.GetEntry(numEntries - 1) > entryString = str(e) > > > in C#. > > So I get as far as > > PythonEngine e = new PythonEngine(); > # The RemoteAdmin module is in an assembly built using > IronPython.Hosting.Compiler and then referenced by the C# project > ClrModule clr = (ClrModule) e.Import("clr"); > clr.AddReference(typeof(RemoteAdmin).Assembly) > e.Import("RemoteAdmin"); > > and then I'm lost. > > Is there a way to make a delegate from a method that exists in the > PythonEngine environment and then call the delegate from C#? > > I'm aware of the Evaluate and Execute methods of PythonEngine, but > I'm looking for a more direct way to call the python methods and > access python object attributes, rather than building up strings to > pass to Evaluate. > > Thanks > > - Jason > > > ___ > users mailing list > users@lists.ironpython.com > http://lists.ironpython.com/listinfo.cgi/users-ironpython.com > ___ > users mailing list > users@lists.ironpython.com > http://lists.ironpython.com/listinfo.cgi/users-ironpython.com ___ users mailing list users@lists.ironpython.com http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
Re: [IronPython] Need help using IronPython from C#
On Aug 11, 2006, at 5:32 PM, Dino Viehland wrote: > You're quickly getting into the guts of the runtime, so you'll find > most of what you want over in Ops. > > To get an attribute off of an object you can do TryGetAttr(object > o, SymbolId name, out object ret). o would be your ls, SymbolId's > our what we use internally to represent attributes - you can get > one by doing SymbolTable.SymbolToId("foo"), and then we'll pass you > out the value. > > As you get the values back you'd need to re-create delegates to > them. Note if you're re-creating delegates of the same type we > won't need to do any additional code gen work - we'll just bind the > new object back to the existing method we created, so this > shouldn't be too nasty to do. If you're getting a property we'll > return the property value from Ops.GetAttr (basically if you hit a > descriptor we will run the descriptor code for you). And if you're > getting some plain old attribute back out then you can do whatever > you want w/ the value from there. > Ah. Thanks. This is what I needed. So to make a C# wrapper for a Python class I should do something like... class LogViewerService { public delegate int GetNumberOfEntriesDelegate(); public GetNumberOfEntriesDelegate GetNumberOfEntries; public delegate object GetEntryDelegate(int entryNumber); public GetEntryDelegate GetEntry; public delegate void closeDelegate(); public closeDelegate close; public LogViewerService(object pythonObject) { object method; IronPython.Runtime.Operations.Ops.TryGetAttr (pythonObject, IronPython.Runtime.SymbolTable.StringToId ("GetNumberOfEntries"), out method); GetNumberOfEntries = (GetNumberOfEntriesDelegate) IronPython.Runtime.Operations.Ops.GetDelegate(method, typeof (GetNumberOfEntriesDelegate)); IronPython.Runtime.Operations.Ops.TryGetAttr (pythonObject, IronPython.Runtime.SymbolTable.StringToId("GetEntry"), out method); GetEntry = (GetEntryDelegate) IronPython.Runtime.Operations.Ops.GetDelegate(method, typeof (GetEntryDelegate)); IronPython.Runtime.Operations.Ops.TryGetAttr (pythonObject, IronPython.Runtime.SymbolTable.StringToId("close"), out method); close = (closeDelegate) IronPython.Runtime.Operations.Ops.GetDelegate(method, typeof (closeDelegate)); } } ___ users mailing list users@lists.ironpython.com http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
[IronPython] custom ConfigurationSection in IronPython
I want to write a custon ConfigurationSection in IronPython. So I try... class MySettings(System.Configuration.ConfigurationSection): # custom configuration stuff here c = System.Configuration.ConfigurationManager.OpenExeConfiguration( \ System.Configuration.ConfigurationUserLevel.PerUserRoaming) c.Sections.Add("mysettings",MySettings())ction File System.Configuration, line unknown, in GetConstructorWithReflectionPermis sion SystemError: Unable to load type 'IronPython.NewTypes.System.Configuration.ConfigurationSection_2, snippets1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' because it is not public. This happened even when the python code is compiled into an assembly. Is there a way to make this work? I saw a post that mentioned an experimental static type compiler. Would I need to use that, and if so how? Thanks. - Jason ___ users mailing list users@lists.ironpython.com http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
Re: [IronPython] custom ConfigurationSection in IronPython
I have another related question. The "Item" property of System.Configuration.ConfigurationElement (base class for ConfigurationSection) doesn't seem to be accessible from IronPython. Is this because its overloaded by parameter type? Is there a way to access it from IronPython? Thanks - Jason On Aug 30, 2006, at 2:33 PM, Jason Ferrara wrote: > I want to write a custon ConfigurationSection in IronPython. So I > try... > > class MySettings(System.Configuration.ConfigurationSection): > # custom configuration stuff here > > c = System.Configuration.ConfigurationManager.OpenExeConfiguration( \ > System.Configuration.ConfigurationUserLevel.PerUserRoaming) > c.Sections.Add("mysettings",MySettings()) > > and get... > >File , line 0, in Add##32 >File System.Configuration, line unknown, in Add >File System.Configuration, line unknown, in AddConfigurationSection >File System.Configuration, line unknown, in > GetConstructorWithReflectionPermis > sion > SystemError: Unable to load type > 'IronPython.NewTypes.System.Configuration.ConfigurationSection_2, > snippets1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' > because it is not public. > > This happened even when the python code is compiled into an assembly. > > Is there a way to make this work? > > I saw a post that mentioned an experimental static type compiler. > Would I need to use that, and if so how? > > Thanks. > > - Jason > ___ > users mailing list > users@lists.ironpython.com > http://lists.ironpython.com/listinfo.cgi/users-ironpython.com ___ users mailing list users@lists.ironpython.com http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
Re: [IronPython] custom ConfigurationSection in IronPython
On Aug 31, 2006, at 4:00 PM, Dino Viehland wrote: > The Item property is the default indexer, so you should be able to > access it using foo[index]. Thats what I thought, but it doesn't work. And if I do dir() on ConfigurationElement I don't see a __getitem__ or __setitem__, though with other .NET classes that have the Item property I do. > > As for your other question - Martin looked into this but I didn't > see a response from him... The problem seems to be that we don't > define a parameterless constructor that the configuration section > can call. The reason for that is that our objects actually need to > receive a DynamicType object which represents the class - without > this we wouldn't be able to know your type was MySettings. > Unfortunately I think this might make it impossible for you to > define this class in IronPython. You could define a stub in C# > that calls into your Python using the engine APIs but that might be > more work than it's worth. > > -Original Message- > From: [EMAIL PROTECTED] [mailto:users- > [EMAIL PROTECTED] On Behalf Of Jason Ferrara > Sent: Thursday, August 31, 2006 12:56 PM > To: Discussion of IronPython > Subject: Re: [IronPython] custom ConfigurationSection in IronPython > > I have another related question. The "Item" property of > System.Configuration.ConfigurationElement (base class for > ConfigurationSection) doesn't seem to be accessible from IronPython. > Is this because its overloaded by parameter type? Is there a way to > access it from IronPython? > > Thanks > > - Jason > ___ users mailing list users@lists.ironpython.com http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
Re: [IronPython] custom ConfigurationSection in IronPython
On Aug 31, 2006, at 4:00 PM, Dino Viehland wrote: > The Item property is the default indexer, so you should be able to > access it using foo[index]. > > As for your other question - Martin looked into this but I didn't > see a response from him... The problem seems to be that we don't > define a parameterless constructor that the configuration section > can call. The reason for that is that our objects actually need to > receive a DynamicType object which represents the class - without > this we wouldn't be able to know your type was MySettings. > Unfortunately I think this might make it impossible for you to > define this class in IronPython. You could define a stub in C# > that calls into your Python using the engine APIs but that might be > more work than it's worth. > If I wanted to write a stub in C#, how do I get access to a PythonEngine that represents the python environment that called the C# code? Just calling IronPython.Hosting.PythonEngine() seems to get me a new environment. ___ users mailing list users@lists.ironpython.com http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
Re: [IronPython] What PythonEngine called my C# code? (was: custom ConfigurationSection in IronPython)
Not that I saw. On Sep 18, 2006, at 11:14 AM, J. Merrill wrote: > Was an answer to this ever given? > > At 12:34 PM 9/1/2006, Jason Ferrara wrote >> If I wanted to write a stub in C#, how do I get access to a >> PythonEngine that represents the python environment that called the >> C# code? Just calling IronPython.Hosting.PythonEngine() seems to get >> me a new environment. > > > J. Merrill / Analytical Software Corp > > > ___ > users mailing list > users@lists.ironpython.com > http://lists.ironpython.com/listinfo.cgi/users-ironpython.com ___ users mailing list users@lists.ironpython.com http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
Re: [IronPython] What PythonEngine called my C# code? (was: custom ConfigurationSection in IronPython)
In my case I'm looking to write assemblies in C# that makes use of modules defined in IronPython that others can use without having to know or care that they use IronPython (except for having to have the IronPython dlls around). Things are complicated by the fact that some of the modules used need to have a single global environment. If C# assemblies A and B both use IronPython assembly C, A and B need to use the same PythonEngine or things won't work right. And if A and B are being used from IronPython, then they need to use the PythonEngine of the caller. So I guess I need some sort of magic that when a call is made into the assembly it looks back up the call stack to see if there is a PythonEngine, and if so uses that one. If not create its own and then keep that one around for the next time the assembly is entered without a PythonEngine in the call stack. On Sep 18, 2006, at 12:11 PM, Dino Viehland wrote: > Probably the lack of an answer is due to the fact that there isn't > a really great way to do this. Here's two possible ways to pull > this off: > > For #1 you presumably kicked off the Python code via the hosting > APIs, and therefore you know the engine that kicked it off. If you > have multiple Python engines this might be tricky (if you have only > one running on each thread at a time you could store it in a > [ThreadStatic]). If you start getting into more complicated > scenarios obviously this is going to break down quickly... > > For #2 you're looking at using ICallerContext. This is a bit of > internal machinery that IronPython uses to flow state around for > things that might need state (e.g. hiding CLR methods, locals(), > exec, etc...). Off of ICallerContext there is both a SystemState > and a PythonModule property. Unfortunately there's nothing that > leads you directly to a PythonEngine. Instead you'd need to > maintain a table of either modules->engines or SystemState (sys > module) -> engines. > > #2 will work reliably if you control the creation of all engines in > the process - the instance you go out of that it'll break down. > The alternate plan here might be that having access to a > SystemState and PythonModule you could already do some interesting > things even though you don't have the full blown PythonEngine. > It'd be interesting to hear if those are sufficient or if you > really do need the engine in this case (and how horrible you think > the 2 solutions are :) ). > ___ users mailing list users@lists.ironpython.com http://lists.ironpython.com/listinfo.cgi/users-ironpython.com