Python 2 vs Python 3: DevString with bytes
Hi all,
I noticed an intriguing behavior of PyTango running within a Python 3 environment.
Scenario
An old, existing C++ server to control a RS232 serial line. The server has a DevSerReadString
method to read chars from the serial line ; Tango output data type is DevString.
The equipment connected to the serial line sends binary data.
Problem
When calling the command from a Python 2 client, everything works fine -- the returned string corresponds to the bytes sent by the equipment.
When calling the command from a Python 3 client, None is returned.
Minimal example to reproduce the problem
-
Server in Python 2
from tango.server import run from tango.server import Device from tango.server import attribute, command class BytesTest(Device): @command(dtype_out=str) def bytes_str1(self): return "binary_data\xee\xff" if __name__ == "__main__": run((BytesTest,)) -
Python 3 client
Python 3.7.1 (default, Dec 14 2018, 19:28:38) [GCC 7.3.0] :: Anaconda, Inc. on linux Type "help", "copyright", "credits" or "license" for more information. >>> import tango; dev=tango.DeviceProxy("id00/tango/test") >>> print(dev.bytes_str1()) None >>>
Additional information
Of course the problem comes from bytes/unicode handling in Python. It is also probably a
bad idea to use DevString for this kind of data transfer, maybe DevVarCharArray would
have been better...
According to the PyTango documentation, DevString is encoded as latin-1, but it does not seem to be the case in reality.
>>> s = "binary_data\xee\xff"
>>> print(s)
'binary_dataîÿ'
>>> print(s.encode("latin-1"))
b'binary_data\xee\xff'