[Users] [IronPython] IronPython Attribute Workaround
Michael Foord
fuzzyman at voidspace.org.uk
Tue Jul 24 01:09:38 CEST 2007
I'm pretty sure that it is impossible to dynamically generate classes
decorated with attributes at runtime using 'pure C#'.
The two alternatives are either to use the Reflection.Emit API - which
is probably the best way but requires more digging than I have time for
at this point in time.
Another alternative is to dynamically generate C# and compile to in
memory assemblies. This is less memory efficient because it requires an
assembly and type object for every command you wish to add. It is a lot
faster than you might expect.
Attached are two files. One is 'generate.py'. It has a function called
'Generate' which compiles C# using the CodeDom API with the
CSharpCodeProvider.
As an example I have provided another file - DllImport.py. This uses
Generate to compile the C# from my screenshot example :
http://www.voidspace.org.uk/ironpython/winforms/part10.shtml
It works fine. :-)
The specific call is :
assembly = Generate(unmanaged_code, 'UnamangedCode', inMemory=True)
clr.AddReference(assembly)
from UnmanagedCode import User32, GDI32
(You can also use it to save assemblies to disk.)
For your use you will need to pass in a list of references (absolute
file paths) to the AutoCAD DLLs that your C# code is dependent on.
I think you need to generate C# code that looks something like:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
namespace AutoCADStuff
{
public class AutoCADStuffBase
{
[CommandMethod("myname")]
public void method
{
_method();
}
public virtual void _method
{
return null;
}
}
In IronPython you can call 'Generate', then import and subclass
AutoCADStuffBase and override '_method':
class AutoCADStuff(AutoCADStuffBase):
def _method(self):
some code ...
I have used this approach with Silverlight assemblies for creating
classes with methods marked with attributes.
I hope this helps.
Please no one post this code as is - I'll write up and post an article
shortly. :-)
Michael Foord
Michael Foord wrote:
> Tim Riley wrote:
> [snip..]
>
>> AutoCAD's .NET API allows
>> you to register a command that is callable from the AutoCAD via a CommandMethod attribute[1]. Since IP doesn't support attributes I'd like to develop some sort of decorator that would clone the functionality of the CommandMethod attribute. So I could execute
>> python code like:
>>
>> @commandmethod("test")
>> def tester:
>> print "test worked"
>>
>> and it would register the test command so I could call it from the
>> command line.
>>
>>
>>
>
> Right - so you want to dynamically create methods (or functions) with
> attributes. The attribute takes the name that the command will be
> exposed with.
>
> I wonder if AutoCAD even supports these being dynamically created?
>
> If it does I wonder if we can do it by creating an inner class in C#.
> The method marked with the attribute would call down to another method
> (marked as virtual) that we can override from IronPython.
>
> I'm not exactly sure of the C# syntax/semantics for inner classes - (a
> class factory) - so I'll have to do some digging. (i.e. will it allow us
> to set the argument to the attribute at runtime rather than compile time
> and can we return classes or only instances.)
>
> AFAIK, attributes are normally bound at compile time rather than
> runtime, so using C# to create classes in this way may not work.
>
> The proper way (*sigh*) is to use the Reflection.Emit API to add
> attributes. I've experimented Reflection.Emit - but never got as far as
> adding attributes dynamically. (You need to 'program in bytecode' using
> this API - which isn't too bad but has a bit of a learning curve
> associated.)
>
> A *third* approach is to dynamically generate C# and compile to in
> memory assemblies (using the CodeDOM API if I remember correctly). That
> turns out to be surprisingly easy.
>
> Michael Foord
> http://www.voidspace.org.uk/ironpython/index.shtml
>
>
>> [1] As an example:
>> http://through-the-interface.typepad.com/through_the_interface/2007/07/updating-a-spec.html
>>
>>
>> Tim
>>
>> On 7/23/07, Michael Foord <fuzzyman at voidspace.org.uk> wrote:
>>
>>
>>> Tim Riley wrote:
>>>
>>>
>>>> Michael:
>>>>
>>>> Thanks for the reply. However when reading it my eyes glazed over. Is
>>>> there any way you could provide a simple man like myself with some
>>>> example code for me to peruse?
>>>>
>>>>
>>>>
>>> What do you want to achieve? Write the IronPython code you would like -
>>> and I will try and provide a C# stub that you can subclass. (You will
>>> need a C# compiler - Visual Studio Express C# is probably the most
>>> straightforward if you are using Windows.)
>>>
>>> Michael Foord
>>> http://www.voidspace.org.uk/ironpython/index.shtml
>>>
>>>
>>>
>>>> Tim
>>>>
>>>> On 7/23/07, Michael Foord <fuzzyman at voidspace.org.uk> wrote:
>>>>
>>>>
>>>>
>>>>> Tim Riley wrote:
>>>>>
>>>>>
>>>>>
>>>>>> I know that IronPython doesn't support attributes but does anyone know
>>>>>> of a workaround that will allow IP code to use them?
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>> The IronPython team are strangely quiet every time someone asks this... ;-)
>>>>>
>>>>> A lot of people would like an answer to this question. Currently the
>>>>> only way is to use stub C# classes.
>>>>>
>>>>> Michael Foord
>>>>> http://www.voidspace.org.uk/ironpython/index.shtml
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>> _______________________________________________
>>>>>> users mailing list
>>>>>> users at lists.ironpython.com
>>>>>> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>> _______________________________________________
>>>>> users mailing list
>>>>> users at lists.ironpython.com
>>>>> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
>>>>>
>>>>>
>>>>>
>>>>>
>>>> _______________________________________________
>>>> Users mailing list
>>>> Users at lists.ironpython.com
>>>> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
>>>>
>>>>
>>>>
>>>>
>>> _______________________________________________
>>> Users mailing list
>>> Users at lists.ironpython.com
>>> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
>>>
>>>
>>>
>> _______________________________________________
>> Users mailing list
>> Users at lists.ironpython.com
>> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
>>
>>
>>
>
> _______________________________________________
> Users mailing list
> Users at lists.ironpython.com
> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
>
>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: DllImport.py
URL: <http://mail.python.org/pipermail/ironpython-users/attachments/20070724/527d22ed/attachment.ksh>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: generate.py
URL: <http://mail.python.org/pipermail/ironpython-users/attachments/20070724/527d22ed/attachment-0001.ksh>
More information about the Ironpython-users
mailing list