Menu

#260 PyTango.Group.read_attribute() return values

closed-fixed
5
2009-12-22
2009-12-07
No

PyTango.Group.read_attribute() returns a list of sequence<GroupAttrReply>. If you try to read twice the value of one of this objects, the first time you'll get the right value, but the second time you'll get nothing. A sample code:

>>> import PyTango
>>> group = PyTango.Group("test")
>>> group.add("BO01/DI/BPM-01")
>>> res = group.read_attribute("XPosDD")[0]
>>> res.get_data().value
array([ 1.65694536, -3.06832737, -0.27192519, ..., -4.05291414,
2.45052059, 0.00959389])
>>> res.get_data().value
>>>

Discussion

  • ollupaC De La Pradera

    r = group.read_attribute() does not return a python list but a C++ std::vector. So r[0] is a different python object each time referring to the same internal C++ object.
    r[0].get_data() returns a DeviceAttribute, a new different DeviceAttribute each time because in PyTango we do the extraction of 'value' and 'w_value'. The problem is internally we are doing a copy of DeviceAttribute with the constructor
    DeviceAttribute::DeviceAttribute(const DeviceAttribute & source) and then we extract from this one.
    But there is a lie there, 'source' is not really const! The copy constructor is stealing the value from the original DeviceAttribute! Which is nice in some cases for performance, but it is still a lie. I would expect having two constructors, one getting a "DeviceAttribute &" (or even better, in the future, "DeviceAttribute &&") that does what the current one does, and another "const DeviceAttribute &" which really does not modify the original. Then with each call to get_data() you would get a new copy of the DeviceAttribute.

    Or we could make group.read_attribute() return a list, then we can do the get_data() once and store the result in the python GroupAttrReply object, so following calls to get_data() return the cached value. This however implies creating a new list each time an attribute is read and copying all the GroupAttrReply objects there, instead of just returning the raw 'C++' structure.

    What does people think?

     
  • Jairo Moldes

    Jairo Moldes - 2009-12-11

    There's an even worse problem I had noticed that if you call the has_failed() function, the result dissapears. Here's a sample:

    Python 2.6 (r26:66714, Feb 3 2009, 20:49:49)
    [GCC 4.3.2 [gcc-4_3-branch revision 141291]] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import PyTango
    >>> grupo = PyTango.Group("test")
    >>> grupo.add("BO01/DI/BPM-01")
    >>> grupo.add("BO03/DI/BPM-01")
    >>> reply = grupo.read_attribute("DDTriggerCounter")
    >>> reply[0].get_data().value
    0
    >>> reply[0].get_data().value
    >>> reply = grupo.read_attribute("DDTriggerCounter")
    >>> reply[0].has_failed()
    False
    >>> reply[0].get_data().value
    >>> reply = grupo.read_attribute("DDTriggerCounter")
    >>> reply[0].get_data().value
    0
    >>>

     
  • Tiago Coutinho

    Tiago Coutinho - 2009-12-17
    • assigned_to: tiagocoutinho --> ollupac
     
  • ollupaC De La Pradera

    Mmm the second bug found by Jairo is worse...
    Both fixed at svn revision 860, will be available in the next PyTango version.

     
  • ollupaC De La Pradera

    • status: open --> closed-fixed
     

Log in to post a comment.