<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US"><title type="html">Haibo Luo's weblog</title><subtitle type="html" /><id>http://blogs.msdn.com/haibo_luo/atom.xml</id><link rel="alternate" type="text/html" href="http://blogs.msdn.com/haibo_luo/default.aspx" /><link rel="self" type="application/atom+xml" href="http://blogs.msdn.com/haibo_luo/atom.xml" /><generator uri="http://communityserver.org" version="2.1.61025.2">Community Server</generator><updated>2007-08-03T12:37:00Z</updated><entry><title>IronPython: System.Reflection.Assembly object</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/haibo_luo/archive/2008/03/12/8177924.aspx" /><id>http://blogs.msdn.com/haibo_luo/archive/2008/03/12/8177924.aspx</id><published>2008-03-13T06:12:00Z</published><updated>2008-03-13T06:12:00Z</updated><content type="html">&lt;P&gt;IronPython offers a little bit more love to the &lt;A href="http://msdn2.microsoft.com/en-us/library/system.reflection.assembly.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/system.reflection.assembly.aspx"&gt;Assembly&lt;/A&gt; object instance: we can directly access the assembly's top-level members (namespace, public type) via the dot operation. System.Reflection provides many ways to let you hold the assembly object, such as Assembly.Load method, Type.Assembly property, ... 
&lt;P&gt;For example, given assembly1.dll compiled from the C# file below, &lt;A href="http://docs.python.org/lib/built-in-funcs.html" mce_href="http://docs.python.org/lib/built-in-funcs.html"&gt;dir&lt;/A&gt;(a1) in the python below shows the class name "C2" and the top level namespace "NS1" in its' dictionary. &lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: green"&gt;// assembly1.cs
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;namespace &lt;/SPAN&gt;NS1 {
    &lt;SPAN style="COLOR: blue"&gt;namespace &lt;/SPAN&gt;NS2 {
        &lt;SPAN style="COLOR: blue"&gt;public class &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;C1 &lt;/SPAN&gt;{ }
    }
}
&lt;SPAN style="COLOR: blue"&gt;public class &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;C2 &lt;/SPAN&gt;{
    &lt;SPAN style="COLOR: blue"&gt;public class &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;C3 &lt;/SPAN&gt;{ }
}
&lt;SPAN style="COLOR: blue"&gt;class &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;C4 &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;PRE class=code&gt;&lt;SPAN style="COLOR: green"&gt;# part 1 from file/test1.py
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;import &lt;/SPAN&gt;System
a1 = System.Reflection.Assembly.Load(&lt;SPAN style="COLOR: maroon"&gt;"assembly1"&lt;/SPAN&gt;)

&lt;SPAN style="COLOR: blue"&gt;print &lt;/SPAN&gt;dir(a1)  &lt;SPAN style="COLOR: green"&gt;# ['C2', ..., 'NS1', ...]
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;print &lt;/SPAN&gt;a1.NS1   &lt;SPAN style="COLOR: green"&gt;# &amp;lt;module 'NS1' (CLS module from assembly1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)&amp;gt;
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;print &lt;/SPAN&gt;a1.C2    &lt;SPAN style="COLOR: green"&gt;# &amp;lt;type 'C2'&amp;gt;

# access non-public type
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;print &lt;/SPAN&gt;a1.C4    &lt;SPAN style="COLOR: green"&gt;# AttributeError: 'Assembly' object has no attribute 'C4'

# access the down-level namespace, type with the dot operations
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;print &lt;/SPAN&gt;a1.NS1.NS2.C1         &lt;SPAN style="COLOR: green"&gt;# &amp;lt;type 'C1'&amp;gt;
# access the nested type
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;print &lt;/SPAN&gt;a1.C2.C3              &lt;SPAN style="COLOR: green"&gt;# &amp;lt;type 'C3'&amp;gt;&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;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;Normally I would use &lt;A href="http://blogs.msdn.com/haibo_luo/archive/2007/09/25/5130072.aspx" mce_href="http://blogs.msdn.com/haibo_luo/archive/2007/09/25/5130072.aspx"&gt;clr.AddReference&lt;/A&gt; to bring in the CLR assembly. The python code below gives the similar output. &lt;PRE class=code&gt;&lt;SPAN style="COLOR: green"&gt;# part 1 of file/test2.py
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;import &lt;/SPAN&gt;clr
clr.AddReference(&lt;SPAN style="COLOR: maroon"&gt;"assembly1"&lt;/SPAN&gt;)
&lt;SPAN style="COLOR: blue"&gt;import &lt;/SPAN&gt;NS1 
&lt;SPAN style="COLOR: blue"&gt;import &lt;/SPAN&gt;C2

&lt;SPAN style="COLOR: blue"&gt;print &lt;/SPAN&gt;NS1        &lt;SPAN style="COLOR: green"&gt;# &amp;lt;module 'NS1' (CLS module from assembly1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)&amp;gt;
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;print &lt;/SPAN&gt;C2         &lt;SPAN style="COLOR: green"&gt;# &amp;lt;type 'C2'&amp;gt;
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;print &lt;/SPAN&gt;NS1.NS2    &lt;SPAN style="COLOR: green"&gt;# &amp;lt;module 'NS2' (CLS module from assembly1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)&amp;gt;
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;print &lt;/SPAN&gt;NS1.NS2.C1 &lt;SPAN style="COLOR: green"&gt;# &amp;lt;type 'C1'&amp;gt;
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;print &lt;/SPAN&gt;C2.C3      &lt;SPAN style="COLOR: green"&gt;# &amp;lt;type 'C3'&amp;gt;
&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;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;However the first approach may help keep the global (and local) dictionary less "polluted" and &lt;EM&gt;sometimes&lt;/EM&gt; can be used to avoid the namespace/type name collision. For example, suppose we need to load in another assembly built from the following C# code, and we use the clr.AddReference approach.&lt;PRE class=code&gt;&lt;SPAN style="COLOR: green"&gt;// assembly2.cs
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;namespace &lt;/SPAN&gt;NS1 { 
    &lt;SPAN style="COLOR: blue"&gt;public class &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;NS2 &lt;/SPAN&gt;{ } 
}&lt;/PRE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: green"&gt;# part 2 of file/test2.py
&lt;/SPAN&gt;clr.AddReference(&lt;SPAN style="COLOR: maroon"&gt;"assembly2"&lt;/SPAN&gt;)
&lt;SPAN style="COLOR: blue"&gt;print &lt;/SPAN&gt;NS1.NS2    &lt;SPAN style="COLOR: green"&gt;# &amp;lt;type 'NS2'&amp;gt;
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;print &lt;/SPAN&gt;NS1.NS2.C1 &lt;SPAN style="COLOR: green"&gt;# AttributeError: 'type' object has no attribute 'C1'
&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;P&gt;NS2 is a type now (no longer the namespace (or python module) NS1.NS2 from "assembly1"), and we lost the access to the type NS1.NS2.C1. If we use the assembly object approach, we can hold both the namespace NS1.NS2 from assembly1 and the type NS1.NS2 from assembly2; basically we can think the assembly variable name adds one more layer to prevent the name collision. Or in the other direction of thinking, what clr.AddReference does for you (related to implicit name merge/override) may not be what exactly you want.&lt;PRE class=code&gt;&lt;SPAN style="COLOR: green"&gt;# part 2 from file/test1.py
&lt;/SPAN&gt;a2 = System.Reflection.Assembly.Load(&lt;SPAN style="COLOR: maroon"&gt;"assembly2"&lt;/SPAN&gt;)
&lt;SPAN style="COLOR: blue"&gt;print &lt;/SPAN&gt;a2.NS1     &lt;SPAN style="COLOR: green"&gt;# &amp;lt;module 'NS1' (CLS module from assembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)&amp;gt;
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;print &lt;/SPAN&gt;a2.NS1.NS2 &lt;SPAN style="COLOR: green"&gt;# &amp;lt;type 'NS2'&amp;gt;
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;print &lt;/SPAN&gt;a1.NS1     &lt;SPAN style="COLOR: green"&gt;# &amp;lt;module 'NS1' (CLS module from assembly1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)&amp;gt;
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;print &lt;/SPAN&gt;a1.NS1.NS2 &lt;SPAN style="COLOR: green"&gt;# &amp;lt;module 'NS2' (CLS module from assembly1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)&amp;gt;
&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;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;Note that such name collision should rarely happen for well-designed framework assemblies. Also IronPython merge types/down-level namespaces under the same namespaces, even if they are from different assemblies. One simple example is System.Int32 from mscorlib.dll and System.Uri from System.dll, both peacefully under the "System" module.&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;import &lt;/SPAN&gt;System
&lt;SPAN style="COLOR: blue"&gt;print &lt;/SPAN&gt;System            
&lt;SPAN style="COLOR: green"&gt;# &amp;lt;module 'System' (CLS module, 2 assemblies loaded)&amp;gt;
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;print &lt;/SPAN&gt;System.__file__   
&lt;SPAN style="COLOR: green"&gt;# ['mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089', 
#  'System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089']
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;import &lt;/SPAN&gt;clr
&lt;SPAN style="COLOR: blue"&gt;print &lt;/SPAN&gt;clr.GetClrType(System.Int32).Assembly  
&lt;SPAN style="COLOR: green"&gt;# &amp;lt;Assembly mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&amp;gt;
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;print &lt;/SPAN&gt;clr.GetClrType(System.Uri).Assembly    
&lt;SPAN style="COLOR: green"&gt;# &amp;lt;Assembly System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&amp;gt;&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;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8177924" width="1" height="1"&gt;</content><author><name>Haibo_Luo</name><uri>http://blogs.msdn.com/members/Haibo_Luo.aspx</uri></author><category term="IronPython" scheme="http://blogs.msdn.com/haibo_luo/archive/tags/IronPython/default.aspx" /></entry><entry><title>IronPython: System.Array</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/haibo_luo/archive/2008/03/12/8177915.aspx" /><id>http://blogs.msdn.com/haibo_luo/archive/2008/03/12/8177915.aspx</id><published>2008-03-13T06:04:13Z</published><updated>2008-03-13T06:04:13Z</updated><content type="html">&lt;p&gt;When you start interop'ing with .NET in IronPython, sooner or later, you will find that you are in need of creating an array as argument. There are mainly 2 ways to create array objects: &lt;/p&gt; &lt;ul&gt; &lt;li&gt;Array with type indexing (for one-dimensional array object only), and  &lt;li&gt;classic reflection API: Array.CreateInstance &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;System.Array indexing with a type creates a concrete array type, which can then take a collection of the element objects (or an enumerable) and form the array object. There are half dozen &lt;a href="http://msdn2.microsoft.com/en-us/library/system.array.createinstance.aspx"&gt;Array.CreateInstance&lt;/a&gt; overloads, which allow us to create one-dimensional empty array, also multi-dimensional/non-zero lower-bound arrays. &lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;import &lt;/span&gt;System
array_int = System.Array[int]
&lt;span style="color: blue"&gt;print &lt;/span&gt;array_int               &lt;span style="color: green"&gt;# &amp;lt;type 'Array[int]'&amp;gt;

# list
&lt;/span&gt;&lt;span style="color: blue"&gt;print &lt;/span&gt;array_int([1, 2])       &lt;span style="color: green"&gt;# System.Int32[](1, 2)
# tuple
&lt;/span&gt;&lt;span style="color: blue"&gt;print &lt;/span&gt;array_int((3, 4, 5))    &lt;span style="color: green"&gt;# System.Int32[](3, 4, 5)
# xrange
&lt;/span&gt;&lt;span style="color: blue"&gt;print &lt;/span&gt;array_int(xrange(6,10)) &lt;span style="color: green"&gt;# System.Int32[](6, 7, 8, 9)
# CLR List
&lt;/span&gt;&lt;span style="color: blue"&gt;print &lt;/span&gt;array_int(System.Collections.Generic.List[int]()) &lt;span style="color: green"&gt;# System.Int32[]()

# one-dimensional array 
&lt;/span&gt;a1 = System.Array.CreateInstance(int, 5)
&lt;span style="color: blue"&gt;for &lt;/span&gt;i &lt;span style="color: blue"&gt;in &lt;/span&gt;range(5): a1[i] = i * 10
&lt;span style="color: blue"&gt;print &lt;/span&gt;a1        &lt;span style="color: green"&gt;# System.Int32[](0, 10, 20, 30, 40)

# two-dimensional array 
&lt;/span&gt;a2 = System.Array.CreateInstance(float, 2, 2)
a2[1, 1] = 3.14
&lt;span style="color: blue"&gt;print &lt;/span&gt;a2        &lt;span style="color: green"&gt;# System.Double[,](
                # 0.0, 0.0
                # 0.0, 3.14)&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;IronPython also supports some python list-like operation to the CLR array objects, such as indexing with slice, +, *, in...&lt;/p&gt;&lt;pre class="code"&gt;a1 = array_int(range(5))
a2 = array_int([100])

&lt;span style="color: green"&gt;# slice
&lt;/span&gt;&lt;span style="color: blue"&gt;print &lt;/span&gt;a1[1:-1]      &lt;span style="color: green"&gt;# System.Int32[](1, 2, 3)
# +
&lt;/span&gt;&lt;span style="color: blue"&gt;print &lt;/span&gt;a1 + a2       &lt;span style="color: green"&gt;# System.Int32[](0, 1, 2, 3, 4, 100)
# *
&lt;/span&gt;&lt;span style="color: blue"&gt;print &lt;/span&gt;a1 * 2        &lt;span style="color: green"&gt;# System.Int32[](0, 1, 2, 3, 4, 0, 1, 2, 3, 4)
# +, upcast the result to object[]
&lt;/span&gt;&lt;span style="color: blue"&gt;print &lt;/span&gt;a2 + System.Array[str](&lt;span style="color: maroon"&gt;'py'&lt;/span&gt;)  &lt;span style="color: green"&gt;# System.Object[](100, 'p', 'y')

# slice with step
&lt;/span&gt;&lt;span style="color: blue"&gt;print &lt;/span&gt;a1[1::2]      &lt;span style="color: green"&gt;# System.Int32[](1, 3)
# assignment 
&lt;/span&gt;a1[1::2] = [11, 13]
&lt;span style="color: blue"&gt;print &lt;/span&gt;a1            &lt;span style="color: green"&gt;# System.Int32[](0, 11, 2, 13, 4)

# in/__contains__
&lt;/span&gt;&lt;span style="color: blue"&gt;print &lt;/span&gt;11 &lt;span style="color: blue"&gt;in &lt;/span&gt;a1      &lt;span style="color: green"&gt;# True
&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8177915" width="1" height="1"&gt;</content><author><name>Haibo_Luo</name><uri>http://blogs.msdn.com/members/Haibo_Luo.aspx</uri></author><category term="IronPython" scheme="http://blogs.msdn.com/haibo_luo/archive/tags/IronPython/default.aspx" /></entry><entry><title>IronPython: ipyw.exe</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/haibo_luo/archive/2008/03/12/8177907.aspx" /><id>http://blogs.msdn.com/haibo_luo/archive/2008/03/12/8177907.aspx</id><published>2008-03-13T06:03:48Z</published><updated>2008-03-13T06:03:48Z</updated><content type="html">&lt;p&gt;Each IronPython binary release ships two executable files: ipy.exe and ipyw.exe. Their (only) difference is, ipy.exe is a console application and ipyw.exe is a windows application. So given the following winform.py, &lt;pre class="code"&gt;&lt;span style="color: green"&gt;## winform.py
&lt;/span&gt;&lt;span style="color: blue"&gt;import &lt;/span&gt;clr
clr.AddReference(&lt;span style="color: maroon"&gt;"System.Windows.Forms"&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;*

&lt;span style="color: blue"&gt;class &lt;/span&gt;SimpleForm(Form):
    &lt;span style="color: blue"&gt;def &lt;/span&gt;__init__(self):
        self.Text = &lt;span style="color: maroon"&gt;'Simple Winform'

&lt;/span&gt;Application.Run(SimpleForm())
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;Running it with ipy.exe will keep the associated console; however, if I launch it with ipyw.exe in a console window, I can continue working on other stuffs within that console. 
&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/haibo_luo/WindowsLiveWriter/IronPythonipyw.exe_1377C/ipy.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" border="0" alt="ipy" align="left" src="http://blogs.msdn.com/blogfiles/haibo_luo/WindowsLiveWriter/IronPythonipyw.exe_1377C/ipy_thumb.png" width="369" height="226"&gt;&lt;/a&gt; 
&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/haibo_luo/WindowsLiveWriter/IronPythonipyw.exe_1377C/ipyw_1.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" border="0" alt="ipyw" src="http://blogs.msdn.com/blogfiles/haibo_luo/WindowsLiveWriter/IronPythonipyw.exe_1377C/ipyw_thumb_1.png" width="357" height="232"&gt;&lt;/a&gt; 
&lt;p&gt;I found that Shawn wrote some background about WINDOW_CUI/WINDOW_GUI subsystem &lt;a href="http://blogs.msdn.com/shawnfa/archive/2005/06/06/425804.aspx"&gt;here&lt;/a&gt;. 
&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8177907" width="1" height="1"&gt;</content><author><name>Haibo_Luo</name><uri>http://blogs.msdn.com/members/Haibo_Luo.aspx</uri></author><category term="IronPython" scheme="http://blogs.msdn.com/haibo_luo/archive/tags/IronPython/default.aspx" /></entry><entry><title>SignatureResolver (unfinished)</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/haibo_luo/archive/2008/03/08/8115220.aspx" /><link rel="enclosure" type="application/x-zip-compressed" length="7963" href="http://blogs.msdn.com/haibo_luo/attachment/8115220.ashx" /><id>http://blogs.msdn.com/haibo_luo/archive/2008/03/08/8115220.aspx</id><published>2008-03-09T01:44:00Z</published><updated>2008-03-09T01:44:00Z</updated><content type="html">&lt;p&gt;While writing the ILVisualizer for dynamic method late 2005, I'd like to show the local variable information as well; so I started working on the managed signature parser, at least to parse LocalVarSig (Ecma-335 23.2.6). It was 2+ years ago, and never got to a finished state. Now perhaps I will never spend more time on it, so I refreshed the code a bit and you may find it useful for some scenarios.&lt;/p&gt;
&lt;p&gt;Here is an example of how to use SignatureResolver to get LocalVarSig in IronPython. The static method SignatureResolver.GetLocalVarSig takes the byte array (the signature blob) and the enclosing method, and returns an array of LocalVar (which includes mainly the runtime type) inside that method.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: green;"&gt;# show local variables for every Array.CreateInstance overload methods&lt;br&gt;&lt;/span&gt;&lt;span style="color: blue;"&gt;import &lt;/span&gt;clr&lt;br&gt;&lt;span style="color: blue;"&gt;import &lt;/span&gt;System&lt;br&gt;clr.AddReference(&lt;span style="color: maroon;"&gt;"ClrTest.Reflection.SignatureResolver"&lt;/span&gt;)&lt;br&gt;&lt;span style="color: blue;"&gt;from &lt;/span&gt;ClrTest.Reflection &lt;span style="color: blue;"&gt;import &lt;/span&gt;*&lt;br&gt;&lt;br&gt;&lt;span style="color: blue;"&gt;for &lt;/span&gt;method &lt;span style="color: blue;"&gt;in &lt;/span&gt;clr.GetClrType(System.Array).GetMember(&lt;span style="color: maroon;"&gt;"CreateInstance"&lt;/span&gt;):&lt;br&gt;    body = method.GetMethodBody()   &lt;span style="color: green;"&gt;# C# won't allow this&lt;br&gt;    &lt;/span&gt;tok = body.LocalSignatureMetadataToken&lt;br&gt;    sig = method.DeclaringType.Module.ResolveSignature(tok)&lt;br&gt;    &lt;span style="color: blue;"&gt;print &lt;/span&gt;&lt;span style="color: maroon;"&gt;"&amp;gt; %s, 0x%x" &lt;/span&gt;% (method, tok)&lt;br&gt;    &lt;span style="color: blue;"&gt;for &lt;/span&gt;lv &lt;span style="color: blue;"&gt;in &lt;/span&gt;SignatureResolver.GetLocalVarSig(sig, method):&lt;br&gt;        &lt;span style="color: blue;"&gt;print &lt;/span&gt;lv&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;Next is part of the output showing one &lt;a href="http://msdn2.microsoft.com/en-us/library/x836773a.aspx" target="_blank" mce_href="http://msdn2.microsoft.com/en-us/library/x836773a.aspx"&gt;Array.CreateInstance&lt;/a&gt; method's local variable types. The result is, of course, same as what Reflector tells us in the below picture. "(p)" means the local variable is pinned.&lt;/p&gt;&lt;pre class="code"&gt;&amp;gt; System.Array CreateInstance(System.Type, Int32[], Int32[]), 0x11000009&lt;br&gt;System.RuntimeType &lt;br&gt;System.Int32 &lt;br&gt;System.Int32&amp;amp; (p)&lt;br&gt;System.Int32&amp;amp; (p)&lt;br&gt;System.Array &lt;br&gt;System.Int32[] &lt;br&gt;System.Int32[] &lt;br&gt;System.RuntimeTypeHandle &lt;br&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/haibo_luo/WindowsLiveWriter/ManagedSignatureResolverincomplete_DEB4/arraycreateinstanceloc.png" mce_href="http://blogs.msdn.com/blogfiles/haibo_luo/WindowsLiveWriter/ManagedSignatureResolverincomplete_DEB4/arraycreateinstanceloc.png"&gt;&lt;img src="http://blogs.msdn.com/blogfiles/haibo_luo/WindowsLiveWriter/ManagedSignatureResolverincomplete_DEB4/arraycreateinstanceloc_thumb.png" style="border-width: 0px;" alt="arraycreateinstanceloc" mce_src="http://blogs.msdn.com/blogfiles/haibo_luo/WindowsLiveWriter/ManagedSignatureResolverincomplete_DEB4/arraycreateinstanceloc_thumb.png" border="0" height="233" width="823"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Yes, I understand the &lt;a href="http://msdn2.microsoft.com/en-us/library/system.reflection.methodbody.localvariables.aspx" target="_blank" mce_href="http://msdn2.microsoft.com/en-us/library/system.reflection.methodbody.localvariables.aspx"&gt;MethodBody.LocalVariables&lt;/a&gt; property gives us the similar information; but the dynamic method can not. That was why I wanted to decode the bytes, and to use DynamicScopeTokenResolver to get a meaningful type string. I admit this version of code diverts from its original goal: it only works for RuntimeMethodInfo/RuntimeConstructorInfo, and won't work for dynamic method; but if one day, you are in need of parsing blob, the functions like GetToken/GetInt32Uncompressed could be handy. GetToken basically is the reverse of TypeDefOrRefEncoded (ecma-335: 23.2.8)&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue;"&gt;int &lt;/span&gt;GetToken() {&lt;br&gt;    &lt;span style="color: blue;"&gt;int &lt;/span&gt;token = GetInt32Uncompressed();&lt;br&gt;    &lt;span style="color: blue;"&gt;return &lt;/span&gt;s_mapForTokenType[token &amp;amp; 0x03] | (token &amp;gt;&amp;gt; 2);&lt;br&gt;}&lt;br&gt;&lt;br&gt;&lt;span style="color: blue;"&gt;int &lt;/span&gt;GetInt32Uncompressed() {&lt;br&gt;    &lt;span style="color: blue;"&gt;byte &lt;/span&gt;first = _sig[_pos];&lt;br&gt;&lt;br&gt;    &lt;span style="color: blue;"&gt;if &lt;/span&gt;(first &amp;lt;= 0x7F) {&lt;br&gt;        &lt;span style="color: blue;"&gt;return &lt;/span&gt;_sig[_pos++];&lt;br&gt;    } &lt;span style="color: blue;"&gt;else if &lt;/span&gt;(first &amp;lt;= 0xBF) {&lt;br&gt;        &lt;span style="color: blue;"&gt;byte&lt;/span&gt;[] bytes = &lt;span style="color: blue;"&gt;new byte&lt;/span&gt;[2];&lt;br&gt;        bytes[1] = (&lt;span style="color: blue;"&gt;byte&lt;/span&gt;)(_sig[_pos++] - 0x80);&lt;br&gt;        bytes[0] = _sig[_pos++];&lt;br&gt;        &lt;span style="color: blue;"&gt;return &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;BitConverter&lt;/span&gt;.ToInt16(bytes, 0);&lt;br&gt;    } &lt;span style="color: blue;"&gt;else &lt;/span&gt;{&lt;br&gt;        &lt;span style="color: blue;"&gt;byte&lt;/span&gt;[] bytes = &lt;span style="color: blue;"&gt;new byte&lt;/span&gt;[4];&lt;br&gt;        bytes[3] = (&lt;span style="color: blue;"&gt;byte&lt;/span&gt;)(_sig[_pos++] - 0xC0);&lt;br&gt;        bytes[2] = _sig[_pos++];&lt;br&gt;        bytes[1] = _sig[_pos++]; ;&lt;br&gt;        bytes[0] = _sig[_pos++];&lt;br&gt;        &lt;span style="color: blue;"&gt;return &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;BitConverter&lt;/span&gt;.ToInt32(bytes, 0);&lt;br&gt;    }&lt;br&gt;}&lt;br&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;My SignatureResolver also provide another static method GetMethodRefSig to get MethodRefSig (Ecma-335 22.25 and 23.2.2). &lt;/p&gt;
&lt;p&gt;If you are interested in this topic, you may download the attached file, unzip it, and take a look at the source. Also try to use VS2008 to build it. &lt;/p&gt;
&lt;p&gt;If you are an &lt;a href="http://www.codeplex.com/IronPython" mce_href="http://www.codeplex.com/IronPython"&gt;IronPython&lt;/a&gt; user, you may try the accompanying tests (in IronPython). I compare the SignatureResolver.GetLocalVarSig result with the official reflection API MethodBody.LocalVariables: they are same for all method/constructors from all simple-LoadFrom-successful framework assemblies. If you have ClrTest.Reflection.ILReader.dll (or know how to get one), you can try test_methodrefsig.py, which tests GetMethodRefSig. &lt;/p&gt;
&lt;p&gt;As stated in the title, this is *unfinished* and could be buggy. &lt;/p&gt;
&lt;p&gt;Disclaimer: THE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES INTENDED OR IMPLIED. USE AT YOUR OWN RISK.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8115220" width="1" height="1"&gt;</content><author><name>Haibo_Luo</name><uri>http://blogs.msdn.com/members/Haibo_Luo.aspx</uri></author><category term="Reflection" scheme="http://blogs.msdn.com/haibo_luo/archive/tags/Reflection/default.aspx" /></entry><entry><title>ILVisualizer VS2008 solution</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/haibo_luo/archive/2008/03/07/8107924.aspx" /><link rel="enclosure" type="application/x-zip-compressed" length="49179" href="http://blogs.msdn.com/haibo_luo/attachment/8107924.ashx" /><id>http://blogs.msdn.com/haibo_luo/archive/2008/03/07/8107924.aspx</id><published>2008-03-08T03:11:00Z</published><updated>2008-03-08T03:11:00Z</updated><content type="html">&lt;P&gt;I attached the ILVisualizer VS2008 solution in this post. There is no source code update; the only change is to upgrade the Microsoft.VisualStudio.DebuggerVisualizers.dll reference from version 8.0.0.0 to version 9.0.0.0. &lt;/P&gt;
&lt;P&gt;Just for your convenience, so you can see a successful build after downloading in VS2008.&lt;/P&gt;
&lt;P&gt;Thanks Julien for leaving the &lt;A class="" target=_blank&gt;instruction&lt;/A&gt;&amp;nbsp;&lt;A class="" href="http://blogs.msdn.com/haibo_luo/archive/2006/11/16/take-two-il-visualizer.aspx#4555501" mce_href="http://blogs.msdn.com/haibo_luo/archive/2006/11/16/take-two-il-visualizer.aspx#4555501"&gt;here&lt;/A&gt;. &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8107924" width="1" height="1"&gt;</content><author><name>Haibo_Luo</name><uri>http://blogs.msdn.com/members/Haibo_Luo.aspx</uri></author><category term="VisualStudio" scheme="http://blogs.msdn.com/haibo_luo/archive/tags/VisualStudio/default.aspx" /></entry><entry><title>IronPython: Accessing the .NET Field</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/haibo_luo/archive/2007/10/28/5753681.aspx" /><id>http://blogs.msdn.com/haibo_luo/archive/2007/10/28/5753681.aspx</id><published>2007-10-29T06:10:00Z</published><updated>2007-10-29T06:10:00Z</updated><content type="html">&lt;p&gt;The .NET libraries normally do not expose the public field, but we can still find its' presence for certain scenarios. IronPython treats the .NET fields like python attribute. For python attribute, the typical operations are set, get and delete. In general, IronPython throws TypeError when deleting members of CLR types and their objects (so for fields). To do set and get operation, the IronPython code looks similar to C# code. Updating (setting) values to the read-only or literal fields throws as we expect.&lt;br&gt;&lt;/p&gt; &lt;div class="csharp"&gt;&lt;span class="cskeyword"&gt;public class&lt;/span&gt; &lt;span class="cstype"&gt;C&lt;/span&gt; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cskeyword"&gt;public static int&lt;/span&gt; StaticField;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cskeyword"&gt;public int&lt;/span&gt; InstanceField;&lt;br&gt;} &lt;/div&gt; &lt;div class="csharp"&gt;&amp;gt;&amp;gt;&amp;gt; ...&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="typein"&gt;C.StaticField = 1&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # set&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="typein"&gt;C.StaticField&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # get&lt;br&gt;1&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="typein"&gt;c = C()&lt;/span&gt;&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="typein"&gt;c.InstanceField = 2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # set&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="typein"&gt;c.InstanceField&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # get&lt;br&gt;2&lt;br&gt;&lt;/div&gt; &lt;p&gt;Guess what you will get for C.InstanceField? It is "field descriptor", same as C.__dict__['InstanceField'], upon which we can call __set__/__get__ or two equivalent helper methods SetValue/GetValue (feel like repeating CLR reflection FieldInfo API here). Although not shown below, we can also set/get the value of the static field too by calling these methods on C.__dict__['StaticField']. &lt;/p&gt; &lt;div class="csharp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="typein"&gt;C.InstanceField&lt;/span&gt;&lt;br&gt;&amp;lt;field# InstanceField on C&amp;gt;&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="typein"&gt;C.InstanceField is C.__dict__['InstanceField']&lt;/span&gt;&lt;br&gt;True&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="typein"&gt;C.InstanceField.__set__(c, 3)&lt;/span&gt;&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="typein"&gt;C.InstanceField.__get__(c)&lt;/span&gt;&lt;br&gt;3&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="typein"&gt;C.InstanceField.SetValue(c, 4)&lt;/span&gt;&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="typein"&gt;C.InstanceField.GetValue(c)&lt;/span&gt;&lt;br&gt;4 &lt;/div&gt; &lt;p&gt;IronPython allows accessing static field on instance too. On the other hand, C# compiler requires type name to access static member (otherwise &lt;a href="http://msdn2.microsoft.com/en-us/library/zhcxt2bd%28vs.71%29.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/zhcxt2bd(vs.71).aspx"&gt;CS0176&lt;/a&gt;). &lt;/p&gt; &lt;div class="csharp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="typein"&gt;c.StaticField = 5&lt;/span&gt;&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="typein"&gt;c.StaticField, C.StaticField&lt;/span&gt;&lt;br&gt;(5, 5)&lt;br&gt;&lt;/div&gt; &lt;p&gt;Updating fields of &lt;i&gt;value types&lt;/i&gt; is not allowed. If interested, you may go ahead read the design decision &lt;a href="http://channel9.msdn.com/wiki/default.aspx/IronPython.ValueTypes" mce_href="http://channel9.msdn.com/wiki/default.aspx/IronPython.ValueTypes"&gt;here&lt;/a&gt;. Until recently I did not know that as a remedy, the feature of &lt;a href="http://blogs.msdn.com/haibo_luo/archive/2007/10/02/5246577.aspx" mce_href="http://blogs.msdn.com/haibo_luo/archive/2007/10/02/5246577.aspx"&gt;setting fields/properties in the constructor call&lt;/a&gt; should be able to set field for value types while still keeping value types effectively immutable after the creation. Unfortunately we had no tests to cover this part (which never worked). This code below illustrates the expected behavior. I expect it to work soon.&lt;br&gt;&lt;/p&gt; &lt;div class="csharp"&gt;&lt;span class="cskeyword"&gt;public struct &lt;/span&gt;&lt;span class="cstype"&gt;MyPoint &lt;/span&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cskeyword"&gt;public int&lt;/span&gt; X, Y;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cskeyword"&gt;public override string&lt;/span&gt; ToString() { &lt;span class="cskeyword"&gt;return string&lt;/span&gt;.Format(&lt;span class="csstring"&gt;"X: {0}, Y: {1}"&lt;/span&gt;, X, Y); }&lt;br&gt;} &lt;/div&gt; &lt;div class="csharp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="typein"&gt;p = MyPoint(X=1, Y=2)&lt;/span&gt;&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="typein"&gt;p&lt;/span&gt; &lt;br&gt;&amp;lt;MyPoint object at 0x000000000000002C [&lt;span class="special"&gt;X: 1, Y: 2&lt;/span&gt;]&amp;gt;&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="typein"&gt;p.X = 3&lt;/span&gt;&lt;br&gt;# one kind of exception still throws&lt;br&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5753681" width="1" height="1"&gt;</content><author><name>Haibo_Luo</name><uri>http://blogs.msdn.com/members/Haibo_Luo.aspx</uri></author><category term="IronPython" scheme="http://blogs.msdn.com/haibo_luo/archive/tags/IronPython/default.aspx" /></entry><entry><title>VisualStudio as my IronPython editor</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/haibo_luo/archive/2007/10/16/5482940.aspx" /><link rel="enclosure" type="application/x-zip-compressed" length="34131" href="http://blogs.msdn.com/haibo_luo/attachment/5482940.ashx" /><id>http://blogs.msdn.com/haibo_luo/archive/2007/10/16/5482940.aspx</id><published>2007-10-17T08:00:00Z</published><updated>2007-10-17T08:00:00Z</updated><content type="html">&lt;P&gt;The following steps are what I did to get Visual Studio ready as my IronPython (and IronRuby) editor.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Install the latest internal dogfood build of Visual Studio 2008. 
&lt;UL&gt;
&lt;LI&gt;you may use Visual Studio 2005 or download the &lt;A href="http://www.microsoft.com/downloads/details.aspx?FamilyId=B98A61BA-99B0-40B7-AB6E-5386A2B94217&amp;amp;displaylang=en" target=_blank mce_href="http://www.microsoft.com/downloads/details.aspx?FamilyId=B98A61BA-99B0-40B7-AB6E-5386A2B94217&amp;amp;displaylang=en"&gt;VS 2008 public beta2&lt;/A&gt;;&lt;/LI&gt;&lt;/UL&gt;
&lt;LI&gt;Download and install &lt;A href="http://www.microsoft.com/downloads/details.aspx?familyid=A5189BCB-EF81-4C12-9733-E294D13A58E6&amp;amp;displaylang=en" target=_blank mce_href="http://www.microsoft.com/downloads/details.aspx?familyid=A5189BCB-EF81-4C12-9733-E294D13A58E6&amp;amp;displaylang=en"&gt;ASP.NET futures release (July 2007)&lt;/A&gt;. This will give me the nice syntax coloring and (well... limited) intellisense for python code. 
&lt;UL&gt;
&lt;LI&gt;you may download &lt;A href="http://www.microsoft.com/downloads/details.aspx?familyid=d9000e2c-bd3f-4717-a181-723960814e16&amp;amp;displaylang=en" target=_blank mce_href="http://www.microsoft.com/downloads/details.aspx?familyid=d9000e2c-bd3f-4717-a181-723960814e16&amp;amp;displaylang=en"&gt;VSSDK 2008 CTP&lt;/A&gt;, and build the IronPython integration sample, which will give you the similar editing experience;&lt;/LI&gt;&lt;/UL&gt;
&lt;LI&gt;Download the attached add-in binary zip (poorly named as DlrToolsAddin); for my Vista box, I extract them under "%USERPROFILE%\Documents\Visual Studio 2008\Addins". I wrote this add-in basically to allow me to run the script inside the Visual Studio, and show the output in the output window. 
&lt;UL&gt;
&lt;LI&gt;if you consider using it for VS 2005, you will need put it in "Visual Studio 2005\Addins".&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Say, I am trying the example in my previous post, I create a new C# file (sample.cs) without creating solution/project, I can press Ctrl+1 (or the first button in the DlrTools toobar)&amp;nbsp; to get it compiled to sample.dll in the local directory. You see the compile result at the bottom output window. Then I create a python file (method.py) in the same directory, type in some code (shown in color). Again, I can press Ctrl+1, the result are shown in the output window. I do not need leave VS and run these files in the cmd.exe window.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/haibo_luo/WindowsLiveWriter/DlrToolsAddin_8432/image_16.png" mce_href="http://blogs.msdn.com/blogfiles/haibo_luo/WindowsLiveWriter/DlrToolsAddin_8432/image_16.png"&gt;&lt;IMG style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=529 alt=image src="http://blogs.msdn.com/blogfiles/haibo_luo/WindowsLiveWriter/DlrToolsAddin_8432/image_thumb_7.png" width=697 border=0 mce_src="http://blogs.msdn.com/blogfiles/haibo_luo/WindowsLiveWriter/DlrToolsAddin_8432/image_thumb_7.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;A href="http://blogs.msdn.com/blogfiles/haibo_luo/WindowsLiveWriter/DlrToolsAddin_8432/image_14.png" mce_href="http://blogs.msdn.com/blogfiles/haibo_luo/WindowsLiveWriter/DlrToolsAddin_8432/image_14.png"&gt;&lt;IMG style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=526 alt=image src="http://blogs.msdn.com/blogfiles/haibo_luo/WindowsLiveWriter/DlrToolsAddin_8432/image_thumb_6.png" width=693 border=0 mce_src="http://blogs.msdn.com/blogfiles/haibo_luo/WindowsLiveWriter/DlrToolsAddin_8432/image_thumb_6.png"&gt;&lt;/A&gt;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Sometimes I want to run the same code with different tools (for example, to check IronPython compatibility, I often run the same .py file against C-Python 2.5 too). That is the first combo box comes to play. &lt;/P&gt;
&lt;P&gt;The second combo box is to set the working directory: "." means the current directory where the active file lives, ".." for the parent directory of the current file, or you may use the absolute path. Such support is needed to run C-Python regression tests. (For the add-in implementation side, I feel what I really want is a combo box of type vsCommandControlTypeDynamicCombo, which seems not available for add-in development).&lt;/P&gt;
&lt;P&gt;The delete button is to remove your tool choice for those files you pressed "Run Script". By clicking the last button, an XML file (specifying which tools for which file extension) is opened so you may change it. &lt;STRONG&gt;You must update it with your tool paths&lt;/STRONG&gt;, since the default setting is suited for myself. &lt;/P&gt;
&lt;P&gt;You may also run part of the file by selecting those lines first (A temporary file is created and will be deleted after VS shutdown). &lt;/P&gt;
&lt;P&gt;One bad thing I noticed of this add-in is that sometimes I press the "run script" button to start debugging, both icons have similar shapes.&lt;/P&gt;
&lt;P&gt;To uninstall it, delete DlrToolsAddin.* files under "Addins"; and then run once "devenv.exe /resetaddin DlrToolsAddin.Connect".&lt;/P&gt;
&lt;P&gt;The source code (VS2008 project) is also attached. &lt;EM&gt;Disclaimer: THE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES INTENDED OR IMPLIED. USE AT YOUR OWN RISK. &lt;/EM&gt;Hope you like Visual Studio as your IronPython editor.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5482940" width="1" height="1"&gt;</content><author><name>Haibo_Luo</name><uri>http://blogs.msdn.com/members/Haibo_Luo.aspx</uri></author><category term="IronPython" scheme="http://blogs.msdn.com/haibo_luo/archive/tags/IronPython/default.aspx" /><category term="IronRuby" scheme="http://blogs.msdn.com/haibo_luo/archive/tags/IronRuby/default.aspx" /><category term="VisualStudio" scheme="http://blogs.msdn.com/haibo_luo/archive/tags/VisualStudio/default.aspx" /></entry><entry><title>IronPython: explicitly choose one method</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/haibo_luo/archive/2007/10/11/5413239.aspx" /><id>http://blogs.msdn.com/haibo_luo/archive/2007/10/11/5413239.aspx</id><published>2007-10-12T06:32:47Z</published><updated>2007-10-12T06:32:47Z</updated><content type="html">&lt;p&gt;C# allows method overloading. Given an argument list, the compiler performs the overload resolution to select the best method to invoke. The chosen method token is baked into the assembly. IronPython does the method resolution at the IronPython &lt;em&gt;run time&lt;/em&gt;; for most scenarios, it has no problem in picking up the most reasonable one based on the argument list. The rules are a bit complicated, and I will leave them for a future post. If you believe IronPython chooses the "unexpected" method for your scenario, please do let us know.&lt;/p&gt; &lt;p&gt;IronPython also provides the "Overloads" (python) attribute for the bound method, on which we can do index operation with parameter types to get the exact method we want. In the example below, the .NET reflection API &lt;a href="http://msdn2.microsoft.com/en-us/library/system.type.makebyreftype.aspx"&gt;Type.MakeByRefType&lt;/a&gt; and &lt;a href="http://msdn2.microsoft.com/en-us/library/system.type.makearraytype.aspx"&gt;MakeArrayType&lt;/a&gt; are used in order to get those constructed types. Since these calls are only available for System.Type object, clr.GetClrType is called first on the python type to get the underlying CLR type. However, I am able to use the python type for the first 2 index calls (thanks to the type conversion).&lt;/p&gt; &lt;p class="csharp"&gt;&lt;span class="cskeyword"&gt;public class&lt;/span&gt; &lt;span class="cstype"&gt;ChooseOverload &lt;/span&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp; &lt;span class="cskeyword"&gt;public void&lt;/span&gt; M(&lt;span class="cskeyword"&gt;int &lt;/span&gt;arg) { &lt;span class="cstype"&gt;Console&lt;/span&gt;.WriteLine(1); }&lt;br&gt;&amp;nbsp;&amp;nbsp; &lt;span class="cskeyword"&gt;public void&lt;/span&gt; M(&lt;span class="cskeyword"&gt;byte &lt;/span&gt;arg1, &lt;span class="cskeyword"&gt;byte &lt;/span&gt;arg2) { &lt;span class="cstype"&gt;Console&lt;/span&gt;.WriteLine(2); }&lt;br&gt;&amp;nbsp;&amp;nbsp; &lt;span class="cskeyword"&gt;public void&lt;/span&gt; M(&lt;span class="cskeyword"&gt;ref int&lt;/span&gt; arg) { &lt;span class="cstype"&gt;Console&lt;/span&gt;.WriteLine(3); arg = 10; }&lt;br&gt;&amp;nbsp;&amp;nbsp; &lt;span class="cskeyword"&gt;public void&lt;/span&gt; M(&lt;span class="cskeyword"&gt;int&lt;/span&gt;[] arg) { &lt;span class="cstype"&gt;Console&lt;/span&gt;.WriteLine(4); }&lt;br&gt;}&lt;/p&gt; &lt;p class="csharp"&gt;&amp;gt;&amp;gt;&amp;gt; ... # add the assembly&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="typein"&gt;import ChooseOverload&lt;/span&gt;&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="typein"&gt;o = ChooseOverload()&lt;/span&gt;&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="typein"&gt;o.M&lt;/span&gt;&lt;br&gt;&amp;lt;built-in method M of ChooseOverload object at 0x000000000000002B&amp;gt;&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="typein"&gt;o.M.Overloads&lt;/span&gt;&lt;br&gt;{'M(self, int arg)': &amp;lt;built-in function M&amp;gt;, 'M(self, Byte arg1, Byte arg2)': &amp;lt;built-in function M&amp;gt;, 'int M(self, int arg)': &amp;lt;built-in function M&amp;gt;, 'M(self, Array[int] arg)': &amp;lt;built-in function M&amp;gt;}&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="typein"&gt;o.M.Overloads[int](1)&lt;/span&gt;&lt;br&gt;1&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="typein"&gt;o.M.Overloads[System.Byte, System.Byte](1, 2)&lt;/span&gt;&lt;br&gt;2&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="typein"&gt;o.M.Overloads[clr.GetClrType(int).MakeByRefType()](1)&lt;/span&gt;&lt;br&gt;3&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="typein"&gt;o.M.Overloads[clr.GetClrType(int).MakeArrayType()](None)&lt;/span&gt;&lt;br&gt;4&lt;br&gt;&lt;/p&gt; &lt;p class="style1"&gt;When generics come to the picture, o.M could mean the generic method. &lt;a href="http://blogs.msdn.com/haibo_luo/archive/2007/09/25/5130087.aspx"&gt;Similar to the generic type&lt;/a&gt;, IronPython chooses the index operation to hold the instantiated generic method. Currently IronPython has no support to specify parameter types which are (or made from) generic type parameters (of either the generic method or type). Expect this will be supported one day.&lt;/p&gt; &lt;p class="csharp"&gt;&amp;nbsp;&lt;span class="cskeyword"&gt;public void&lt;/span&gt; M2&amp;lt;T&amp;gt;(T arg)&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;span class="cstype"&gt;Console&lt;/span&gt;.WriteLine(5); }&lt;br&gt;&amp;nbsp;&lt;span class="cskeyword"&gt;public void&lt;/span&gt; M2&amp;lt;T&amp;gt;(&lt;span class="cskeyword"&gt;byte &lt;/span&gt;arg) { &lt;span class="cstype"&gt;Console&lt;/span&gt;.WriteLine(6); }&lt;/p&gt; &lt;p class="csharp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="typein"&gt;o.M2[int](1)&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # bind to the first M2 given the argument "1"&lt;br&gt;5&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="typein"&gt;o.M2[int].Overloads[System.Byte](1)&amp;nbsp; &lt;/span&gt;# in order to get the second M2&lt;br&gt;6 &lt;br&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="typein"&gt;o.M2[int].Overloads[???](1)&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # unable to pick the first M2 currently &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5413239" width="1" height="1"&gt;</content><author><name>Haibo_Luo</name><uri>http://blogs.msdn.com/members/Haibo_Luo.aspx</uri></author><category term="IronPython" scheme="http://blogs.msdn.com/haibo_luo/archive/tags/IronPython/default.aspx" /></entry><entry><title>IronPython: Provide (or not) Argument for by-ref Parameter</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/haibo_luo/archive/2007/10/04/5284947.aspx" /><id>http://blogs.msdn.com/haibo_luo/archive/2007/10/04/5284947.aspx</id><published>2007-10-05T08:21:00Z</published><updated>2007-10-05T08:21:00Z</updated><content type="html">&lt;P&gt;Python function may return multiple objects as a tuple. The .NET method can only return one object as the result of a call; in order to return more than one objects, by-ref parameters are needed. They are decorated with the &lt;A href="http://msdn2.microsoft.com/en-us/library/aa645761(VS.71).aspx" mce_href="http://msdn2.microsoft.com/en-us/library/aa645761(VS.71).aspx"&gt;parameter modifier&lt;/A&gt; (ref, out) in C#.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://msdn2.microsoft.com/en-us/library/zkw5c9ak.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/zkw5c9ak.aspx"&gt;Dictionary.TryGetValue&lt;/A&gt;(TKey key, out TValue value) has an &lt;A href="http://msdn2.microsoft.com/en-us/library/aa645764(VS.71).aspx" mce_href="http://msdn2.microsoft.com/en-us/library/aa645764(VS.71).aspx"&gt;output parameter&lt;/A&gt; "value". The API returns true if the dictionary contains an element with the specified key (the element value itself is returned to the parameter "value"), otherwise it returns false. When making calls to such methods in IronPython, we may not pass in argument for the output parameter. Instead, the result of such .NET method call in IronPython will likely be a tuple (unless the .NET method's return type is void and the method has only one by-ref parameter), which contains the value of the output parameter (see the example below). &lt;/P&gt;
&lt;DIV class=csharp&gt;&lt;SPAN class=cskeyword&gt;import&lt;/SPAN&gt; System&lt;BR&gt;d = System.Collections.Generic.Dictionary[int, str]()&lt;BR&gt;d[1], d[2] = &lt;SPAN class=csstring&gt;'One'&lt;/SPAN&gt;, &lt;SPAN class=csstring&gt;'Two'&lt;/SPAN&gt;&lt;BR&gt;&amp;nbsp;&lt;BR&gt;&lt;SPAN class=cskeyword&gt;print &lt;/SPAN&gt;d.TryGetValue(1) &lt;SPAN class=cscomment&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # (True, 'One')&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN class=cskeyword&gt;print &lt;/SPAN&gt;d.TryGetValue(2)[1]&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cscomment&gt;# Two&lt;/SPAN&gt;&amp;nbsp; &lt;BR&gt;&lt;SPAN class=cskeyword&gt;print &lt;/SPAN&gt;d.TryGetValue(3)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cscomment&gt;# (False, None)&lt;/SPAN&gt;&lt;BR&gt;&lt;/DIV&gt;
&lt;P&gt;We may also pass a clr.Reference object for the output parameter. The clr.Reference object has only one member "Value", which will carry the output parameter value after the call. "clr.Reference" object is of the type identical to System.Runtime.CompilerServices.StrongBox&amp;lt;T&amp;gt; in the new .NET Framework 3.5. When encountering this type of argument, IronPython codegen/runtime does something special to update the "Value".&lt;/P&gt;
&lt;DIV class=csharp&gt;x = clr.Reference[str]()&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cscomment&gt;# like "new StrongBox&amp;lt;string&amp;gt;()" in C#&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN class=cskeyword&gt;print &lt;/SPAN&gt;d.TryGetValue(1, x), x.Value&amp;nbsp;&amp;nbsp; &lt;SPAN class=cscomment&gt;# True One&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN class=cskeyword&gt;print &lt;/SPAN&gt;d.TryGetValue(3, x), x.Value&amp;nbsp;&amp;nbsp; &lt;SPAN class=cscomment&gt;# False None&lt;/SPAN&gt;&lt;BR&gt;&lt;/DIV&gt;
&lt;P&gt;For &lt;A href="http://msdn2.microsoft.com/en-us/library/aa645763(VS.71).aspx" mce_href="http://msdn2.microsoft.com/en-us/library/aa645763(VS.71).aspx"&gt;reference parameter&lt;/A&gt;, we are required to pass in something. If the argument is not clr.Reference object, such reference argument value will also be part of the returned tuple; otherwise, the by-ref change is tracked inside clr.Reference. The following C# code is my twisted way to find the maximum number; the IronPython snippet shows the behaviors of calling that method not using and using clr.Reference.&lt;/P&gt;
&lt;DIV class=csharp&gt;&lt;SPAN class=cskeyword&gt;public class&lt;/SPAN&gt; &lt;SPAN class=cstype&gt;C &lt;/SPAN&gt;{&lt;BR&gt;&amp;nbsp; &lt;SPAN class=cskeyword&gt;public bool&lt;/SPAN&gt; M(&lt;SPAN class=cskeyword&gt;int &lt;/SPAN&gt;current, &lt;SPAN class=cskeyword&gt;ref int&lt;/SPAN&gt; max) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cskeyword&gt;if &lt;/SPAN&gt;(current &amp;gt; max) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; max = current; &lt;SPAN class=cskeyword&gt;return &lt;/SPAN&gt;true;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;SPAN class=cskeyword&gt;else&lt;/SPAN&gt; &lt;SPAN class=cskeyword&gt;return &lt;/SPAN&gt;false;&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;BR&gt;&lt;/DIV&gt;
&lt;DIV class=csharp&gt;&lt;SPAN class=cskeyword&gt;import &lt;/SPAN&gt;C&lt;BR&gt;o = C()&lt;BR&gt;&amp;nbsp;&lt;BR&gt;&lt;SPAN class=cskeyword&gt;print &lt;/SPAN&gt;o.M(10, 20)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cscomment&gt;# (False, 20)&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN class=cskeyword&gt;print &lt;/SPAN&gt;o.M(30, 20)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cscomment&gt;# (True, 30)&lt;/SPAN&gt;&lt;BR&gt;&amp;nbsp;&lt;BR&gt;x = clr.Reference[int](20)&lt;BR&gt;&lt;SPAN class=cskeyword&gt;print &lt;/SPAN&gt;o.M(10, x), x&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cscomment&gt;# False 20&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN class=cskeyword&gt;print &lt;/SPAN&gt;o.M(30, x), x&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cscomment&gt;# True 30&lt;/SPAN&gt;&lt;BR&gt;&amp;nbsp;&lt;BR&gt;o.M(1)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cscomment&gt;# TypeError: M() takes exactly 2 arguments (1 given)&lt;/SPAN&gt;&lt;BR&gt;&lt;/DIV&gt;
&lt;P&gt;Note if the .NET method contains more than one by-ref parameters, IronPython expects the user to provide proper clr.Reference objects for either ALL or NONE of them. A mix of clr.Reference object and normal argument/omission (for out parameter) will cause error (as illustrated below).&lt;/P&gt;
&lt;DIV class=csharp&gt;&lt;SPAN class=cskeyword&gt;public int&lt;/SPAN&gt; M2(&lt;SPAN class=cskeyword&gt;ref int&lt;/SPAN&gt; x, &lt;SPAN class=cskeyword&gt;ref int&lt;/SPAN&gt; y) {...}&lt;/DIV&gt;
&lt;DIV class=csharp&gt;o.M2(clr.Reference[int](1), 2) &lt;SPAN class=cscomment&gt;# TypeError&lt;/SPAN&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5284947" width="1" height="1"&gt;</content><author><name>Haibo_Luo</name><uri>http://blogs.msdn.com/members/Haibo_Luo.aspx</uri></author><category term="IronPython" scheme="http://blogs.msdn.com/haibo_luo/archive/tags/IronPython/default.aspx" /></entry><entry><title>IronPython: Keyword Argument to Set .NET Property/Field</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/haibo_luo/archive/2007/10/02/5246577.aspx" /><id>http://blogs.msdn.com/haibo_luo/archive/2007/10/02/5246577.aspx</id><published>2007-10-02T22:16:00Z</published><updated>2007-10-02T22:16:00Z</updated><content type="html">&lt;P&gt;Use keyword arguments to set properties or fields… you likely ask the question: where can we do this? IronPython allows it in the constructor call, the call against the .NET type. Such keyword should be the name of public field, or property (which is not read-only). After creating the object instance, each keyword argument value is then set to the corresponding field or property. Note keyword arguments can be used for the constructor parameters as usual.&lt;/P&gt;
&lt;P&gt;The IronPython code below is to monitor any python file change under the directory "C:\temp". I used this special argument passing in the 2nd line.&lt;/P&gt;
&lt;DIV class=csharp&gt;&lt;SPAN class=cskeyword&gt;import &lt;/SPAN&gt;System &lt;BR&gt;fsw = System.IO.FileSystemWatcher(&lt;SPAN class=csstring&gt;r"C:\temp"&lt;/SPAN&gt;, &lt;B&gt;Filter=&lt;/B&gt;&lt;SPAN class=style1&gt;"*.py"&lt;/SPAN&gt;&lt;B&gt;, IncludeSubdirectories = True, EnableRaisingEvents = True&lt;/B&gt;)&lt;BR&gt;&lt;SPAN class=cskeyword&gt;def &lt;/SPAN&gt;on_changed(o,e): &lt;SPAN class=cskeyword&gt;print &lt;/SPAN&gt;e.ChangeType, e.FullPath&lt;BR&gt;fsw.Changed += on_changed&lt;BR&gt;&lt;BR&gt;System.Console.ReadLine()&lt;/DIV&gt;
&lt;P&gt;&lt;A href="http://msdn2.microsoft.com/en-us/library/system.io.filesystemwatcher.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/system.io.filesystemwatcher.aspx"&gt;FileSystemWatcher&lt;/A&gt; has three constructors (see below). The code uses the second one (not the third one)."c:\temp" is positional argument for "path"; the next 3 keywords arguments are transformed to the property (Filter/IncludeSubdirectories/…) assignments after the object creation. &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;public FileSystemWatcher(); 
&lt;LI&gt;public FileSystemWatcher(string path); 
&lt;LI&gt;public FileSystemWatcher(string path, string filter); &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;I am not going to argue whether this feature is good or bad. You may find it handy in some places. The user could get confused when the constructor parameter name is same as the field/property name (Although it is unlikely as most libraries are following the .NET framework guideline: property name starts with the capital character, while the parameter name does opposite). One of our summer interns also proposed to extend this feature to event setting as keyword argument. It is currently not supported, not sure whether it will ever come in the future.&lt;/P&gt;
&lt;P&gt;Note this code above actually doe not work in IronPython 2.0 alpha 4 (due to bugs). The upcoming &lt;A href="http://www.codeplex.com/IronPython/Release/ProjectReleases.aspx?ReleaseId=2573" target=_blank mce_href="http://www.codeplex.com/IronPython/Release/ProjectReleases.aspx?ReleaseId=2573"&gt;2.0 alpha5&lt;/A&gt; will have the fix. &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5246577" width="1" height="1"&gt;</content><author><name>Haibo_Luo</name><uri>http://blogs.msdn.com/members/Haibo_Luo.aspx</uri></author><category term="IronPython" scheme="http://blogs.msdn.com/haibo_luo/archive/tags/IronPython/default.aspx" /></entry><entry><title>IronPython: Passing Arguments for a Call</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/haibo_luo/archive/2007/10/01/5230964.aspx" /><id>http://blogs.msdn.com/haibo_luo/archive/2007/10/01/5230964.aspx</id><published>2007-10-02T02:06:41Z</published><updated>2007-10-02T02:06:41Z</updated><content type="html">&lt;p&gt;After getting a CLR type, we can play it like a python type. We can get the class/static methods using the dot operator ("attribute reference") on the type, or create an instance of it and then get the instance methods. In Python’s word, these methods are callable objects, and we can make "&lt;a href="http://docs.python.org/ref/calls.html"&gt;calls&lt;/a&gt;" on them using the call operator ("()"). I will write about the method call in the next couple of posts, this one is about passing arguments for calls in IronPython.&lt;/p&gt; &lt;p&gt;Python &lt;a href="http://docs.python.org/ref/function.html#function"&gt;function definition&lt;/a&gt; allows several different &lt;i&gt;parameter&lt;/i&gt; styles: &lt;/p&gt; &lt;ul&gt; &lt;li&gt;parameter which accepts excess positional arguments,  &lt;li&gt;parameter with default value,  &lt;li&gt;parameter which accepts excess keyword arguments. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Here are some examples showing the common parameter style, and each of 3 styles listed above. &lt;/p&gt; &lt;div class="csharp"&gt;&lt;span class="cskeyword"&gt;def &lt;/span&gt;f1(x, y):&amp;nbsp;&amp;nbsp; &lt;span class="cskeyword"&gt;print &lt;/span&gt;x, y&lt;br&gt;&lt;span class="cskeyword"&gt;def &lt;/span&gt;f2(x, *y):&amp;nbsp; &lt;span class="cskeyword"&gt;print &lt;/span&gt;x, len(y)&lt;br&gt;&lt;span class="cskeyword"&gt;def &lt;/span&gt;f3(x, y=5): &lt;span class="cskeyword"&gt;print &lt;/span&gt;x, y&lt;br&gt;&lt;span class="cskeyword"&gt;def &lt;/span&gt;f4(x, **y): &lt;span class="cskeyword"&gt;print &lt;/span&gt;x, y&lt;/div&gt; &lt;p&gt;When making calls (on these functions), Python allows many different &lt;i&gt;argument&lt;/i&gt; styles too. The following type (in C#) defines some methods, each with interesting &lt;i&gt;parameter&lt;/i&gt; list.&lt;/p&gt; &lt;div class="csharp"&gt;&lt;span class="cscomment"&gt;// sample.cs&lt;/span&gt;&lt;br&gt;&lt;span class="cskeyword"&gt;public class&lt;/span&gt; &lt;span class="cstype"&gt;ArgumentList &lt;/span&gt;&lt;br&gt;&amp;nbsp; &lt;span class="cskeyword"&gt;public void&lt;/span&gt; M1(&lt;span class="cskeyword"&gt;int &lt;/span&gt;x, &lt;span class="cskeyword"&gt;int &lt;/span&gt;y) { &lt;span class="cstype"&gt;Console&lt;/span&gt;.WriteLine(&lt;span class="csstring"&gt;"{0} {1}"&lt;/span&gt;, x, y); }&lt;br&gt;&amp;nbsp; &lt;span class="cskeyword"&gt;public void&lt;/span&gt; M2(&lt;span class="cskeyword"&gt;int &lt;/span&gt;x, &lt;span class="cskeyword"&gt;params int&lt;/span&gt;[] y) { &lt;span class="cstype"&gt;Console&lt;/span&gt;.WriteLine(&lt;span class="csstring"&gt;"{0} {1}"&lt;/span&gt;, x, y.Length); }&lt;br&gt;&amp;nbsp; &lt;span class="cskeyword"&gt;public void&lt;/span&gt; M3(&lt;span class="cskeyword"&gt;int &lt;/span&gt;x, [&lt;span class="cstype"&gt;DefaultParameterValue&lt;/span&gt;(5)] &lt;span class="cskeyword"&gt;int &lt;/span&gt;y) { &lt;span class="cstype"&gt;Console&lt;/span&gt;.WriteLine(&lt;span class="csstring"&gt;"{0} {1}"&lt;/span&gt;, x, y); }&lt;br&gt;}&lt;/div&gt; &lt;p&gt;In terms of the parameter style, we will see that M1 is equivalent as pure python function f1, same for M2/f2, M3/f3 (I was unable to find similar parameter kind in C# for f4). When calling these .NET methods, IronPython supports all &lt;i&gt;argument&lt;/i&gt; styles as Python does. &lt;/p&gt; &lt;p&gt;M1 is the simplest in the parameter definition, but we can call it with different argument lists. Each call below prints "1, 2", same as if the python function "f1" is called. &lt;/p&gt; &lt;div class="csharp"&gt;&lt;span class="cskeyword"&gt;import &lt;/span&gt;clr&lt;br&gt;clr.AddReference(&lt;span class="csstring"&gt;"sample"&lt;/span&gt;)&lt;br&gt;&lt;br&gt;&lt;span class="cskeyword"&gt;import &lt;/span&gt;ArgumentList&lt;br&gt;o = ArgumentList()&lt;br&gt;f1 = o.M1&lt;br&gt;&lt;br&gt;f1(1, 2)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cscomment"&gt;# positional arguments&lt;/span&gt; &lt;br&gt;f1(1, y = 2)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cscomment"&gt;# positional &amp;amp; keyword arguments&lt;/span&gt;&lt;br&gt;f1(y = 2, x = 1)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cscomment"&gt;# keyword arguments&lt;/span&gt;&lt;br&gt;f1(*(1, 2))&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cscomment"&gt;# unpack the sequence as positional args&lt;/span&gt;&lt;br&gt;f1(1, *(2,))&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cscomment"&gt;# positional &amp;amp; unpack&lt;/span&gt;&lt;br&gt;f1(**{'x': 1, 'y': 2})&amp;nbsp;&amp;nbsp; &lt;span class="cscomment"&gt;# unpack the dictionary as keyword args&lt;/span&gt;&lt;/div&gt; &lt;p&gt;C# parameter array (parameter with &lt;i&gt;"params", &lt;/i&gt;or exactly &lt;a href="http://msdn2.microsoft.com/en-us/library/system.paramarrayattribute.aspx"&gt;ParamArrayAttribute&lt;/a&gt;) is treated like "*y" in f2. The user are allowed to pass 0 or more arguments to the parameter "y".&lt;/p&gt; &lt;div class="csharp"&gt;f2 = o.M2&lt;br&gt;f2(1)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cscomment"&gt;# print: 1 0&lt;/span&gt;&lt;br&gt;f2(1, 2)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cscomment"&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1 1&lt;/span&gt;&lt;br&gt;f2(*(1, 2, 3))&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cscomment"&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1 2&lt;/span&gt;&lt;br&gt;f2(1, 2, 3, 4, 5)&amp;nbsp; &lt;span class="cscomment"&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1 4&lt;/span&gt;&lt;/div&gt; &lt;p&gt;The C# language does not have built-in support for the default value argument (IL does, with the .param directive inside the method body); even if the parameter is decorated with &lt;a href="http://msdn2.microsoft.com/en-us/library/system.runtime.interopservices.defaultparametervalueattribute.aspx"&gt;System.Runtime.InteropServices.DefaultParameterValueAttribute&lt;/a&gt;, C# calls on such methods still require argument passed in for that parameter. However IronPython (like Python) honors such default value parameters. &lt;/p&gt; &lt;div class="csharp"&gt;f3 = o.M3&lt;br&gt;f2(1)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cscomment"&gt;# print: 1 5&lt;/span&gt;&lt;br&gt;f2(x = 1)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cscomment"&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1 5&lt;/span&gt;&lt;br&gt;f2(1, 2)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cscomment"&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1 2&lt;/span&gt;&lt;/div&gt; &lt;p&gt;Another parameter attribute (&lt;a href="http://msdn2.microsoft.com/en-us/library/system.runtime.interopservices.optionalattribute.aspx"&gt;OptionalAttribute&lt;/a&gt;) received similar treatment from IronPython: you do not need pass in values either; IronPython assign it a special value (the .NET run-time default value for most of primitive types, &lt;a href="https://msdn2.microsoft.com/en-us/library/system.type.missing.aspx"&gt;System.Type.Missing.&lt;/a&gt;Value for "object" type, null otherwise). Such supports are useful when using IronPython to call into the COM libraries (such as Office automation). The user can avoid typing in every arguments.&lt;/p&gt; &lt;div class="csharp"&gt;&amp;nbsp;&lt;span class="cskeyword"&gt;public void&lt;/span&gt; M6([&lt;span class="cstype"&gt;Optional&lt;/span&gt;] &lt;span class="cskeyword"&gt;int &lt;/span&gt;x, [&lt;span class="cstype"&gt;Optional&lt;/span&gt;] &lt;span class="cskeyword"&gt;object &lt;/span&gt;y) { &lt;br&gt;&amp;nbsp;&amp;nbsp; &lt;span class="cstype"&gt;Console&lt;/span&gt;.WriteLine(&lt;span class="csstring"&gt;"{0} {1}"&lt;/span&gt;, x, y); &lt;br&gt;}&lt;br&gt;&amp;nbsp;&lt;span class="cskeyword"&gt;public void&lt;/span&gt; M7([&lt;span class="cstype"&gt;Optional&lt;/span&gt;] &lt;span class="cskeyword"&gt;string &lt;/span&gt;x, [&lt;span class="cstype"&gt;Optional&lt;/span&gt;] &lt;span class="cstype"&gt;Type &lt;/span&gt;y) { &lt;br&gt;&amp;nbsp;&amp;nbsp; &lt;span class="cstype"&gt;Console&lt;/span&gt;.WriteLine(&lt;span class="csstring"&gt;"{0} {1}"&lt;/span&gt;, x == &lt;span class="cskeyword"&gt;null&lt;/span&gt;, y == &lt;span class="cskeyword"&gt;null&lt;/span&gt;); &lt;br&gt;}&lt;/div&gt; &lt;div class="csharp"&gt;o.M6()&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cscomment"&gt;# print: 0 System.Type.Missing&lt;/span&gt;&lt;br&gt;o.M6(10)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cscomment"&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 10 System.Type.Missing&lt;/span&gt;&lt;br&gt;o.M6(20, "hi")&amp;nbsp;&amp;nbsp; &lt;span class="cscomment"&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 20 hi&lt;/span&gt;&lt;br&gt;o.M7()&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cscomment"&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; True True&lt;/span&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5230964" width="1" height="1"&gt;</content><author><name>Haibo_Luo</name><uri>http://blogs.msdn.com/members/Haibo_Luo.aspx</uri></author><category term="IronPython" scheme="http://blogs.msdn.com/haibo_luo/archive/tags/IronPython/default.aspx" /></entry><entry><title>IronPython: Grab the .NET Type</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/haibo_luo/archive/2007/09/25/5130087.aspx" /><id>http://blogs.msdn.com/haibo_luo/archive/2007/09/25/5130087.aspx</id><published>2007-09-26T00:58:00Z</published><updated>2007-09-26T00:58:00Z</updated><content type="html">&lt;P&gt;After loading the assembly by &lt;A class="" href="http://blogs.msdn.com/haibo_luo/archive/2007/09/25/5130072.aspx" mce_href="http://blogs.msdn.com/haibo_luo/archive/2007/09/25/5130072.aspx"&gt;clr.AddReference&lt;/A&gt; and then import namespace, we are ready to take hold of types and down-level namespaces using "&lt;A href="http://docs.python.org/ref/attribute-references.html" mce_href="http://docs.python.org/ref/attribute-references.html"&gt;attribute references&lt;/A&gt;". &lt;/P&gt;
&lt;DIV class=csharp&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;import System&lt;/SPAN&gt;&lt;BR&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;System.DateTime&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # type&lt;BR&gt;&amp;lt;type 'DateTime'&amp;gt;&lt;BR&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;System.Diagnostics&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # still namespace&lt;BR&gt;&amp;lt;module 'Diagnostics' (CLS module, 2 assemblies loaded)&amp;gt;&lt;BR&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;System.Diagnostics.Debug&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # type again&lt;BR&gt;&amp;lt;type 'Debug'&amp;gt;&lt;BR&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;System.Diagnostics.CodeAnalysis&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; # namespace again&lt;BR&gt;&amp;lt;module 'CodeAnalysis' (CLS module from mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)&amp;gt;&lt;BR&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/DIV&gt;
&lt;P&gt;We can also access public nested type from the declaring type same way. (I was unable to find such example in mscorlib.dll/system.dll)&lt;/P&gt;
&lt;DIV class=csharp&gt;&lt;SPAN class=cscomment&gt;// lib.cs &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN class=cskeyword&gt;public class&lt;/SPAN&gt; &lt;SPAN class=cstype&gt;C&lt;/SPAN&gt; { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cskeyword&gt;public class&lt;/SPAN&gt; &lt;SPAN class=cstype&gt;NestedC &lt;/SPAN&gt;{} &lt;BR&gt;}&lt;/DIV&gt;
&lt;DIV class=csharp&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;import clr&lt;/SPAN&gt;&lt;BR&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;clr.AddReference("lib")&lt;/SPAN&gt;&lt;BR&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;import C &lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # C has no namespace here&lt;BR&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;C.NestedC&lt;/SPAN&gt;&lt;BR&gt;&amp;lt;type 'NestedC'&amp;gt;&lt;/DIV&gt;
&lt;P&gt;When the type is generic type, such attribute reference returns the &lt;A href="http://msdn2.microsoft.com/en-us/library/ms172334.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms172334.aspx"&gt;open generic type&lt;/A&gt;. We need then call the index operation (&lt;A href="http://docs.python.org/ref/subscriptions.html" mce_href="http://docs.python.org/ref/subscriptions.html"&gt;subscriptions&lt;/A&gt;) to construct the closed generic type, and do something interesting with it. A type tuple is expected as the index, but the parentheses can be omitted most of time. &lt;/P&gt;
&lt;DIV class=csharp&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;System.Collections.Generic.Dictionary&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # open generic type&lt;BR&gt;&amp;lt;type 'Dictionary[TKey, TValue]'&amp;gt;&lt;BR&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;System.Collections.Generic.Dictionary[int, str]&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # closed generic type&lt;BR&gt;&amp;lt;type 'Dictionary[int, str]'&amp;gt;&lt;BR&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;System.Collections.Generic.Dictionary[(int, object)]&lt;/SPAN&gt;&amp;nbsp; # closed generic type&lt;BR&gt;&amp;lt;type 'Dictionary[int, object]'&amp;gt;&lt;/DIV&gt;
&lt;P&gt;Also the .NET type names could be "same" or similar; one example is System.Nullable and System.Nullable&amp;lt;T&amp;gt; in mscorlib.dll. Many experimental code of mine has types like C, C&amp;lt;T&amp;gt;, C&amp;lt;T1, T2&amp;gt; . As shown below, "System.Nullable" now returns a type group, including 2 types. In order to distinguish the non-generic type from the generic one, an empty tuple need be passed in as index.&lt;/P&gt;
&lt;DIV class=csharp&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;System.Nullable&lt;/SPAN&gt;&lt;BR&gt;&amp;lt;types 'Nullable', 'Nullable[T]'&amp;gt;&lt;BR&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;System.Nullable[()]&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # get the non-generic type&lt;BR&gt;&amp;lt;type 'Nullable'&amp;gt;&lt;BR&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;System.Nullable[System.DateTime]&lt;/SPAN&gt;&lt;BR&gt;&amp;lt;type 'Nullable[DateTime]'&amp;gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5130087" width="1" height="1"&gt;</content><author><name>Haibo_Luo</name><uri>http://blogs.msdn.com/members/Haibo_Luo.aspx</uri></author><category term="IronPython" scheme="http://blogs.msdn.com/haibo_luo/archive/tags/IronPython/default.aspx" /></entry><entry><title>IronPython: clr.AddReference</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/haibo_luo/archive/2007/09/25/5130072.aspx" /><id>http://blogs.msdn.com/haibo_luo/archive/2007/09/25/5130072.aspx</id><published>2007-09-26T00:57:00Z</published><updated>2007-09-26T00:57:00Z</updated><content type="html">&lt;P&gt;In order to interop with .NET libraries, we need first load in the assemblies we want to play with. The family of AddReference methods in the &lt;EM&gt;clr&lt;/EM&gt; module serves the purpose.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;clr.AddReference 
&lt;LI&gt;clr.AddReferenceByName 
&lt;LI&gt;clr.AddReferenceByPartialName 
&lt;LI&gt;clr.AddReferenceToFile 
&lt;LI&gt;clr.AddReferenceToFileAndPath &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;clr.AddReference&lt;/STRONG&gt; accepts System.Reflection.Assembly objects and/or assembly names. The typical usage looks like:&lt;/P&gt;
&lt;DIV class=csharp&gt;asm = ... # any approach of getting an Assembly object&lt;BR&gt;clr.AddReference(asm)&lt;BR&gt;clr.AddReference("System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")&lt;BR&gt;clr.AddReference("System.Drawing")&lt;BR&gt;&lt;/DIV&gt;
&lt;P&gt;If a string is passed in, Assembly.Load(string) is used to load the assembly. If failed, it re-tries with Assembly.LoadWithPartialName(string).&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;clr.AddReferenceByName&lt;/STRONG&gt; basically is the wrapper of &lt;A href="https://msdn2.microsoft.com/en-us/library/ky3942xh.aspx" mce_href="https://msdn2.microsoft.com/en-us/library/ky3942xh.aspx"&gt;Assembly.Load&lt;/A&gt;, which means the assembly full name is expected. Similarly, &lt;STRONG&gt;clr.AddReferenceByPartialName&lt;/STRONG&gt; is the wrapper around the obsolete &lt;A href="https://msdn2.microsoft.com/en-us/library/12xc5368.aspx" mce_href="https://msdn2.microsoft.com/en-us/library/12xc5368.aspx"&gt;Assembly.LoadWithPartialName&lt;/A&gt;: "System.Drawing" and "System.Drawing, Version=2.0.0.0" are examples of valid arguments. &lt;/P&gt;
&lt;P&gt;A typical usage of &lt;STRONG&gt;clr.AddReferenceToFile &lt;/STRONG&gt;looks like: &lt;/P&gt;
&lt;DIV class=csharp&gt;clr.AddReferenceToFile("my1.dll", "my2")&amp;nbsp; # load my1.dll and my2.dll&lt;/DIV&gt;
&lt;P&gt;It expects file name(s) without the directory path as the argument. To locate my1.dll, it searches each directory in sys.path until the specified file is found (it also tries to append ".dll" or ".exe"). Behind the scene, the loading is via &lt;A href="https://msdn2.microsoft.com/en-us/library/b61s44e8.aspx" mce_href="https://msdn2.microsoft.com/en-us/library/b61s44e8.aspx"&gt;Assembly.LoadFile&lt;/A&gt;. Normally sys.path includes the current working directory; so if my1.dll and my2.dll exist in the current directory, clr.AddReferenceToFile("my1.dll", "my2") should succeed. If you know the exact full path of a clr assembly, you may use &lt;STRONG&gt;clr.AddReferenceToFileAndPath&lt;/STRONG&gt; to load. As a by-product, the path of the assembly file will be appended to sys.path. Note &lt;A href="https://msdn2.microsoft.com/en-us/library/system.reflection.assembly.loadfrom.aspx" mce_href="https://msdn2.microsoft.com/en-us/library/system.reflection.assembly.loadfrom.aspx"&gt;Assembly.LoadFrom&lt;/A&gt; is never used underneath by these 5 methods due to the &lt;A href="http://blogs.msdn.com/suzcook/archive/2003/05/29/57143.aspx" mce_href="http://blogs.msdn.com/suzcook/archive/2003/05/29/57143.aspx"&gt;loading context&lt;/A&gt; concern.&lt;/P&gt;
&lt;P&gt;We can use &lt;STRONG&gt;clr.References&lt;/STRONG&gt; to list which assemblies have been loaded. The output shows that mscorlib.dll and System.dll are implicitly loaded/added (without the need of calling clr.AddReference).&lt;/P&gt;
&lt;DIV class=csharp&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;import clr&lt;/SPAN&gt;&lt;BR&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;for r in clr.References: print r&lt;/SPAN&gt;&lt;BR&gt;...&lt;BR&gt;mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&lt;BR&gt;System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&lt;BR&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;clr.AddReference("System.Drawing")&lt;/SPAN&gt;&lt;BR&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;for r in clr.References: print r &lt;/SPAN&gt;&lt;BR&gt;...&lt;BR&gt;mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 &lt;BR&gt;System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 &lt;BR&gt;System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a&lt;/DIV&gt;
&lt;P&gt;By treating the namespace like the python module, IronPython extends the &lt;EM&gt;import&lt;/EM&gt; statement semantics to bring in the clr namespace. In current implementation the "classical" python module is still preferred by &lt;EM&gt;import&lt;/EM&gt;: given the statement "import MyLib", if the file "MyLib.py" is present under any directory of sys.path, that file will be imported; if not, for each loaded assembly, import tries to find the namespace "MyLib". Although not common in well-designed .NET frameworks, a type could have empty namespace; so "import MyLib" also tries to find type "MyLib" in the loaded assemblies.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;The namespace of "MyLib" could exist more than 1 loaded assemblies. The following snippet shows that, "import System" adds a CLS module to sys.modules and this CLS module contains members from 2 assemblies: mscorlib.dll and System.dll (since both assemblies has types and down-level namespaces like System.*).&amp;nbsp; &lt;/P&gt;
&lt;DIV class=csharp&gt;&amp;gt; &lt;SPAN class=typein&gt;ipy.exe&lt;/SPAN&gt;&lt;BR&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;import sys&lt;/SPAN&gt;&lt;BR&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;sys.modules.keys()&lt;/SPAN&gt;&lt;BR&gt;['sys', '__builtin__', '__main__', 'site']&lt;BR&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;import System&lt;/SPAN&gt;&lt;BR&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;sys.modules.keys()&lt;/SPAN&gt;&lt;BR&gt;['sys', '__builtin__', '__main__', 'site', 'System']&lt;BR&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;sys.modules['System']&lt;/SPAN&gt;&lt;BR&gt;&amp;lt;module 'System' (CLS module, 2 assemblies loaded)&amp;gt; &lt;BR&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;System == sys.modules['System']&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #&amp;nbsp;better use "is" to check identity as Michael pointed out in the comment&lt;BR&gt;True&lt;BR&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;System.__file__&lt;/SPAN&gt;&lt;BR&gt;['mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089', 'System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089']&lt;BR&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;System.Console.WriteLine('later')&lt;/SPAN&gt;&lt;BR&gt;later&lt;BR&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5130072" width="1" height="1"&gt;</content><author><name>Haibo_Luo</name><uri>http://blogs.msdn.com/members/Haibo_Luo.aspx</uri></author><category term="IronPython" scheme="http://blogs.msdn.com/haibo_luo/archive/tags/IronPython/default.aspx" /></entry><entry><title>IronPython: import clr</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/haibo_luo/archive/2007/09/25/5130066.aspx" /><id>http://blogs.msdn.com/haibo_luo/archive/2007/09/25/5130066.aspx</id><published>2007-09-26T00:56:00Z</published><updated>2007-09-26T00:56:00Z</updated><content type="html">&lt;P&gt;&lt;EM&gt;clr&lt;/EM&gt; is an IronPython built-in module, which provides some functionalities in order to interop with .NET. When writing "import clr" in a python module, it means you intend to leverage the .NET libraries. One classical example is python string's methods. In IronPython, python type &lt;I&gt;str&lt;/I&gt; is implemented by the .NET type &lt;I&gt;System.String&lt;/I&gt;. We can call System.String's methods on string objects after the line of "import clr" (see the example below); of course those python string methods are still available.&lt;/P&gt;
&lt;DIV class=csharp&gt;&amp;gt; &lt;SPAN class=typein&gt;ipy.exe&lt;/SPAN&gt;&lt;BR&gt;IronPython console: IronPython 2.0 (2.0.0.00) on .NET 2.0.50727.1378&lt;BR&gt;Copyright (c) Microsoft Corporation. All rights reserved. &lt;BR&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;s = "IronPython"&lt;/SPAN&gt;&lt;BR&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;s.upper()&lt;/SPAN&gt;&lt;BR&gt;'IRONPYTHON'&lt;BR&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;s.ToUpper()&lt;/SPAN&gt;&lt;BR&gt;Traceback (most recent call last):&lt;BR&gt;&amp;nbsp; File , line 0, in ##14&lt;BR&gt;&amp;nbsp; File , line 0, in _stub_##15&lt;BR&gt;AttributeError: 'str' object has no attribute 'ToUpper'&lt;BR&gt;&lt;BR&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;import clr&lt;/SPAN&gt;&lt;BR&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;s.upper()&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # python method still works&lt;BR&gt;'IRONPYTHON'&lt;BR&gt;&amp;gt;&amp;gt;&amp;gt; &lt;SPAN class=typein&gt;s.ToUpper()&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # works&lt;BR&gt;'IRONPYTHON'&lt;BR&gt;&lt;/DIV&gt;
&lt;P&gt;Such context change is per-python-module. Although lib.py (below) imports the &lt;EM&gt;clr&lt;/EM&gt; module and app.py then imports the &lt;I&gt;lib&lt;/I&gt; module, app.py will not see the .NET methods. Running this app.py under C-Python will fail (ImportError) due to the usage of the clr module in lib.py. But if we make lib.py platform-neutral next time, we are ensured that no change in app.py is needed in order to run it under both C-Python and IronPython.&lt;/P&gt;
&lt;DIV class=csharp&gt;# lib.py&lt;BR&gt;import clr&lt;BR&gt;def my_upper(s): return s.ToUpper() &lt;/DIV&gt;
&lt;DIV class=csharp&gt;# app.py&lt;BR&gt;import lib&lt;BR&gt;s = "hello world"&lt;BR&gt;print lib.my_upper(s)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # print "HELLO WORLD"&lt;BR&gt;#print s.ToUpper()&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # AttributeError would throw&lt;BR&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5130066" width="1" height="1"&gt;</content><author><name>Haibo_Luo</name><uri>http://blogs.msdn.com/members/Haibo_Luo.aspx</uri></author><category term="IronPython" scheme="http://blogs.msdn.com/haibo_luo/archive/tags/IronPython/default.aspx" /></entry><entry><title>DebuggerTypeProxy for IronPython Old-style Class and Instance</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/haibo_luo/archive/2007/08/03/4210344.aspx" /><link rel="enclosure" type="application/x-zip-compressed" length="8704" href="http://blogs.msdn.com/haibo_luo/attachment/4210344.ashx" /><id>http://blogs.msdn.com/haibo_luo/archive/2007/08/03/4210344.aspx</id><published>2007-08-03T22:37:00Z</published><updated>2007-08-03T22:37:00Z</updated><content type="html">&lt;P&gt;First I want to make it clear that this post means nothing related to IronPython's plan about debugging python code in the future; it serves more as an interesting example to demonstrate &lt;A href="http://msdn2.microsoft.com/en-us/library/d8eyd8zc.aspx" target=_blank mce_href="http://msdn2.microsoft.com/en-us/library/d8eyd8zc.aspx"&gt;DebuggerTypeProxyAttribute&lt;/A&gt; and how types can be created dynamically and be used in the VS debugger windows to display information the end users are interested in.&lt;/P&gt;
&lt;P&gt;The python code below shows one old style class and some operations on the instance. After downloading the binary zip of &lt;A href="http://www.codeplex.com/IronPython/Release/ProjectReleases.aspx?ReleaseId=3749" target=_blank mce_href="http://www.codeplex.com/IronPython/Release/ProjectReleases.aspx?ReleaseId=3749"&gt;IronPython 2.0 Alpha 3&lt;/A&gt;, we can create a solution, set it to launch ipy.exe for debugging, and step through the code inside Visual Studio; the locals window may show something like this after hitting the breakpoint.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/haibo_luo/WindowsLiveWriter/Debugger_E941/withoutproxy-final.jpg" mce_href="http://blogs.msdn.com/blogfiles/haibo_luo/WindowsLiveWriter/Debugger_E941/withoutproxy-final.jpg" atomicselection="true"&gt;&lt;IMG height=538 alt=withoutproxy-final src="http://blogs.msdn.com/blogfiles/haibo_luo/WindowsLiveWriter/Debugger_E941/withoutproxy-final_thumb.jpg" width=541 border=0 mce_src="http://blogs.msdn.com/blogfiles/haibo_luo/WindowsLiveWriter/Debugger_E941/withoutproxy-final_thumb.jpg"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;The local variable &lt;I&gt;alpha3&lt;/I&gt;'s .NET type is IronPython.Runtime.Types.OldInstance, the way this object is displayed in the locals window is based on that type's fields and properties, which exposes many implementation details. While debugging, what the python users really want to know is the object attributes. My goal is to make python object attributes look like C# object's public fields; how can I achieve this?&lt;/P&gt;
&lt;P&gt;DebuggerTypeProxyAttribute allows us to specify a proxy type for the target type. VS debugger uses the proxy type to display the target object. We already see such proxy types a lot: when viewing objects of most collection types, we are actually viewing their proxy type layouts. &lt;/P&gt;
&lt;P&gt;In current IronPython implementation, every old style instance is of type I.R.T.OldInstance, so my first step is to define a proxy type "OldInstanceProxy" to expose the object attributes only. Clearly old style instances can have different attribute set of different names; but I can only specify one proxy type for the I.R.T.OldInstance type. [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] is part of the solution to achieve the look-and-feel. The proxy type (OldInstanceProxy) has an object field (&lt;EM&gt;m_oldInstance&lt;/EM&gt;) decorated with that attribute so that &lt;EM&gt;m_oldInstance&lt;/EM&gt; will be hiden in the debugger window, but the fields &lt;EM&gt;m_oldInstance&lt;/EM&gt; has will be shown. What should &lt;EM&gt;m_oldInstance&lt;/EM&gt; look like? A .NET type (let me call it the "real" proxy type) with as many public fields as python object attributes, each having the same name as the attribute name, and we are going to create such types on the fly. Also the "real" proxy type's constructor is emitted with the code to assign these public fields properly. We then instantiate the new type with the original OldInstance object, and assign it to &lt;EM&gt;m_oldInstance&lt;/EM&gt;. &lt;/P&gt;
&lt;DIV class=csharp&gt;[assembly:&lt;SPAN class=cstype&gt;DebuggerTypeProxy&lt;/SPAN&gt;(&lt;SPAN class=cskeyword&gt;&lt;BR&gt;&amp;nbsp; typeof&lt;/SPAN&gt;(IronPython.DebuggingSupport.&lt;SPAN class=cstype&gt;OldInstanceProxy&lt;/SPAN&gt;),&lt;BR&gt;&amp;nbsp;&amp;nbsp;TargetTypeName = &lt;SPAN class=csstring&gt;"IronPython.Runtime.Types.OldInstance, IronPython, Version=2.0.0.300, ..."&lt;/SPAN&gt;)&lt;BR&gt;]&lt;BR&gt;&lt;BR&gt;&lt;SPAN class=cskeyword&gt;public class &lt;/SPAN&gt;&lt;SPAN class=cstype&gt;OldInstanceProxy&lt;/SPAN&gt;{&lt;BR&gt;&amp;nbsp; [&lt;SPAN class=cstype&gt;DebuggerBrowsable&lt;/SPAN&gt;(&lt;SPAN class=cstype&gt;DebuggerBrowsableState&lt;/SPAN&gt;.RootHidden)]&lt;BR&gt;&amp;nbsp; &lt;SPAN class=cskeyword&gt;public object &lt;/SPAN&gt;m_oldInstance;&lt;BR&gt;&lt;BR&gt;&amp;nbsp; &lt;SPAN class=cskeyword&gt;public &lt;/SPAN&gt;OldInstanceProxy(&lt;SPAN class=cskeyword&gt;object &lt;/SPAN&gt;target) {&lt;BR&gt;&amp;nbsp; &amp;nbsp; &lt;SPAN class=cskeyword&gt;try &lt;/SPAN&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;SPAN class=cstype&gt;OldInstance &lt;/SPAN&gt;obj = target &lt;SPAN class=cskeyword&gt;as&lt;/SPAN&gt; &lt;SPAN class=cstype&gt;OldInstance&lt;/SPAN&gt;;&lt;BR&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;SPAN class=cstype&gt;TypeBuilder &lt;/SPAN&gt;tb = CodeGen.CreateTemporaryType();&lt;BR&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;SPAN class=cstype&gt;ConstructorBuilder &lt;/SPAN&gt;cb = tb.DefineConstructor(&lt;SPAN class=cstype&gt;MethodAttributes&lt;/SPAN&gt;.Public, &lt;SPAN class=cstype&gt;CallingConventions&lt;/SPAN&gt;.Standard, &lt;SPAN class=cskeyword&gt;new &lt;/SPAN&gt;&lt;SPAN class=cstype&gt;Type&lt;/SPAN&gt;[] { &lt;SPAN class=cskeyword&gt;typeof&lt;/SPAN&gt;(&lt;SPAN class=cstype&gt;OldInstance&lt;/SPAN&gt;) });&lt;BR&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;SPAN class=cstype&gt;ILGenerator &lt;/SPAN&gt;il = cb.GetILGenerator();&lt;BR&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; il.Emit(&lt;SPAN class=cstype&gt;OpCodes&lt;/SPAN&gt;.Ldarg_0);&lt;BR&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; il.Emit(&lt;SPAN class=cstype&gt;OpCodes&lt;/SPAN&gt;.Call, &lt;SPAN class=cskeyword&gt;typeof&lt;/SPAN&gt;(&lt;SPAN class=cstype&gt;Object&lt;/SPAN&gt;).GetConstructor(&lt;SPAN class=cstype&gt;Type&lt;/SPAN&gt;.EmptyTypes));&lt;BR&gt;&lt;BR&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;SPAN class=cskeyword&gt;foreach &lt;/SPAN&gt;(&lt;SPAN class=cstype&gt;KeyValuePair&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=cskeyword&gt;object&lt;/SPAN&gt;,&lt;SPAN class=cskeyword&gt;object&lt;/SPAN&gt;&amp;gt; pair &lt;SPAN class=cskeyword&gt;in &lt;/SPAN&gt;obj.Dictionary) {&lt;BR&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cskeyword&gt;string &lt;/SPAN&gt;key = pair.Key.ToString();&lt;BR&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cstype&gt;Type &lt;/SPAN&gt;fieldType = pair.Value == &lt;SPAN class=cskeyword&gt;null &lt;/SPAN&gt;? &lt;SPAN class=cskeyword&gt;typeof&lt;/SPAN&gt;(&lt;SPAN class=cskeyword&gt;object&lt;/SPAN&gt;) : pair.Value.GetType();&lt;BR&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cstype&gt;FieldBuilder &lt;/SPAN&gt;fb = tb.DefineField(key, fieldType, &lt;SPAN class=cstype&gt;FieldAttributes&lt;/SPAN&gt;.Pub.Public);&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cscomment&gt;// emit code for the ctor ...&lt;/SPAN&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; il.Emit(&lt;SPAN class=cstype&gt;OpCodes&lt;/SPAN&gt;.Ret);&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_oldInstance = &lt;SPAN class=cstype&gt;Activator&lt;/SPAN&gt;.CreateInstance(tb.CreateType(), obj);&lt;BR&gt;&lt;BR&gt;&lt;/DIV&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Few discussions:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The attached solution also includes another proxy type: OldClassProxy for IronPython.Runtime.Types.OldClass. With that, viewing class attributes feels like viewing C# class static fields. Such coding pattern can be applied to other similar scenarios. 
&lt;LI&gt;It is a bit hard to apply this for IronPython new style instances. For each new style class, IronPython creates a new type on the fly. For example, "class C(object): pass" generates a IronPython.Runtime.NewTypes.Object_1. The proxy type (which will create the "real" proxy type) &amp;nbsp;need be created at the same time. 
&lt;LI&gt;Types created by Reflection.Emit are not GC-collectible. In my proxy type implementation,&amp;nbsp;a simple&amp;nbsp;caching mechanism is implemented to reuse those "real" proxy types; but considering the python dynamism, object attributes can be added, removed, their values' type can be changed; such "real" proxy type may have to be created frequently, each click to expand in the debugger window could cause one type creation, so use wisely if you use such proxy type in real world scenarios.&amp;nbsp;&amp;nbsp; 
&lt;LI&gt;Unlike DebuggerVisualizer where VS provides a way to debug it, it is a bit inconvenient to debug DebuggerTypeProxy code. So I found having the constructor code wrapped inside try-catch and saving the exception if thrown is useful. The exception object can be viewed in the debugger window if the type proxy dll is compiled with the "Debug" configuration.&amp;nbsp; The messages from Debug.WriteLine are helpful too. 
&lt;LI&gt;The proxy type implementation depends on the rapidly changing code of the DLR/IronPython project. It is not surprising that the attached solution could be broken in the future. . &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The following pictures show the proxy type in action. Compared to the previous picture, now you can easily check out the values of the attribute "url" and "version", as well as the class attribute "project_name"&amp;nbsp;(shown in the first picture). The new attribute "release_date" appears in the second picture after stepping through the breakpoint line. &lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/haibo_luo/WindowsLiveWriter/Debugger_E941/withproxy1.jpg" mce_href="http://blogs.msdn.com/blogfiles/haibo_luo/WindowsLiveWriter/Debugger_E941/withproxy1.jpg" atomicselection="true"&gt;&lt;IMG style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=319 alt=withproxy1 src="http://blogs.msdn.com/blogfiles/haibo_luo/WindowsLiveWriter/Debugger_E941/withproxy1_thumb.jpg" width=574 border=0 mce_src="http://blogs.msdn.com/blogfiles/haibo_luo/WindowsLiveWriter/Debugger_E941/withproxy1_thumb.jpg"&gt;&lt;/A&gt;&lt;A href="http://blogs.msdn.com/blogfiles/haibo_luo/WindowsLiveWriter/Debugger_E941/withproxy2.jpg" mce_href="http://blogs.msdn.com/blogfiles/haibo_luo/WindowsLiveWriter/Debugger_E941/withproxy2.jpg" atomicselection="true"&gt;&lt;IMG style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=244 alt=withproxy2 src="http://blogs.msdn.com/blogfiles/haibo_luo/WindowsLiveWriter/Debugger_E941/withproxy2_thumb.jpg" width=574 border=0 mce_src="http://blogs.msdn.com/blogfiles/haibo_luo/WindowsLiveWriter/Debugger_E941/withproxy2_thumb.jpg"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;To use the attached solution, you need download IronPython 2.0 alpha 3 binary zip, and I assume you unzip it to C:\. Your comments are welcome.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4210344" width="1" height="1"&gt;</content><author><name>Haibo_Luo</name><uri>http://blogs.msdn.com/members/Haibo_Luo.aspx</uri></author><category term="Reflection.Emit" scheme="http://blogs.msdn.com/haibo_luo/archive/tags/Reflection.Emit/default.aspx" /><category term="IronPython" scheme="http://blogs.msdn.com/haibo_luo/archive/tags/IronPython/default.aspx" /></entry></feed>