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 st