Skip to content

Commit

Permalink
Make compatible with python 3 (esphome#281)
Browse files Browse the repository at this point in the history
* Make compatible with python 3

* Update travis

* Env

* Fix typo

* Fix install correct platformio

* Lint

* Fix build flags

* Lint

* Upgrade pylint

* Lint
  • Loading branch information
OttoWinter authored Jan 2, 2019
1 parent 5db70be commit 22fd4ec
Show file tree
Hide file tree
Showing 39 changed files with 249 additions and 181 deletions.
32 changes: 21 additions & 11 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,20 +1,30 @@
sudo: false
language: python
python:
- "2.7"
jobs:

matrix:
fast_finish: true
include:
- name: "Lint"
install:
- pip install -r requirements.txt
- pip install flake8==3.5.0 pylint==1.9.3 tzlocal pillow
- python: "2.7"
env: TARGET=Lint2.7
install: pip install -e . && pip install flake8==3.6.0 pylint==1.9.4 tzlocal pillow
script:
- flake8 esphomeyaml
- pylint esphomeyaml
- name: "Test"
install:
- pip install -e .
- pip install tzlocal pillow
- python: "3.5.3"
env: TARGET=Lint3.5
install: pip install -U https://github.com/platformio/platformio-core/archive/develop.zip && pip install -e . && pip install flake8==3.6.0 pylint==2.2.2 tzlocal pillow
script:
- flake8 esphomeyaml
- pylint esphomeyaml
- python: "2.7"
env: TARGET=Test2.7
install: pip install -e . && pip install flake8==3.6.0 pylint==1.9.4 tzlocal pillow
script:
- esphomeyaml tests/test1.yaml compile
- esphomeyaml tests/test2.yaml compile
- python: "3.5.3"
env: TARGET=Test3.5
install: pip install -U https://github.com/platformio/platformio-core/archive/develop.zip && pip install -e . && pip install flake8==3.6.0 pylint==2.2.2 tzlocal pillow
script:
- esphomeyaml tests/test1.yaml compile
- esphomeyaml tests/test2.yaml compile
2 changes: 1 addition & 1 deletion docker/Dockerfile.lint
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ FROM python:2.7
COPY requirements.txt /requirements.txt

RUN pip install -r /requirements.txt && \
pip install flake8==3.5.0 pylint==1.9.3 tzlocal pillow
pip install flake8==3.6.0 pylint==1.9.4 tzlocal pillow
15 changes: 8 additions & 7 deletions esphomeyaml/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
from esphomeyaml.core import CORE, EsphomeyamlError
from esphomeyaml.cpp_generator import Expression, RawStatement, add, statement
from esphomeyaml.helpers import color, indent
from esphomeyaml.storage_json import StorageJSON, storage_path, start_update_check_thread, \
esphomeyaml_storage_path
from esphomeyaml.py_compat import safe_input, text_type
from esphomeyaml.storage_json import StorageJSON, esphomeyaml_storage_path, \
start_update_check_thread, storage_path
from esphomeyaml.util import run_external_command, safe_print

_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -50,7 +51,7 @@ def choose_prompt(options):
safe_print(u" [{}] {}".format(i + 1, desc))

while True:
opt = raw_input('(number): ')
opt = safe_input('(number): ')
if opt in options:
opt = options.index(opt)
break
Expand Down Expand Up @@ -140,7 +141,7 @@ def write_cpp(config):
if not config[CONF_ESPHOMEYAML][CONF_USE_CUSTOM_CODE]:
if isinstance(exp, Expression) and not exp.required:
continue
all_code.append(unicode(statement(exp)))
all_code.append(text_type(statement(exp)))

writer.write_platformio_project()

Expand Down Expand Up @@ -199,7 +200,7 @@ def upload_program(config, args, host):
if storage is not None and not storage.use_legacy_ota:
return res

_LOGGER.warn("OTA v2 method failed. Trying with legacy OTA...")
_LOGGER.warning("OTA v2 method failed. Trying with legacy OTA...")
return espota2.run_legacy_ota(verbose, host_port, host, remote_port, password,
CORE.firmware_bin)

Expand All @@ -208,9 +209,9 @@ def show_logs(config, args, port):
if get_port_type(port) == 'SERIAL':
run_miniterm(config, port)
return 0
elif get_port_type(port) == 'NETWORK':
if get_port_type(port) == 'NETWORK':
return run_logs(config, port)
elif get_port_type(port) == 'MQTT':
if get_port_type(port) == 'MQTT':
return mqtt.show_logs(config, args.topic, args.username, args.password, args.client_id)

raise ValueError
Expand Down
13 changes: 8 additions & 5 deletions esphomeyaml/api/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from esphomeyaml.const import CONF_PASSWORD, CONF_PORT
from esphomeyaml.core import EsphomeyamlError
from esphomeyaml.helpers import resolve_ip_address, indent, color
from esphomeyaml.py_compat import text_type
from esphomeyaml.util import safe_print

_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -254,14 +255,14 @@ def _write(self, data): # type: (bytes) -> None

def _send_message(self, msg):
# type: (message.Message) -> None
for message_type, klass in MESSAGE_TYPE_TO_PROTO.iteritems():
for message_type, klass in MESSAGE_TYPE_TO_PROTO.items():
if isinstance(msg, klass):
break
else:
raise ValueError

encoded = msg.SerializeToString()
_LOGGER.debug("Sending %s:\n%s", type(msg), indent(unicode(msg)))
_LOGGER.debug("Sending %s:\n%s", type(msg), indent(text_type(msg)))
req = chr(0x00)
req += _varuint_to_bytes(len(encoded))
req += _varuint_to_bytes(message_type)
Expand Down Expand Up @@ -435,12 +436,14 @@ def try_connect(tries=0, is_disconnect=True):
while retry_timer:
retry_timer.pop(0).cancel()

error = None
try:
cli.connect()
cli.login()
except APIConnectionError as error:
pass
else:
except APIConnectionError as err: # noqa
error = err

if error is None:
_LOGGER.info("Successfully connected to %s", address)
return

Expand Down
4 changes: 2 additions & 2 deletions esphomeyaml/automation.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def validate_recursive_condition(value):
raise vol.Invalid(u"Unable to find condition with the name '{}', is the "
u"component loaded?".format(key), path + [key])
item.setdefault(CONF_CONDITION_ID, None)
key2 = next((x for x in item if x != CONF_CONDITION_ID and x != key), None)
key2 = next((x for x in item if x not in (CONF_CONDITION_ID, key)), None)
if key2 is not None:
raise vol.Invalid(u"Cannot have two conditions in one item. Key '{}' overrides '{}'! "
u"Did you forget to indent the block inside the condition?"
Expand Down Expand Up @@ -76,7 +76,7 @@ def validate_recursive_action(value):
raise vol.Invalid(u"Unable to find action with the name '{}', is the component loaded?"
u"".format(key), path + [key])
item.setdefault(CONF_ACTION_ID, None)
key2 = next((x for x in item if x != CONF_ACTION_ID and x != key), None)
key2 = next((x for x in item if x not in (CONF_ACTION_ID, key)), None)
if key2 is not None:
raise vol.Invalid(u"Cannot have two actions in one item. Key '{}' overrides '{}'! "
u"Did you forget to indent the block inside the action?"
Expand Down
2 changes: 1 addition & 1 deletion esphomeyaml/components/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def to_code(config):
def lib_deps(config):
if CORE.is_esp32:
return '[email protected]'
elif CORE.is_esp8266:
if CORE.is_esp8266:
return '[email protected]'
raise NotImplementedError

Expand Down
3 changes: 2 additions & 1 deletion esphomeyaml/components/binary_sensor/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from esphomeyaml.cpp_generator import process_lambda, ArrayInitializer, add, Pvariable, \
StructInitializer, get_variable
from esphomeyaml.cpp_types import esphomelib_ns, Nameable, Trigger, NoArg, Component, App, bool_
from esphomeyaml.py_compat import string_types

DEVICE_CLASSES = [
'', 'battery', 'cold', 'connectivity', 'door', 'garage_door', 'gas',
Expand Down Expand Up @@ -70,7 +71,7 @@


def parse_multi_click_timing_str(value):
if not isinstance(value, basestring):
if not isinstance(value, string_types):
return value

parts = value.lower().split(' ')
Expand Down
24 changes: 12 additions & 12 deletions esphomeyaml/components/binary_sensor/remote_receiver.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,40 +73,40 @@ def receiver_base(full_config):
key, config = next((k, v) for k, v in full_config.items() if k in REMOTE_KEYS)
if key == CONF_LG:
return LGReceiver.new(name, config[CONF_DATA], config[CONF_NBITS])
elif key == CONF_NEC:
if key == CONF_NEC:
return NECReceiver.new(name, config[CONF_ADDRESS], config[CONF_COMMAND])
elif key == CONF_PANASONIC:
if key == CONF_PANASONIC:
return PanasonicReceiver.new(name, config[CONF_ADDRESS], config[CONF_COMMAND])
elif key == CONF_SAMSUNG:
if key == CONF_SAMSUNG:
return SamsungReceiver.new(name, config[CONF_DATA])
elif key == CONF_SONY:
if key == CONF_SONY:
return SonyReceiver.new(name, config[CONF_DATA], config[CONF_NBITS])
elif key == CONF_RAW:
if key == CONF_RAW:
data = ArrayInitializer(*config, multiline=False)
return RawReceiver.new(name, data)
elif key == CONF_RC_SWITCH_RAW:
if key == CONF_RC_SWITCH_RAW:
return RCSwitchRawReceiver.new(name, build_rc_switch_protocol(config[CONF_PROTOCOL]),
binary_code(config[CONF_CODE]), len(config[CONF_CODE]))
elif key == CONF_RC_SWITCH_TYPE_A:
if key == CONF_RC_SWITCH_TYPE_A:
return RCSwitchTypeAReceiver.new(name, build_rc_switch_protocol(config[CONF_PROTOCOL]),
binary_code(config[CONF_GROUP]),
binary_code(config[CONF_DEVICE]),
config[CONF_STATE])
elif key == CONF_RC_SWITCH_TYPE_B:
if key == CONF_RC_SWITCH_TYPE_B:
return RCSwitchTypeBReceiver.new(name, build_rc_switch_protocol(config[CONF_PROTOCOL]),
config[CONF_ADDRESS], config[CONF_CHANNEL],
config[CONF_STATE])
elif key == CONF_RC_SWITCH_TYPE_C:
if key == CONF_RC_SWITCH_TYPE_C:
return RCSwitchTypeCReceiver.new(name, build_rc_switch_protocol(config[CONF_PROTOCOL]),
ord(config[CONF_FAMILY][0]) - ord('a'),
config[CONF_GROUP], config[CONF_DEVICE],
config[CONF_STATE])
elif key == CONF_RC_SWITCH_TYPE_D:
if key == CONF_RC_SWITCH_TYPE_D:
return RCSwitchTypeDReceiver.new(name, build_rc_switch_protocol(config[CONF_PROTOCOL]),
ord(config[CONF_GROUP][0]) - ord('a'),
config[CONF_DEVICE], config[CONF_STATE])
else:
raise NotImplementedError("Unknown receiver type {}".format(config))

raise NotImplementedError("Unknown receiver type {}".format(config))


def to_code(config):
Expand Down
9 changes: 4 additions & 5 deletions esphomeyaml/components/font.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,9 @@ def comparator(x, y):

if len(x_) < len(y_):
return -1
elif len(x_) > len(y_):
if len(x_) > len(y_):
return 1
else:
raise vol.Invalid(u"Found duplicate glyph {}".format(x))
raise vol.Invalid(u"Found duplicate glyph {}".format(x))

value.sort(cmp=comparator)
return value
Expand All @@ -47,11 +46,11 @@ def validate_pillow_installed(value):
import PIL
except ImportError:
raise vol.Invalid("Please install the pillow python package to use this feature. "
"(pip2 install pillow)")
"(pip install pillow)")

if PIL.__version__[0] < '4':
raise vol.Invalid("Please update your pillow installation to at least 4.0.x. "
"(pip2 install -U pillow)")
"(pip install -U pillow)")

return value

Expand Down
12 changes: 7 additions & 5 deletions esphomeyaml/components/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
from esphomeyaml.cpp_generator import Pvariable, RawExpression, add, process_lambda, statement
from esphomeyaml.cpp_types import App, Component, esphomelib_ns, global_ns

from esphomeyaml.py_compat import text_type

LOG_LEVELS = {
'NONE': global_ns.ESPHOMELIB_LOG_LEVEL_NONE,
'ERROR': global_ns.ESPHOMELIB_LOG_LEVEL_ERROR,
Expand Down Expand Up @@ -37,7 +39,7 @@

def validate_local_no_higher_than_global(value):
global_level = value.get(CONF_LEVEL, 'DEBUG')
for tag, level in value.get(CONF_LOGS, {}).iteritems():
for tag, level in value.get(CONF_LOGS, {}).items():
if LOG_LEVEL_SEVERITY.index(level) > LOG_LEVEL_SEVERITY.index(global_level):
raise EsphomeyamlError(u"The local log level {} for {} must be less severe than the "
u"global log level {}.".format(level, tag, global_level))
Expand All @@ -64,7 +66,7 @@ def to_code(config):
add(log.set_tx_buffer_size(config[CONF_TX_BUFFER_SIZE]))
if CONF_LEVEL in config:
add(log.set_global_log_level(LOG_LEVELS[config[CONF_LEVEL]]))
for tag, level in config.get(CONF_LOGS, {}).iteritems():
for tag, level in config.get(CONF_LOGS, {}).items():
add(log.set_log_level(tag, LOG_LEVELS[level]))


Expand Down Expand Up @@ -120,7 +122,7 @@ def validate_printf(value):
[cCdiouxXeEfgGaAnpsSZ] # type
) | # OR
%%) # literal "%%"
"""
""" # noqa
matches = re.findall(cfmt, value[CONF_FORMAT], flags=re.X)
if len(matches) != len(value[CONF_ARGS]):
raise vol.Invalid(u"Found {} printf-patterns ({}), but {} args were given!"
Expand All @@ -140,9 +142,9 @@ def validate_printf(value):
@ACTION_REGISTRY.register(CONF_LOGGER_LOG, LOGGER_LOG_ACTION_SCHEMA)
def logger_log_action_to_code(config, action_id, arg_type, template_arg):
esp_log = LOG_LEVEL_TO_ESP_LOG[config[CONF_LEVEL]]
args = [RawExpression(unicode(x)) for x in config[CONF_ARGS]]
args = [RawExpression(text_type(x)) for x in config[CONF_ARGS]]

text = unicode(statement(esp_log(config[CONF_TAG], config[CONF_FORMAT], *args)))
text = text_type(statement(esp_log(config[CONF_TAG], config[CONF_FORMAT], *args)))

for lambda_ in process_lambda(Lambda(text), [(arg_type, 'x')]):
yield None
Expand Down
4 changes: 2 additions & 2 deletions esphomeyaml/components/ota.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def get_port(config):
return config[CONF_OTA][CONF_PORT]
if CORE.is_esp32:
return 3232
elif CORE.is_esp8266:
if CORE.is_esp8266:
return 8266
raise NotImplementedError

Expand All @@ -52,6 +52,6 @@ def get_auth(config):
def lib_deps(config):
if CORE.is_esp32:
return ['Update', 'ESPmDNS']
elif CORE.is_esp8266:
if CORE.is_esp8266:
return ['Hash', 'ESP8266mDNS']
raise NotImplementedError
2 changes: 1 addition & 1 deletion esphomeyaml/components/output/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def validate_custom_output(value):
value[CONF_TYPE] = type
if type == 'binary':
return BINARY_SCHEMA(value)
elif type == 'float':
if type == 'float':
return FLOAT_SCHEMA(value)
raise vol.Invalid("type must either be binary or float, not {}!".format(type))

Expand Down
3 changes: 2 additions & 1 deletion esphomeyaml/components/remote_receiver.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from esphomeyaml.cpp_generator import Pvariable, add
from esphomeyaml.cpp_helpers import gpio_input_pin_expression, setup_component
from esphomeyaml.cpp_types import App, Component, esphomelib_ns
from esphomeyaml.py_compat import string_types

remote_ns = esphomelib_ns.namespace('remote')
MULTI_CONF = True
Expand All @@ -30,7 +31,7 @@


def validate_dumpers_all(value):
if not isinstance(value, (str, unicode)):
if not isinstance(value, string_types):
raise vol.Invalid("Not valid dumpers")
if value.upper() == "ALL":
return list(sorted(list(DUMPERS)))
Expand Down
3 changes: 2 additions & 1 deletion esphomeyaml/components/remote_transmitter.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from esphomeyaml.cpp_generator import Pvariable, add
from esphomeyaml.cpp_helpers import gpio_output_pin_expression, setup_component
from esphomeyaml.cpp_types import App, Component
from esphomeyaml.py_compat import text_type

RemoteTransmitterComponent = remote_ns.class_('RemoteTransmitterComponent',
RemoteControlComponentBase, Component)
Expand All @@ -20,7 +21,7 @@


def validate_rc_switch_code(value):
if not isinstance(value, (str, unicode)):
if not isinstance(value, (str, text_type)):
raise vol.Invalid("All RCSwitch codes must be in quotes ('')")
for c in value:
if c not in ('0', '1'):
Expand Down
3 changes: 2 additions & 1 deletion esphomeyaml/components/sensor/ads1115.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from esphomeyaml.const import CONF_ADS1115_ID, CONF_GAIN, CONF_MULTIPLEXER, CONF_NAME, \
CONF_UPDATE_INTERVAL
from esphomeyaml.cpp_generator import get_variable
from esphomeyaml.py_compat import string_types

DEPENDENCIES = ['ads1115']

Expand Down Expand Up @@ -35,7 +36,7 @@
def validate_gain(value):
if isinstance(value, float):
value = u'{:0.03f}'.format(value)
elif not isinstance(value, (str, unicode)):
elif not isinstance(value, string_types):
raise vol.Invalid('invalid gain "{}"'.format(value))

return cv.one_of(*GAIN)(value)
Expand Down
2 changes: 1 addition & 1 deletion esphomeyaml/components/sensor/pmsx003.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@


def validate_pmsx003_sensors(value):
for key, types in SENSORS_TO_TYPE.iteritems():
for key, types in SENSORS_TO_TYPE.items():
if key in value and value[CONF_TYPE] not in types:
raise vol.Invalid(u"{} does not have {} sensor!".format(value[CONF_TYPE], key))
return value
Expand Down
Loading

0 comments on commit 22fd4ec

Please sign in to comment.