From d3afc25e5b87f407b3279606681569469955b6de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20RAMAGE?= Date: Wed, 13 Sep 2017 20:31:37 +0200 Subject: [PATCH 01/11] add datetime and support for unpacksequence add datetime to builtin and support for unpacksequence a,b = (1,2) for a,b in [(1,2),(3,4)] --- homeassistant/components/python_script.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/python_script.py b/homeassistant/components/python_script.py index 386abba59aed2..f80dea839443d 100644 --- a/homeassistant/components/python_script.py +++ b/homeassistant/components/python_script.py @@ -2,6 +2,7 @@ import glob import os import logging +import datetime import voluptuous as vol @@ -63,7 +64,8 @@ def execute_script(hass, name, data=None): def execute(hass, filename, source, data=None): """Execute Python source.""" from RestrictedPython import compile_restricted_exec - from RestrictedPython.Guards import safe_builtins, full_write_guard + from RestrictedPython.Guards import safe_builtins, full_write_guard, \ + guarded_iter_unpack_sequence, guarded_unpack_sequence from RestrictedPython.Utilities import utility_builtins from RestrictedPython.Eval import default_guarded_getitem @@ -94,13 +96,16 @@ def protected_getattr(obj, name, default=None): builtins = safe_builtins.copy() builtins.update(utility_builtins) + builtins['datetime'] = datetime restricted_globals = { '__builtins__': builtins, '_print_': StubPrinter, '_getattr_': protected_getattr, '_write_': full_write_guard, '_getiter_': iter, - '_getitem_': default_guarded_getitem + '_getitem_': default_guarded_getitem, + '_iter_unpack_sequence_': guarded_iter_unpack_sequence, + '_unpack_sequence_': guarded_unpack_sequence, } logger = logging.getLogger('{}.{}'.format(__name__, filename)) local = { From 61f72f36bb13cba8e3c43c211aecc8281cf25688 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20RAMAGE?= Date: Wed, 13 Sep 2017 20:37:17 +0200 Subject: [PATCH 02/11] add test for python_script --- tests/components/test_python_script.py | 237 ++++++------------------- 1 file changed, 56 insertions(+), 181 deletions(-) diff --git a/tests/components/test_python_script.py b/tests/components/test_python_script.py index 62c1b67eba994..1f8705539a506 100644 --- a/tests/components/test_python_script.py +++ b/tests/components/test_python_script.py @@ -1,182 +1,57 @@ -"""Test the python_script component.""" -import asyncio -import logging -from unittest.mock import patch, mock_open +"""The tests for the Python Script component.""" +# pylint: disable=protected-access +import unittest + +from homeassistant.core import callback +from homeassistant.bootstrap import setup_component +from homeassistant.components import python_script + +from tests.common import get_test_home_assistant + + +ENTITY_ID = 'python_script.test' + + +class TestPythonScriptComponent(unittest.TestCase): + """Test the Script component.""" + + # pylint: disable=invalid-name + def setUp(self): + """Setup things to be run when tests are started.""" + self.hass = get_test_home_assistant() + self.hass.config.components.append('group') + + # pylint: disable=invalid-name + def tearDown(self): + """Stop down everything that was started.""" + self.hass.stop() + + def test_datetime(self): + pass + + def test_unpack_sequence(self): + calls = [] + @callback + def record_call(service): + """Add recorded event to set.""" + calls.append(service) + + self.hass.services.register('test', 'python_script', record_call) + assert setup_component(self.hass, 'python_script', { + 'python_script': { + }, + }) + source = ''' + + a,b = (1,2) + ab_list = [(a,b) for a,b in [(1,2),(3,4)]] + data['a'] = a + data['b'] = b + data['ab_list'] = ab_list + ''' + data = {} + python_script.execute(self.hass, 'dummy.py', source, data) + assert data['a'] == 1 + assert data['b'] == 2 + assert data['ab_list'] == [(1,2),(3,4)] -from homeassistant.setup import async_setup_component -from homeassistant.components.python_script import execute - - -@asyncio.coroutine -def test_setup(hass): - """Test we can discover scripts.""" - scripts = [ - '/some/config/dir/python_scripts/hello.py', - '/some/config/dir/python_scripts/world_beer.py' - ] - with patch('homeassistant.components.python_script.os.path.isdir', - return_value=True), \ - patch('homeassistant.components.python_script.glob.iglob', - return_value=scripts): - res = yield from async_setup_component(hass, 'python_script', {}) - - assert res - assert hass.services.has_service('python_script', 'hello') - assert hass.services.has_service('python_script', 'world_beer') - - with patch('homeassistant.components.python_script.open', - mock_open(read_data='fake source'), create=True), \ - patch('homeassistant.components.python_script.execute') as mock_ex: - yield from hass.services.async_call( - 'python_script', 'hello', {'some': 'data'}, blocking=True) - - assert len(mock_ex.mock_calls) == 1 - hass, script, source, data = mock_ex.mock_calls[0][1] - - assert hass is hass - assert script == 'hello.py' - assert source == 'fake source' - assert data == {'some': 'data'} - - -@asyncio.coroutine -def test_setup_fails_on_no_dir(hass, caplog): - """Test we fail setup when no dir found.""" - with patch('homeassistant.components.python_script.os.path.isdir', - return_value=False): - res = yield from async_setup_component(hass, 'python_script', {}) - - assert not res - assert 'Folder python_scripts not found in config folder' in caplog.text - - -@asyncio.coroutine -def test_execute_with_data(hass, caplog): - """Test executing a script.""" - caplog.set_level(logging.WARNING) - source = """ -hass.states.set('test.entity', data.get('name', 'not set')) - """ - - hass.async_add_job(execute, hass, 'test.py', source, {'name': 'paulus'}) - yield from hass.async_block_till_done() - - assert hass.states.is_state('test.entity', 'paulus') - - # No errors logged = good - assert caplog.text == '' - - -@asyncio.coroutine -def test_execute_warns_print(hass, caplog): - """Test print triggers warning.""" - caplog.set_level(logging.WARNING) - source = """ -print("This triggers warning.") - """ - - hass.async_add_job(execute, hass, 'test.py', source, {}) - yield from hass.async_block_till_done() - - assert "Don't use print() inside scripts." in caplog.text - - -@asyncio.coroutine -def test_execute_logging(hass, caplog): - """Test logging works.""" - caplog.set_level(logging.INFO) - source = """ -logger.info('Logging from inside script') - """ - - hass.async_add_job(execute, hass, 'test.py', source, {}) - yield from hass.async_block_till_done() - - assert "Logging from inside script" in caplog.text - - -@asyncio.coroutine -def test_execute_compile_error(hass, caplog): - """Test compile error logs error.""" - caplog.set_level(logging.ERROR) - source = """ -this is not valid Python - """ - - hass.async_add_job(execute, hass, 'test.py', source, {}) - yield from hass.async_block_till_done() - - assert "Error loading script test.py" in caplog.text - - -@asyncio.coroutine -def test_execute_runtime_error(hass, caplog): - """Test compile error logs error.""" - caplog.set_level(logging.ERROR) - source = """ -raise Exception('boom') - """ - - hass.async_add_job(execute, hass, 'test.py', source, {}) - yield from hass.async_block_till_done() - - assert "Error executing script: boom" in caplog.text - - -@asyncio.coroutine -def test_accessing_async_methods(hass, caplog): - """Test compile error logs error.""" - caplog.set_level(logging.ERROR) - source = """ -hass.async_stop() - """ - - hass.async_add_job(execute, hass, 'test.py', source, {}) - yield from hass.async_block_till_done() - - assert "Not allowed to access async methods" in caplog.text - - -@asyncio.coroutine -def test_using_complex_structures(hass, caplog): - """Test that dicts and lists work.""" - caplog.set_level(logging.INFO) - source = """ -mydict = {"a": 1, "b": 2} -mylist = [1, 2, 3, 4] -logger.info('Logging from inside script: %s %s' % (mydict["a"], mylist[2])) - """ - - hass.async_add_job(execute, hass, 'test.py', source, {}) - yield from hass.async_block_till_done() - - assert "Logging from inside script: 1 3" in caplog.text - - -@asyncio.coroutine -def test_accessing_forbidden_methods(hass, caplog): - """Test compile error logs error.""" - caplog.set_level(logging.ERROR) - source = """ -hass.stop() - """ - - hass.async_add_job(execute, hass, 'test.py', source, {}) - yield from hass.async_block_till_done() - - assert "Not allowed to access HomeAssistant.stop" in caplog.text - - -@asyncio.coroutine -def test_iterating(hass): - """Test compile error logs error.""" - source = """ -for i in [1, 2]: - hass.states.set('hello.{}'.format(i), 'world') - """ - - hass.async_add_job(execute, hass, 'test.py', source, {}) - yield from hass.async_block_till_done() - - assert hass.states.is_state('hello.1', 'world') - assert hass.states.is_state('hello.2', 'world') From 4bca6a3fa3dfef6eae6bbfc4ea1554adca2a4491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20RAMAGE?= Date: Wed, 13 Sep 2017 20:39:44 +0200 Subject: [PATCH 03/11] fix test --- tests/components/test_python_script.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/components/test_python_script.py b/tests/components/test_python_script.py index 1f8705539a506..19abbe7900a70 100644 --- a/tests/components/test_python_script.py +++ b/tests/components/test_python_script.py @@ -42,12 +42,11 @@ def record_call(service): }, }) source = ''' - - a,b = (1,2) - ab_list = [(a,b) for a,b in [(1,2),(3,4)]] - data['a'] = a - data['b'] = b - data['ab_list'] = ab_list +a,b = (1,2) +ab_list = [(a,b) for a,b in [(1,2),(3,4)]] +data['a'] = a +data['b'] = b +data['ab_list'] = ab_list ''' data = {} python_script.execute(self.hass, 'dummy.py', source, data) From 77f4a0ce8d7b921e096f22760ce636b9bd0a3cfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20RAMAGE?= Date: Thu, 14 Sep 2017 08:37:49 +0200 Subject: [PATCH 04/11] restore previous test restore previous tests, removed by mistake sorry... --- tests/components/test_python_script.py | 248 ++++++++++++++++++++----- 1 file changed, 198 insertions(+), 50 deletions(-) diff --git a/tests/components/test_python_script.py b/tests/components/test_python_script.py index 19abbe7900a70..41d2a9e475505 100644 --- a/tests/components/test_python_script.py +++ b/tests/components/test_python_script.py @@ -1,56 +1,204 @@ -"""The tests for the Python Script component.""" -# pylint: disable=protected-access -import unittest - -from homeassistant.core import callback -from homeassistant.bootstrap import setup_component -from homeassistant.components import python_script - -from tests.common import get_test_home_assistant - - -ENTITY_ID = 'python_script.test' - - -class TestPythonScriptComponent(unittest.TestCase): - """Test the Script component.""" - - # pylint: disable=invalid-name - def setUp(self): - """Setup things to be run when tests are started.""" - self.hass = get_test_home_assistant() - self.hass.config.components.append('group') - - # pylint: disable=invalid-name - def tearDown(self): - """Stop down everything that was started.""" - self.hass.stop() - - def test_datetime(self): - pass - - def test_unpack_sequence(self): - calls = [] - @callback - def record_call(service): - """Add recorded event to set.""" - calls.append(service) - - self.hass.services.register('test', 'python_script', record_call) - assert setup_component(self.hass, 'python_script', { - 'python_script': { - }, - }) - source = ''' +"""Test the python_script component.""" +import asyncio +import logging +from unittest.mock import patch, mock_open + +from homeassistant.setup import async_setup_component +from homeassistant.components.python_script import execute + + +@asyncio.coroutine +def test_setup(hass): + """Test we can discover scripts.""" + scripts = [ + '/some/config/dir/python_scripts/hello.py', + '/some/config/dir/python_scripts/world_beer.py' + ] + with patch('homeassistant.components.python_script.os.path.isdir', + return_value=True), \ + patch('homeassistant.components.python_script.glob.iglob', + return_value=scripts): + res = yield from async_setup_component(hass, 'python_script', {}) + + assert res + assert hass.services.has_service('python_script', 'hello') + assert hass.services.has_service('python_script', 'world_beer') + + with patch('homeassistant.components.python_script.open', + mock_open(read_data='fake source'), create=True), \ + patch('homeassistant.components.python_script.execute') as mock_ex: + yield from hass.services.async_call( + 'python_script', 'hello', {'some': 'data'}, blocking=True) + + assert len(mock_ex.mock_calls) == 1 + hass, script, source, data = mock_ex.mock_calls[0][1] + + assert hass is hass + assert script == 'hello.py' + assert source == 'fake source' + assert data == {'some': 'data'} + + +@asyncio.coroutine +def test_setup_fails_on_no_dir(hass, caplog): + """Test we fail setup when no dir found.""" + with patch('homeassistant.components.python_script.os.path.isdir', + return_value=False): + res = yield from async_setup_component(hass, 'python_script', {}) + + assert not res + assert 'Folder python_scripts not found in config folder' in caplog.text + + +@asyncio.coroutine +def test_execute_with_data(hass, caplog): + """Test executing a script.""" + caplog.set_level(logging.WARNING) + source = """ +hass.states.set('test.entity', data.get('name', 'not set')) + """ + + hass.async_add_job(execute, hass, 'test.py', source, {'name': 'paulus'}) + yield from hass.async_block_till_done() + + assert hass.states.is_state('test.entity', 'paulus') + + # No errors logged = good + assert caplog.text == '' + + +@asyncio.coroutine +def test_execute_warns_print(hass, caplog): + """Test print triggers warning.""" + caplog.set_level(logging.WARNING) + source = """ +print("This triggers warning.") + """ + + hass.async_add_job(execute, hass, 'test.py', source, {}) + yield from hass.async_block_till_done() + + assert "Don't use print() inside scripts." in caplog.text + + +@asyncio.coroutine +def test_execute_logging(hass, caplog): + """Test logging works.""" + caplog.set_level(logging.INFO) + source = """ +logger.info('Logging from inside script') + """ + + hass.async_add_job(execute, hass, 'test.py', source, {}) + yield from hass.async_block_till_done() + + assert "Logging from inside script" in caplog.text + + +@asyncio.coroutine +def test_execute_compile_error(hass, caplog): + """Test compile error logs error.""" + caplog.set_level(logging.ERROR) + source = """ +this is not valid Python + """ + + hass.async_add_job(execute, hass, 'test.py', source, {}) + yield from hass.async_block_till_done() + + assert "Error loading script test.py" in caplog.text + + +@asyncio.coroutine +def test_execute_runtime_error(hass, caplog): + """Test compile error logs error.""" + caplog.set_level(logging.ERROR) + source = """ +raise Exception('boom') + """ + + hass.async_add_job(execute, hass, 'test.py', source, {}) + yield from hass.async_block_till_done() + + assert "Error executing script: boom" in caplog.text + + +@asyncio.coroutine +def test_accessing_async_methods(hass, caplog): + """Test compile error logs error.""" + caplog.set_level(logging.ERROR) + source = """ +hass.async_stop() + """ + + hass.async_add_job(execute, hass, 'test.py', source, {}) + yield from hass.async_block_till_done() + + assert "Not allowed to access async methods" in caplog.text + + +@asyncio.coroutine +def test_using_complex_structures(hass, caplog): + """Test that dicts and lists work.""" + caplog.set_level(logging.INFO) + source = """ +mydict = {"a": 1, "b": 2} +mylist = [1, 2, 3, 4] +logger.info('Logging from inside script: %s %s' % (mydict["a"], mylist[2])) + """ + + hass.async_add_job(execute, hass, 'test.py', source, {}) + yield from hass.async_block_till_done() + + assert "Logging from inside script: 1 3" in caplog.text + + +@asyncio.coroutine +def test_accessing_forbidden_methods(hass, caplog): + """Test compile error logs error.""" + caplog.set_level(logging.ERROR) + source = """ +hass.stop() + """ + + hass.async_add_job(execute, hass, 'test.py', source, {}) + yield from hass.async_block_till_done() + + assert "Not allowed to access HomeAssistant.stop" in caplog.text + + +@asyncio.coroutine +def test_iterating(hass): + """Test compile error logs error.""" + source = """ +for i in [1, 2]: + hass.states.set('hello.{}'.format(i), 'world') + """ + + hass.async_add_job(execute, hass, 'test.py', source, {}) + yield from hass.async_block_till_done() + + assert hass.states.is_state('hello.1', 'world') + assert hass.states.is_state('hello.2', 'world') + +@asyncio.coroutine +def test_unpacking_sequence(hass): + """Test compile error logs error.""" + source = """ a,b = (1,2) ab_list = [(a,b) for a,b in [(1,2),(3,4)]] data['a'] = a data['b'] = b data['ab_list'] = ab_list - ''' - data = {} - python_script.execute(self.hass, 'dummy.py', source, data) - assert data['a'] == 1 - assert data['b'] == 2 - assert data['ab_list'] == [(1,2),(3,4)] +for i in [1, 2]: + hass.states.set('hello.{}'.format(i), 'world') + """ + + data = {} + hass.async_add_job(execute, hass, 'test.py', source, data) + yield from hass.async_block_till_done() + + assert data['a'] == 1 + assert data['b'] == 2 + assert data['ab_list'] == [(1,2),(3,4)] From 989f01946f661779b25aa84bf721a02ea05b77c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20RAMAGE?= Date: Thu, 14 Sep 2017 08:47:44 +0200 Subject: [PATCH 05/11] fix test --- tests/components/test_python_script.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/components/test_python_script.py b/tests/components/test_python_script.py index 41d2a9e475505..80e81341be6ae 100644 --- a/tests/components/test_python_script.py +++ b/tests/components/test_python_script.py @@ -180,18 +180,17 @@ def test_iterating(hass): assert hass.states.is_state('hello.1', 'world') assert hass.states.is_state('hello.2', 'world') - + + @asyncio.coroutine def test_unpacking_sequence(hass): """Test compile error logs error.""" source = """ a,b = (1,2) -ab_list = [(a,b) for a,b in [(1,2),(3,4)]] +ab_list = [(a,b) for a,b in [(1,2), (3,4)]] data['a'] = a data['b'] = b data['ab_list'] = ab_list -for i in [1, 2]: - hass.states.set('hello.{}'.format(i), 'world') """ data = {} From 4cf17706c5e8b5b9806dba1e6882c7ef8a5688c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20RAMAGE?= Date: Thu, 14 Sep 2017 08:48:42 +0200 Subject: [PATCH 06/11] Update test_python_script.py --- tests/components/test_python_script.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/components/test_python_script.py b/tests/components/test_python_script.py index 80e81341be6ae..f257b17c42a18 100644 --- a/tests/components/test_python_script.py +++ b/tests/components/test_python_script.py @@ -191,7 +191,7 @@ def test_unpacking_sequence(hass): data['a'] = a data['b'] = b data['ab_list'] = ab_list - """ +""" data = {} hass.async_add_job(execute, hass, 'test.py', source, data) From c18f3d6db1afb6850d5fd7b4a3375d52d1d43602 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20RAMAGE?= Date: Thu, 14 Sep 2017 12:58:09 +0200 Subject: [PATCH 07/11] fix travis --- tests/components/test_python_script.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/components/test_python_script.py b/tests/components/test_python_script.py index f257b17c42a18..1eee5a9d428b8 100644 --- a/tests/components/test_python_script.py +++ b/tests/components/test_python_script.py @@ -187,17 +187,16 @@ def test_unpacking_sequence(hass): """Test compile error logs error.""" source = """ a,b = (1,2) -ab_list = [(a,b) for a,b in [(1,2), (3,4)]] +ab_list = [(a,b) for a,b in [(1, 2), (3, 4)]] data['a'] = a data['b'] = b data['ab_list'] = ab_list """ - + data = {} hass.async_add_job(execute, hass, 'test.py', source, data) yield from hass.async_block_till_done() - + assert data['a'] == 1 assert data['b'] == 2 - assert data['ab_list'] == [(1,2),(3,4)] - + assert data['ab_list'] == [(1, 2), (3, 4)] From 2141cf67a771e924171aaba32679e59c3e157303 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20RAMAGE?= Date: Thu, 14 Sep 2017 13:35:46 +0200 Subject: [PATCH 08/11] fix test --- tests/components/test_python_script.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/tests/components/test_python_script.py b/tests/components/test_python_script.py index 1eee5a9d428b8..396f85f4fe9d2 100644 --- a/tests/components/test_python_script.py +++ b/tests/components/test_python_script.py @@ -183,20 +183,24 @@ def test_iterating(hass): @asyncio.coroutine -def test_unpacking_sequence(hass): +def test_unpacking_sequence(hass, caplog): """Test compile error logs error.""" + caplog.set_level(logging.ERROR) source = """ a,b = (1,2) ab_list = [(a,b) for a,b in [(1, 2), (3, 4)]] -data['a'] = a -data['b'] = b -data['ab_list'] = ab_list +hass.states.set('a', a) +hass.states.set('b', b) +hass.states.set('ab_list', '{}'.format(ab_list)) """ data = {} hass.async_add_job(execute, hass, 'test.py', source, data) yield from hass.async_block_till_done() - assert data['a'] == 1 - assert data['b'] == 2 - assert data['ab_list'] == [(1, 2), (3, 4)] + assert hass.states.is_state('a', 1) + assert hass.states.is_state('b', 2) + assert hass.states.is_state('ab_list', '[(1, 2), (3, 4)]') + + # No errors logged = good + assert caplog.text == '' From dde736cb12e58e5be46d9a38d725822ab22f96ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20RAMAGE?= Date: Thu, 14 Sep 2017 13:40:00 +0200 Subject: [PATCH 09/11] Update test_python_script.py --- tests/components/test_python_script.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/components/test_python_script.py b/tests/components/test_python_script.py index 396f85f4fe9d2..282e7c39d332b 100644 --- a/tests/components/test_python_script.py +++ b/tests/components/test_python_script.py @@ -201,6 +201,6 @@ def test_unpacking_sequence(hass, caplog): assert hass.states.is_state('a', 1) assert hass.states.is_state('b', 2) assert hass.states.is_state('ab_list', '[(1, 2), (3, 4)]') - + # No errors logged = good assert caplog.text == '' From 00686396fb86e67b80f758f0f9c516a9b27610f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20RAMAGE?= Date: Thu, 14 Sep 2017 13:55:22 +0200 Subject: [PATCH 10/11] Add files via upload --- tests/components/test_python_script.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/tests/components/test_python_script.py b/tests/components/test_python_script.py index 282e7c39d332b..993d568f92308 100644 --- a/tests/components/test_python_script.py +++ b/tests/components/test_python_script.py @@ -189,18 +189,17 @@ def test_unpacking_sequence(hass, caplog): source = """ a,b = (1,2) ab_list = [(a,b) for a,b in [(1, 2), (3, 4)]] -hass.states.set('a', a) -hass.states.set('b', b) -hass.states.set('ab_list', '{}'.format(ab_list)) +hass.states.set('hello.a', a) +hass.states.set('hello.b', b) +hass.states.set('hello.ab_list', '{}'.format(ab_list)) """ - data = {} - hass.async_add_job(execute, hass, 'test.py', source, data) + hass.async_add_job(execute, hass, 'test.py', source, {}) yield from hass.async_block_till_done() - assert hass.states.is_state('a', 1) - assert hass.states.is_state('b', 2) - assert hass.states.is_state('ab_list', '[(1, 2), (3, 4)]') + assert hass.states.is_state('hello.a', 1) + assert hass.states.is_state('hello.b', 2) + assert hass.states.is_state('hello.ab_list', '[(1, 2), (3, 4)]') # No errors logged = good assert caplog.text == '' From 2ea7f8eca26bdd90369de308b4e70d83f8355f78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20RAMAGE?= Date: Thu, 14 Sep 2017 14:54:01 +0200 Subject: [PATCH 11/11] fix travis... --- tests/components/test_python_script.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/components/test_python_script.py b/tests/components/test_python_script.py index 993d568f92308..3ff32cc312a77 100644 --- a/tests/components/test_python_script.py +++ b/tests/components/test_python_script.py @@ -197,8 +197,8 @@ def test_unpacking_sequence(hass, caplog): hass.async_add_job(execute, hass, 'test.py', source, {}) yield from hass.async_block_till_done() - assert hass.states.is_state('hello.a', 1) - assert hass.states.is_state('hello.b', 2) + assert hass.states.is_state('hello.a', '1') + assert hass.states.is_state('hello.b', '2') assert hass.states.is_state('hello.ab_list', '[(1, 2), (3, 4)]') # No errors logged = good