I've fixed the crash bug and added a couple of tests (see PR #196, already merged into develop).
For an example of how to implement an event declared on an interface see testEvents in src/tests/test_subclass.py. Note that it's a pretty simple implementation and isn't thread safe so may need modifying if you need it to be. This could be wrapped up into something a bit more friendly, but it works for now. Best regards, Tony On Sun, Apr 3, 2016 at 6:57 PM Denis Akhiyarov <denis.akhiya...@gmail.com> wrote: > is it possible to workaround this non-implemented feature by using > ___setattr__() hook? seems like people were able to do this in ironpython: > > http://stackoverflow.com/questions/3856905/ > > On Sun, Apr 3, 2016 at 10:40 AM, Tony Roberts <t...@pyxll.com> wrote: > >> Yeah, it looks like the crash is probably because of the missing event >> implementation as suspected. I'm a bit surprised that it didn't fail >> earlier when trying to instantiate the type. >> >> If you do get a chance to take a look at adding that functionality be >> sure to submit a pull request! >> >> Best regards, >> Tony >> >> >> On Sun, Apr 3, 2016 at 4:30 PM Hansong Huang <hhsp...@live.com> wrote: >> >>> Tony, >>> >>> thanks for the hint. >>> >>> the event PropertyChanged was declared in INotifyPropertyChanged >>> interface by pythonnet, but obviously not implemented. >>> [('PropertyChanged', <unbound event 'PropertyChanged'>), >>> >>> anyway, the stackoverflow only happens if both following are present >>> 1. the class is derived from INotifyPropertyChanged interface >>> 2. the class exposes property back to .Net vis @clrproperty >>> >>> which seems to prove that it is the PropertyChanged event that is not >>> implemented in python class resulted in the crash. >>> >>> I was not sure if .Net event can be handled by pythonnet. I found a few >>> examples with IronPython, but there, a python class of "event" seems to be >>> implemented instead. >>> >>> Below is the stack trace >>> >>> >>> [External Code] >>> clr.dll!CallDescrWorkerInternal () Unknown >>> clr.dll!CallDescrWorkerWithHandler(struct CallDescrData *,int) Unknown >>> clr.dll!CallDescrWorkerReflectionWrapper(struct CallDescrData *,class >>> Frame *) Unknown >>> clr.dll!RuntimeMethodHandle::InvokeMethod(class Object *,class >>> PtrArray *,class SignatureNative *,bool) Unknown >>> mscorlib.ni.dll!00007fffb86e1ca4() Unknown >>> mscorlib.ni.dll!00007fffb8618272() Unknown >>> mscorlib.ni.dll!00007fffb867fc4a() Unknown >>> [External Code] >>> mscorlib.ni.dll!00007fffb86dbaf5() Unknown >>> mscorlib.ni.dll!00007fffb86d281f() Unknown >>> System.ni.dll!00007fffb77556d4() Unknown >>> System.ni.dll!00007fffb7755637() Unknown >>> System.ni.dll!00007fffb775541d() Unknown >>> PresentationFramework.ni.dll!00007fff96c1ca70() Unknown >>> PresentationFramework.ni.dll!00007fff96c23902() Unknown >>> PresentationFramework.ni.dll!00007fff96c22ea1() Unknown >>> PresentationFramework.ni.dll!00007fff96c22693() Unknown >>> PresentationFramework.ni.dll!00007fff96c223c9() Unknown >>> PresentationFramework.ni.dll!00007fff96c21a03() Unknown >>> PresentationFramework.ni.dll!00007fff96c0d84c() Unknown >>> PresentationFramework.ni.dll!00007fff96b97299() Unknown >>> PresentationFramework.ni.dll!00007fff96b9720e() Unknown >>> PresentationFramework.ni.dll!00007fff96c852f0() Unknown >>> WindowsBase.ni.dll!00007fff9f6f9bc9() Unknown >>> WindowsBase.ni.dll!00007fff9f6f9ac6() Unknown >>> WindowsBase.ni.dll!00007fff9f6fca2b() Unknown >>> mscorlib.ni.dll!00007fffb86ca79e() Unknown >>> mscorlib.ni.dll!00007fffb86ca637() Unknown >>> mscorlib.ni.dll!00007fffb86ca5f2() Unknown >>> WindowsBase.ni.dll!00007fff9f913810() Unknown >>> WindowsBase.ni.dll!00007fff9f6fc784() Unknown >>> WindowsBase.ni.dll!00007fff9f6f7c24() Unknown >>> WindowsBase.ni.dll!00007fff9f6f8061() Unknown >>> WindowsBase.ni.dll!00007fff9f6f9e53() Unknown >>> WindowsBase.ni.dll!00007fff9f6f9d82() Unknown >>> WindowsBase.ni.dll!00007fff9f6f9bc9() Unknown >>> WindowsBase.ni.dll!00007fff9f6f9ac6() Unknown >>> WindowsBase.ni.dll!00007fff9f6f7583() Unknown >>> WindowsBase.ni.dll!00007fff9f6f94ff() Unknown >>> WindowsBase.ni.dll!00007fff9f8c496a() Unknown >>> clr.dll!UMThunkStub () Unknown >>> user32.dll!UserCallWinProcCheckWow() Unknown >>> user32.dll!DispatchMessageWorker() Unknown >>> WindowsBase.ni.dll!00007fff9f730ee8() Unknown >>> WindowsBase.ni.dll!00007fff9f70d8fc() Unknown >>> PresentationFramework.ni.dll!00007fff96af98b3() Unknown >>> PresentationFramework.ni.dll!00007fff96af969d() Unknown >>> clr.dll!CallDescrWorkerInternal () Unknown >>> clr.dll!CallDescrWorkerWithHandler(struct CallDescrData *,int) Unknown >>> clr.dll!CallDescrWorkerReflectionWrapper(struct CallDescrData *,class >>> Frame *) Unknown >>> clr.dll!RuntimeMethodHandle::InvokeMethod(class Object *,class >>> PtrArray *,class SignatureNative *,bool) Unknown >>> mscorlib.ni.dll!00007fffb86e1c20() Unknown >>> mscorlib.ni.dll!00007fffb8618272() Unknown >>> [External Code] >>> clr.dll!UMThunkStub () Unknown >>> [External Code] >>> > WPFPy.py!threadStart Line 256 Python >>> [External Code] >>> >>> >>> ------------------------------ >>> From: t...@pyxll.com >>> Date: Sun, 3 Apr 2016 15:20:47 +0000 >>> Subject: Re: [Python.NET] How to handle INotifyPropertyChanged interface >>> To: hhsp...@pine.cc; pythondotnet@python.org >>> >>> >>> What's the full stack trace? >>> >>> I suspect it's something to do with the event declared on the interface >>> not being implemented. The managed type constructed doesn't define any >>> events, so that would cause the construction of the type of fail - which is >>> probably the error you're getting (although without the stack trace it's >>> just an educated guess). >>> >>> It shouldn't be too hard to add events to the derived type if someone >>> wanted to have a go at implementing it. The code is in the >>> CreateDerivedType method in src/runtime/classderived.cs. To be consistent >>> with how methods and properties work, it would need a clrevent function >>> adding to the clr module (src/runtime/resource/clr.py) - maybe it could >>> work like this: >>> >>> class MyClass(INotifyPropertyChanged): >>> OnPropertyChanged = clr.clrevent(event_attributes, event_type) >>> >>> Then in classderived.cs the class any clrevents on the python class >>> could be added to the managed type using TypeBuilder.DefineEvent. >>> >>> So, anyway - short answer is that what you're trying to do won't work >>> without changes to pythonnet; but the changes required shouldn't be too >>> hard if you wanted to have a go. >>> >>> Best regards, >>> Tony >>> >>> >>> On Sun, Apr 3, 2016 at 3:37 PM Hansong Huang <hhsp...@live.com> wrote: >>> >>> It seems inheriting from INotifyPropertyChanged is the cause >>> >>> self.window = System.Windows.Markup.XamlReader.Load(outStream) >>> self.window.DataContext = MyViewModel() >>> class MyViewModel(System.Object): >>> __namespace__ = "WPFPyDemo" >>> def __init__(self): >>> super(MyViewModel,self).__init__() >>> self._inputText = "Line - in" >>> @clr.clrproperty(str) >>> def inputText(self): >>> return self._inputText >>> @inputText.setter >>> def inputText(self,value): >>> self._inputText = value >>> self.OnPropertyChanged("inputText") >>> >>> The above code works fine. >>> >>> but if switch inheritance to >>> class MyViewModel(System.ComponentModel.INotifyPropertyChanged): >>> and nothing else changed, python gives >>> >>> "The process terminates due to StackOverflowException" >>> >>> Not sure why. >>> >>> >>> Thanks for the help >>> >>> ------------------------------ >>> From: hhsp...@live.com >>> To: pythondotnet@python.org >>> Subject: How to handle INotifyPropertyChanged interface >>> Date: Thu, 31 Mar 2016 20:38:38 -0400 >>> >>> >>> I am still trying to figure out how to implement WPF MVVM with >>> Python.Net. >>> Previously, I have successfully used System.Dynamic.ExpandoObject as a >>> ViewModel container >>> >>> self.window = System.Windows.Markup.XamlReader.Load(outStream) >>> self.window.DataContext = DotNetExpandoObject() >>> >>> where DotNetExpandoObject is a wrapper class for >>> System.Dynamic.ExpandoObject >>> class DotNetExpandoObject(System.Dynamic.ExpandoObject): >>> ... in which I redefined __getattr__ and __setattr__ >>> >>> it works flawlessly as System.Dynamic.ExpandoObject implements >>> INotifyPropertyChange interface already >>> >>> Now, I would like to get away from using System.Dynamic.ExpandoObject >>> but to implement my own >>> >>> I first tried to expose a python class back to .Net >>> class MyViewModel(System.Object): >>> __namespace__ = "WPFPyDemo" >>> def __init__(self): >>> super(MyViewModel,self).__init__() >>> self._inputText = "Line - in" >>> @clr.clrproperty(str) >>> def inputText(self): >>> return self._inputText >>> @inputText.setter >>> def inputText(self,value): >>> self._inputText = value >>> self.OnPropertyChanged("inputText") >>> >>> self.window.DataContext = MyViewModel() >>> >>> The one direction data binding works fine, and the "Line - in" text >>> correctly shows up in the textblock control. >>> obviously this is not sufficient as there is no INotifyPropertyChange >>> interface. >>> >>> So, I inherit the interface , and tries to implement the typical C# code >>> " public event PropertyChangedEventHandler PropertyChanged" >>> >>> -- not sure how to handle event in Python.Net, the follow code probably >>> is completely wrong >>> >>> class ViewModel(System.ComponentModel.INotifyPropertyChanged): >>> __namespace__ = "WPFPy" >>> def __init__(self): >>> super(ViewModel, self).__init__() >>> self.PropertyChanged = >>> System.ComponentModel.PropertyChangedEventHandler >>> def OnPropertyChanged(self, propertyName): >>> if self.PropertyChanged != None: >>> PropertyChanged(self, >>> System.ComponentModel.PropertyChangedEventArgs(propertyName)) >>> >>> class MyViewModel(ViewModel): >>> __namespace__ = "WPFPyDemo" >>> def __init__(self): >>> super(MyViewModel,self).__init__() >>> self._inputText = "Line - in" >>> >>> @clr.clrproperty(str) >>> def inputText(self): >>> return self._inputText >>> @inputText.setter >>> def inputText(self,value): >>> self._inputText = value >>> self.OnPropertyChanged("inputText") >>> >>> >>> The process terminates due to StackOverflowException. >>> Looks like the error happens when WFP recoganized INotifyPropertyChange >>> interface and tries to access MyViewModel class via it. >>> _________________________________________________ >>> Python.NET mailing list - PythonDotNet@python.org >>> https://mail.python.org/mailman/listinfo/pythondotnet >>> >>> >> _________________________________________________ >> Python.NET mailing list - PythonDotNet@python.org >> https://mail.python.org/mailman/listinfo/pythondotnet >> > > _________________________________________________ > Python.NET mailing list - PythonDotNet@python.org > https://mail.python.org/mailman/listinfo/pythondotnet
_________________________________________________ Python.NET mailing list - PythonDotNet@python.org https://mail.python.org/mailman/listinfo/pythondotnet