0

I'm writing a Python script in IronPython that uses a C# DLL implementing the observer/observable pattern, the C# library has the observable class and I want to implement the observer in Python.

I'm registering my Python function as the observer method, but when it gets called, I get an "System.MissingMemberException: 'PeripheralDiscoveredEventArgs' object has no attribute 'ChangeType' exception thrown.

I can't find any documentation on how to use custom arguments with C# events when using IronPython, looked here, here, here and here.

My Python code is:

central = None

def MyCallback(sender, event_args):
    print event_args.ChangeType, event_args.Name

def main():

    global central

    central = objFactory.GetCentral();

    d = System.EventHandler[CustomEventArgs](MyCallback)

    central.myHandler += d

    (do something)

if __name__ == "__main__":
    main()

I also tried to do just this:

central.myHandler += MyCallback

But I got the same exception.

The central variable as a Central instantance and the central.myHandler property in the is defined in the Central class as:

public event EventHandler<CustomEventArgs> myHandler = delegate { };

The CustomEventArgs class is defined as:

public class CustomEventArgs: EventArgs
{
    public CustomEventArgs(Class1 obj1, int i, Class2 obj2, bool tf);

    public Class1 Obj1 { get; }

    public int I{ get; }

    public Class2 Obj2t { get; }

    public bool Tf{ get; }
}

The observable class method that calls my callback is:

  internal abstract class EventHelper
  {
    internal static void TriggerEvent<T>(EventHandler<T> eventHandler, object source, T args)
    {
      // event handle no used ?
      if (eventHandler == null) return;

        try
        {
        // call event handler
          eventHandler(source, args);
        }
        catch (Exception ex)
        {
          var target = eventHandler.Target != null ? eventHandler.Target : "unknown";
          var methodName = (eventHandler.Method != null && eventHandler.Method.Name != null) ? eventHandler.Method.Name : "unknown";
          Log.Error(string.Format("Exception in event handler '{0}' in '{1}'", methodName, target), ex);
        }
    }

The whole exception is:

    "System.MissingMemberException: 'CustomEventArgs' object has no attribute 'ChangeType'
    at IronPython.Runtime.Binding.PythonGetMemberBinder.FastErrorGet`1.GetError(CallSite site, TSelfType target, CodeContext context)
    at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1)
    at __main__$1.MyCallback$74(PythonFunction $function, Object sender, Object event_args) in C:\\code\\Launcher.py:line 51
    at System.Dynamic.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2)
    at _Scripting_(Object[] , Object , CustomEventArgs )
    at System.EventHandler`1.Invoke(Object sender, TEventArgs e)
    at EventHelper.TriggerEvent[T](EventHandler`1 eventHandler, Object source, T args) in C:\\code\\Utility\\EventHelper.cs:line 27"

Any pointers on how to use custom event arguments in C# with IronPython? Thanks!!

Environment:

  • Windows 7 Enterprise 64 bits
  • IronPython 2.7.8 (2.7.8.0) on .NET 4.0.30319.42000 (32-bit)
  • .NET Framework 4.5.2
Leonardo
  • 783
  • 5
  • 18
  • By the way, your `CustomEventArgs` class in fact has no such property `ChangeType`. – dymanoid Sep 27 '18 at 15:00
  • No, company policy is to use Windows 7, so trying another OS is not possible unless I'm dead certain that it would solve the problem. OK, yeah, but when using custom arguments, do I **need** to define the Python class members that are being passed to my Python observer? For example, the FileSystemWatcher in C# doesn't have any specific arguments... And my CustomEventArgs **IS** extending the System.EventArgs class. – Leonardo Sep 27 '18 at 15:16
  • Can you please explain what do you mean by the `FileSystemWatcher` example? The `FileSystemWatcher` class doesn't derive from `EventArgs`. – dymanoid Sep 27 '18 at 15:19
  • Remover the c# tag, your problem looks related to ironphyton – Cleptus Sep 27 '18 at 15:25
  • Oh, gosh... I feel **SO** dumb right now... Yeah, The problem as in the keyboard/screen interface (i.e. myself). I was using a piece of the example code and didn't realize that I was trying to access a member that didn't exist... But wait! Isn't Python MAGICAL? It should have thrown a `UserIsDumb` exception instead... Thanks for the help! – Leonardo Sep 27 '18 at 15:33

1 Answers1

0

Nevermind, it was my mistake (as usual). Trying to access a non-existent member of a class usually leads to errors/exceptions...

Just changing the observer code to :

def centralOnPeripheralDiscovered_callback(sender, event_args):

    print sender
    print event_args

Solves the problem. Thanks for the help!

Leonardo
  • 783
  • 5
  • 18