Fixes for Python 3 Compatability (#297)

This commit is contained in:
Otto Winter 2019-01-03 16:05:33 +01:00 committed by GitHub
parent 1d0c812e44
commit 1e12cba176
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 64 additions and 20 deletions

View file

@ -16,7 +16,7 @@ from esphomeyaml.const import CONF_BAUD_RATE, CONF_ESPHOMEYAML, CONF_LOGGER, CON
from esphomeyaml.core import CORE, EsphomeyamlError from esphomeyaml.core import CORE, EsphomeyamlError
from esphomeyaml.cpp_generator import Expression, RawStatement, add, statement from esphomeyaml.cpp_generator import Expression, RawStatement, add, statement
from esphomeyaml.helpers import color, indent from esphomeyaml.helpers import color, indent
from esphomeyaml.py_compat import safe_input, text_type from esphomeyaml.py_compat import safe_input, text_type, IS_PY2
from esphomeyaml.storage_json import StorageJSON, esphomeyaml_storage_path, \ from esphomeyaml.storage_json import StorageJSON, esphomeyaml_storage_path, \
start_update_check_thread, storage_path start_update_check_thread, storage_path
from esphomeyaml.util import run_external_command, safe_print from esphomeyaml.util import run_external_command, safe_print
@ -110,7 +110,11 @@ def run_miniterm(config, port):
except serial.SerialException: except serial.SerialException:
_LOGGER.error("Serial port closed!") _LOGGER.error("Serial port closed!")
return return
line = raw.replace('\r', '').replace('\n', '') if IS_PY2:
line = raw.replace('\r', '').replace('\n', '')
else:
line = raw.replace(b'\r', b'').replace(b'\n', b'').decode('utf8',
'backslashreplace')
time = datetime.now().time().strftime('[%H:%M:%S]') time = datetime.now().time().strftime('[%H:%M:%S]')
message = time + line message = time + line
safe_print(message) safe_print(message)

View file

@ -14,7 +14,7 @@ import esphomeyaml.api.api_pb2 as pb
from esphomeyaml.const import CONF_PASSWORD, CONF_PORT from esphomeyaml.const import CONF_PASSWORD, CONF_PORT
from esphomeyaml.core import EsphomeyamlError from esphomeyaml.core import EsphomeyamlError
from esphomeyaml.helpers import resolve_ip_address, indent, color from esphomeyaml.helpers import resolve_ip_address, indent, color
from esphomeyaml.py_compat import text_type from esphomeyaml.py_compat import text_type, IS_PY2, byte, char, format_bytes
from esphomeyaml.util import safe_print from esphomeyaml.util import safe_print
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -67,16 +67,16 @@ MESSAGE_TYPE_TO_PROTO = {
def _varuint_to_bytes(value): def _varuint_to_bytes(value):
if value <= 0x7F: if value <= 0x7F:
return chr(value) return byte(value)
ret = bytes() ret = bytes()
while value: while value:
temp = value & 0x7F temp = value & 0x7F
value >>= 7 value >>= 7
if value: if value:
ret += chr(temp | 0x80) ret += byte(temp | 0x80)
else: else:
ret += chr(temp) ret += byte(temp)
return ret return ret
@ -85,7 +85,7 @@ def _bytes_to_varuint(value):
result = 0 result = 0
bitpos = 0 bitpos = 0
for c in value: for c in value:
val = ord(c) val = char(c)
result |= (val & 0x7F) << bitpos result |= (val & 0x7F) << bitpos
bitpos += 7 bitpos += 7
if (val & 0x80) == 0: if (val & 0x80) == 0:
@ -245,7 +245,7 @@ class APIClient(threading.Thread):
if self._socket is None: if self._socket is None:
raise APIConnectionError("Socket closed") raise APIConnectionError("Socket closed")
_LOGGER.debug("Write: %s", ' '.join('{:02X}'.format(ord(x)) for x in data)) _LOGGER.debug("Write: %s", format_bytes(data))
with self._socket_write_lock: with self._socket_write_lock:
try: try:
self._socket.sendall(data) self._socket.sendall(data)
@ -263,7 +263,10 @@ class APIClient(threading.Thread):
encoded = msg.SerializeToString() encoded = msg.SerializeToString()
_LOGGER.debug("Sending %s:\n%s", type(msg), indent(text_type(msg))) _LOGGER.debug("Sending %s:\n%s", type(msg), indent(text_type(msg)))
req = chr(0x00) if IS_PY2:
req = chr(0x00)
else:
req = bytes([0])
req += _varuint_to_bytes(len(encoded)) req += _varuint_to_bytes(len(encoded))
req += _varuint_to_bytes(message_type) req += _varuint_to_bytes(message_type)
req += encoded req += encoded
@ -358,7 +361,7 @@ class APIClient(threading.Thread):
def _recv_varint(self): def _recv_varint(self):
raw = bytes() raw = bytes()
while not raw or ord(raw[-1]) & 0x80: while not raw or char(raw[-1]) & 0x80:
raw += self._recv(1) raw += self._recv(1)
return _bytes_to_varuint(raw) return _bytes_to_varuint(raw)
@ -367,7 +370,7 @@ class APIClient(threading.Thread):
return return
# Preamble # Preamble
if ord(self._recv(1)[0]) != 0x00: if char(self._recv(1)[0]) != 0x00:
raise APIConnectionError("Invalid preamble") raise APIConnectionError("Invalid preamble")
length = self._recv_varint() length = self._recv_varint()

View file

@ -439,7 +439,7 @@ def load_config():
try: try:
config = yaml_util.load_yaml(CORE.config_path) config = yaml_util.load_yaml(CORE.config_path)
except OSError: except OSError:
raise EsphomeyamlError(u"Could not read configuration file at {}".format(CORE.config_path)) raise EsphomeyamlError(u"Invalid YAML at {}".format(CORE.config_path))
CORE.raw_config = config CORE.raw_config = config
config = substitutions.do_substitution_pass(config) config = substitutions.do_substitution_pass(config)
core_config.preload_core_config(config) core_config.preload_core_config(config)

View file

@ -26,6 +26,7 @@ import tornado.websocket
from esphomeyaml import const from esphomeyaml import const
from esphomeyaml.__main__ import get_serial_ports from esphomeyaml.__main__ import get_serial_ports
from esphomeyaml.helpers import mkdir_p, run_system_command from esphomeyaml.helpers import mkdir_p, run_system_command
from esphomeyaml.py_compat import IS_PY2
from esphomeyaml.storage_json import EsphomeyamlStorageJSON, StorageJSON, \ from esphomeyaml.storage_json import EsphomeyamlStorageJSON, StorageJSON, \
esphomeyaml_storage_path, ext_storage_path esphomeyaml_storage_path, ext_storage_path
from esphomeyaml.util import shlex_quote from esphomeyaml.util import shlex_quote
@ -77,7 +78,13 @@ class EsphomeyamlCommandWebSocket(tornado.websocket.WebSocketHandler):
def redirect_stream(self): def redirect_stream(self):
while True: while True:
try: try:
data = yield self.proc.stdout.read_until_regex('[\n\r]') if IS_PY2:
reg = '[\n\r]'
else:
reg = b'[\n\r]'
data = yield self.proc.stdout.read_until_regex(reg)
if not IS_PY2:
data = data.decode('utf-8', 'backslashreplace')
except tornado.iostream.StreamClosedError: except tornado.iostream.StreamClosedError:
break break
try: try:
@ -166,7 +173,8 @@ class SerialPortRequestHandler(BaseHandler):
desc = split_desc[0] desc = split_desc[0]
data.append({'port': port, 'desc': desc}) data.append({'port': port, 'desc': desc})
data.append({'port': 'OTA', 'desc': 'Over-The-Air'}) data.append({'port': 'OTA', 'desc': 'Over-The-Air'})
self.write(json.dumps(sorted(data, reverse=True))) data.sort(key=lambda x: x['port'], reverse=True)
self.write(json.dumps(data))
class WizardRequestHandler(BaseHandler): class WizardRequestHandler(BaseHandler):
@ -390,7 +398,7 @@ class EditRequestHandler(BaseHandler):
self.set_status(401) self.set_status(401)
return return
with open(os.path.join(CONFIG_DIR, configuration), 'w') as f: with open(os.path.join(CONFIG_DIR, configuration), 'wb') as f:
f.write(self.request.body) f.write(self.request.body)
self.set_status(200) self.set_status(200)
return return

View file

@ -7,6 +7,7 @@ import time
from esphomeyaml.core import EsphomeyamlError from esphomeyaml.core import EsphomeyamlError
from esphomeyaml.helpers import resolve_ip_address, is_ip_address from esphomeyaml.helpers import resolve_ip_address, is_ip_address
from esphomeyaml.py_compat import IS_PY2
RESPONSE_OK = 0 RESPONSE_OK = 0
RESPONSE_REQUEST_AUTH = 1 RESPONSE_REQUEST_AUTH = 1
@ -125,10 +126,17 @@ def check_error(data, expect):
def send_check(sock, data, msg): def send_check(sock, data, msg):
try: try:
if isinstance(data, (list, tuple)): if IS_PY2:
data = ''.join([chr(x) for x in data]) if isinstance(data, (list, tuple)):
elif isinstance(data, int): data = ''.join([chr(x) for x in data])
data = chr(data) elif isinstance(data, int):
data = chr(data)
else:
if isinstance(data, (list, tuple)):
data = bytes(data)
elif isinstance(data, int):
data = bytes([data])
sock.sendall(data) sock.sendall(data)
except socket.error as err: except socket.error as err:
raise OTAError("Error sending {}: {}".format(msg, err)) raise OTAError("Error sending {}: {}".format(msg, err))

View file

@ -63,7 +63,7 @@ FLASH_SIZE_1_MB = 2**20
FLASH_SIZE_512_KB = FLASH_SIZE_1_MB // 2 FLASH_SIZE_512_KB = FLASH_SIZE_1_MB // 2
FLASH_SIZE_2_MB = 2 * FLASH_SIZE_1_MB FLASH_SIZE_2_MB = 2 * FLASH_SIZE_1_MB
FLASH_SIZE_4_MB = 4 * FLASH_SIZE_1_MB FLASH_SIZE_4_MB = 4 * FLASH_SIZE_1_MB
FLASH_SIZE_16_MB = 4 * FLASH_SIZE_1_MB FLASH_SIZE_16_MB = 16 * FLASH_SIZE_1_MB
ESP8266_FLASH_SIZES = { ESP8266_FLASH_SIZES = {
'd1': FLASH_SIZE_4_MB, 'd1': FLASH_SIZE_4_MB,

View file

@ -23,3 +23,24 @@ else:
string_types = (str,) string_types = (str,)
integer_types = (int,) integer_types = (int,)
binary_type = bytes binary_type = bytes
def byte(val):
if IS_PY2:
return chr(val)
else:
return bytes([val])
def char(val):
if IS_PY2:
return ord(val)
else:
return val
def format_bytes(val):
if IS_PY2:
return ' '.join('{:02X}'.format(ord(x)) for x in val)
else:
return ' '.join('{:02X}'.format(x) for x in val)