How to handle INotifyPropertyChanged interface
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 .Netclass 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.
All stackoverflow exceptions should be posted on stackoverflow! On Thursday, March 31, 2016, Hansong Huang <hhspiny@live.com> wrote:
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.
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@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 .Netclass 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.
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@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@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
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 present1. the class is derived from INotifyPropertyChanged interface2. 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@pyxll.com Date: Sun, 3 Apr 2016 15:20:47 +0000 Subject: Re: [Python.NET] How to handle INotifyPropertyChanged interface To: hhspiny@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 <hhspiny@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@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 .Netclass 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
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@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@pyxll.com Date: Sun, 3 Apr 2016 15:20:47 +0000 Subject: Re: [Python.NET] How to handle INotifyPropertyChanged interface To: hhspiny@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 <hhspiny@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@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
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@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@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@pyxll.com Date: Sun, 3 Apr 2016 15:20:47 +0000 Subject: Re: [Python.NET] How to handle INotifyPropertyChanged interface To: hhspiny@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 <hhspiny@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@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
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.akhiyarov@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 <tony@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@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@pyxll.com Date: Sun, 3 Apr 2016 15:20:47 +0000 Subject: Re: [Python.NET] How to handle INotifyPropertyChanged interface To: hhspiny@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 <hhspiny@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@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
New update: I found why the stackoverflow happened, and how to avoid it and make MVVM model work. however, it did not entirely solve the problem. The StackOverFlow was not directly because of the INotifyPropertyChanged interface, but because I used a class derived from it. if I define my ViewModel as class ViewModel(System.ComponentModel.INotifyPropertyChanged):and implement all components such as clr.clrproperty, PropertyChanged, add_PropertyChanged, remove_PropertyChanged etc as previous posted, and assign this class to window.DataContext, everything actually worked. The problem is that I used a derived classclass ViewModelBase(System.ComponentModel.INotifyPropertyChanged): where PropertyChanged, add_PropertyChanged, remove_PropertyChanged are implementedthenclass ViewModel(ViewModelBase): where clr.clrproperty is implemented. This results in the StackOverflow.... To make a simpler case, I tested out the following code that is entirely self-contained. import clr, Systemclass DotNetINotifyPropertyChanged(System.ComponentModel.INotifyPropertyChanged): __namespace__ = "DotNetINotifyPropertyChanged" def __init__(self): super(DotNetINotifyPropertyChanged, self).__init__() def add_PropertyChanged(self, value): pass def remove_PropertyChanged(self, value): passc1=DotNetINotifyPropertyChanged()c1.add_PropertyChanged("text")print "C1 success" class A(DotNetINotifyPropertyChanged): __namespace__ = "A" def __init__(self): super(A,self).__init__()a1 = A()a1.add_PropertyChanged("text")print "a1 success" if you run it, you can see that "C1 success" is printed, but python can not find a1.add_PropertyChanged method and throws exception. which I believe is the direct cause of StackOverflow above. Obviously, if DotNetINotifyPropertyChanged is derived from "object", the above code runs fine. Therefore the question is, what is it that inheriting from .NET interface that is unique, that the method defined in base class is not inherited by child class? Hansong From: tony@pyxll.com Date: Sun, 3 Apr 2016 15:40:17 +0000 Subject: Re: [Python.NET] How to handle INotifyPropertyChanged interface To: hhspiny@pine.cc; pythondotnet@python.org 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@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 present1. the class is derived from INotifyPropertyChanged interface2. 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@pyxll.com Date: Sun, 3 Apr 2016 15:20:47 +0000 Subject: Re: [Python.NET] How to handle INotifyPropertyChanged interface To: hhspiny@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 <hhspiny@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@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 .Netclass 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
I think this is related to another issue that I'm experiencing: https://github.com/pythonnet/pythonnet/issues/148 In your case I was very interested what is difference between 2 calls to add_PropertyChanged and uploaded a notebook showing the difference: https://gist.github.com/denfromufa/8ef691ca571b736278d751b1b256e814 Note that from console the results are hard crashes! I'm using the current development branch. ::## this is with interface python MVVM.py ['__call__', '__class__', '__cmp__', '__delattr__', '__doc__', '__format__', '__ func__', '__get__', '__getattribute__', '__hash__', '__init__', '__new__', '__re duce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__', '__sizeof__', ' __str__', '__subclasshook__', 'im_class', 'im_func', 'im_self'] success: text ['__call__', '__class__', '__delattr__', '__delete__', '__doc__', '__format__', '__getattribute__', '__getitem__', '__hash__', '__init__', '__module__', '__new_ _', '__reduce__', '__reduce_ex__', '__repr__', '__set__', '__setattr__', '__size of__', '__str__', '__subclasshook__'] Traceback (most recent call last): File "MVVM.py", line 57, in <module> a1.add_PropertyChanged("text") TypeError: No method matches given arguments Unhandled Exception: System.InvalidOperationException: Handle is not initialized . at System.Runtime.InteropServices.GCHandle.Free() at Python.Runtime.PythonDerivedType.Finalize(IPythonDerivedType obj) at A.A.Finalize() ::## this is with System.Object python MVVM.py ['__call__', '__class__', '__cmp__', '__delattr__', '__doc__', '__format__', '__ func__', '__get__', '__getattribute__', '__hash__', '__init__', '__new__', '__re duce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__', '__sizeof__', ' __str__', '__subclasshook__', 'im_class', 'im_func', 'im_self'] success: text ['__call__', '__class__', '__cmp__', '__delattr__', '__doc__', '__format__', '__ func__', '__get__', '__getattribute__', '__hash__', '__init__', '__new__', '__re duce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__', '__sizeof__', ' __str__', '__subclasshook__', 'im_class', 'im_func', 'im_self'] success: text Unhandled Exception: System.InvalidOperationException: Handle is not initialized . at System.Runtime.InteropServices.GCHandle.Free() at Python.Runtime.PythonDerivedType.Finalize(IPythonDerivedType obj) at A.A.Finalize() On Mon, Apr 4, 2016 at 8:47 PM, Hansong Huang <hhspiny@live.com> wrote:
New update:
I found why the stackoverflow happened, and how to avoid it and make MVVM model work. however, it did not entirely solve the problem.
The StackOverFlow was not directly because of the INotifyPropertyChanged interface, but because I used a class derived from it.
if I define my ViewModel as
class ViewModel(System.ComponentModel.INotifyPropertyChanged): and implement all components such as clr.clrproperty, PropertyChanged, add_PropertyChanged, remove_PropertyChanged etc as previous posted, and assign this class to window.DataContext, everything actually worked.
The problem is that I used a derived class class ViewModelBase(System.ComponentModel.INotifyPropertyChanged): where PropertyChanged, add_PropertyChanged, remove_PropertyChanged are implemented then class ViewModel(ViewModelBase): where clr.clrproperty is implemented. This results in the StackOverflow....
To make a simpler case, I tested out the following code that is entirely self-contained.
import clr, System class DotNetINotifyPropertyChanged(System.ComponentModel.INotifyPropertyChanged): __namespace__ = "DotNetINotifyPropertyChanged" def __init__(self): super(DotNetINotifyPropertyChanged, self).__init__() def add_PropertyChanged(self, value): pass def remove_PropertyChanged(self, value): pass c1=DotNetINotifyPropertyChanged() c1.add_PropertyChanged("text") print "C1 success"
class A(DotNetINotifyPropertyChanged): __namespace__ = "A" def __init__(self): super(A,self).__init__() a1 = A() a1.add_PropertyChanged("text") print "a1 success"
if you run it, you can see that "C1 success" is printed, but python can not find a1.add_PropertyChanged method and throws exception. which I believe is the direct cause of StackOverflow above.
Obviously, if DotNetINotifyPropertyChanged is derived from "object", the above code runs fine.
Therefore the question is, what is it that inheriting from .NET interface that is unique, that the method defined in base class is not inherited by child class?
Hansong
------------------------------ From: tony@pyxll.com Date: Sun, 3 Apr 2016 15:40:17 +0000 Subject: Re: [Python.NET] How to handle INotifyPropertyChanged interface To: hhspiny@pine.cc; pythondotnet@python.org
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@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@pyxll.com Date: Sun, 3 Apr 2016 15:20:47 +0000 Subject: Re: [Python.NET] How to handle INotifyPropertyChanged interface To: hhspiny@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 <hhspiny@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@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
participants (3)
-
Denis Akhiyarov
-
Hansong Huang
-
Tony Roberts