[IronPython] .NET attributes for methods

Shri Borde Shri.Borde at microsoft.com
Fri Nov 13 16:33:04 CET 2009


I can help you create a property. And I can help you get it to work with your decorators (you can check if the "name" property exposes your @notify_property wrapper methods or not, and presumably that works). Beyond that, you are on your own :)

I would try calling the property methods to make sure they are accessible. Something like this. If that works, I am not sure what Silverlight needs to make databinding happy.

props = a.root.listbox1.Items[0].GetType().GetProperties()
prop = props[0]
prop.GetGetMethod.Invoke(a, None) # call using Reflection

About the "SystemError: Application code cannot access System.AppDomain.get_CurrentDomain() using Reflection." error when defining interfaces, it could be worked around. We need to call AppDomain.DefineDynamicAssembly, and IronPython itself does do this. So its just a question of figuring out the right way to access an AppDomain instance. Will look into it, but I doubt it will help you with data binding.

From: users-bounces at lists.ironpython.com [mailto:users-bounces at lists.ironpython.com] On Behalf Of Lukas Cenovsky
Sent: Friday, November 13, 2009 5:42 AM
To: Discussion of IronPython
Subject: Re: [IronPython] .NET attributes for methods

This looks very promising but I cannot make it work. I have changed product.py in DevHawk's example to:

#from clrtypeold import ClrMetaclass

import clrtype



class Product(object):

  #__metaclass__ = ClrMetaclass

  __metaclass__ = clrtype.ClrClass

  _clrnamespace = "DevHawk.IronPython.ClrTypeSeries"

  #_clrproperties = {

    #"name":str,

    #"cost":float,

    #"quantity":int,

    #}



  def __init__(self, name, cost, quantity):

    self.name = name

    self.cost = cost

    self.quantity = quantity



  def calc_total(self):

    return self.cost * self.quantity



  @property

  @clrtype.accepts()

  @clrtype.returns(str)

  def name(self):

      return self._name



  @name.setter

  @clrtype.accepts(str)

  @clrtype.returns()

  def name(self, value):

      self._name = value


When I run it I don't see any items in the listbox. When I check the name, it is a property:

py> a.root.listbox1.Items[0]

=> <Product object at 0x000000000000002B>

py> a.root.listbox1.Items[0].GetType().GetProperties()

=> Array[PropertyInfo]((<System.Reflection.RuntimePropertyInfo object at 0x000000000000002C [System.String name]>))


Whe I used the old clrtype with _clrproperties = {'name': str, ...}, it worked.

--
-- Lukáš


Shri Borde wrote:
Here is an updated version of clrtype.py that uses @property + @clrtype.accepts/@clrtype.returns to indicate a CLR property, instead of using "_clrproperties". I think its more Pythonic in general, but also you should be able to modify @notify_property to work with it.

Note that notify_property won't just work. You will have to change it to propagate the func_name, arg_types, and return_type properties from the old getter/setter function objects to the new getter/setter function objects since these values are used by clrtype to generate the CLR members. Something like this:

class notify_property(property):

    def propagate_attributes(old_function, new_function):
        new_function.func_name = old_function.func_name
        new_function.arg_types = old_function.arg_types
        new_function.return_type = old_function.return_type

    def __init__(self, getter):
        def newgetter(slf):
            try:
                return getter(slf)
            except AttributeError:
                return None
        propagate_attributes(getter, newgetter)
        super(notify_property, self).__init__(newgetter)

    def setter(self, setter):
        def newsetter(slf, newvalue):
            oldvalue = self.fget(slf)
            if oldvalue != newvalue:
                setter(slf, newvalue)
                slf.OnPropertyChanged(setter.__name__)
        propagate_attributes(setter, newsetter)
        return property(
            fget=self.fget,
            fset=newsetter,
            fdel=self.fdel,
            doc=self.__doc__)

From: Lukas Cenovsky [mailto:cenovsky at bakalari.cz]
Sent: Thursday, November 12, 2009 11:01 AM
To: Shri Borde
Subject: Re: [IronPython] .NET attributes for methods

Shri Borde wrote:
So the new clrtype.py still works - cool!
Yep ;-)


 I am not an expert on data binding, so I don't have any suggestions. Why do you say that the decorator approach will not work with Silverlight? Does @notifiy_property from http://gui-at.blogspot.com/2009/11/inotifypropertychanged-in-ironpython.html use any feature not available in Silverlight?
It does not (as far as I know because it is pure IronPython). But @notify_property does not work with clrtypes:

class ViewModel(NotifyPropertyChangedBase):

    __metaclass__ = clrtype.ClrMetaclass

    _clrnamespace = "Cenda.ViewModel"

    _clrproperties = {'size': str}



    def __init__(self):

        super(ViewModel, self).__init__()

        # must be string to two-way binding work correctly

        self.size = '10'



    @notify_property

    def size(self):

        return self._size



    @size.setter

    def size(self, value):

        self._size = value

        print 'Size changed to %r' % self.size



When I run this code, the size is still clr property and Python getter and setter are not run.

So basically I need to override/enhance clr getter and setter created by clrtype._clrproperties.

--
-- Lukáš




From: Lukas Cenovsky [mailto:cenovsky at bakalari.cz]
Sent: Thursday, November 12, 2009 8:09 AM
To: Shri Borde
Subject: Re: [IronPython] .NET attributes for methods

Thanks, that works!

What do you think would be the best approach to create notifiable properties for Silverlight? I did it for WPF (via decorators: http://gui-at.blogspot.com/2009/11/inotifypropertychanged-in-ironpython.html) but it seems to me it won't be possible to do it similarly for Silverlight...

--
-- Lukáš

Shri Borde wrote:
Can you use "_clrproperties" instead of "_clrfields"? DevHawk's same created a field and a property even when you just used "_clrfields". I don't do that anymore. So you will need to use "_clrproperties" to get properties, which SL must use for data binding.

From: users-bounces at lists.ironpython.com<mailto:users-bounces at lists.ironpython.com> [mailto:users-bounces at lists.ironpython.com] On Behalf Of Lukas Cenovsky
Sent: Wednesday, November 11, 2009 2:37 AM
To: Discussion of IronPython
Subject: Re: [IronPython] .NET attributes for methods

I did change __metaclass__ to ClrMetaclass. See the attached source I use for testing - the only difference is to comment/uncomment appropriate part in product.py.

The outputs look the same, there are no visible exceptions:

DevHawk:

py> a.root.FindName('listbox1').ItemsSource[0].GetType().GetFields()

=> Array[FieldInfo]((<System.Reflection.RtFieldInfo object at 0x000000000000002B [Double cost]>,

<System.Reflection.RtFieldInfo object at 0x000000000000002C [Int32 quantity]>,

<System.Reflection.RtFieldInfo object at 0x000000000000002D [System.String name]>,

<System.Reflection.RtFieldInfo object at 0x000000000000002E [IronPython.Runtime.Types.PythonType .class]>,

<System.Reflection.RtFieldInfo object at 0x000000000000002F [IronPython.Runtime.PythonDictionary .dict]>,

<System.Reflection.RtFieldInfo object at 0x0000000000000030 [System.Object[] .slots_and_weakref]>))

Shri:

py> a.root.FindName('listbox1').ItemsSource[0].GetType().GetFields()

=> Array[FieldInfo]((<System.Reflection.RtFieldInfo object at 0x000000000000002B [Double cost]>,

<System.Reflection.RtFieldInfo object at 0x000000000000002C [Int32 quantity]>,

<System.Reflection.RtFieldInfo object at 0x000000000000002D [System.String name]>,

<System.Reflection.RtFieldInfo object at 0x000000000000002E [IronPython.Runtime.Types.PythonType .class]>,

<System.Reflection.RtFieldInfo object at 0x000000000000002F [IronPython.Runtime.PythonDictionary .dict]>,

<System.Reflection.RtFieldInfo object at 0x0000000000000030 [System.Object[] .slots_and_weakref]>))

--
-- Lukáš


Shri Borde wrote:
Note that you will have to set __metaclass__ to ClrMetaclass, not ClrTypeMetaclass as in DevHawk's sample. I had changed the name of the type. The old name will cause a NameError, but maybe SL is hiding exceptions. Can you do "o.GetType().GetFields()" and display that on the page to inspect the object and also make sure that no exceptions were thrown?

From: users-bounces at lists.ironpython.com<mailto:users-bounces at lists.ironpython.com> [mailto:users-bounces at lists.ironpython.com] On Behalf Of Lukas Cenovsky
Sent: Tuesday, November 10, 2009 2:59 PM
To: Discussion of IronPython
Subject: Re: [IronPython] .NET attributes for methods

I have just found that the Silverlight binding does not work with this version of clrtype and/or IronPython 2.6RC2.
I used DevHawk demo [1] and after I added reference to Microsoft.Dynamic in clrtypemetaclass.py it worked flawlessly. But when I switch to your version, no items show in the listbox.

By the way - I have seen a commit message you have added support for interfaces - nice! ;-)

--
-- Lukáš

[1] http://cid-0d9bc809858885a4.skydrive.live.com/self.aspx/DevHawk%20Content/IronPython%20Stuff/^_^_clrtype^_^_/SL%20databinding%20demo.zip<http://cid-0d9bc809858885a4.skydrive.live.com/self.aspx/DevHawk%20Content/IronPython%20Stuff/%5E_%5E_clrtype%5E_%5E_/SL%20databinding%20demo.zip>








________________________________






_______________________________________________

Users mailing list

Users at lists.ironpython.com<mailto:Users at lists.ironpython.com>

http://lists.ironpython.com/listinfo.cgi/users-ironpython.com



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/ironpython-users/attachments/20091113/17593198/attachment.html>


More information about the Ironpython-users mailing list