[Ironpython-users] WDB web debugger for IronPython

Kerray kerray.cz at gmail.com
Tue Nov 25 13:32:21 CET 2014


Hi,
very good point, I've been on beta3. But the upgrade didn't help. I've
figured out how to debug the internals in VS, but there's nothing I could
be able to fix (or even understand) myself at this point.

ad 1) after running wdb.server, Tornado at first says
\tornado\netutil.py", line 88, in bind_sockets
AttributeError: 'module' object has no attribute 'IPV6_V6ONLY'
When I comment the whole if section out, it starts the loop and waits for
connections.

Running the client, the server reports this and continues listening:
Connection received from ('127.0.0.1', 1518)
[E 141125 11:51:35 stack_context:1] Exception in I/O handler for fd 1616
    Traceback (most recent call last):
      File "-\tornado\stack_context.py", line 304, in wrapped
        ret = fn(*args, **kwargs)
      File "-\tornado\netutil.py", line 154, in accept_handler
        callback(connection, address)
      File "-\wdb_server\streams.py", line 95, in handle_connection
        stream.read_bytes(4, partial(read_uuid_size, stream))
      File "-\tornado\iostream.py", line 168, in read_bytes
        self._try_inline_read()
      File "-\tornado\iostream.py", line 424, in _try_inline_read
        if self._read_to_buffer() == 0:
      File "-\tornado\iostream.py", line 447, in _read_to_buffer
        chunk = self.read_from_fd()
      File "-\tornado\iostream.py", line 686, in read_from_fd
        chunk = self.socket.recv(self.read_chunk_size)
    error: [Errno 10022] A request to send or receive data was disallowed
because the socket is not connected and (when sending on a datagram socket
using a sendto call) no address was supplied

And the client crashes with
wdb\client\wdb\_compat.py", line 165, in send_bytes
socket.error: [Errno 10053] An established connection was aborted by the
software in your host machine

When trying to debug this in VS, I came to the conclusion that the Tornado
server's socket handling (or my commenting out a piece, or something else
inside Tornado running under IronPython-) is at fault, since it's not true
what I've written previously (that a message gets communicated and then
coms fail) - in fact nothing gets communicated, it crashes in the client on
trying to send the first message using socket.cs sendallWorker(byte[]
buffer, int flags).


ad 2) running the server in Python and client in IronPython, I get a bit
further, but the error is the same - the client in IronPython reports
Launching browser and wait for connection
Exception Traceback (most recent call last):
  File "-\wdb\client\wdb\__init__.py", line 291, in trace_debug_dispatch
  File "-\wdb\client\wdb\__init__.py", line 250, in trace_dispatch
  File "-\wdb\client\wdb\__init__.py", line 686, in handle_call
  File "-\wdb\client\wdb\__init__.py", line 660, in interaction
  File "-\wdb\client\wdb\ui.py", line 80, in __init__
  File "-\wdb\client\wdb\__init__.py", line 575, in get_trace
TypeError: Unable to cast object of type
'System.Linq.Expressions.FieldExpression' to type
'System.Linq.Expressions.BlockExpression'.

It's the same place and line of code I mentioned in my previous mail:
> startlnos = dis.findlinestarts(code)

Debugging in VS yields an impressive stack trace, but I don't have any idea
where to start with this, so again - I'll be very grateful for any pointers.

Thanks - for even reading this far.


   at
Microsoft.Scripting.Ast.GeneratorRewriter.VisitAssign(BinaryExpression
node) in
c:\Users\jmatysek\Documents\main\Runtime\Microsoft.Dynamic\Ast\GeneratorRewriter.cs:line
831
   at
Microsoft.Scripting.Ast.GeneratorRewriter.VisitBinary(BinaryExpression
node) in
c:\Users\jmatysek\Documents\main\Runtime\Microsoft.Dynamic\Ast\GeneratorRewriter.cs:line
876
   at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor
visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection`1
nodes)
   at Microsoft.Scripting.Ast.GeneratorRewriter.VisitBlock(BlockExpression
node) in
c:\Users\jmatysek\Documents\main\Runtime\Microsoft.Dynamic\Ast\GeneratorRewriter.cs:line
595
   at System.Linq.Expressions.BlockExpression.Accept(ExpressionVisitor
visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection`1
nodes)
   at Microsoft.Scripting.Ast.GeneratorRewriter.VisitBlock(BlockExpression
node) in
c:\Users\jmatysek\Documents\main\Runtime\Microsoft.Dynamic\Ast\GeneratorRewriter.cs:line
595
   at System.Linq.Expressions.BlockExpression.Accept(ExpressionVisitor
visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection`1
nodes)
   at Microsoft.Scripting.Ast.GeneratorRewriter.VisitBlock(BlockExpression
node) in
c:\Users\jmatysek\Documents\main\Runtime\Microsoft.Dynamic\Ast\GeneratorRewriter.cs:line
595
   at System.Linq.Expressions.BlockExpression.Accept(ExpressionVisitor
visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection`1
nodes)
   at Microsoft.Scripting.Ast.GeneratorRewriter.VisitBlock(BlockExpression
node) in
c:\Users\jmatysek\Documents\main\Runtime\Microsoft.Dynamic\Ast\GeneratorRewriter.cs:line
595
   at System.Linq.Expressions.BlockExpression.Accept(ExpressionVisitor
visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection`1
nodes)
   at Microsoft.Scripting.Ast.GeneratorRewriter.VisitBlock(BlockExpression
node) in
c:\Users\jmatysek\Documents\main\Runtime\Microsoft.Dynamic\Ast\GeneratorRewriter.cs:line
595
   at System.Linq.Expressions.BlockExpression.Accept(ExpressionVisitor
visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.Scripting.Ast.GeneratorRewriter.VisitTry(TryExpression
node) in
c:\Users\jmatysek\Documents\main\Runtime\Microsoft.Dynamic\Ast\GeneratorRewriter.cs:line
297
   at System.Linq.Expressions.TryExpression.Accept(ExpressionVisitor
visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection`1
nodes)
   at Microsoft.Scripting.Ast.GeneratorRewriter.VisitBlock(BlockExpression
node) in
c:\Users\jmatysek\Documents\main\Runtime\Microsoft.Dynamic\Ast\GeneratorRewriter.cs:line
595
   at System.Linq.Expressions.BlockExpression.Accept(ExpressionVisitor
visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection`1
nodes)
   at Microsoft.Scripting.Ast.GeneratorRewriter.VisitBlock(BlockExpression
node) in
c:\Users\jmatysek\Documents\main\Runtime\Microsoft.Dynamic\Ast\GeneratorRewriter.cs:line
595
   at System.Linq.Expressions.BlockExpression.Accept(ExpressionVisitor
visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection`1
nodes)
   at Microsoft.Scripting.Ast.GeneratorRewriter.VisitBlock(BlockExpression
node) in
c:\Users\jmatysek\Documents\main\Runtime\Microsoft.Dynamic\Ast\GeneratorRewriter.cs:line
595
   at System.Linq.Expressions.BlockExpression.Accept(ExpressionVisitor
visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection`1
nodes)
   at Microsoft.Scripting.Ast.GeneratorRewriter.VisitBlock(BlockExpression
node) in
c:\Users\jmatysek\Documents\main\Runtime\Microsoft.Dynamic\Ast\GeneratorRewriter.cs:line
595
   at System.Linq.Expressions.BlockExpression.Accept(ExpressionVisitor
visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection`1
nodes)
   at Microsoft.Scripting.Ast.GeneratorRewriter.VisitBlock(BlockExpression
node) in
c:\Users\jmatysek\Documents\main\Runtime\Microsoft.Dynamic\Ast\GeneratorRewriter.cs:line
595
   at System.Linq.Expressions.BlockExpression.Accept(ExpressionVisitor
visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection`1
nodes)
   at Microsoft.Scripting.Ast.GeneratorRewriter.VisitBlock(BlockExpression
node) in
c:\Users\jmatysek\Documents\main\Runtime\Microsoft.Dynamic\Ast\GeneratorRewriter.cs:line
595
   at System.Linq.Expressions.BlockExpression.Accept(ExpressionVisitor
visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection`1
nodes)
   at Microsoft.Scripting.Ast.GeneratorRewriter.VisitBlock(BlockExpression
node) in
c:\Users\jmatysek\Documents\main\Runtime\Microsoft.Dynamic\Ast\GeneratorRewriter.cs:line
595
   at System.Linq.Expressions.BlockExpression.Accept(ExpressionVisitor
visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection`1
nodes)
   at Microsoft.Scripting.Ast.GeneratorRewriter.VisitBlock(BlockExpression
node) in
c:\Users\jmatysek\Documents\main\Runtime\Microsoft.Dynamic\Ast\GeneratorRewriter.cs:line
595
   at System.Linq.Expressions.BlockExpression.Accept(ExpressionVisitor
visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at
Microsoft.Scripting.Ast.GeneratorRewriter.VisitAssign(BinaryExpression
node) in
c:\Users\jmatysek\Documents\main\Runtime\Microsoft.Dynamic\Ast\GeneratorRewriter.cs:line
789
   at
Microsoft.Scripting.Ast.GeneratorRewriter.VisitBinary(BinaryExpression
node) in
c:\Users\jmatysek\Documents\main\Runtime\Microsoft.Dynamic\Ast\GeneratorRewriter.cs:line
876
   at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor
visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection`1
nodes)
   at Microsoft.Scripting.Ast.GeneratorRewriter.VisitBlock(BlockExpression
node) in
c:\Users\jmatysek\Documents\main\Runtime\Microsoft.Dynamic\Ast\GeneratorRewriter.cs:line
595
   at System.Linq.Expressions.BlockExpression.Accept(ExpressionVisitor
visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection`1
nodes)
   at Microsoft.Scripting.Ast.GeneratorRewriter.VisitBlock(BlockExpression
node) in
c:\Users\jmatysek\Documents\main\Runtime\Microsoft.Dynamic\Ast\GeneratorRewriter.cs:line
595
   at System.Linq.Expressions.BlockExpression.Accept(ExpressionVisitor
visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.Scripting.Ast.GeneratorRewriter.Reduce() in
c:\Users\jmatysek\Documents\main\Runtime\Microsoft.Dynamic\Ast\GeneratorRewriter.cs:line
100
   at Microsoft.Scripting.Ast.GeneratorExpression.Reduce() in
c:\Users\jmatysek\Documents\main\Runtime\Microsoft.Dynamic\Ast\GeneratorExpression.cs:line
94
   at System.Linq.Expressions.Expression.ReduceAndCheck()
   at System.Linq.Expressions.Expression.ReduceExtensions()
   at
System.Linq.Expressions.Compiler.StackSpiller.RewriteExtensionExpression(Expression
expr, Stack stack)
   at
System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression
node, Stack stack)
   at
System.Linq.Expressions.Compiler.StackSpiller.RewriteExpressionFreeTemps(Expression
expression, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.Rewrite[T](Expression`1
lambda)
   at System.Linq.Expressions.Expression`1.Accept(StackSpiller spiller)
   at
System.Linq.Expressions.Compiler.LambdaCompiler.Compile(LambdaExpression
lambda, DebugInfoGenerator debugInfoGenerator)
   at System.Linq.Expressions.LambdaExpression.Compile()
   at
Microsoft.Scripting.Debugging.DebuggableLambdaBuilder.CreateFunctionInfo(LambdaExpression
generatorFactoryLambda) in
c:\Users\jmatysek\Documents\main\Runtime\Microsoft.Dynamic\Debugging\DebuggableLambdaBuilder.cs:line
386
   at
Microsoft.Scripting.Debugging.DebuggableLambdaBuilder.TransformLambda(LambdaExpression
lambda) in
c:\Users\jmatysek\Documents\main\Runtime\Microsoft.Dynamic\Debugging\DebuggableLambdaBuilder.cs:line
171
   at
Microsoft.Scripting.Debugging.DebuggableLambdaBuilder.Transform(LambdaExpression
lambda) in
c:\Users\jmatysek\Documents\main\Runtime\Microsoft.Dynamic\Debugging\DebuggableLambdaBuilder.cs:line
111
   at
Microsoft.Scripting.Debugging.CompilerServices.DebugContext.TransformLambda(LambdaExpression
lambda, DebugLambdaInfo lambdaInfo) in
c:\Users\jmatysek\Documents\main\Runtime\Microsoft.Dynamic\Debugging\DebugContext.cs:line
68
   at
IronPython.Runtime.FunctionCode.<>c__DisplayClass1a.<GetGeneratorOrNormalLambdaTracing>b__19(Expression`1
x) in
c:\Users\jmatysek\Documents\main\Languages\IronPython\IronPython\Runtime\FunctionCode.cs:line
787
   at IronPython.Compiler.GeneratorRewriter.Reduce(Boolean shouldInterpret,
Boolean emitDebugSymbols, Int32 compilationThreshold, IList`1 parameters,
Func`2 bodyConverter) in
c:\Users\jmatysek\Documents\main\Languages\IronPython\IronPython\Compiler\GeneratorRewriter.cs:line
147
   at
IronPython.Runtime.FunctionCode.GetGeneratorOrNormalLambdaTracing(PythonContext
context) in
c:\Users\jmatysek\Documents\main\Languages\IronPython\IronPython\Runtime\FunctionCode.cs:line
777
   at IronPython.Runtime.FunctionCode.UpdateDelegate(PythonContext context,
Boolean forceCreation) in
c:\Users\jmatysek\Documents\main\Languages\IronPython\IronPython\Runtime\FunctionCode.cs:line
717
   at IronPython.Runtime.FunctionCode.LazyCompileFirstTarget(PythonFunction
function) in
c:\Users\jmatysek\Documents\main\Languages\IronPython\IronPython\Runtime\FunctionCode.cs:line
697
   at
IronPython.Compiler.PythonCallTargets.OriginalCallTarget1(PythonFunction
function, Object arg0) in
c:\Users\jmatysek\Documents\main\Languages\IronPython\IronPython\Compiler\PythonCallTargets.cs:line
42
   at IronPython.Runtime.FunctionCaller`1.Call1(CallSite site, CodeContext
context, Object func, T0 arg0) in
c:\Users\jmatysek\Documents\main\Languages\IronPython\IronPython\Runtime\PythonFunction.Generated.cs:line
420
   at
System.Dynamic.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet](CallSite
site, T0 arg0, T1 arg1, T2 arg2)
   at get_trace$495(Closure , PythonFunction , Object , Object , Object )
   at
IronPython.Compiler.PythonFunctionRecursionCheck3.CallTarget(PythonFunction
function, Object arg0, Object arg1, Object arg2) in
c:\Users\jmatysek\Documents\main\Languages\IronPython\IronPython\Compiler\PythonCallTargets.cs:line
273
   at
IronPython.Compiler.PythonCallTargets.OriginalCallTarget3(PythonFunction
function, Object arg0, Object arg1, Object arg2) in
c:\Users\jmatysek\Documents\main\Languages\IronPython\IronPython\Compiler\PythonCallTargets.cs:line
53
   at IronPython.Runtime.FunctionCaller`3.Call3(CallSite site, CodeContext
context, Object func, T0 arg0, T1 arg1, T2 arg2) in
c:\Users\jmatysek\Documents\main\Languages\IronPython\IronPython\Runtime\PythonFunction.Generated.cs:line
676
   at
System.Dynamic.UpdateDelegates.UpdateAndExecute5[T0,T1,T2,T3,T4,TRet](CallSite
site, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
   at CallSite.Target(Closure , CallSite , CodeContext , Object , Object ,
Object , Object )
   at IronPython.Runtime.Method.MethodBinding`2.SelfTarget(CallSite site,
CodeContext context, Object target, T0 arg0, T1 arg1) in
c:\Users\jmatysek\Documents\main\Languages\IronPython\IronPython\Runtime\Method.Generated.cs:line
195
   at
System.Dynamic.UpdateDelegates.UpdateAndExecute4[T0,T1,T2,T3,TRet](CallSite
site, T0 arg0, T1 arg1, T2 arg2, T3 arg3)
   at
Microsoft.Scripting.Interpreter.DynamicInstruction`5.Run(InterpretedFrame
frame) in
c:\Users\jmatysek\Documents\main\Runtime\Microsoft.Dynamic\Interpreter\Instructions\DynamicInstructions.Generated.cs:line
218
   at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame
frame) in
c:\Users\jmatysek\Documents\main\Runtime\Microsoft.Dynamic\Interpreter\Interpreter.cs:line
132
   at
Microsoft.Scripting.Interpreter.LightLambda.Run10[T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,TRet](T0
arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8
arg8, T9 arg9) in
c:\Users\jmatysek\Documents\main\Runtime\Microsoft.Dynamic\Interpreter\LightLambda.Generated.cs:line
417
   at
IronPython.Compiler.PythonFunctionRecursionCheck9.CallTarget(PythonFunction
function, Object arg0, Object arg1, Object arg2, Object arg3, Object arg4,
Object arg5, Object arg6, Object arg7, Object arg8) in
c:\Users\jmatysek\Documents\main\Languages\IronPython\IronPython\Compiler\PythonCallTargets.cs:line
375
   at
IronPython.Compiler.PythonCallTargets.OriginalCallTarget9(PythonFunction
function, Object arg0, Object arg1, Object arg2, Object arg3, Object arg4,
Object arg5, Object arg6, Object arg7, Object arg8) in
c:\Users\jmatysek\Documents\main\Languages\IronPython\IronPython\Compiler\PythonCallTargets.cs:line
83





On Mon, Nov 24, 2014 at 3:07 PM, Pawel Jasinski <pawel.jasinski at gmail.com>
wrote:

> hi,
>
> just to be sure,are you using 2.7.5RC1?
> If not, please try it. There were quite a few cpython compatibility
> improvements including socket module.
>
> On Mon, Nov 24, 2014 at 1:53 PM, Kerray <kerray.cz at gmail.com> wrote:
> > Hi everyone,
> > We're using IronPython to script the insides of SharePoint (ASP.NET on
> IIS).
> > For quite some time, I've been looking for a comfortable way to debug
> these
> > scripts without having to install Visual Studio.
> >
> > I've considered using standard PDB, with console redirected over the net
> by
> > some sort of messaging. This was the least preferable option, as the user
> > comfort is quite low and we'd have to take care of the messaging layer.
> >
> > I also considered using IPython to do this, but despite using
> > https://github.com/paweljasinski/ repositories, I haven't been anywhere
> > close to success.
> >
> > However, recently I've re-visited https://github.com/Kozea/wdb and was
> > surprised how far it has come since I've seen it for the first time. It
> > looked exactly like the debugger I was looking for. I tried playing with
> it,
> > added small IPy compatibility changes here and there, and the results are
> > promising.
> >
> > I've been attacking this on two fronts:
> >
> > 1) I've tried running the server side in IronPython, but it uses Tornado,
> > and while I can get it to run (using
> > https://github.com/paweljasinski/tornado), on client connect the server
> > fails with
> > Exception in I/O handler for fd 1492
> >     Traceback (most recent call last):
> >       File "c:\Program Files (x86)\IronPython
> > 2.7\lib\site-packages\tornado-3.1.1-py2.7.egg\tornado\iostream.py", line
> > 694, in read_from_fd
> >         chunk = self.socket.recv(self.read_chunk_size)
> >     error: [Errno 10022] A request to send or receive data was disallowed
> > because the socket is not connected and (when sending on a datagram
> socket
> > using a sendto call) no address was supplied
> >
> > While the client reports:
> > site-packages\wdb\_compat.py", line 135, in recv_bytes
> >     size, = struct.unpack("!i", self._handle.recv(4))
> > struct.error: unpack requires a string argument of length 4
> >
> > But seeing my added debug output, the server and the client have
> > successfully communicated over the socket at least once, succesfully
> sending
> > and receiving a guid, and then crash on the message "ServerBreaks" which
> > should get server breakpoints.
> >
> > Could this be an error with how sockets are handled in IPy/Windows? I've
> no
> > idea.
> >
> > 2) I've also tried running the server side in Python, and the client in
> > IronPython (as I wouldn't mind doing it like this), but this also fails
> with
> > File "c:\Program Files (x86)\IronPython
> > 2.7\lib\site-packages\wdb-2.0.7-py2.7.egg\wdb\__init__.py", line 575, in
> > get_trace
> > TypeError: Unable to cast object of type
> > 'System.Linq.Expressions.FieldExpression' to type
> > 'System.Linq.Expressions.BlockExpression'.
> >
> > And I've been unable to get any further from here - the line 575 in
> question
> > contains
> > startlnos = dis.findlinestarts(code)
> > and even when I take the dis.findlinestarts function, put it into the
> file
> > in question, and enhance it with debug output, it seem the call doesn't
> come
> > through to the inside of the function as none of the debug output
> appears.
> >
> > Both points seem to me more like IronPython issues than an issues with
> WDB
> > directly, which is why I'm trying to ask here.
> >
> > This is far too deep in the insides for my shallow "expertise", but I'd
> be
> > grateful for any pointers or ideas as to what to try next.
> >
> >
> > Thanks - and have a nice day
> >
> > Jaromír Matýšek
> >
> > _______________________________________________
> > Ironpython-users mailing list
> > Ironpython-users at python.org
> > https://mail.python.org/mailman/listinfo/ironpython-users
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/ironpython-users/attachments/20141125/02babf91/attachment.html>


More information about the Ironpython-users mailing list