[IronPython] ArenaNet's Use of IronPython
danielj at arena.net
Tue Mar 15 19:52:32 CET 2011
The biggest problem we had with IronPython originally was probably the fact that I was the only developer on the (very small) tools team that was familiar with Python beyond the fact that it uses whitespace for control flow :)
Other than that, though, the biggest things we ran into:
1. We noticed some odd discrepancies in our programs' runtime when running inside of the debugger versus out of the debugger. Specifically, we have a single line of IronPython that calls a single line of C# code that calls a single P/Invoke into our native code. This native code loads the content data for the game. When we launch the IronPython process from VS2010 with the debugger, then it takes upwards of 10 times as long to execute the native code. When we launch it with Ctrl+F5, then it operates at normal speed. I'm not sure what could be causing this, since the speed issues are happening in the native code, but I do know that launching our C# application that calls the same P/Invoke into the same native code (same build, same file, etc.) then there's no discrepancy between launching it inside of our outside of the debugger.
2. Debugging the IronPython code was difficult. If it was at the top-level of the file, then we couldn't inspect variables, step into some lines, etc. If we made a function at the top level and then called into it immediately, then we'd have the debugging utilities fully available. Don't know what's up with that.
3. There was a weird bug that I could reproduce with smaller code, that I can only attribute to IronPython. We had two larger functions that didn't depend on each other or mutate any shared state, etc.. Each of the functions fires off exceptions down in the stack and catches the exceptions. BUT, when I called one of those functions before the other one, it seemed like it broke the exception catching functionality. What I don't get is how this would be possible even if I were trying to break it in the same way. I would throw an IronPython defined exception directly inside of a try catch block that catches any CLR exception, or any exception, or anything, and it wouldn't catch the exception. The exception would bubble right on through and treat it as unhandled. At one point I literally had the following code, and it would still not get caught:
Test wouldn't get printed, the Exception would take down the program the normal way. I spent a whole day looking into this, and couldn't figure out what was going on, so I gave up and left the two functions in the order that they were in when it was working, and it kept working.
4. The TryInvokeMember/TryGetMember weirdness for methods (http://lists.ironpython.com/pipermail/users-ironpython.com/2010-June/013104.html) is more weird than it lets on. I don't remember the details, but it was something like if the method was called with no parameters then TryGetMember was called first, otherwise it would call directly into TryInvokeMember. This meant that most of our code worked fine (we didn't cover the TryGetMember case at all) until we tried to write a function that didn't take any arguments and call it from IronPython; it didn't work and for apparently no reason (until we discovered that it made sense that it would call TryGetMember first).
5. I understand why the RuntimeBinderException occurs, but it's a really big annoyance to try to develop an application that calls over into IronPython code through DynamicObjects repeatedly. I wish we could decorate a class in such a way that it would just assume that all calls need to be reflected/whatever, so that it wouldn't fire hundreds of RuntimeBinderExceptions at the startup of our application (we were doing scripting from C# using the 'dynamic' keyword here.) We would always have to remember to turn off first-chance exceptions for that one, etc., in our otherwise first-chance exception free development environment.
These are the only things that came to mind when thinking of what we ran into when using IronPython; we've been developing with it for probably 6 months now (we've always used 2.7A1) and now ~40 game developers use our tool full-time to get the game built. :) As the article mentioned, we have some designers writing Python scripts to generate content, mutate existing content, link it together, etc., and it's a pretty awesome time-saver.
On a side note, it seems like IronPython could be enhanced to provide a better Python learning experience for new programmers. For example, it would probably be pretty easy to detect that you have used a function as a statement, like by Console.WriteLine on its own line without parentheses, and offer optional warning levels to help detect cases like this. :)
From: Jeff Hardy [mailto:jdhardy at gmail.com]
Sent: Monday, March 14, 2011 6:22 PM
To: Discussion of IronPython
Cc: Daniel Jennings
Subject: Re: [IronPython] ArenaNet's Use of IronPython
That's awesome. I think it might be time to start a "Who's using
IronPython" page somewhere.
The upgrade to 2.7 should be pretty seamless, BTW. Is there anything
that you're missing? Anything that would make your use case easier?
On Mon, Mar 14, 2011 at 3:30 PM, Daniel Jennings <danielj at arena.net> wrote:
> Just thought I'd share with you guys an article that among other things
> discusses how we at ArenaNet are using IronPython. We don't go into many
> details about how important IronPython is to our editor, but we at least
> allude to it. Every time Python is mentioned it's using IronPython J
> Let me know if you have any questions about the boring details! We're
> currently using 2.7A1, but that's only because we haven't taken the time to
> make sure that we're immediately compatible with the later versions J
> Daniel Jennings
> Users mailing list
> Users at lists.ironpython.com
More information about the Ironpython-users