[IronPython] Autocomplete for .NET Types from IronPython with Wing IDE (update - better return type and parameter name handling)

Michael Foord fuzzyman at voidspace.org.uk
Sun May 17 00:40:45 CEST 2009


Hello all,

Attached is an updated of the generate_pi.py script used to generate 
Python interface files for the Wing IDE.

Since I last worked on it John (from Wingware) merged my changes back 
into their main script so this one is *not* specific to IronPython. On 
top of this I have added a couple of improvements:

* Reflection is now used to get parameter names of methods
* Return types are properly annotated with their namespaces, so Wing 
understands methods that return objects from different namespaces

For details on how the reflection is done, I wrote it up on the 
IronPython cookbook:

    
http://www.ironpython.info/index.php/Introspecting_.NET_Types_and_Methods_from_IronPython

To run the script, create a new directory and add this to the 'Interface 
File Path' (File menu -> Preferences -> Source Analysis -> Advanced -> 
Insert).

Then from the command line switch to this directory (if you are on Vista 
you will need to run cmd with admin privileges due to a defect explained 
below). Execute the command:

   ipy generate_pi_for_net.py --ironpython

This generates the pi files. It doesn't work *as well* on 64 bit windows 
because the .NET XML help files (or whatever they are called) are in a 
different location so the docstrings are not always available.

It currently generates pi files for the following assemblies and 
namespaces (and all contained namespaces):

    'System', 'System.Data', 'System.Windows.Forms', 'System.Drawing', 
'System.Xml', 'Microsoft', 'clr'

These are hardcoded in lines 969-971 of the script. You can easily add 
new ones but eventually we'll enable this from command line arguments.

Warning - it is slow! It takes about ten minutes or so and generates pi 
files for 105 namespaces taking up about 30mb. Using these doesn't 
result in a slowdown in Wing which is impressive.

There are several limitations / caveats. Some of these can be fixed by 
improving the script and some by improving Wing!

When you do "import System." you aren't offered a list of sub-namespaces 
to import from. pi files as packages doesn't yet work but will be 
implemented soon apparently.

Methods called None are valid in IronPython (and common as enumeration 
fields) but are invalid syntax in Python / PI files. These are renamed 
to None_.

The following member types are not recognised by the script and are set 
to None in the PI files. This means that some potentially useful 
information is lost but it isn't immediately obvious how best to 
represent this information for some of these member types:

    * field descriptors (enumerations)
   
      In .NET enumerations behave much more like instances than classes.
      The field descriptor docstrings are usually not helpful but I'm
      also sure that None is not helpful as a value. It should really
      be a property returning an instance of the enumeration.
     
      The enumaration fireld has an underlying value (accessed as .value__)
      but I don't think setting it to that would be useful.
     
    * events (very common and there may be multiple types of events)
   
    * indexers (Item)
   
    * attributes that are classes or enumerations. The docstrings can 
sometimes be useful.
   
      e.g. System.ActivationContext.ContextForm:
      >>> ActivationContext.__dict__['ContextForm'].__doc__
      '\r\n\r\nenum ContextForm, values: Loose (0), StoreBounded 
(1)\r\n\r\n'
 
Return type inferencing from properties would be very useful. (Feature 
request!!) :-)

For .NET types with public constructors an __init__ method could be 
constructed from the type docstring.
Currently they all show in the source assistant as *args.

Properties are created with docstrings - but these docstrings aren't 
shown in the source assistant which is a limitation. :-(

Cross namespace return types now work. They appear in the pi files as:

  import System.Drawing
  return System.Drawing.Point()
 
Something similar will need to be done with base-classes. Many classes 
inherit from types in
different namespaces - so in the PI file the class they inherit from 
will probably need
to be imported (and preferably also excluded from completion).

For most .NET methods the parameter names are determined using reflection.
This doesn't work for some - particularly methods like ReferenceEquals, 
ToObject and
so on. (Are these inherited methods? Needs investigating.)

For these we fallback to __GetCallableSignature which doesn't get the 
argument names from
.NET methods (not really a big deal). This is because they are of the form:

  int Add(self, CodeCatchClause value)
 
__GetCallableSignature also fails to handle indexing in type signature 
for methods
(use of square brackets) is interpreted as optional arguments. E.g.:

  System.ModuleHandle.ResolveFieldHandle(self, arg0, arg1=None, arg2=None)
 
from:

  RuntimeFieldHandle ResolveFieldHandle(self, int fieldToken, 
Array[RuntimeTypeHandle] typeInstantiationContext, 
Array[RuntimeTypeHandle] methodInstantiationContext)

I still intend to write this all up in a HOWTO...

All the best,


Michael Foord

-- 
http://www.ironpythoninaction.com/
http://www.voidspace.org.uk/blog


-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: generate_pi.py
URL: <http://mail.python.org/pipermail/ironpython-users/attachments/20090516/d52e0cde/attachment.ksh>


More information about the Ironpython-users mailing list