[Python.NET] PythonDotNet Digest, Vol 141, Issue 6

Hansong Huang hhspiny at live.com
Sun Apr 3 21:55:29 EDT 2016


Here is how I understand IronPython's implementation
.Net expects an event to be defined by the class that implements INotifyPropertyChanged interface.
However, as python does not support event type, IronPython created two methods at its interface with .Net: add_PropertyChanged and remove_PropertyChanged.   hence, whenever .Net would add or remove a handler from this event,  these two methods are called instead.   then a separate python class is created within IronPython to actual track and invoke callback functions.
well, looks like Python.Net implemented exactly the same as IronPython. dir(System.ComponentModel.INotifyPropertyChanged)  ==>['PropertyChanged', '__class__', '__cmp__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__iter__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'add_PropertyChanged', 'remove_PropertyChanged']so, in principle the same implementation as in IronPython should work.  but instead, I got stackoverflow 
here is my implementation:make_event() and event() and even_handler() classes are copied from IronPython examples, used to track and invoke callback functions
class ViewModel(System.ComponentModel.INotifyPropertyChanged):    ''' this does not work. PropertyChanged event can not be implemented yet'''    __namespace__ = "ViewModel"    PropertyChanged == None    def __init__(self):        super(ViewModel, self).__init__()        self.PropertyChanged, self._propertyChangedCaller = make_event()
    @clr.clrmethod(None, [System.ComponentModel.PropertyChangedEventHandler])    def add_PropertyChanged(self, value):        self.PropertyChanged += value    @clr.clrmethod(None, [System.ComponentModel.PropertyChangedEventHandler])    def remove_PropertyChanged(self, value):        self.PropertyChanged -= value
    def OnPropertyChanged(self, propertyName):        if self.PropertyChanged != None:           self._propertyChangedCaller(self, System.ComponentModel.PropertyChangedEventArgs(propertyName))

One possible reason might be that the types specified in @clr.clrmethod is not correct, therefore, .Net could not find the right method to call. 
Hansong


> ----------------------------------------------------------------------
> 
> Message: 1
> Date: Sun, 3 Apr 2016 11:08:50 -0500
> From: Denis Akhiyarov <denis.akhiyarov at gmail.com>
> To: "A list for users and developers of Python for .NET"
> 	<pythondotnet at python.org>
> Subject: Re: [Python.NET] How to handle INotifyPropertyChanged
> 	interface
> Message-ID:
> 	<CALxxJLTeEjH8Uco+nNWA7tvkxasWBonjkFRJVj9DQR8XRYAaoA at mail.gmail.com>
> Content-Type: text/plain; charset="utf-8"
> 
> 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 <tony at 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 <hhspiny at 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: tony at pyxll.com
> >> Date: Sun, 3 Apr 2016 15:20:47 +0000
> >> Subject: Re: [Python.NET] How to handle INotifyPropertyChanged interface
> >> To: hhspiny at pine.cc; pythondotnet at 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 <hhspiny at 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: hhspiny at live.com
> >> To: pythondotnet at 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 at python.org
> >> https://mail.python.org/mailman/listinfo/pythondotnet
> >>
> >>
> > _________________________________________________
> > Python.NET mailing list - PythonDotNet at python.org
> > https://mail.python.org/mailman/listinfo/pythondotnet
> >
> -------------- next part --------------
> An HTML attachment was scrubbed...
> URL: <http://mail.python.org/pipermail/pythondotnet/attachments/20160403/e88f5e54/attachment.html>
> 
> ------------------------------
> 
> Subject: Digest Footer
> 
> _______________________________________________
> PythonDotNet mailing list
> PythonDotNet at python.org
> https://mail.python.org/mailman/listinfo/pythondotnet
> 
> 
> ------------------------------
> 
> End of PythonDotNet Digest, Vol 141, Issue 6
> ********************************************
 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/pythondotnet/attachments/20160403/54e658b1/attachment-0001.html>


More information about the PythonDotNet mailing list