<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Srivatsn's Blog : IronPython</title><link>http://blogs.msdn.com/srivatsn/archive/tags/IronPython/default.aspx</link><description>Tags: IronPython</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Hosting IronPython made easier</title><link>http://blogs.msdn.com/srivatsn/archive/2008/09/16/hosting-ironpython-made-easier.aspx</link><pubDate>Wed, 17 Sep 2008 01:30:34 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8954481</guid><dc:creator>srivatsn</dc:creator><slash:comments>12</slash:comments><comments>http://blogs.msdn.com/srivatsn/comments/8954481.aspx</comments><wfw:commentRss>http://blogs.msdn.com/srivatsn/commentrss.aspx?PostID=8954481</wfw:commentRss><description>&lt;p&gt;With 2.0 Beta 5 coming out very soon, there is a new hosting helper class in there called IronPython.Hosting.Python . It has a few helper methods to create a ScriptRuntime or ScriptEngine and adds some Python-specific extension methods to ScriptRuntime and ScriptEngine.&lt;/p&gt;  &lt;p&gt;Creating a ScriptRuntime the normal way now requires a LanguageSetup as Sesh &lt;a href="http://blogs.msdn.com/seshadripv/archive/2008/09/07/dlr-hosting-api-latest-version-of-the-spec-is-available-online-includes-changes-to-runtime-initialization.aspx"&gt;explains here&lt;/a&gt;. The Python class has helpers called CreateRuntimeSetup and CreateLanguageSetup which return a pythonic ScriptRuntimeSetup and LanguageSetup&amp;#160; respectively. But if you are not interested in the configuration options of the DLR then you can simply use Python.CreateEngine/ Python.CreateRuntime.&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre class="code"&gt;&lt;span style="color: #2b91af"&gt;ScriptRuntime &lt;/span&gt;runtime = &lt;span style="color: #2b91af"&gt;Python&lt;/span&gt;.CreateRuntime();
runtime.ExecuteFile(&lt;span style="color: #a31515"&gt;&amp;quot;foo.py&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are also three extension methods tacked on to ScriptRuntime and ScriptEngine called GetSysModule, GetBuiltinModule and GetClrModule which directly return a ScriptScope for these modules. You can do something like this for example:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;IronPython.Hosting;

&lt;span style="color: #2b91af"&gt;ScriptEngine &lt;/span&gt;engine = &lt;span style="color: #2b91af"&gt;Python&lt;/span&gt;.CreateEngine();

&lt;span style="color: #2b91af"&gt;ScriptScope &lt;/span&gt;sys = engine.GetSysModule();
&lt;span style="color: blue"&gt;var &lt;/span&gt;platform = sys.GetVariable(&lt;span style="color: #a31515"&gt;&amp;quot;platform&amp;quot;&lt;/span&gt;);
&lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(platform);

&lt;span style="color: #2b91af"&gt;ScriptScope &lt;/span&gt;builtins = engine.GetBuiltinModule();
&lt;span style="color: blue"&gt;var &lt;/span&gt;pow = builtins.GetVariable&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;double&lt;/span&gt;, &lt;span style="color: blue"&gt;double&lt;/span&gt;,&lt;span style="color: blue"&gt;double&lt;/span&gt;&amp;gt;&amp;gt;(&lt;span style="color: #a31515"&gt;&amp;quot;pow&amp;quot;&lt;/span&gt;);
&lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(pow(2,3));

&lt;span style="color: #2b91af"&gt;ScriptScope &lt;/span&gt;clr = engine.GetClrModule();
&lt;span style="color: blue"&gt;var &lt;/span&gt;getPythonType = clr.GetVariable&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Type&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;PythonType&lt;/span&gt;&amp;gt;&amp;gt;(&lt;span style="color: #a31515"&gt;&amp;quot;GetPythonType&amp;quot;&lt;/span&gt;);            
&lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #2b91af"&gt;PythonType&lt;/span&gt;.Get__name__(getPythonType(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: blue"&gt;string&lt;/span&gt;))));&lt;/pre&gt;
&lt;/blockquote&gt;
This will then print out cli, 8 and str respectively. 

&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8954481" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/srivatsn/archive/tags/DLR/default.aspx">DLR</category><category domain="http://blogs.msdn.com/srivatsn/archive/tags/IronPython/default.aspx">IronPython</category></item><item><title>Passing keyword args to C# methods from IronPython</title><link>http://blogs.msdn.com/srivatsn/archive/2008/09/09/passing-keyword-args-to-c-methods-from-ironpython.aspx</link><pubDate>Wed, 10 Sep 2008 00:13:14 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8937438</guid><dc:creator>srivatsn</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/srivatsn/comments/8937438.aspx</comments><wfw:commentRss>http://blogs.msdn.com/srivatsn/commentrss.aspx?PostID=8937438</wfw:commentRss><description>&lt;p&gt;In Python one can call functions with either the argument itself or a named argument i.e f(3) or f(x=3). Python also provides syntax to absorb excess arguments for either style of argument passing with either * or **. So for example for this function f:&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;def &lt;/span&gt;f(x, *args, **kwargs):
    &lt;span style="color: blue"&gt;pass
    
&lt;/span&gt;f(3,4,5,y=6,z=7)&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;The value passed to x is 3 and args then absorbs the extra positional arguments and is passed as a tuple (4,5). kwargs then takes up the keyword arguments and is passed as a dictionary {'y':6, 'z':7}.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Variable number of arguments in the CLS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now if 'f' were a C# method would this still work? Passing the positional and named parameters from IronPython definitely works. The question is can C# accept variable number of parameters? The &lt;a href="http://msdn.microsoft.com/en-us/library/12a7a7h3.aspx"&gt;CLS&lt;/a&gt; clearly states that the only calling convention supported is the standard managed calling convention and variable length argument lists are not allowed. So how does C# support the params keyword then? The C# compiler applies an attribute (&lt;a href="http://msdn.microsoft.com/en-us/library/system.paramarrayattribute.aspx"&gt;System.ParamArray&lt;/a&gt;) and passes the extra positional parameters as an array. Great, so can we then do the same thing for dictionary params as well? &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ParamDictionaryAttribute&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There is a ParamDictionaryAttribute in Microsoft.Scripting.dll that serves the purpose of the System.ParamArray for keyword arguments. But since the C# compiler doesn't know about it there is no syntactic sugar here and it needs to be manually applied. We can, therefore, define a function like this:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System;
&lt;span style="color: blue"&gt;using &lt;/span&gt;Microsoft.Scripting;

&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;foo &lt;/span&gt;{
    &lt;span style="color: blue"&gt;public void &lt;/span&gt;bar(&lt;span style="color: blue"&gt;int &lt;/span&gt;x, [&lt;span style="color: #2b91af"&gt;ParamDictionary&lt;/span&gt;] &lt;span style="color: #2b91af"&gt;IAttributesCollection &lt;/span&gt;kwargs) {
        &lt;span style="color: blue"&gt;foreach &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;SymbolId &lt;/span&gt;key &lt;span style="color: blue"&gt;in &lt;/span&gt;kwargs.SymbolAttributes.Keys) {
            &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;key: {0}, value: {1} &amp;quot;&lt;/span&gt;, key, kwargs[key]);
        }
    }
}&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;font face="Verdana"&gt;The function bar now accepts a dictionary of excess keyword parameters when called from IronPython. IAttributesCollection is another interface defined in Microsoft.Scripting which represents a dictionary that can be accessed using SymbolIds and also arbitrary objects. The SymbolAttributes property returns just the SymbolIds. This can now be called from IronPython like so:&lt;/font&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;import &lt;/span&gt;clr
clr.AddReference(&lt;span style="color: maroon"&gt;&amp;quot;test.dll&amp;quot;&lt;/span&gt;)
&lt;span style="color: blue"&gt;import &lt;/span&gt;foo
foo().bar(2,y=4, z=6)&lt;/pre&gt;
&lt;/blockquote&gt;
And you'll see y:4 and z:6 were indeed passed into the method as items in the dictionary.&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8937438" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/srivatsn/archive/tags/DLR/default.aspx">DLR</category><category domain="http://blogs.msdn.com/srivatsn/archive/tags/IronPython/default.aspx">IronPython</category></item><item><title>Static Compilation of IronPython scripts</title><link>http://blogs.msdn.com/srivatsn/archive/2008/08/06/static-compilation-of-ironpython-scripts.aspx</link><pubDate>Wed, 06 Aug 2008 09:28:01 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8836253</guid><dc:creator>srivatsn</dc:creator><slash:comments>15</slash:comments><comments>http://blogs.msdn.com/srivatsn/comments/8836253.aspx</comments><wfw:commentRss>http://blogs.msdn.com/srivatsn/commentrss.aspx?PostID=8836253</wfw:commentRss><description>&lt;p&gt;The ability to compile IronPython scripts into .NET IL and to save them to disk existed in IronPython 1.0 but has been missing in 2.0 so far. With IronPython 2.0 Beta4 this has been added back. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Why would I compile dynamic language scripts?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;There are a lot of reasons to compile scripts into a binary form. Shri talks about some of them &lt;a href="http://blogs.msdn.com/shrib/archive/2008/07/24/cls-compilation-of-ironpython.aspx"&gt;here&lt;/a&gt;. For folks who don't want to distribute source code in plain text this provides one level of obfuscation. To that end, a function called CompileModules has been added to the clr module to compile scripts into executable IL. The signature of the function is:&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre class="code"&gt;CompileModules(str assemblyName, dict kwArgs, &lt;span style="color: #2b91af"&gt;&lt;font color="#000000"&gt;Array&lt;/font&gt;&lt;/span&gt;[str] filenames)&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;So to compile a file foo.py into foo.dll you would do this:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;import clr
clr.CompileModules(&amp;quot;foo.dll&amp;quot;, &amp;quot;foo.py&amp;quot;)&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This can now be brought in using the regular clr.AddReference. When clr.AddReference sees a compiled assembly, it publishes the module as well. So one can simply import the module into the code.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;clr.AddReference(&amp;quot;foo.dll&amp;quot;)
import foo&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&lt;strong&gt;Multiple files and main&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The function can take multiple python files and compile them into one dll. What if you want it to be a standalone executable? There are two things to be done. First, a stub exe is needed that can load the dll. Second, a way to distinguish the main module is needed. The keyword args that CompileModules can take comes in handy here&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;import clr
clr.CompileModules(&amp;quot;foo.dll&amp;quot;, &amp;quot;foo.py&amp;quot;, &amp;quot;bar.py&amp;quot;, mainModule=&amp;quot;main.py&amp;quot;)&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Now a stub exe can be written that loads up this compiled dll. The IronPython sample pyc.py has code that does shows how to generate a stub exe.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wait, what is -X:SaveAssemblies mode then?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When IronPython is started with -X:SaveAssemblies, it generates a dll containing IL corresponding to the code it executed. Sounds an awful lot like compilation doesn't it? The difference is one is executable IL and the other isn't.&lt;/p&gt;

&lt;p&gt; To understand the difference, one needs to understand that IronPython under normal course of its execution generates IL anyway. Every statement is converted to the DLR AST and IL gets spit out for the ASTs which is then executed. The SaveAssemblies mode simply dumps the generated IL into a dll. It is meant as a debugging device. So what is missing from this IL that prevents it from being re-executable code? The short answer is Dynamic Sites. The sites that are generated during the execution are not persisted. The compilation feature does exactly this - it persists the dynamic sites as well. Lets look at an example here and compare the generated IL in reflector. (Only the relevant code is copied over from reflector). This python code:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;print 2 + 5
print 2 * 5
print 3 / 5&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;when run with -X:SaveAssemblies mode produces this code:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CallSite&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;DynamicSiteTarget&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt;&amp;gt; #Constant207;
&lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CallSite&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;DynamicSiteTarget&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt;&amp;gt; #Constant208;
&lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CallSite&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;DynamicSiteTarget&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt;&amp;gt; #Constant209;&lt;/pre&gt;

&lt;pre class="code"&gt;$lineNo = 1;
&lt;span style="color: #2b91af"&gt;PythonOps&lt;/span&gt;.Print(__global_context, #Constant207.Target(#Constant207, 2, 5));
$lineNo = 2;
&lt;span style="color: #2b91af"&gt;PythonOps&lt;/span&gt;.Print(__global_context, #Constant208.Target(#Constant208, 2, 5));
$lineNo = 3;
&lt;span style="color: #2b91af"&gt;PythonOps&lt;/span&gt;.Print(__global_context, #Constant209.Target(#Constant209, 3, 5));&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Notice that the Constants defined here are actually defined as fields on the generated type and this type doesn't get instantiated anywhere and therefore the sites don't get assigned anywhere. The same python code when compiled with clr.CompiledModules produces this code:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;object&lt;/span&gt;[] objArray = &lt;span style="color: blue"&gt;new object&lt;/span&gt;[] { 
&lt;span style="color: #2b91af"&gt;CallSite&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;DynamicSiteTarget&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt;&amp;gt;.Create(&lt;span style="color: #2b91af"&gt;PythonOps&lt;/span&gt;.MakeOperationAction(context, &lt;span style="color: #a31515"&gt;&amp;quot;Add&amp;quot;&lt;/span&gt;)), 
&lt;span style="color: #2b91af"&gt;CallSite&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;DynamicSiteTarget&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt;&amp;gt;.Create(&lt;span style="color: #2b91af"&gt;PythonOps&lt;/span&gt;.MakeOperationAction(context, &lt;span style="color: #a31515"&gt;&amp;quot;Multiply&amp;quot;&lt;/span&gt;)), 
&lt;span style="color: #2b91af"&gt;CallSite&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;DynamicSiteTarget&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt;&amp;gt;.Create(&lt;span style="color: #2b91af"&gt;PythonOps&lt;/span&gt;.MakeOperationAction(context, &lt;span style="color: #a31515"&gt;&amp;quot;Divide&amp;quot;&lt;/span&gt;)) 
};&lt;/pre&gt;

&lt;pre class="code"&gt;line = 1;
&lt;span style="color: #2b91af"&gt;PythonOps&lt;/span&gt;.Print(context, ((&lt;span style="color: #2b91af"&gt;CallSite&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;DynamicSiteTarget&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt;&amp;gt;)objArray[0]).Target(
    (&lt;span style="color: #2b91af"&gt;CallSite&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;DynamicSiteTarget&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt;&amp;gt;)objArray[0], 2, 5));
line = 2;
&lt;span style="color: #2b91af"&gt;PythonOps&lt;/span&gt;.Print(context, ((&lt;span style="color: #2b91af"&gt;CallSite&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;DynamicSiteTarget&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt;&amp;gt;)objArray[1]).Target(
    (&lt;span style="color: #2b91af"&gt;CallSite&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;DynamicSiteTarget&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt;&amp;gt;)objArray[1], 2, 5));
line = 3;
&lt;span style="color: #2b91af"&gt;PythonOps&lt;/span&gt;.Print(context, ((&lt;span style="color: #2b91af"&gt;CallSite&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;DynamicSiteTarget&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt;&amp;gt;)objArray[2]).Target(
    (&lt;span style="color: #2b91af"&gt;CallSite&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;DynamicSiteTarget&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt;&amp;gt;)objArray[2], 3, 5));&lt;/pre&gt;

&lt;p&gt;You can see that all the dynamic call sites are being created here and their targets are being invoked. This then is perfectly executable code - maybe not as succinct as the python code but it does the same thing :)&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8836253" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/srivatsn/archive/tags/DLR/default.aspx">DLR</category><category domain="http://blogs.msdn.com/srivatsn/archive/tags/IronPython/default.aspx">IronPython</category></item><item><title>IronPython 2.0 Beta 3 is out!</title><link>http://blogs.msdn.com/srivatsn/archive/2008/06/13/ironpython-2-0-beta-3-is-out.aspx</link><pubDate>Sat, 14 Jun 2008 01:58:07 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8595112</guid><dc:creator>srivatsn</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/srivatsn/comments/8595112.aspx</comments><wfw:commentRss>http://blogs.msdn.com/srivatsn/commentrss.aspx?PostID=8595112</wfw:commentRss><description>&lt;p&gt;The next stop on the path to IronPython 2.0 is Beta 3 and we pushed it out today. You can get the sources and binaries of IronPython &lt;a href="http://www.codeplex.com/IronPython/Release/ProjectReleases.aspx?ReleaseId=12988"&gt;here&lt;/a&gt;. As Jimmy mentioned in &lt;a href="http://blog.jimmy.schementi.com/2008/06/dynamic-languages-in-silverlight-2-beta.html"&gt;his release notes&lt;/a&gt; for Dynamic Silverlight last week, this release also contains the sources and binaries of IronPython and Dynamic Silverlight needed to build Silverlight applications with IronPython. This release builds against &lt;a href="http://www.microsoft.com/silverlight/resources/install.aspx?v=2.0"&gt;Silverlight 2.0 Beta 2&lt;/a&gt; – so make sure that is installed. &lt;/p&gt;  &lt;p&gt;Head over to the &lt;a href="http://www.codeplex.com/IronPython/Wiki/View.aspx?title=v2.0%20Beta%203%20Release%20Notes&amp;amp;referringTitle=Home"&gt;release notes&lt;/a&gt; to find out what has changed since the last release and the list of bugs that have been fixed. Congratulations to the team and the community on the release.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8595112" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/srivatsn/archive/tags/IronPython/default.aspx">IronPython</category><category domain="http://blogs.msdn.com/srivatsn/archive/tags/Silverlight/default.aspx">Silverlight</category></item><item><title>Accessing IronPython objects from native Javascript</title><link>http://blogs.msdn.com/srivatsn/archive/2008/05/09/accessing-ironpython-objects-from-native-javascript.aspx</link><pubDate>Fri, 09 May 2008 10:16:52 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8478042</guid><dc:creator>srivatsn</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/srivatsn/comments/8478042.aspx</comments><wfw:commentRss>http://blogs.msdn.com/srivatsn/commentrss.aspx?PostID=8478042</wfw:commentRss><description>&lt;p&gt;Today I got a question by e-mail from someone who wanted to implement something like this &lt;a href="http://msdn.microsoft.com/en-us/library/a0746166.aspx"&gt;MSDN article&lt;/a&gt; in IronPython. The gist of the article is that there is a property called &lt;em&gt;ObjectForScripting&lt;/em&gt; on a WinForms WebBrowser control. If one sets the property to an object, then that object will be available to javascript that executes in the page through &lt;em&gt;window.external&lt;/em&gt;. The Form needs to add the ComVisible attribute.&lt;/p&gt;  &lt;p&gt;.NET attributes cannot be added to a class from IronPython but fortunately objects created are ComVisible by default. So we can try a direct translation of the code in the article :&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;import &lt;/span&gt;clr
clr.AddReference(&lt;span style="color: maroon"&gt;&amp;quot;System.Windows.Forms&amp;quot;&lt;/span&gt;)
&lt;span style="color: blue"&gt;from &lt;/span&gt;System.Windows.Forms &lt;span style="color: blue"&gt;import &lt;/span&gt;Application, Form, WebBrowser, MessageBox

&lt;span style="color: blue"&gt;class &lt;/span&gt;MyForm(Form):
    &lt;span style="color: blue"&gt;def &lt;/span&gt;__init__(self):
        self.wb = WebBrowser()
        self.Controls.Add(self.wb)
        self.wb.ObjectForScripting = self
        self.wb.DocumentText = &lt;span style="color: maroon"&gt;&amp;quot;&amp;quot;&amp;quot;
                               &lt;/span&gt;&lt;font color="#800000"&gt;&amp;lt;html&amp;gt;
                                &amp;lt;body&amp;gt;
                                 &amp;lt;button onclick=&amp;quot;window.external.Test('hello')&amp;quot;&amp;gt;
                                   call client code &lt;span style="color: blue"&gt;&lt;font color="#800000"&gt;from&lt;/font&gt; &lt;/span&gt;script code
                                 &amp;lt;/button&amp;gt;
                                &amp;lt;/body&amp;gt;
                               &amp;lt;/html&amp;gt;&lt;/font&gt;
                               &lt;span style="color: maroon"&gt;&amp;quot;&amp;quot;&amp;quot;
    &lt;/span&gt;&lt;span style="color: blue"&gt;def &lt;/span&gt;Test(self, msg):
        MessageBox.Show(msg)
    
        
Application.Run(MyForm())&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;Unfortunately this doesn't work because ObjectForScripting is being set to an instance of the python type MyForm. In the CLR-world this type will be generated dynamically and will be something like IronPython.NewTypes.System.Windows.Form_1$0 and will not contain any of the python methods. You can verify this by doing &lt;em&gt;clr.GetClrType(MyForm).GetMembers()&lt;/em&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;. The easiest solution then is to define an interface in C# with the methods that you want on your type and implement that interface on your type. So define a simple interface like this:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public interface &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IWebBrowserInterop
&lt;/span&gt;{
    &lt;span style="color: blue"&gt;void &lt;/span&gt;Test(&lt;span style="color: blue"&gt;string &lt;/span&gt;message);
}&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;and in the python code make your class implement that interface:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;from &lt;/span&gt;ClassLibrary1 &lt;span style="color: blue"&gt;import &lt;/span&gt;IWebBrowserInterop
&lt;font color="#0000ff"&gt;&lt;/font&gt;
&lt;span style="color: blue"&gt;class &lt;/span&gt;MyForm(Form, IWebBrowserInterop):
...&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Now if you fire up the app and click on the button the MessageBox will popup. You just reached across from unmanaged javascript through COM/.NET to python&lt;/p&gt;

&lt;p&gt;Caveat(s):&amp;#160; This is not type-safe. The IronPython runtime caches the types that are generated. So if there is another class in the python code that is &amp;quot;similar&amp;quot; (same base classes/interfaces and not different __slots__-wise) then this type can be reused. So if you are not bound by other factors, you should try to use Managed JScript instead and the hosting APIs to interact with the python objects.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8478042" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/srivatsn/archive/tags/IronPython/default.aspx">IronPython</category><category domain="http://blogs.msdn.com/srivatsn/archive/tags/Silverlight/default.aspx">Silverlight</category></item><item><title>Turning your .NET object models dynamic for IronPython</title><link>http://blogs.msdn.com/srivatsn/archive/2008/04/12/turning-your-net-object-models-dynamic-for-ironpython.aspx</link><pubDate>Sat, 12 Apr 2008 05:16:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8383517</guid><dc:creator>srivatsn</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/srivatsn/comments/8383517.aspx</comments><wfw:commentRss>http://blogs.msdn.com/srivatsn/commentrss.aspx?PostID=8383517</wfw:commentRss><description>&lt;P&gt;Say you want to interop with a .NET library but you also want it to behave like objects in dynamic languages do. You want to be able to add/delete methods/properties to the object dynamically. In python you can do something like this:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;class &lt;/SPAN&gt;x(object):
    &lt;SPAN style="COLOR: blue"&gt;pass

&lt;/SPAN&gt;y = x()
y.z = 42
dir(y)&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;And the dir(y) will contain z in it. Now if&amp;nbsp;x were a .NET class&amp;nbsp;instead of a python class would you still be able to do the same? Let’s try a simple .NET&amp;nbsp;class&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;public class &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;TestExt
&lt;/SPAN&gt;{
}&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;From IronPython you would do something like this:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;import &lt;/SPAN&gt;clr
clr.AddReference(&lt;SPAN style="COLOR: maroon"&gt;"TestExtensions.dll"&lt;/SPAN&gt;)
&lt;SPAN style="COLOR: blue"&gt;from &lt;/SPAN&gt;TestExtensions &lt;SPAN style="COLOR: blue"&gt;import &lt;/SPAN&gt;TestExt
y = TestExt()
y.z = 42&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;But this code throws a AttributeError saying ‘TestExt’ object has no attribute ‘z’. What now? Enter Stage Right DLR’s extension mechanism. There are five methods that a .NET class can implement that have a special meaning to the binder if you tell it so. The methods are:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;GetCustomMember&amp;nbsp;– runs before normal .NET lookups&lt;/LI&gt;
&lt;LI&gt;GetBoundMember&amp;nbsp;– runs after normal .NET lookups&lt;/LI&gt;
&lt;LI&gt;SetMember&amp;nbsp;– runs before normal .NET member assignment&lt;/LI&gt;
&lt;LI&gt;SetMemberAfter&amp;nbsp;– runs after normal .NET member assignment&lt;/LI&gt;
&lt;LI&gt;DeleteMember&amp;nbsp;– runs before normal .NET operator access (there’s no .NET version&amp;nbsp;– so its the only one)&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;A .NET class can implement these functions and mark them with a &lt;A href="http://msdn2.microsoft.com/en-us/library/system.runtime.compilerservices.specialnameattribute(VS.80).aspx"&gt;&lt;FONT color=#0000ff&gt;SpecialName attribute&lt;/FONT&gt;&lt;/A&gt;. The rule generated for binding now makes a call to Getter/Setter before and after the normal .NET binding is done. GetCustomMember/SetMember&amp;nbsp;&amp;nbsp;is called first and if it returns a value that is treated as the result of the member-lookup. This overrides any .NET members that may exist. But if you return OperationFailed.Value from the function, then it will proceed with the normal lookup as well. GetBoundMember/SetMemberAfter is called if the normal binding fails&amp;nbsp;– that is there is no&amp;nbsp;member of the name that it is trying to bind to. So with that in mind let’s modify the .NET class&amp;nbsp;and add&amp;nbsp;this:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Dictionary&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;, &lt;SPAN style="COLOR: blue"&gt;object&lt;/SPAN&gt;&amp;gt; dict = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Dictionary&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;, &lt;SPAN style="COLOR: blue"&gt;object&lt;/SPAN&gt;&amp;gt;();
[&lt;SPAN style="COLOR: #2b91af"&gt;SpecialName&lt;/SPAN&gt;]
&lt;SPAN style="COLOR: blue"&gt;public object &lt;/SPAN&gt;GetBoundMember(&lt;SPAN style="COLOR: blue"&gt;string &lt;/SPAN&gt;name)
{
    &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(dict.ContainsKey(name))
        &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;dict[name];
    &lt;SPAN style="COLOR: blue"&gt;else
        return &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;OperationFailed&lt;/SPAN&gt;.Value;
}

[&lt;SPAN style="COLOR: #2b91af"&gt;SpecialName&lt;/SPAN&gt;]
&lt;SPAN style="COLOR: blue"&gt;public void &lt;/SPAN&gt;SetMemberAfter(&lt;SPAN style="COLOR: blue"&gt;string &lt;/SPAN&gt;methodName, &lt;SPAN style="COLOR: blue"&gt;object &lt;/SPAN&gt;o)
{
    dict.Add(methodName, o);
}&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;A href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;Now if I try to do a y.z = 42, it works. I can assign y.z to a function as well and will be able to call y.z(). I could have overridden GetCustomMember and SetMember instead and the behaviour&amp;nbsp;would be exactly the same since OperationFailed.Value is returned for member that are not in the dict but then there is this overhead involved for any .NET member lookup.&lt;/P&gt;
&lt;P&gt;The SetMember function can choose to return a bool instead of void and in that case, the returnvalue would control whether further binding lookups happen or not.&lt;/P&gt;
&lt;P&gt;So, what exactly is the use of all this, why would I want to do this? Consider writing an object model for something like&amp;nbsp;the following xml file:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&amp;lt;foo&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;bar&amp;gt;baz&amp;lt;/bar&amp;gt;&lt;BR&gt;&amp;lt;/foo&amp;gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Now I want to access this xml as foo.bar and the value of that should be baz. To implement this all that I would need to do is add the GetBoundMember method to the .NET XmlElement class to do a search and return&amp;nbsp;another XmlElement or add a extension method to XmlElement. Now here is the part where things come a little unstuck in IronPython. Extension methods dont show up in reflection, so the IronPython support for that currently isn’t where we want it to be. There is a way around though. You can decorate an assembly with an ExtensionType attribute describing what type you are extending and with what class. After that you would need to register the assembly once so that those methods get injected at the right places. This might change in the future with a better way but this works for now. This is the code you’d need to implement: 
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;[&lt;SPAN style="COLOR: blue"&gt;assembly&lt;/SPAN&gt;: &lt;SPAN style="COLOR: #2b91af"&gt;ExtensionType&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt;(System.Xml.&lt;SPAN style="COLOR: #2b91af"&gt;XmlElement&lt;/SPAN&gt;), &lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt;(TestExtensions.&lt;SPAN style="COLOR: #2b91af"&gt;ExtClass&lt;/SPAN&gt;.&lt;SPAN style="COLOR: #2b91af"&gt;XmlElementExtension&lt;/SPAN&gt;))]
&lt;SPAN style="COLOR: blue"&gt;namespace &lt;/SPAN&gt;TestExtensions
{    
    &lt;SPAN style="COLOR: blue"&gt;public class &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ExtClass
    &lt;/SPAN&gt;{
        &lt;SPAN style="COLOR: blue"&gt;static &lt;/SPAN&gt;ExtClass()
        {
            Microsoft.Scripting.Runtime.&lt;SPAN style="COLOR: #2b91af"&gt;RuntimeHelpers&lt;/SPAN&gt;.RegisterAssembly(&lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #2b91af"&gt;ExtClass&lt;/SPAN&gt;).Assembly);
        }

        &lt;SPAN style="COLOR: blue"&gt;public static &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;XmlElement &lt;/SPAN&gt;Load(&lt;SPAN style="COLOR: blue"&gt;string &lt;/SPAN&gt;fileName)
        {
            &lt;SPAN style="COLOR: #2b91af"&gt;XmlDocument &lt;/SPAN&gt;doc = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;XmlDocument&lt;/SPAN&gt;();
            doc.Load(fileName);
            &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;doc.DocumentElement;
        }
        &lt;SPAN style="COLOR: blue"&gt;public static class &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;XmlElementExtension
        &lt;/SPAN&gt;{
            [&lt;SPAN style="COLOR: #2b91af"&gt;SpecialName&lt;/SPAN&gt;]
            &lt;SPAN style="COLOR: blue"&gt;public static object &lt;/SPAN&gt;GetCustomMember(&lt;SPAN style="COLOR: blue"&gt;object &lt;/SPAN&gt;myObj, &lt;SPAN style="COLOR: blue"&gt;string &lt;/SPAN&gt;name)
            {
                &lt;SPAN style="COLOR: #2b91af"&gt;XmlElement &lt;/SPAN&gt;xml = myObj &lt;SPAN style="COLOR: blue"&gt;as &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;XmlElement&lt;/SPAN&gt;;

                &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(xml != &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;)
                {
                    &lt;SPAN style="COLOR: blue"&gt;for &lt;/SPAN&gt;(&lt;SPAN style="COLOR: #2b91af"&gt;XmlNode &lt;/SPAN&gt;n = xml.FirstChild; n != &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;; n = n.NextSibling)
                    {
                        &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(n &lt;SPAN style="COLOR: blue"&gt;is &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;XmlElement &lt;/SPAN&gt;&amp;amp;&amp;amp; &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;.CompareOrdinal(n.Name, name) == 0)
                        {
                            &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(n.HasChildNodes &amp;amp;&amp;amp; n.FirstChild == n.LastChild &amp;amp;&amp;amp; n.FirstChild &lt;SPAN style="COLOR: blue"&gt;is &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;XmlText&lt;/SPAN&gt;)
                            {
                                &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;n.InnerText;
                            }
                            &lt;SPAN style="COLOR: blue"&gt;else
                            &lt;/SPAN&gt;{
                                &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;n;
                            }

                        }
                    }
                }
                &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;OperationFailed&lt;/SPAN&gt;.Value;
            }
        }
    }
}
&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;A href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;Now from IronPython do this: 
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;import &lt;/SPAN&gt;clr
clr.AddReference(&lt;SPAN style="COLOR: maroon"&gt;"TestExtensions.dll"&lt;/SPAN&gt;)
&lt;SPAN style="COLOR: blue"&gt;from &lt;/SPAN&gt;TestExtensions &lt;SPAN style="COLOR: blue"&gt;import &lt;/SPAN&gt;ExtClass
foo = ExtClass.Load(&lt;SPAN style="COLOR: maroon"&gt;"test.xml"&lt;/SPAN&gt;)
&lt;SPAN style="COLOR: blue"&gt;print &lt;/SPAN&gt;foo.bar&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;This prints out “baz”. Sweet!&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8383517" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/srivatsn/archive/tags/DLR/default.aspx">DLR</category><category domain="http://blogs.msdn.com/srivatsn/archive/tags/IronPython/default.aspx">IronPython</category></item><item><title>PyCon 2008</title><link>http://blogs.msdn.com/srivatsn/archive/2008/03/18/pycon-2008.aspx</link><pubDate>Tue, 18 Mar 2008 03:15:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8299156</guid><dc:creator>srivatsn</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/srivatsn/comments/8299156.aspx</comments><wfw:commentRss>http://blogs.msdn.com/srivatsn/commentrss.aspx?PostID=8299156</wfw:commentRss><description>&lt;P&gt;&lt;A href="http://us.pycon.org/2008/about/" mce_href="http://us.pycon.org/2008/about/"&gt;&lt;FONT color=#0000ff&gt;PyCon 2008&lt;/FONT&gt;&lt;/A&gt; was a lot of fun. This was my first PyCon and until now my interaction with the python community had been nothing beyond a few mails in the IronPython forum. My experiences of conferences so far has been limited to Microsoft ones like TechEd and TechMela(the equivalent of MIX/TechEd in India). This was so very different from that - the mood was different. PyCon is organized by the community. Everything from stuffing swagbags to debugging WiFi issues was managed by volunteers. There seemed to be more hallway chats between everyone than between just organizers/attendees. The keynotes&amp;nbsp;that interested me were&amp;nbsp;Guido's (I hadn't seen his last year's, so all the Python3k stuff was new for me) and Fitz's keynote on software development in general(it was a very well structured talk). I was pleasantly surprised by the amount of positive buzz about IronPython. Apart from the two regular IronPython talks (Jim Hugunin's talk on IronPython, and Michael Foord's on Silverlight with IronPython) IronPython was mentioned in many other talks as well starting from Guido's keynote to Python.NET to Resolver systems' talks to even Van Lindberg's keynote on IP :). The sessions were at best most illuminating and at worst interesting. 
&lt;P&gt;So what did I get out of PyCon (other than four cool t-shirts) in the order of most tangible to least tangible.&amp;nbsp; 
&lt;UL&gt;
&lt;LI&gt;Learnt a lot more things about python itself from talks.&amp;nbsp;Some talks&amp;nbsp;that I enjoyed a lot&amp;nbsp;- &lt;A href="http://us.pycon.org/2008/conference/schedule/event/12/" mce_href="http://us.pycon.org/2008/conference/schedule/event/12/"&gt;&lt;FONT color=#0000ff&gt;How Import Does Its Thing&lt;/FONT&gt;&lt;/A&gt;, &lt;A href="http://us.pycon.org/2008/conference/schedule/event/51/" mce_href="http://us.pycon.org/2008/conference/schedule/event/51/"&gt;&lt;FONT color=#0000ff&gt;Unicode In Python, Completely Demystified&lt;/FONT&gt;&lt;/A&gt;, &lt;A href="http://us.pycon.org/2008/conference/schedule/event/75/" mce_href="http://us.pycon.org/2008/conference/schedule/event/75/"&gt;&lt;FONT color=#0000ff&gt;More Iterators in Action&lt;/FONT&gt;&lt;/A&gt;&amp;nbsp;and &lt;A href="http://us.pycon.org/2008/conference/schedule/event/78/" mce_href="http://us.pycon.org/2008/conference/schedule/event/78/"&gt;&lt;FONT color=#0000ff&gt;Core Python Containers -- Under the Hood&lt;/FONT&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;Learnt about the different important projects in the community (like Django and its new features, about PyPy, PyGame, SqlAlchemy, zope.&amp;nbsp;It will be a useful exercise to see which parts&amp;nbsp;of IronPython get worked out by these . For example, Django uses metaclasses heavily.&lt;/LI&gt;
&lt;LI&gt;The birds of a feather session was very interesting just in terms of hearing what people wanted in IronPython and what their priorities were. (For example a lot of them said VS integration is important to them, shipping standard libraries would be awesome, better performance with exceptions was discussed at length.) &lt;/LI&gt;
&lt;LI&gt;Got introduced personally to many of the IronPython users and people whose mails I get to see in the mailing list and also met a lot of people in the hallways from various companies using python internally. The variety of companies who had set-up booths varied from YouTube&amp;nbsp; to CCP to LucasArts!&lt;/LI&gt;
&lt;LI&gt;A sense of the kind of stuff being developed in the python community and sense of what is important to the community and what is not. I don't claim to have grokked the community in just 3 days but I'm way better off than I was 3 days back. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;I was mostly in listening mode the entire time. In some ways I learned more in the last 3 days than in the last 3 months (I know what the first comment is going to be&amp;nbsp;- So you&amp;nbsp;didn't learn anything in the last three months?)&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8299156" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/srivatsn/archive/tags/IronPython/default.aspx">IronPython</category></item><item><title>Decorators to convert return statements to yield statements</title><link>http://blogs.msdn.com/srivatsn/archive/2008/03/17/decorators-to-convert-return-statements-to-yield-statements.aspx</link><pubDate>Tue, 18 Mar 2008 01:07:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8297350</guid><dc:creator>srivatsn</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/srivatsn/comments/8297350.aspx</comments><wfw:commentRss>http://blogs.msdn.com/srivatsn/commentrss.aspx?PostID=8297350</wfw:commentRss><description>&lt;P&gt;We have this really cool tool that parses a python file into a AST and then morphs it according to some transformation and then spits out python code corresponding to the new AST. I've been playing around with it lately to come up with some transformations. One of the things I wanted to do was convert all return statements to yield expressions. That will give a good amount of coverage for yield. So this is the code I want to convert: 
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;def &lt;/SPAN&gt;f(a,b):
    &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;a + b
    
&lt;SPAN style="COLOR: blue"&gt;def &lt;/SPAN&gt;g(f, *args):
    &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;f(*args)

f(3,42)
g(f, 3, 42)&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;A href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;Now, its easy enough to change a&amp;nbsp; "return &amp;lt;expr&amp;gt;" to "yield &amp;lt;expr&amp;gt;" but now I cannot just call the function directly as f(). That will return the generator. I need to do f().next(). Now one naive approach would be to go change all the invocations of the function to f().next(). That would work except for the cases where I pass the function as a parameter to another function (like g in the example). Now when g calls calls f, it could blow up because it will get a generator instead of&amp;nbsp;f's returnvalue. I could solve that also by doing replacing every f with lambda : f().next(). So the call to g become this: 
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;g(&lt;SPAN style="COLOR: blue"&gt;lambda &lt;/SPAN&gt;*args: f(*args).next(), 3, 42)&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;A href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;That almost solves the problem except that even fs which are not references to this function (like the locally scoped f variable inside the g method) will get replaced since in a parsed AST we don't have any idea of scope (that happens during the conversion of the Python AST to the DLR AST). Now come python decorators to the rescue. In python you can wrap a function with a decorator like so: 
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;@dec
&lt;SPAN style="COLOR: blue"&gt;def &lt;/SPAN&gt;f():
    &lt;SPAN style="COLOR: blue"&gt;pass&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;A href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;dec can be defined as a function. Then python&amp;nbsp;will start treating f&amp;nbsp;as dec(f) and any calls to f() will be semantically equivalent to dec(f)(). This is great because now python will take care of that little scoping problem for me. So now the morphed code is simply: 
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;def &lt;/SPAN&gt;yieldwrapper(func):
    f = &lt;SPAN style="COLOR: blue"&gt;lambda &lt;/SPAN&gt;*args, **kwargs: func(*args, **kwargs).next()
    f.__name = func.__name
    &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;f

@yieldwrapper
&lt;SPAN style="COLOR: blue"&gt;def &lt;/SPAN&gt;f(a,b):
    &lt;SPAN style="COLOR: blue"&gt;yield &lt;/SPAN&gt;a + b

@yieldwrappeer
&lt;SPAN style="COLOR: blue"&gt;def &lt;/SPAN&gt;g(f, *args):
    &lt;SPAN style="COLOR: blue"&gt;yield &lt;/SPAN&gt;f(*args)

f(3,42)
g(f, 3, 42)&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;A href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;The name of the wrapper is also set to the function's name so that it can masquerade as the real function just in case anyone's looking. Except for a few weird issues, this worked for most of the tests.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8297350" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/srivatsn/archive/tags/DLR/default.aspx">DLR</category><category domain="http://blogs.msdn.com/srivatsn/archive/tags/IronPython/default.aspx">IronPython</category></item><item><title>DeepZoom in dynamic languages</title><link>http://blogs.msdn.com/srivatsn/archive/2008/03/17/deepzoom-in-dynamic-languages.aspx</link><pubDate>Tue, 18 Mar 2008 01:03:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8296681</guid><dc:creator>srivatsn</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/srivatsn/comments/8296681.aspx</comments><wfw:commentRss>http://blogs.msdn.com/srivatsn/commentrss.aspx?PostID=8296681</wfw:commentRss><description>&lt;P&gt;There's been a lot of talk lately about the DeepZoom technology in Silverlight 2. If you have seen it yet you should definitely goto HardRock's &lt;A href="http://memorabilia.hardrock.com/" mce_href="http://memorabilia.hardrock.com/"&gt;&lt;FONT color=#0000ff&gt;memorabilia&lt;/FONT&gt;&lt;/A&gt; site. That is a 2 billion pixels image that you see in that 640X480 segment there. Instead of getting all those pixels down the wire and killing your system, you only get the pixels needed to display the zoom level you are in. To me one of the reasons this is cool is because it introduces a new paradigm of photo sharing. You can have a long shot picture that captures the essence of your album and then have smaller pictures embedded at the right places which can be zoomed into. I wanted to do that for some photos I'd taken when I went rafting with some friends in the Himalayas some time back. &lt;A href="http://wotc.members.winisp.net/SLDeepZoom/index.html" mce_href="http://wotc.members.winisp.net/SLDeepZoom/index.html"&gt;&lt;FONT color=#0000ff&gt;Here&lt;/FONT&gt;&lt;/A&gt; is the picture of the camp and other pictures embedded in approximate positions of where they were. (Ok I know it sucks, I pretend to have some artistic sense whereas I don't but in my defense I didn't know about deepzoom then or I'd have taken a good long range shot) &lt;/P&gt;
&lt;P&gt;So how do I go about doing this? First thing is obviously you need Silverlight. Then if you are going to use a dynamic language (and there is no reason to use anything else) then you need to download &lt;A href="http://dynamicsilverlight.net/" mce_href="http://dynamicsilverlight.net/"&gt;&lt;FONT color=#0000ff&gt;dynamic silverlight&lt;/FONT&gt;&lt;/A&gt;. John Lam has &lt;A href="http://www.iunknown.com/2008/03/dynamic-silverl.html" mce_href="http://www.iunknown.com/2008/03/dynamic-silverl.html"&gt;&lt;FONT color=#0000ff&gt;a series&lt;/FONT&gt;&lt;/A&gt; &lt;A href="http://www.iunknown.com/2008/03/dynamic-silve-1.html" mce_href="http://www.iunknown.com/2008/03/dynamic-silve-1.html"&gt;&lt;FONT color=#0000ff&gt;of excellent posts&lt;/FONT&gt;&lt;/A&gt; that introduce dynamic silverlight. To create the deepzoom images, you would need &lt;A href="http://www.microsoft.com/downloads/details.aspx?FamilyID=457B17B7-52BF-4BDA-87A3-FA8A4673F8BF&amp;amp;displaylang=en" mce_href="http://www.microsoft.com/downloads/details.aspx?FamilyID=457B17B7-52BF-4BDA-87A3-FA8A4673F8BF&amp;amp;displaylang=en"&gt;&lt;FONT color=#0000ff&gt;DeepZoom composer&lt;/FONT&gt;&lt;/A&gt;. The DeepZoom composer is fairly straightforward. Import the pics you want in your project and drop on to the composer. Make sure that you zoom into the main image and drop the embedded images with the right size. Once your images are ready all you need is a simple app.xaml like so: &lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Canvas &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;x&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Class&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="System.Windows.Controls.Canvas"
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;xmlns&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="http://schemas.microsoft.com/client/2007"
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;xmlns&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;x&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="http://schemas.microsoft.com/winfx/2006/xaml"
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;x&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="parentCanvas"
    &amp;gt;
    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;StackPanel&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;MultiScaleImage &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;ViewportWidth&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="1.0" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;x&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="msi" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Source&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="raftingcamp/info.bin"/&amp;gt;
    &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;StackPanel&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Canvas&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt; &lt;/SPAN&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;Now you need some simple python code that hooks the mouse click/wheel event handlers and zooms in and out appropriately. Scott Hanselman has an &lt;A href="http://www.hanselman.com/blog/TheWeeklySourceCode18DeepZoomSeadragonSilverlight2MultiScaleImageMouseWheelZoomingAndPanningEdition.aspx" mce_href="http://www.hanselman.com/blog/TheWeeklySourceCode18DeepZoomSeadragonSilverlight2MultiScaleImageMouseWheelZoomingAndPanningEdition.aspx"&gt;&lt;FONT color=#0000ff&gt;excellent sample of that in C#.&lt;/FONT&gt;&lt;/A&gt; I just wrote python code that does the same thing (ofcourse its python so its simpler and more elegant :)). In the constructor, you need to load the xaml and hook up the events: &lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;class &lt;/SPAN&gt;DeepZoomScene(object):
    
    &lt;SPAN style="COLOR: blue"&gt;def &lt;/SPAN&gt;__init__(self):
        self.scene = Application.Current.LoadRootVisual(Canvas(), &lt;SPAN style="COLOR: maroon"&gt;"app.xaml"&lt;/SPAN&gt;)

        self.scene.msi.MouseLeftButtonDown += self.mouseButtonDown
        self.scene.msi.MouseLeftButtonUp += self.mouseButtonUp
        self.scene.msi.MouseMove += self.mouseMove
        self.scene.msi.MouseEnter += self.mouseEnter
        self.scene.msi.MouseLeave += self.mouseLeave

        &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;HtmlPage.IsEnabled:
            HtmlPage.Window.AttachEvent(&lt;SPAN style="COLOR: maroon"&gt;"DOMMouseScroll"&lt;/SPAN&gt;, EventHandler[HtmlEventArgs](self.mouseWheel))
            HtmlPage.Window.AttachEvent(&lt;SPAN style="COLOR: maroon"&gt;"onmousewheel"&lt;/SPAN&gt;, EventHandler[HtmlEventArgs](self.mouseWheel))
            HtmlPage.Document.AttachEvent(&lt;SPAN style="COLOR: maroon"&gt;"onmousewheel"&lt;/SPAN&gt;, EventHandler[HtmlEventArgs](self.mouseWheel))&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Now its just a matter of writing the event handlers. For example, here is the scroll wheel handler (thanks to Pete Blois for his C# sample). Notice how using a dynamic language massively reduces the lines of code needed. &lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;def &lt;/SPAN&gt;mouseWheel(self, sender, args):
    &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;self.IsMouseOver:
        delta = args.EventObject.GetProperty(&lt;SPAN style="COLOR: maroon"&gt;"wheelDelta"&lt;/SPAN&gt;)
        &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;HtmlPage.Window.GetProperty(&lt;SPAN style="COLOR: maroon"&gt;"opera"&lt;/SPAN&gt;) != None:
            delta = -delta
        &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;delta == None:
            delta = -(args.EventObject.GetProperty(&lt;SPAN style="COLOR: maroon"&gt;"detail"&lt;/SPAN&gt;))/3
            &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;HtmlPage.BrowserInformation.UserAgent.IndexOf(&lt;SPAN style="COLOR: maroon"&gt;"Macintosh"&lt;/SPAN&gt;) != -1:
                delta = delta*3

        &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;delta &amp;gt; 0:
            self.zoom(1.1, self.lastMousePos)
        &lt;SPAN style="COLOR: blue"&gt;else&lt;/SPAN&gt;:
            self.zoom(0.9, self.lastMousePos)&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;(The entire python file is attached). After this, ideally all I'd have to do should be run chiron and create the xap. But there seems to be a bug in Silverlight beta1 wherein if I have the deepzoom files in both the xap then it refuses to read the read the file (this doesnt happen for normal jpgs - only with MultiScaleImage). So I xap'ed just the app folder by doing chiron /d:app /z:app.xap and then keeping my deepzoom folder along with the xap. &lt;/P&gt;
&lt;P&gt;Note: The code is provided "as is" and all that - aka don't blame if it blows up.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8296681" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/srivatsn/attachment/8296681.ashx" length="2733" type="text/plain" /><category domain="http://blogs.msdn.com/srivatsn/archive/tags/DLR/default.aspx">DLR</category><category domain="http://blogs.msdn.com/srivatsn/archive/tags/IronPython/default.aspx">IronPython</category><category domain="http://blogs.msdn.com/srivatsn/archive/tags/Silverlight/default.aspx">Silverlight</category></item><item><title>What I like about Python</title><link>http://blogs.msdn.com/srivatsn/archive/2008/01/22/what-i-like-about-python.aspx</link><pubDate>Tue, 22 Jan 2008 06:03:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7192097</guid><dc:creator>srivatsn</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/srivatsn/comments/7192097.aspx</comments><wfw:commentRss>http://blogs.msdn.com/srivatsn/commentrss.aspx?PostID=7192097</wfw:commentRss><description>&lt;P&gt;I've been dabbling with &lt;A href="http://www.codeplex.com/IronPython" mce_href="http://www.codeplex.com/IronPython"&gt;IronPython&lt;/A&gt; for the past two weeks now. For me it compares quite favourably to the experience I had driving in this country. I used to drive a manual transmission car back in India and I used C# primarily. When I came to the US two weeks back I started driving an automatic transmission vehicle and I started using python. Initially the car felt weird - it was like driving some toy car, every time I'd slow down and my hands used to reach for the gears and my legs kept going towards the non-existent clutch. Similarly, I'd constantly put semicolons and braces everywhere, add type information all over the place and new up everything, indent the code wrongly. Now I'm getting used to the automatic and python and probably somwhere down the line, it might make me lazy enough to start disliking the manuals and static languages. (Although I dont see that happening with C# seeing as how I'm still going to be doing a lot of coding in C#).&lt;/P&gt;
&lt;P&gt;Anyway I thought, I'll come up with the list of things I find cool and/or useful (not necessarily the same) in python.&lt;/P&gt;
&lt;H3&gt;Lists and &lt;A href="http://en.wikipedia.org/wiki/List_comprehension" mce_href="http://en.wikipedia.org/wiki/List_comprehension"&gt;List Comprehension&lt;/A&gt;&lt;/H3&gt;
&lt;P&gt;Being a fan of LINQ this was one of the first things about the language that interested me. I think the creation and maintenance of lists in python is very light on syntax and though it might not be as powerful as LINQ it does what it does well.&lt;/P&gt;
&lt;P&gt;List comprehension is an easy way of constructing new lists from existing ones. To get a list of all IronPython process Ids&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;procIds = [ x.Id &lt;SPAN style="COLOR: blue"&gt;for &lt;/SPAN&gt;x &lt;SPAN style="COLOR: blue"&gt;in &lt;/SPAN&gt;Process.GetProcesses() &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;x.ProcessName == &lt;SPAN style="COLOR: maroon"&gt;"ipy"&lt;/SPAN&gt;]&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;&lt;/BLOCKQUOTE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;Or say you have some functions and parameters and you want to call them in a cross-productish way:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;results = [ [y(x) &lt;SPAN style="COLOR: blue"&gt;for &lt;/SPAN&gt;y &lt;SPAN style="COLOR: blue"&gt;in &lt;/SPAN&gt;funcs] &lt;SPAN style="COLOR: blue"&gt;for &lt;/SPAN&gt;x &lt;SPAN style="COLOR: blue"&gt;in &lt;/SPAN&gt;params ]&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;It also supports filter, map, reduce (equivalent of where, select and aggregate in C#) and the usual suspects like sorted, reversed etc..&lt;/P&gt;
&lt;H3&gt;Sequence packing/unpacking:&lt;/H3&gt;
&lt;P&gt;Sequences (lists, tuples etc) can be constructed from loose elements or can be disintegrated into individual variables. For example this can be done:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;t = 3, 30, 300
a,b,c = t&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;A tuple t is constructed from the loose values and then it is unpacked into three loose variables a, b and c. This enables a bunch of cool scenarios. For examples I can now return multiple values from a function and assign them intuitively:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;def &lt;/SPAN&gt;f():
    &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;"a"&lt;/SPAN&gt;, 3
a, b = f()&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;The return value of that function was just a tuple packed and unpacked for you. This also lets you do this to swap numbers which I find pretty cool:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;a, b = b, a&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;A related feature is &lt;STRONG&gt;argument unpacking&lt;/STRONG&gt;. You can pass a tuple to a function and ask it to unpack the tuple and distribute it to the parameters. All you need to do this put a * in front of the tuple while passing it. For example:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;def &lt;/SPAN&gt;Multiply(a, b):
    &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;a*b;
params = [ (4,5), (4, &lt;SPAN style="COLOR: maroon"&gt;"thisrepeats!"&lt;/SPAN&gt;) ]
results = [ Multiply(*p) &lt;SPAN style="COLOR: blue"&gt;for &lt;/SPAN&gt;p &lt;SPAN style="COLOR: blue"&gt;in &lt;/SPAN&gt;params ]&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;You can also pass in a dictionary and assign specific values. &lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;Multiply( **{&lt;SPAN style="COLOR: maroon"&gt;'a'&lt;/SPAN&gt;:2, &lt;SPAN style="COLOR: maroon"&gt;'b'&lt;/SPAN&gt;:&lt;SPAN style="COLOR: maroon"&gt;"c"&lt;/SPAN&gt;})&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;&lt;STRONG&gt;Else clause&lt;/STRONG&gt; &lt;/P&gt;
&lt;P&gt;for loops (or try/catch blocks) can have else clauses: I dont have to have a flag now checking to see if the loop has exited on a break or otherwise:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;for &lt;/SPAN&gt;item &lt;SPAN style="COLOR: blue"&gt;in &lt;/SPAN&gt;listToSearch:
    &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;item == theOneImLookingFor:
        &lt;SPAN style="COLOR: blue"&gt;print &lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;"Found it"
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;break
else&lt;/SPAN&gt;:  &lt;SPAN style="COLOR: green"&gt;#loop fell through
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;print &lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;"Sorry, its not there"&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: maroon"&gt;&lt;FONT face=Verdana color=#000000 size=2&gt;There's more but those probably warrant another post.&lt;/FONT&gt; &lt;/SPAN&gt;&lt;/PRE&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7192097" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/srivatsn/archive/tags/IronPython/default.aspx">IronPython</category></item></channel></rss>