Skip to content
This repository has been archived by the owner on Apr 7, 2022. It is now read-only.

DevEncoded attribute should produce a bytes object in python 3 #214

Merged
merged 2 commits into from
Sep 7, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 28 additions & 21 deletions ext/device_attribute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ try { \
if (strcmp(e.errors[0].reason.in(),"API_EmptyDeviceAttribute") != 0) \
throw; \
}


namespace PyDeviceAttribute
{
Expand Down Expand Up @@ -133,11 +133,11 @@ namespace PyDeviceAttribute
Tango::DevVarEncodedArray* value_ptr;
EXTRACT_VALUE(self, value_ptr)
unique_pointer<Tango::DevVarEncodedArray> guard(value_ptr);

Tango::DevEncoded* buffer = value_ptr->get_buffer();
Tango::DevEncoded& r_buffer = buffer[0];
bopy::str r_encoded_format(r_buffer.encoded_format);

Tango::DevVarCharArray& r_encoded_data_array = r_buffer.encoded_data;
char* r_ch_ptr = (char*) r_encoded_data_array.get_buffer();
Py_ssize_t r_size = r_encoded_data_array.length();
Expand Down Expand Up @@ -165,7 +165,7 @@ namespace PyDeviceAttribute
py_value.attr(w_value_attr_name) =
bopy::make_tuple(w_encoded_format, w_encoded_data);
}
else
else
{
Tango::DevEncoded& w_buffer = buffer[1];
bopy::str w_encoded_format(w_buffer.encoded_format);
Expand Down Expand Up @@ -238,17 +238,20 @@ namespace PyDeviceAttribute
Tango::DevVarEncodedArray* value_ptr;
EXTRACT_VALUE(self, value_ptr)
unique_pointer<Tango::DevVarEncodedArray> guard(value_ptr);

Tango::DevEncoded* buffer = value_ptr->get_buffer();

Tango::DevEncoded& r_buffer = buffer[0];
bopy::str r_encoded_format(r_buffer.encoded_format);

Tango::DevVarCharArray& r_encoded_data_array = r_buffer.encoded_data;
char* r_ch_ptr = (char*)r_encoded_data_array.get_buffer();
bopy::str r_encoded_data(r_ch_ptr, r_encoded_data_array.length());

py_value.attr(value_attr_name) =

bopy::object r_encoded_data(
bopy::handle<>(PyBytes_FromStringAndSize(
r_ch_ptr, r_encoded_data_array.length())));

py_value.attr(value_attr_name) =
bopy::make_tuple(r_encoded_format, r_encoded_data);

if (self.get_written_dim_x() > 0)
Expand All @@ -268,8 +271,12 @@ namespace PyDeviceAttribute

Tango::DevVarCharArray& w_encoded_data_array = w_buffer.encoded_data;
char* w_ch_ptr = (char*)w_encoded_data_array.get_buffer();
bopy::str w_encoded_data(w_ch_ptr, w_encoded_data_array.length());
py_value.attr(w_value_attr_name) =

bopy::object w_encoded_data(
bopy::handle<>(PyBytes_FromStringAndSize(
w_ch_ptr, w_encoded_data_array.length())));

py_value.attr(w_value_attr_name) =
bopy::make_tuple(w_encoded_format, w_encoded_data);
}
}
Expand All @@ -290,7 +297,7 @@ namespace PyDeviceAttribute
_update_scalar_values(Tango::DeviceAttribute &self, bopy::object py_value)
{
typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;

if (self.get_written_dim_x() > 0)
{
std::vector<TangoScalarType> val;
Expand All @@ -312,7 +319,7 @@ namespace PyDeviceAttribute
}
}

template<> inline void
template<> inline void
_update_scalar_values<Tango::DEV_ENCODED>(Tango::DeviceAttribute &self,
bopy::object py_value)
{
Expand Down Expand Up @@ -340,7 +347,7 @@ namespace PyDeviceAttribute
}
}

template<> inline void
template<> inline void
_update_scalar_values<Tango::DEV_PIPE_BLOB>(Tango::DeviceAttribute &self,
bopy::object py_value)
{
Expand Down Expand Up @@ -368,7 +375,7 @@ namespace PyDeviceAttribute

TangoScalarType* buffer = value_ptr->get_buffer();
int total_length = value_ptr->length();

// Determine if the attribute is AttrWriteType.WRITE
int read_size =0, write_size = 0;
if (isImage) {
Expand All @@ -379,7 +386,7 @@ namespace PyDeviceAttribute
write_size = self.get_written_dim_x();
}
bool is_write_type = (read_size + write_size) > total_length;

// Convert to a list of lists
long offset = 0;
for(int it=1; it>=0; --it) { // 2 iterations: read part/write part
Expand All @@ -388,11 +395,11 @@ namespace PyDeviceAttribute
continue;
}
bopy::list result;

if (isImage) {
const int dim_x = it? self.get_dim_x() : self.get_written_dim_x();
const int dim_y = it? self.get_dim_y() : self.get_written_dim_y();

for (int y=0; y < dim_y; ++y) {
bopy::list row;
for (int x=0; x < dim_x; ++x)
Expand Down Expand Up @@ -439,7 +446,7 @@ namespace PyDeviceAttribute

TangoScalarType* buffer = value_ptr->get_buffer();
int total_length = value_ptr->length();

// Determine if the attribute is AttrWriteType.WRITE
int read_size =0, write_size = 0;
if (isImage) {
Expand All @@ -450,15 +457,15 @@ namespace PyDeviceAttribute
write_size = self.get_written_dim_x();
}
bool is_write_type = (read_size + write_size) > total_length;

// Convert to a tuple of tuples
long offset = 0;
for(int it=1; it>=0; --it) { // 2 iterations: read part/write part
if ((!it) && is_write_type) {
py_value.attr(w_value_attr_name) = py_value.attr(value_attr_name);
continue;
}

object result_guard;
if (isImage) {
const int dim_x = it? self.get_dim_x() : self.get_written_dim_x();
Expand Down Expand Up @@ -516,7 +523,7 @@ namespace PyDeviceAttribute
{
// We do not want is_empty to launch an exception!!
self.reset_exceptions(Tango::DeviceAttribute::isempty_flag);

// self.get_type() already does self.is_empty()
const int data_type = self.get_type();
const bool is_empty = data_type < 0;
Expand Down
18 changes: 17 additions & 1 deletion tests/test_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import pytest
import enum

from tango import DevState, AttrWriteType, GreenMode, DevFailed
from tango import DevState, AttrWriteType, GreenMode, DevFailed, DevEncoded
from tango.server import Device
from tango.server import command, attribute, device_property
from tango.test_utils import DeviceTestContext, assert_close, \
Expand Down Expand Up @@ -392,3 +392,19 @@ def test_get_enum_labels_success(good_enum):
def test_get_enum_labels_fail(bad_enum):
with pytest.raises(EnumTypeError):
get_enum_labels(bad_enum)


# DevEncoded

def test_read_write_dev_encoded(server_green_mode):

class TestDevice(Device):
green_mode = server_green_mode

@attribute(dtype=DevEncoded,
access=AttrWriteType.READ)
def attr(self):
return ("uint8", b"\xd2\xd3")

with DeviceTestContext(TestDevice) as proxy:
assert proxy.attr == ("uint8", b"\xd2\xd3")