[IronPython] Monkey-patching CLR types

Jimmy Schementi Jimmy.Schementi at microsoft.com
Wed Feb 17 07:05:27 CET 2010


By the way, I fixed this by just overloading the "+" operator the normal way C# operators are overloaded, had it accept "object" on the right-hand-side so Python functions would make their way into it, and then used ObjectOperations.ConvertTo to convert the Python function to a System.EventHandler.

From: Jimmy Schementi
Sent: Tuesday, February 16, 2010 12:09 AM
To: Discussion of IronPython
Subject: RE: Monkey-patching CLR types


Dino Viehland wrote:

> If you strongly type handler to a delegate type IronPython should convert the

> function to the delegate type on the call.



Unfortunately it doesn't seem to :(. I repro'd that it doesn't on the desktop as well as in Silverlight; here's a desktop repro:



>>> import clr

>>> clr.AddReferenceToFile("pyext")

>>> import pyext

>>> t = pyext.TestClass()

>>> def foo(s, e): pass

...

>>> import System

>>> t.AttachEvent("foo", System.EventHandler(foo))

foo hooked!

>>> t.foo += foo

Traceback (most recent call last):

  File "<stdin>", line unknown, in <module>

TypeError: unsupported operand type(s) for +=: 'MyEvent' and 'function'



Also, when using a EventHandler as the right-hand-side of the +=, the AttachEvent method gets called, but still complains that the "foo" attribute doesn't exist:



>>> t.foo += System.EventHandler(foo)

foo hooked!

Traceback (most recent call last):

  File "<stdin>", line unknown, in <module>

AttributeError: 'TestClass' object has no attribute 'foo'



Any ideas? Here's the pyext.cs stub that I used:



//

// pyext.cs

//



using Microsoft.Scripting.Runtime;

using System;

using Microsoft.Scripting.Utils;

using System.Runtime.CompilerServices;



[assembly: ExtensionType(typeof(pyext.TestClass), typeof(pyext.TestClassExtension))]



namespace pyext {

  public class TestClass {

    public void AttachEvent(string eventName, EventHandler handler) {

      Console.WriteLine(string.Format("{0} hooked!", eventName));

    }

  }



  public static class TestClassExtension {

    [System.Runtime.CompilerServices.SpecialNameAttribute]

    public static object GetBoundMember(TestClass obj, string name) {

      return new MyEvent(obj, name);

    }

  }



  public class MyEvent {

    private readonly TestClass _obj;

    private readonly string _event;



    internal MyEvent(TestClass obj, string eventStr) {

      _obj = obj;

      _event = eventStr;

    }



    [System.Runtime.CompilerServices.SpecialNameAttribute]

    public object op_AdditionAssignment(EventHandler func) {

      _obj.AttachEvent(_event, func);

      return null;

    }

  }

}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/ironpython-users/attachments/20100217/2b5c9e8f/attachment.html>


More information about the Ironpython-users mailing list