Skip to content

Commit

Permalink
Enhance python_script to support "_getitem_" (home-assistant#8541)
Browse files Browse the repository at this point in the history
* Enhance python_script to support "_getitem_"

In order to use dict / list structures in python scripts we need
_getitem_ allowed in the RestrictedPython environment. There is a
default_guarded_getitem included with RestrictedPython, which is a
pass through used in the Eval code paths.

* Add tests for dict/list support in python_scripts

* Lint
  • Loading branch information
sdague authored and dethpickle committed Aug 18, 2017
1 parent 5e0d8d0 commit d59eb21
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 0 deletions.
2 changes: 2 additions & 0 deletions homeassistant/components/python_script.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ def execute(hass, filename, source, data=None):
from RestrictedPython import compile_restricted_exec
from RestrictedPython.Guards import safe_builtins, full_write_guard
from RestrictedPython.Utilities import utility_builtins
from RestrictedPython.Eval import default_guarded_getitem

compiled = compile_restricted_exec(source, filename=filename)

Expand Down Expand Up @@ -99,6 +100,7 @@ def protected_getattr(obj, name, default=None):
'_getattr_': protected_getattr,
'_write_': full_write_guard,
'_getiter_': iter,
'_getitem_': default_guarded_getitem
}
logger = logging.getLogger('{}.{}'.format(__name__, filename))
local = {
Expand Down
16 changes: 16 additions & 0 deletions tests/components/test_python_script.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,22 @@ def test_accessing_async_methods(hass, caplog):
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."""
Expand Down

0 comments on commit d59eb21

Please sign in to comment.