Upgrade restrictedpython to 4.0b2 (#10179)

* Upgrade restrictedpython to 4.0b2

* Update test
pull/10228/head
Fabian Affolter 2017-10-30 08:02:15 +01:00 committed by Paulus Schoutsen
parent fc44a4ed99
commit 2891b0cb2e
4 changed files with 31 additions and 22 deletions

View File

@ -1,4 +1,9 @@
"""Component to allow running Python scripts.""" """
Component to allow running Python scripts.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/python_script/
"""
import datetime import datetime
import glob import glob
import logging import logging
@ -7,16 +12,19 @@ import time
import voluptuous as vol import voluptuous as vol
import homeassistant.util.dt as dt_util
from homeassistant.const import SERVICE_RELOAD from homeassistant.const import SERVICE_RELOAD
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
from homeassistant.loader import bind_hass from homeassistant.loader import bind_hass
from homeassistant.util import sanitize_filename from homeassistant.util import sanitize_filename
import homeassistant.util.dt as dt_util
REQUIREMENTS = ['restrictedpython==4.0b2']
_LOGGER = logging.getLogger(__name__)
DOMAIN = 'python_script' DOMAIN = 'python_script'
REQUIREMENTS = ['restrictedpython==4.0a3']
FOLDER = 'python_scripts' FOLDER = 'python_scripts'
_LOGGER = logging.getLogger(__name__)
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema(dict) DOMAIN: vol.Schema(dict)
@ -43,11 +51,11 @@ class ScriptError(HomeAssistantError):
def setup(hass, config): def setup(hass, config):
"""Initialize the python_script component.""" """Initialize the Python script component."""
path = hass.config.path(FOLDER) path = hass.config.path(FOLDER)
if not os.path.isdir(path): if not os.path.isdir(path):
_LOGGER.warning('Folder %s not found in config folder', FOLDER) _LOGGER.warning("Folder %s not found in configuration folder", FOLDER)
return False return False
discover_scripts(hass) discover_scripts(hass)
@ -65,7 +73,7 @@ def discover_scripts(hass):
path = hass.config.path(FOLDER) path = hass.config.path(FOLDER)
if not os.path.isdir(path): if not os.path.isdir(path):
_LOGGER.warning('Folder %s not found in config folder', FOLDER) _LOGGER.warning("Folder %s not found in configuration folder", FOLDER)
return False return False
def python_script_service_handler(call): def python_script_service_handler(call):
@ -104,19 +112,19 @@ def execute(hass, filename, source, data=None):
compiled = compile_restricted_exec(source, filename=filename) compiled = compile_restricted_exec(source, filename=filename)
if compiled.errors: if compiled.errors:
_LOGGER.error('Error loading script %s: %s', filename, _LOGGER.error("Error loading script %s: %s", filename,
', '.join(compiled.errors)) ", ".join(compiled.errors))
return return
if compiled.warnings: if compiled.warnings:
_LOGGER.warning('Warning loading script %s: %s', filename, _LOGGER.warning("Warning loading script %s: %s", filename,
', '.join(compiled.warnings)) ", ".join(compiled.warnings))
def protected_getattr(obj, name, default=None): def protected_getattr(obj, name, default=None):
"""Restricted method to get attributes.""" """Restricted method to get attributes."""
# pylint: disable=too-many-boolean-expressions # pylint: disable=too-many-boolean-expressions
if name.startswith('async_'): if name.startswith('async_'):
raise ScriptError('Not allowed to access async methods') raise ScriptError("Not allowed to access async methods")
elif (obj is hass and name not in ALLOWED_HASS or elif (obj is hass and name not in ALLOWED_HASS or
obj is hass.bus and name not in ALLOWED_EVENTBUS or obj is hass.bus and name not in ALLOWED_EVENTBUS or
obj is hass.states and name not in ALLOWED_STATEMACHINE or obj is hass.states and name not in ALLOWED_STATEMACHINE or
@ -124,7 +132,7 @@ def execute(hass, filename, source, data=None):
obj is dt_util and name not in ALLOWED_DT_UTIL or obj is dt_util and name not in ALLOWED_DT_UTIL or
obj is datetime and name not in ALLOWED_DATETIME or obj is datetime and name not in ALLOWED_DATETIME or
isinstance(obj, TimeWrapper) and name not in ALLOWED_TIME): isinstance(obj, TimeWrapper) and name not in ALLOWED_TIME):
raise ScriptError('Not allowed to access {}.{}'.format( raise ScriptError("Not allowed to access {}.{}".format(
obj.__class__.__name__, name)) obj.__class__.__name__, name))
return getattr(obj, name, default) return getattr(obj, name, default)
@ -152,13 +160,13 @@ def execute(hass, filename, source, data=None):
} }
try: try:
_LOGGER.info('Executing %s: %s', filename, data) _LOGGER.info("Executing %s: %s", filename, data)
# pylint: disable=exec-used # pylint: disable=exec-used
exec(compiled.code, restricted_globals, local) exec(compiled.code, restricted_globals, local)
except ScriptError as err: except ScriptError as err:
logger.error('Error executing script: %s', err) logger.error("Error executing script: %s", err)
except Exception as err: # pylint: disable=broad-except except Exception as err: # pylint: disable=broad-except
logger.exception('Error executing script: %s', err) logger.exception("Error executing script: %s", err)
class StubPrinter: class StubPrinter:
@ -172,7 +180,7 @@ class StubPrinter:
"""Print text.""" """Print text."""
# pylint: disable=no-self-use # pylint: disable=no-self-use
_LOGGER.warning( _LOGGER.warning(
"Don't use print() inside scripts. Use logger.info() instead.") "Don't use print() inside scripts. Use logger.info() instead")
class TimeWrapper: class TimeWrapper:
@ -186,8 +194,8 @@ class TimeWrapper:
"""Sleep method that warns once.""" """Sleep method that warns once."""
if not TimeWrapper.warned: if not TimeWrapper.warned:
TimeWrapper.warned = True TimeWrapper.warned = True
_LOGGER.warning('Using time.sleep can reduce the performance of ' _LOGGER.warning("Using time.sleep can reduce the performance of "
'Home Assistant') "Home Assistant")
time.sleep(*args, **kwargs) time.sleep(*args, **kwargs)

View File

@ -929,7 +929,7 @@ raincloudy==0.0.3
regenmaschine==0.4.1 regenmaschine==0.4.1
# homeassistant.components.python_script # homeassistant.components.python_script
restrictedpython==4.0a3 restrictedpython==4.0b2
# homeassistant.components.rflink # homeassistant.components.rflink
rflink==0.0.34 rflink==0.0.34

View File

@ -137,7 +137,7 @@ pyunifi==2.13
pywebpush==1.1.0 pywebpush==1.1.0
# homeassistant.components.python_script # homeassistant.components.python_script
restrictedpython==4.0a3 restrictedpython==4.0b2
# homeassistant.components.rflink # homeassistant.components.rflink
rflink==0.0.34 rflink==0.0.34

View File

@ -47,7 +47,8 @@ def test_setup_fails_on_no_dir(hass, caplog):
res = yield from async_setup_component(hass, 'python_script', {}) res = yield from async_setup_component(hass, 'python_script', {})
assert not res assert not res
assert 'Folder python_scripts not found in config folder' in caplog.text assert 'Folder python_scripts not found in configuration folder' in \
caplog.text
@asyncio.coroutine @asyncio.coroutine