things with "bytes".. python 3 compatibility
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: