Writing of empty list affects the subsequent reading
In PyTango we have an issue, related to the reading if empty list (Reading an empty list returns a None value). During tracking of our problem, I found strange behavior: the attribute type is affected by the previous writing - why is it so?
This is the simple server, which always returns an empty list:
#include <Test_server.h>
#include <Test_serverClass.h>
namespace Test_server_ns
{
Test_server::Test_server(Tango::DeviceClass *cl, string &s)
: TANGO_BASE_CLASS(cl, s.c_str())
{
init_device();
}
Test_server::Test_server(Tango::DeviceClass *cl, const char *s)
: TANGO_BASE_CLASS(cl, s)
{
init_device();
}
Test_server::Test_server(Tango::DeviceClass *cl, const char *s, const char *d)
: TANGO_BASE_CLASS(cl, s, d)
{
init_device();
}
void Test_server::init_device()
{
attr_test_read = new Tango::DevString[10];
long dim_test_read = 0;
}
void Test_server::delete_device()
{
int s = 0;
if (attr_test_read) {
for (s = 0; s < 10; s++)
CORBA::string_free(attr_test_read[s]);
}
delete[] attr_test_read;
}
void Test_server::read_test(Tango::Attribute &attr)
{
attr.set_value(attr_test_read, dim_test_read);
}
void Test_server::write_test(Tango::WAttribute &attr){}
void Test_server::always_executed_hook(){}
void Test_server::read_attr_hardware(TANGO_UNUSED(vector<long> &attr_list)){}
void Test_server::write_attr_hardware(TANGO_UNUSED(vector<long> &attr_list)){}
void Test_server::add_dynamic_attributes(){}
void Test_server::add_dynamic_commands(){}
}
When you read for the first time - you get an empty list with type DEV_STRING:
>>> d.read_attribute('test')
DeviceAttribute(data_format = tango._tango.AttrDataFormat.SPECTRUM, dim_x = 0, dim_y = 0, has_failed = False, is_empty = False, name = 'test', nb_read = 0, nb_written = 1, quality = tango._tango.AttrQuality.ATTR_VALID, r_dimension = AttributeDimension(dim_x = 0, dim_y = 0), time = TimeVal(tv_nsec = 35, tv_sec = 1665750213, tv_usec = 914578), type = tango._tango.CmdArgType.DevString, value = (), w_dim_x = 1, w_dim_y = 0, w_dimension = AttributeDimension(dim_x = 1, dim_y = 0), w_value = ('Not initialised',))
But if then an empty list was written (even write method does not do anything) and read again, you get type DATA_TYPE_UNKNOWN:
>>> d.write_attribute('test', [])
>>> d.read_attribute('test')
DeviceAttribute(data_format = tango._tango.AttrDataFormat.SPECTRUM, dim_x = 0, dim_y = 0, has_failed = False, is_empty = True, name = 'test', nb_read = 0, nb_written = 0, quality = tango._tango.AttrQuality.ATTR_VALID, r_dimension = AttributeDimension(dim_x = 0, dim_y = 0), time = TimeVal(tv_nsec = 784, tv_sec = 1665750219, tv_usec = 684224), type = tango._tango.CmdArgType(100), value = None, w_dim_x = 0, w_dim_y = 0, w_dimension = AttributeDimension(dim_x = 0, dim_y = 0), w_value = None)
If you then write a non-empty list and read - everything is back: answer has type DEV_STRING
>>>dd.write_attribute('test', ['a'])
>>>dd.read_attribute('test')
DeviceAttribute(data_format = tango._tango.AttrDataFormat.SPECTRUM, dim_x = 0, dim_y = 0, has_failed = False, is_empty = False, name = 'test', nb_read = 0, nb_written = 1, quality = tango._tango.AttrQuality.ATTR_VALID, r_dimension = AttributeDimension(dim_x = 0, dim_y = 0), time = TimeVal(tv_nsec = 0, tv_sec = 1665996979, tv_usec = 574306), type = tango._tango.CmdArgType.DevString, value = (), w_dim_x = 1, w_dim_y = 0, w_dimension = AttributeDimension(dim_x = 1, dim_y = 0), w_value = ('a',))
The question is: is such behavior bug or feature? If the second options - then we have to somehow handle in later in pytango layer, and convert None value in empty list, is the attribute originally was a list...
The whole packadge with server is there:
https://drive.google.com/file/d/1JvfgxI4qsNXmye_CfEmQ46JzfYzceXM-/view