things with "bytes".. python 3 compatibility
diff --git a/examples/port_publisher.py b/examples/port_publisher.py
index 22b97a7..bf25ed1 100755
--- a/examples/port_publisher.py
+++ b/examples/port_publisher.py
@@ -118,8 +118,8 @@
def open(self):
"""open serial port, start network server and publish service"""
- self.buffer_net2ser = ''
- self.buffer_ser2net = ''
+ self.buffer_net2ser = bytearray()
+ self.buffer_ser2net = bytearray()
# open serial port
try:
@@ -199,7 +199,7 @@
error_map[self.socket] = self.handle_socket_error
else:
# no connection, ensure clear buffer
- self.buffer_ser2net = ''
+ self.buffer_ser2net = bytearray()
# check the server socket
read_map[self.server_socket] = self.handle_connect
error_map[self.server_socket] = self.handle_server_error
@@ -225,7 +225,7 @@
"""Writing to serial port"""
try:
# write a chunk
- n = os.write(self.serial.fileno(), self.buffer_net2ser)
+ n = os.write(self.serial.fileno(), bytes(self.buffer_net2ser))
# and see how large that chunk was, remove that from buffer
self.buffer_net2ser = self.buffer_net2ser[n:]
except Exception as msg:
@@ -257,7 +257,7 @@
"""Write to socket"""
try:
# write a chunk
- count = self.socket.send(self.buffer_ser2net)
+ count = self.socket.send(bytes(self.buffer_ser2net))
# and remove the sent data from the buffer
self.buffer_ser2net = self.buffer_ser2net[count:]
except socket.error:
@@ -288,6 +288,8 @@
print('%s: Connected by %s:%s' % (self.device, addr[0], addr[1]))
self.serial.setRTS(True)
self.serial.setDTR(True)
+ # XXX set logger only optionally
+ #~ self.rfc2217 = serial.rfc2217.PortManager(self.serial, self, logger=logging.getLogger('rfc2217.%s' % self.device))
self.rfc2217 = serial.rfc2217.PortManager(self.serial, self)
else:
# reject connection if there is already one
@@ -311,7 +313,7 @@
# stop RFC 2217 state machine
self.rfc2217 = None
# clear send buffer
- self.buffer_ser2net = ''
+ self.buffer_ser2net = bytearray()
# close network connection
if self.socket is not None:
self.socket.close()
@@ -328,6 +330,7 @@
if __name__ == '__main__':
+ import logging
import optparse
parser = optparse.OptionParser(usage="""\
@@ -381,6 +384,9 @@
(options, args) = parser.parse_args()
+ # XXX make it depend on command line option
+ #~ logging.basicConfig(level=logging.DEBUG)
+
# redirect output if specified
if options.log_file is not None:
class WriteFlushed:
diff --git a/serial/rfc2217.py b/serial/rfc2217.py
index 64bcdff..7298c44 100644
--- a/serial/rfc2217.py
+++ b/serial/rfc2217.py
@@ -7,7 +7,7 @@
# protocol to access serial ports over TCP/IP and allows setting the baud rate,
# modem control lines etc.
#
-# (C) 2001-2013 Chris Liechti <cliechti@gmx.net>
+# (C) 2001-2015 Chris Liechti <cliechti@gmx.net>
# this is distributed under a free software license, see license.txt
# TODO:
@@ -51,7 +51,7 @@
# rfc2217://<host>:<port>[/option[/option...]]
#
# options:
-# - "debug" print diagnostic messages
+# - "logging" set log level print diagnostic messages (e.g. "logging=debug")
# - "ign_set_control": do not look at the answers to SET_CONTROL
# - "poll_modem": issue NOTIFY_MODEMSTATE requests when CTS/DTR/RI/CD is read.
# Without this option it expects that the server sends notifications
@@ -480,12 +480,12 @@
# Setup the connection
# to get good performance, all parameter changes are sent first...
- if not isinstance(self._baudrate, (int, long)) or not 0 < self._baudrate < 2**32:
+ if not 0 < self._baudrate < 2**32:
raise ValueError("invalid baudrate: %r" % (self._baudrate))
- self._rfc2217_port_settings['baudrate'].set(struct.pack('!I', self._baudrate))
- self._rfc2217_port_settings['datasize'].set(struct.pack('!B', self._bytesize))
- self._rfc2217_port_settings['parity'].set(struct.pack('!B', RFC2217_PARITY_MAP[self._parity]))
- self._rfc2217_port_settings['stopsize'].set(struct.pack('!B', RFC2217_STOPBIT_MAP[self._stopbits]))
+ self._rfc2217_port_settings['baudrate'].set(struct.pack(b'!I', self._baudrate))
+ self._rfc2217_port_settings['datasize'].set(struct.pack(b'!B', self._bytesize))
+ self._rfc2217_port_settings['parity'].set(struct.pack(b'!B', RFC2217_PARITY_MAP[self._parity]))
+ self._rfc2217_port_settings['stopsize'].set(struct.pack(b'!B', RFC2217_STOPBIT_MAP[self._stopbits]))
# and now wait until parameters are active
items = self._rfc2217_port_settings.values()
@@ -584,7 +584,7 @@
while len(data) < size:
if self._thread is None:
raise SerialException('connection failed (reader thread died)')
- data.append(self._read_buffer.get(True, self._timeout))
+ data += self._read_buffer.get(True, self._timeout)
except Queue.Empty: # -> timeout
pass
return bytes(data)
@@ -596,14 +596,11 @@
closed.
"""
if not self._isOpen: raise portNotOpenError
- self._write_lock.acquire()
- try:
+ with self._write_lock:
try:
self._socket.sendall(to_bytes(data).replace(IAC, IAC_DOUBLED))
except socket.error as e:
raise SerialException("connection failed (socket error): %s" % e) # XXX what exception if socket connection fails
- finally:
- self._write_lock.release()
return len(data)
def flushInput(self):
@@ -708,7 +705,9 @@
self.logger.debug("socket error in reader thread: %s" % (e,))
break
if not data: break # lost connection
- for byte in data:
+ #~ for byte in data: # fails for python3 as it returns ints instead of b''
+ for x in range(len(data)):
+ byte = data[x:x+1]
if mode == M_NORMAL:
# interpret as command or as data
if byte == IAC:
@@ -717,7 +716,7 @@
# store data in read buffer or sub option buffer
# depending on state
if suboption is not None:
- suboption.append(byte)
+ suboption += byte
else:
self._read_buffer.put(byte)
elif mode == M_IAC_SEEN:
@@ -725,7 +724,7 @@
# interpret as command doubled -> insert character
# itself
if suboption is not None:
- suboption.append(IAC)
+ suboption += IAC
else:
self._read_buffer.put(IAC)
mode = M_NORMAL
@@ -816,11 +815,8 @@
def _internal_raw_write(self, data):
"""internal socket write with no data escaping. used to send telnet stuff."""
- self._write_lock.acquire()
- try:
+ with self._write_lock:
self._socket.sendall(data)
- finally:
- self._write_lock.release()
def telnetSendOption(self, action, option):
"""Send DO, DONT, WILL, WONT."""
@@ -874,9 +870,10 @@
# when expiration time is updated, it means that there is a new
# value
if self._modemstate_expires > time.time():
- if self.logger:
- self.logger.warning('poll for modem state failed')
break
+ else:
+ if self.logger:
+ self.logger.warning('poll for modem state failed')
# even when there is a timeout, do not generate an error just
# return the last known value. this way we can support buggy
# servers that do not respond to polls, but send automatic
@@ -1033,7 +1030,9 @@
(socket error handling code left as exercise for the reader)
"""
- for byte in data:
+ #~ for byte in data: # XXX fails for python3 as it returns ints instead of bytes
+ for x in range(len(data)):
+ byte = data[x:x+1]
if self.mode == M_NORMAL:
# interpret as command or as data
if byte == IAC:
@@ -1042,7 +1041,7 @@
# store data in sub option buffer or pass it to our
# consumer depending on state
if self.suboption is not None:
- self.suboption.append(byte)
+ self.suboption += byte
else:
yield byte
elif self.mode == M_IAC_SEEN:
@@ -1050,7 +1049,7 @@
# interpret as command doubled -> insert character
# itself
if self.suboption is not None:
- self.suboption.append(byte)
+ self.suboption += byte
else:
yield byte
self.mode = M_NORMAL
@@ -1111,7 +1110,7 @@
if suboption[1:2] == SET_BAUDRATE:
backup = self.serial.baudrate
try:
- (baudrate,) = struct.unpack("!I", suboption[2:6])
+ (baudrate,) = struct.unpack(b"!I", suboption[2:6])
if baudrate != 0:
self.serial.baudrate = baudrate
except ValueError as e:
@@ -1121,7 +1120,7 @@
else:
if self.logger:
self.logger.info("%s baud rate: %s" % (baudrate and 'set' or 'get', self.serial.baudrate))
- self.rfc2217SendSubnegotiation(SERVER_SET_BAUDRATE, struct.pack("!I", self.serial.baudrate))
+ self.rfc2217SendSubnegotiation(SERVER_SET_BAUDRATE, struct.pack(b"!I", self.serial.baudrate))
elif suboption[1:2] == SET_DATASIZE:
backup = self.serial.bytesize
try:
@@ -1135,11 +1134,11 @@
else:
if self.logger:
self.logger.info("%s data size: %s" % (datasize and 'set' or 'get', self.serial.bytesize))
- self.rfc2217SendSubnegotiation(SERVER_SET_DATASIZE, struct.pack("!B", self.serial.bytesize))
+ self.rfc2217SendSubnegotiation(SERVER_SET_DATASIZE, struct.pack(b"!B", self.serial.bytesize))
elif suboption[1:2] == SET_PARITY:
backup = self.serial.parity
try:
- parity = struct.unpack("!B", suboption[2:3])[0]
+ parity = struct.unpack(b"!B", suboption[2:3])[0]
if parity != 0:
self.serial.parity = RFC2217_REVERSE_PARITY_MAP[parity]
except ValueError as e:
@@ -1156,7 +1155,7 @@
elif suboption[1:2] == SET_STOPSIZE:
backup = self.serial.stopbits
try:
- stopbits = struct.unpack("!B", suboption[2:3])[0]
+ stopbits = struct.unpack(b"!B", suboption[2:3])[0]
if stopbits != 0:
self.serial.stopbits = RFC2217_REVERSE_STOPBIT_MAP[stopbits]
except ValueError as e:
@@ -1168,7 +1167,7 @@
self.logger.info("%s stop bits: %s" % (stopbits and 'set' or 'get', self.serial.stopbits))
self.rfc2217SendSubnegotiation(
SERVER_SET_STOPSIZE,
- struct.pack("!B", RFC2217_STOPBIT_MAP[self.serial.stopbits])
+ struct.pack(b"!B", RFC2217_STOPBIT_MAP[self.serial.stopbits])
)
elif suboption[1:2] == SET_CONTROL:
if suboption[2:3] == SET_CONTROL_REQ_FLOW_SETTING: