Upgrade restrictedpython to 4.0b2 (#10179)
* Upgrade restrictedpython to 4.0b2 * Update testpull/10228/head
parent
fc44a4ed99
commit
2891b0cb2e
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue