Improve Python 3 support in variable_server.py

Correct send_on_copy's variable server string

Closes #777
This commit is contained in:
Derek Bankieris 2019-05-22 11:38:35 -05:00
parent c4bc35d897
commit 881ee69757

View File

@ -6,7 +6,6 @@ a tutorial and examples.
""" """
from collections import namedtuple from collections import namedtuple
import itertools
import os import os
import re import re
import socket import socket
@ -14,6 +13,19 @@ import struct
import threading import threading
import time import time
# In Python 2, basestring is the parent for both str (ASCII) and unicode.
# In Python 3, str and unicode were unified into str, and basestring is gone.
try:
basestring
except NameError:
basestring = str
# In Python 3, itertools.izip became zip.
try:
from itertools import izip as zip
except ImportError:
pass
class VariableServerError(Exception): class VariableServerError(Exception):
''' '''
Variable Server communication I/O error. Variable Server communication I/O error.
@ -248,7 +260,7 @@ class VariableServer(object):
# Besides, it would be corrected with the next # Besides, it would be corrected with the next
# message. # message.
if len(values) <= len(self._variables): if len(values) <= len(self._variables):
for variable, value in itertools.izip( for variable, value in zip(
self._variables, values): self._variables, values):
variable.value, variable.units = \ variable.value, variable.units = \
_parse_value(value) _parse_value(value)
@ -460,7 +472,7 @@ class VariableServer(object):
_assert_value_count(len(variables), len(values)) _assert_value_count(len(variables), len(values))
# update each Variable, checking units conversions # update each Variable, checking units conversions
for variable, entry in itertools.izip(variables, values): for variable, entry in zip(variables, values):
value, units = _parse_value(entry) value, units = _parse_value(entry)
if variable.units is not None: if variable.units is not None:
_assert_units_conversion(variable.name, variable.units, units) _assert_units_conversion(variable.name, variable.units, units)
@ -752,7 +764,7 @@ class VariableServer(object):
False to send values asynchronously on an independent False to send values asynchronously on an independent
thread. thread.
""" """
self.send('trick.var_set_copy_mode({0})'.format(bool(enable)), self.send('trick.var_set_write_mode({0})'.format(bool(enable)),
self.Channel.ASYNC) self.Channel.ASYNC)
def validate_addresses(self, validate=True, channel=Channel.BOTH): def validate_addresses(self, validate=True, channel=Channel.BOTH):
@ -869,13 +881,16 @@ class VariableServer(object):
send and expect a response from the variable server. The newline send and expect a response from the variable server. The newline
character is stripped. character is stripped.
Parameters
----------
synchronous_channel : bool
True to read from the synchronous channel.
False to read from the asynchronous channel.
Returns Returns
------- -------
Message Message
The next available message. The next available message.
synchronous_channel : bool
True to read from the synchronous channel.
False to read from the asynchronous channel.
Raises Raises
------ ------
@ -977,11 +992,15 @@ class VariableServer(object):
called after this one. A new connection can be established only called after this one. A new connection can be established only
by creating a new instance. by creating a new instance.
""" """
# In Python 3, self._asynchronous_file_interface.close() hangs if
# shutdown isn't called first. Something to do with self._thread
# always blocking on a read from the asynchronous_socket. I suspect
# Python 3's new io module.
self._open = False self._open = False
self._synchronous_file_interface.close()
self._asynchronous_file_interface.close()
self._synchronous_socket.shutdown(socket.SHUT_RDWR) self._synchronous_socket.shutdown(socket.SHUT_RDWR)
self._asynchronous_socket.shutdown(socket.SHUT_RDWR) self._asynchronous_socket.shutdown(socket.SHUT_RDWR)
self._synchronous_file_interface.close()
self._asynchronous_file_interface.close()
self._synchronous_socket.close() self._synchronous_socket.close()
self._asynchronous_socket.close() self._asynchronous_socket.close()
self._thread.join() self._thread.join()