mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 16:57:53 +00:00
Use literal string interpolation in core (f-strings) (#26166)
This commit is contained in:
parent
1efa29d6ff
commit
decf13b948
@ -168,7 +168,7 @@ def get_arguments() -> argparse.Namespace:
|
||||
parser.add_argument(
|
||||
"--runner",
|
||||
action="store_true",
|
||||
help="On restart exit with code {}".format(RESTART_EXIT_CODE),
|
||||
help=f"On restart exit with code {RESTART_EXIT_CODE}",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--script", nargs=argparse.REMAINDER, help="Run one of the embedded scripts"
|
||||
@ -240,7 +240,7 @@ def write_pid(pid_file: str) -> None:
|
||||
with open(pid_file, "w") as file:
|
||||
file.write(str(pid))
|
||||
except IOError:
|
||||
print("Fatal Error: Unable to write pid file {}".format(pid_file))
|
||||
print(f"Fatal Error: Unable to write pid file {pid_file}")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
@ -326,7 +326,7 @@ def try_to_restart() -> None:
|
||||
thread.is_alive() and not thread.daemon for thread in threading.enumerate()
|
||||
)
|
||||
if nthreads > 1:
|
||||
sys.stderr.write("Found {} non-daemonic threads.\n".format(nthreads))
|
||||
sys.stderr.write(f"Found {nthreads} non-daemonic threads.\n")
|
||||
|
||||
# Somehow we sometimes seem to trigger an assertion in the python threading
|
||||
# module. It seems we find threads that have no associated OS level thread
|
||||
|
@ -278,9 +278,7 @@ class AuthManager:
|
||||
|
||||
module = self.get_auth_mfa_module(mfa_module_id)
|
||||
if module is None:
|
||||
raise ValueError(
|
||||
"Unable find multi-factor auth module: {}".format(mfa_module_id)
|
||||
)
|
||||
raise ValueError(f"Unable find multi-factor auth module: {mfa_module_id}")
|
||||
|
||||
await module.async_setup_user(user.id, data)
|
||||
|
||||
@ -295,9 +293,7 @@ class AuthManager:
|
||||
|
||||
module = self.get_auth_mfa_module(mfa_module_id)
|
||||
if module is None:
|
||||
raise ValueError(
|
||||
"Unable find multi-factor auth module: {}".format(mfa_module_id)
|
||||
)
|
||||
raise ValueError(f"Unable find multi-factor auth module: {mfa_module_id}")
|
||||
|
||||
await module.async_depose_user(user.id)
|
||||
|
||||
@ -356,7 +352,7 @@ class AuthManager:
|
||||
):
|
||||
# Each client_name can only have one
|
||||
# long_lived_access_token type of refresh token
|
||||
raise ValueError("{} already exists".format(client_name))
|
||||
raise ValueError(f"{client_name} already exists")
|
||||
|
||||
return await self._store.async_create_refresh_token(
|
||||
user,
|
||||
|
@ -94,7 +94,7 @@ class AuthStore:
|
||||
for group_id in group_ids or []:
|
||||
group = self._groups.get(group_id)
|
||||
if group is None:
|
||||
raise ValueError("Invalid group specified {}".format(group_id))
|
||||
raise ValueError(f"Invalid group specified {group_id}")
|
||||
groups.append(group)
|
||||
|
||||
kwargs = {
|
||||
|
@ -144,15 +144,13 @@ async def auth_mfa_module_from_config(
|
||||
|
||||
async def _load_mfa_module(hass: HomeAssistant, module_name: str) -> types.ModuleType:
|
||||
"""Load an mfa auth module."""
|
||||
module_path = "homeassistant.auth.mfa_modules.{}".format(module_name)
|
||||
module_path = f"homeassistant.auth.mfa_modules.{module_name}"
|
||||
|
||||
try:
|
||||
module = importlib.import_module(module_path)
|
||||
except ImportError as err:
|
||||
_LOGGER.error("Unable to load mfa module %s: %s", module_name, err)
|
||||
raise HomeAssistantError(
|
||||
"Unable to load mfa module {}: {}".format(module_name, err)
|
||||
)
|
||||
raise HomeAssistantError(f"Unable to load mfa module {module_name}: {err}")
|
||||
|
||||
if hass.config.skip_pip or not hasattr(module, "REQUIREMENTS"):
|
||||
return module
|
||||
|
@ -144,14 +144,10 @@ async def load_auth_provider_module(
|
||||
) -> types.ModuleType:
|
||||
"""Load an auth provider."""
|
||||
try:
|
||||
module = importlib.import_module(
|
||||
"homeassistant.auth.providers.{}".format(provider)
|
||||
)
|
||||
module = importlib.import_module(f"homeassistant.auth.providers.{provider}")
|
||||
except ImportError as err:
|
||||
_LOGGER.error("Unable to load auth provider %s: %s", provider, err)
|
||||
raise HomeAssistantError(
|
||||
"Unable to load auth provider {}: {}".format(provider, err)
|
||||
)
|
||||
raise HomeAssistantError(f"Unable to load auth provider {provider}: {err}")
|
||||
|
||||
if hass.config.skip_pip or not hasattr(module, "REQUIREMENTS"):
|
||||
return module
|
||||
@ -166,7 +162,7 @@ async def load_auth_provider_module(
|
||||
# https://github.com/python/mypy/issues/1424
|
||||
reqs = module.REQUIREMENTS # type: ignore
|
||||
await requirements.async_process_requirements(
|
||||
hass, "auth provider {}".format(provider), reqs
|
||||
hass, f"auth provider {provider}", reqs
|
||||
)
|
||||
|
||||
processed.add(provider)
|
||||
|
@ -163,7 +163,7 @@ def async_enable_logging(
|
||||
# ensure that the handlers it sets up wraps the correct streams.
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
colorfmt = "%(log_color)s{}%(reset)s".format(fmt)
|
||||
colorfmt = f"%(log_color)s{fmt}%(reset)s"
|
||||
logging.getLogger().handlers[0].setFormatter(
|
||||
ColoredFormatter(
|
||||
colorfmt,
|
||||
|
@ -138,7 +138,7 @@ class APIEventStream(HomeAssistantView):
|
||||
if payload is stop_obj:
|
||||
break
|
||||
|
||||
msg = "data: {}\n\n".format(payload)
|
||||
msg = f"data: {payload}\n\n"
|
||||
_LOGGER.debug("STREAM %s WRITING %s", id(stop_obj), msg.strip())
|
||||
await response.write(msg.encode("UTF-8"))
|
||||
except asyncio.TimeoutError:
|
||||
@ -316,7 +316,7 @@ class APIEventView(HomeAssistantView):
|
||||
event_type, event_data, ha.EventOrigin.remote, self.context(request)
|
||||
)
|
||||
|
||||
return self.json_message("Event {} fired.".format(event_type))
|
||||
return self.json_message(f"Event {event_type} fired.")
|
||||
|
||||
|
||||
class APIServicesView(HomeAssistantView):
|
||||
@ -388,7 +388,7 @@ class APITemplateView(HomeAssistantView):
|
||||
return tpl.async_render(data.get("variables"))
|
||||
except (ValueError, TemplateError) as ex:
|
||||
return self.json_message(
|
||||
"Error rendering template: {}".format(ex), HTTP_BAD_REQUEST
|
||||
f"Error rendering template: {ex}", HTTP_BAD_REQUEST
|
||||
)
|
||||
|
||||
|
||||
|
@ -143,7 +143,7 @@ async def async_setup(hass, config):
|
||||
async def turn_onoff_service_handler(service_call):
|
||||
"""Handle automation turn on/off service calls."""
|
||||
tasks = []
|
||||
method = "async_{}".format(service_call.service)
|
||||
method = f"async_{service_call.service}"
|
||||
for entity in await component.async_extract_from_service(service_call):
|
||||
tasks.append(getattr(entity, method)())
|
||||
|
||||
@ -378,7 +378,7 @@ async def _async_process_config(hass, config, component):
|
||||
|
||||
for list_no, config_block in enumerate(conf):
|
||||
automation_id = config_block.get(CONF_ID)
|
||||
name = config_block.get(CONF_ALIAS) or "{} {}".format(config_key, list_no)
|
||||
name = config_block.get(CONF_ALIAS) or f"{config_key} {list_no}"
|
||||
|
||||
hidden = config_block[CONF_HIDE_ENTITY]
|
||||
initial_state = config_block.get(CONF_INITIAL_STATE)
|
||||
@ -431,7 +431,7 @@ def _async_get_action(hass, config, name):
|
||||
await script_obj.async_run(variables, context)
|
||||
except Exception as err: # pylint: disable=broad-except
|
||||
script_obj.async_log_exception(
|
||||
_LOGGER, "Error while executing automation {}".format(entity_id), err
|
||||
_LOGGER, f"Error while executing automation {entity_id}", err
|
||||
)
|
||||
|
||||
return action
|
||||
|
@ -36,7 +36,7 @@ async def async_setup(hass, config):
|
||||
|
||||
async def setup_panel(panel_name):
|
||||
"""Set up a panel."""
|
||||
panel = importlib.import_module(".{}".format(panel_name), __name__)
|
||||
panel = importlib.import_module(f".{panel_name}", __name__)
|
||||
|
||||
if not panel:
|
||||
return
|
||||
@ -44,7 +44,7 @@ async def async_setup(hass, config):
|
||||
success = await panel.async_setup(hass)
|
||||
|
||||
if success:
|
||||
key = "{}.{}".format(DOMAIN, panel_name)
|
||||
key = f"{DOMAIN}.{panel_name}"
|
||||
hass.bus.async_fire(EVENT_COMPONENT_LOADED, {ATTR_COMPONENT: key})
|
||||
|
||||
@callback
|
||||
@ -82,8 +82,8 @@ class BaseEditConfigView(HomeAssistantView):
|
||||
post_write_hook=None,
|
||||
):
|
||||
"""Initialize a config view."""
|
||||
self.url = "/api/config/%s/%s/{config_key}" % (component, config_type)
|
||||
self.name = "api:config:%s:%s" % (component, config_type)
|
||||
self.url = f"/api/config/{component}/{config_type}/{{config_key}}"
|
||||
self.name = f"api:config:{component}:{config_type}"
|
||||
self.path = path
|
||||
self.key_schema = key_schema
|
||||
self.data_schema = data_schema
|
||||
@ -126,14 +126,14 @@ class BaseEditConfigView(HomeAssistantView):
|
||||
try:
|
||||
self.key_schema(config_key)
|
||||
except vol.Invalid as err:
|
||||
return self.json_message("Key malformed: {}".format(err), 400)
|
||||
return self.json_message(f"Key malformed: {err}", 400)
|
||||
|
||||
try:
|
||||
# We just validate, we don't store that data because
|
||||
# we don't want to store the defaults.
|
||||
self.data_schema(data)
|
||||
except vol.Invalid as err:
|
||||
return self.json_message("Message malformed: {}".format(err), 400)
|
||||
return self.json_message(f"Message malformed: {err}", 400)
|
||||
|
||||
hass = request.app["hass"]
|
||||
path = hass.config.path(self.path)
|
||||
|
@ -61,10 +61,10 @@ def async_request_config(
|
||||
Will return an ID to be used for sequent calls.
|
||||
"""
|
||||
if link_name is not None and link_url is not None:
|
||||
description += "\n\n[{}]({})".format(link_name, link_url)
|
||||
description += f"\n\n[{link_name}]({link_url})"
|
||||
|
||||
if description_image is not None:
|
||||
description += "\n\n".format(description_image)
|
||||
description += f"\n\n"
|
||||
|
||||
instance = hass.data.get(_KEY_INSTANCE)
|
||||
|
||||
|
@ -28,7 +28,7 @@ class DemoCamera(Camera):
|
||||
self._images_index = (self._images_index + 1) % 4
|
||||
|
||||
image_path = os.path.join(
|
||||
os.path.dirname(__file__), "demo_{}.jpg".format(self._images_index)
|
||||
os.path.dirname(__file__), f"demo_{self._images_index}.jpg"
|
||||
)
|
||||
_LOGGER.debug("Loading camera_image: %s", image_path)
|
||||
with open(image_path, "rb") as file:
|
||||
|
@ -417,7 +417,7 @@ class DemoTVShowPlayer(AbstractDemoPlayer):
|
||||
@property
|
||||
def media_title(self):
|
||||
"""Return the title of current playing media."""
|
||||
return "Chapter {}".format(self._cur_episode)
|
||||
return f"Chapter {self._cur_episode}"
|
||||
|
||||
@property
|
||||
def media_series_title(self):
|
||||
|
@ -244,7 +244,7 @@ class DemoVacuum(VacuumDevice):
|
||||
if self.supported_features & SUPPORT_SEND_COMMAND == 0:
|
||||
return
|
||||
|
||||
self._status = "Executing {}({})".format(command, params)
|
||||
self._status = f"Executing {command}({params})"
|
||||
self._state = True
|
||||
self.schedule_update_ha_state()
|
||||
|
||||
|
@ -274,9 +274,7 @@ async def async_setup(hass, config):
|
||||
("frontend_latest", True),
|
||||
("frontend_es5", True),
|
||||
):
|
||||
hass.http.register_static_path(
|
||||
"/{}".format(path), str(root_path / path), should_cache
|
||||
)
|
||||
hass.http.register_static_path(f"/{path}", str(root_path / path), should_cache)
|
||||
|
||||
hass.http.register_static_path(
|
||||
"/auth/authorize", str(root_path / "authorize.html"), False
|
||||
@ -294,9 +292,7 @@ async def async_setup(hass, config):
|
||||
# To smooth transition to new urls, add redirects to new urls of dev tools
|
||||
# Added June 27, 2019. Can be removed in 2021.
|
||||
for panel in ("event", "info", "service", "state", "template", "mqtt"):
|
||||
hass.http.register_redirect(
|
||||
"/dev-{}".format(panel), "/developer-tools/{}".format(panel)
|
||||
)
|
||||
hass.http.register_redirect(f"/dev-{panel}", f"/developer-tools/{panel}")
|
||||
|
||||
async_register_built_in_panel(
|
||||
hass,
|
||||
|
@ -271,7 +271,7 @@ async def async_setup(hass, config):
|
||||
hass.components.persistent_notification.async_create(
|
||||
"Config error. See dev-info panel for details.",
|
||||
"Config validating",
|
||||
"{0}.check_config".format(HASS_DOMAIN),
|
||||
f"{HASS_DOMAIN}.check_config",
|
||||
)
|
||||
return
|
||||
|
||||
|
@ -80,7 +80,7 @@ class HassIO:
|
||||
|
||||
This method return a coroutine.
|
||||
"""
|
||||
return self.send_command("/addons/{}/info".format(addon), method="get")
|
||||
return self.send_command(f"/addons/{addon}/info", method="get")
|
||||
|
||||
@_api_data
|
||||
def get_ingress_panels(self):
|
||||
@ -120,7 +120,7 @@ class HassIO:
|
||||
|
||||
This method return a coroutine.
|
||||
"""
|
||||
return self.send_command("/discovery/{}".format(uuid), method="get")
|
||||
return self.send_command(f"/discovery/{uuid}", method="get")
|
||||
|
||||
@_api_bool
|
||||
async def update_hass_api(self, http_config, refresh_token):
|
||||
@ -156,7 +156,7 @@ class HassIO:
|
||||
with async_timeout.timeout(timeout):
|
||||
request = await self.websession.request(
|
||||
method,
|
||||
"http://{}{}".format(self._ip, command),
|
||||
f"http://{self._ip}{command}",
|
||||
json=payload,
|
||||
headers={X_HASSIO: os.environ.get("HASSIO_TOKEN", "")},
|
||||
)
|
||||
|
@ -75,7 +75,7 @@ class HassIOView(HomeAssistantView):
|
||||
|
||||
method = getattr(self._websession, request.method.lower())
|
||||
client = await method(
|
||||
"http://{}/{}".format(self._host, path),
|
||||
f"http://{self._host}/{path}",
|
||||
data=data,
|
||||
headers=headers,
|
||||
timeout=read_timeout,
|
||||
|
@ -42,7 +42,7 @@ class HassIOIngress(HomeAssistantView):
|
||||
|
||||
def _create_url(self, token: str, path: str) -> str:
|
||||
"""Create URL to service."""
|
||||
return "http://{}/ingress/{}/{}".format(self._host, token, path)
|
||||
return f"http://{self._host}/ingress/{token}/{path}"
|
||||
|
||||
async def _handle(
|
||||
self, request: web.Request, token: str, path: str
|
||||
@ -91,7 +91,7 @@ class HassIOIngress(HomeAssistantView):
|
||||
|
||||
# Support GET query
|
||||
if request.query_string:
|
||||
url = "{}?{}".format(url, request.query_string)
|
||||
url = f"{url}?{request.query_string}"
|
||||
|
||||
# Start proxy
|
||||
async with self._websession.ws_connect(
|
||||
@ -175,15 +175,15 @@ def _init_header(
|
||||
headers[X_HASSIO] = os.environ.get("HASSIO_TOKEN", "")
|
||||
|
||||
# Ingress information
|
||||
headers[X_INGRESS_PATH] = "/api/hassio_ingress/{}".format(token)
|
||||
headers[X_INGRESS_PATH] = f"/api/hassio_ingress/{token}"
|
||||
|
||||
# Set X-Forwarded-For
|
||||
forward_for = request.headers.get(hdrs.X_FORWARDED_FOR)
|
||||
connected_ip = ip_address(request.transport.get_extra_info("peername")[0])
|
||||
if forward_for:
|
||||
forward_for = "{}, {!s}".format(forward_for, connected_ip)
|
||||
forward_for = f"{forward_for}, {connected_ip!s}"
|
||||
else:
|
||||
forward_for = "{!s}".format(connected_ip)
|
||||
forward_for = f"{connected_ip!s}"
|
||||
headers[hdrs.X_FORWARDED_FOR] = forward_for
|
||||
|
||||
# Set X-Forwarded-Host
|
||||
|
@ -133,12 +133,12 @@ class ApiConfig:
|
||||
if host.startswith(("http://", "https://")):
|
||||
self.base_url = host
|
||||
elif use_ssl:
|
||||
self.base_url = "https://{}".format(host)
|
||||
self.base_url = f"https://{host}"
|
||||
else:
|
||||
self.base_url = "http://{}".format(host)
|
||||
self.base_url = f"http://{host}"
|
||||
|
||||
if port is not None:
|
||||
self.base_url += ":{}".format(port)
|
||||
self.base_url += f":{port}"
|
||||
|
||||
|
||||
async def async_setup(hass, config):
|
||||
@ -268,15 +268,11 @@ class HomeAssistantHTTP:
|
||||
|
||||
if not hasattr(view, "url"):
|
||||
class_name = view.__class__.__name__
|
||||
raise AttributeError(
|
||||
'{0} missing required attribute "url"'.format(class_name)
|
||||
)
|
||||
raise AttributeError(f'{class_name} missing required attribute "url"')
|
||||
|
||||
if not hasattr(view, "name"):
|
||||
class_name = view.__class__.__name__
|
||||
raise AttributeError(
|
||||
'{0} missing required attribute "name"'.format(class_name)
|
||||
)
|
||||
raise AttributeError(f'{class_name} missing required attribute "name"')
|
||||
|
||||
view.register(self.app, self.app.router)
|
||||
|
||||
|
@ -127,7 +127,7 @@ async def process_wrong_login(request):
|
||||
_LOGGER.warning("Banned IP %s for too many login attempts", remote_addr)
|
||||
|
||||
hass.components.persistent_notification.async_create(
|
||||
"Too many login attempts from {}".format(remote_addr),
|
||||
f"Too many login attempts from {remote_addr}",
|
||||
"Banning IP address",
|
||||
NOTIFICATION_ID_BAN,
|
||||
)
|
||||
|
@ -43,9 +43,7 @@ class RequestDataValidator:
|
||||
kwargs["data"] = self._schema(data)
|
||||
except vol.Invalid as err:
|
||||
_LOGGER.error("Data does not match schema: %s", err)
|
||||
return view.json_message(
|
||||
"Message format incorrect: {}".format(err), 400
|
||||
)
|
||||
return view.json_message(f"Message format incorrect: {err}", 400)
|
||||
|
||||
result = await method(view, request, *args, **kwargs)
|
||||
return result
|
||||
|
@ -10,7 +10,7 @@ from aiohttp.web_urldispatcher import StaticResource
|
||||
# mypy: allow-untyped-defs
|
||||
|
||||
CACHE_TIME = 31 * 86400 # = 1 month
|
||||
CACHE_HEADERS = {hdrs.CACHE_CONTROL: "public, max-age={}".format(CACHE_TIME)}
|
||||
CACHE_HEADERS = {hdrs.CACHE_CONTROL: f"public, max-age={CACHE_TIME}"}
|
||||
|
||||
|
||||
# https://github.com/PyCQA/astroid/issues/633
|
||||
|
@ -49,13 +49,11 @@ def _cv_input_number(cfg):
|
||||
maximum = cfg.get(CONF_MAX)
|
||||
if minimum >= maximum:
|
||||
raise vol.Invalid(
|
||||
"Maximum ({}) is not greater than minimum ({})".format(minimum, maximum)
|
||||
f"Maximum ({minimum}) is not greater than minimum ({maximum})"
|
||||
)
|
||||
state = cfg.get(CONF_INITIAL)
|
||||
if state is not None and (state < minimum or state > maximum):
|
||||
raise vol.Invalid(
|
||||
"Initial value {} not in range {}-{}".format(state, minimum, maximum)
|
||||
)
|
||||
raise vol.Invalid(f"Initial value {state} not in range {minimum}-{maximum}")
|
||||
return cfg
|
||||
|
||||
|
||||
|
@ -45,12 +45,12 @@ def _cv_input_text(cfg):
|
||||
maximum = cfg.get(CONF_MAX)
|
||||
if minimum > maximum:
|
||||
raise vol.Invalid(
|
||||
"Max len ({}) is not greater than min len ({})".format(minimum, maximum)
|
||||
f"Max len ({minimum}) is not greater than min len ({maximum})"
|
||||
)
|
||||
state = cfg.get(CONF_INITIAL)
|
||||
if state is not None and (len(state) < minimum or len(state) > maximum):
|
||||
raise vol.Invalid(
|
||||
"Initial value {} length not in range {}-{}".format(state, minimum, maximum)
|
||||
f"Initial value {state} length not in range {minimum}-{maximum}"
|
||||
)
|
||||
return cfg
|
||||
|
||||
|
@ -94,7 +94,7 @@ class IntegrationSensor(RestoreEntity):
|
||||
self._state = 0
|
||||
self._method = integration_method
|
||||
|
||||
self._name = name if name is not None else "{} integral".format(source_entity)
|
||||
self._name = name if name is not None else f"{source_entity} integral"
|
||||
|
||||
if unit_of_measurement is None:
|
||||
self._unit_template = "{}{}{}".format(
|
||||
|
@ -55,7 +55,7 @@ async def async_setup(hass, config):
|
||||
for intent_type, conf in intents.items():
|
||||
if CONF_ACTION in conf:
|
||||
conf[CONF_ACTION] = script.Script(
|
||||
hass, conf[CONF_ACTION], "Intent Script {}".format(intent_type)
|
||||
hass, conf[CONF_ACTION], f"Intent Script {intent_type}"
|
||||
)
|
||||
intent.async_register(hass, ScriptIntentHandler(intent_type, conf))
|
||||
|
||||
|
@ -113,7 +113,7 @@ def discover_scripts(hass):
|
||||
@bind_hass
|
||||
def execute_script(hass, name, data=None):
|
||||
"""Execute a script."""
|
||||
filename = "{}.py".format(name)
|
||||
filename = f"{name}.py"
|
||||
with open(hass.config.path(FOLDER, sanitize_filename(filename))) as fil:
|
||||
source = fil.read()
|
||||
execute(hass, filename, source, data)
|
||||
@ -166,9 +166,7 @@ def execute(hass, filename, source, data=None):
|
||||
or isinstance(obj, TimeWrapper)
|
||||
and name not in ALLOWED_TIME
|
||||
):
|
||||
raise ScriptError(
|
||||
"Not allowed to access {}.{}".format(obj.__class__.__name__, name)
|
||||
)
|
||||
raise ScriptError(f"Not allowed to access {obj.__class__.__name__}.{name}")
|
||||
|
||||
return getattr(obj, name, default)
|
||||
|
||||
@ -188,7 +186,7 @@ def execute(hass, filename, source, data=None):
|
||||
"_iter_unpack_sequence_": guarded_iter_unpack_sequence,
|
||||
"_unpack_sequence_": guarded_unpack_sequence,
|
||||
}
|
||||
logger = logging.getLogger("{}.{}".format(__name__, filename))
|
||||
logger = logging.getLogger(f"{__name__}.{filename}")
|
||||
local = {"hass": hass, "data": data or {}, "logger": logger}
|
||||
|
||||
try:
|
||||
|
@ -107,7 +107,7 @@ def _drop_index(engine, table_name, index_name):
|
||||
|
||||
# Engines like DB2/Oracle
|
||||
try:
|
||||
engine.execute(text("DROP INDEX {index}".format(index=index_name)))
|
||||
engine.execute(text(f"DROP INDEX {index_name}"))
|
||||
except SQLAlchemyError:
|
||||
pass
|
||||
else:
|
||||
@ -170,7 +170,7 @@ def _add_columns(engine, table_name, columns_def):
|
||||
table_name,
|
||||
)
|
||||
|
||||
columns_def = ["ADD {}".format(col_def) for col_def in columns_def]
|
||||
columns_def = [f"ADD {col_def}" for col_def in columns_def]
|
||||
|
||||
try:
|
||||
engine.execute(
|
||||
@ -265,9 +265,7 @@ def _apply_update(engine, new_version, old_version):
|
||||
# 'context_parent_id CHARACTER(36)',
|
||||
# ])
|
||||
else:
|
||||
raise ValueError(
|
||||
"No schema migration defined for version {}".format(new_version)
|
||||
)
|
||||
raise ValueError(f"No schema migration defined for version {new_version}")
|
||||
|
||||
|
||||
def _inspect_schema_version(engine, session):
|
||||
|
@ -209,7 +209,7 @@ class ScriptEntity(ToggleEntity):
|
||||
await self.script.async_run(kwargs.get(ATTR_VARIABLES), context)
|
||||
except Exception as err: # pylint: disable=broad-except
|
||||
self.script.async_log_exception(
|
||||
_LOGGER, "Error executing script {}".format(self.entity_id), err
|
||||
_LOGGER, f"Error executing script {self.entity_id}", err
|
||||
)
|
||||
raise err
|
||||
|
||||
|
@ -198,7 +198,7 @@ async def async_setup(hass, config):
|
||||
return
|
||||
if service.service == "write":
|
||||
logger = logging.getLogger(
|
||||
service.data.get(CONF_LOGGER, "{}.external".format(__name__))
|
||||
service.data.get(CONF_LOGGER, f"{__name__}.external")
|
||||
)
|
||||
level = service.data[CONF_LEVEL]
|
||||
getattr(logger, level)(service.data[CONF_MESSAGE])
|
||||
|
@ -165,9 +165,7 @@ async def async_setup(hass, config):
|
||||
DOMAIN_MP, SERVICE_PLAY_MEDIA, data, blocking=True
|
||||
)
|
||||
|
||||
service_name = p_config.get(
|
||||
CONF_SERVICE_NAME, "{}_{}".format(p_type, SERVICE_SAY)
|
||||
)
|
||||
service_name = p_config.get(CONF_SERVICE_NAME, f"{p_type}_{SERVICE_SAY}")
|
||||
hass.services.async_register(
|
||||
DOMAIN, service_name, async_say_handle, schema=SCHEMA_SERVICE_SAY
|
||||
)
|
||||
@ -229,7 +227,7 @@ class SpeechManager:
|
||||
init_tts_cache_dir, cache_dir
|
||||
)
|
||||
except OSError as err:
|
||||
raise HomeAssistantError("Can't init cache dir {}".format(err))
|
||||
raise HomeAssistantError(f"Can't init cache dir {err}")
|
||||
|
||||
def get_cache_files():
|
||||
"""Return a dict of given engine files."""
|
||||
@ -251,7 +249,7 @@ class SpeechManager:
|
||||
try:
|
||||
cache_files = await self.hass.async_add_job(get_cache_files)
|
||||
except OSError as err:
|
||||
raise HomeAssistantError("Can't read cache dir {}".format(err))
|
||||
raise HomeAssistantError(f"Can't read cache dir {err}")
|
||||
|
||||
if cache_files:
|
||||
self.file_cache.update(cache_files)
|
||||
@ -293,7 +291,7 @@ class SpeechManager:
|
||||
# Languages
|
||||
language = language or provider.default_language
|
||||
if language is None or language not in provider.supported_languages:
|
||||
raise HomeAssistantError("Not supported language {0}".format(language))
|
||||
raise HomeAssistantError(f"Not supported language {language}")
|
||||
|
||||
# Options
|
||||
if provider.default_options and options:
|
||||
@ -308,9 +306,7 @@ class SpeechManager:
|
||||
if opt_name not in (provider.supported_options or [])
|
||||
]
|
||||
if invalid_opts:
|
||||
raise HomeAssistantError(
|
||||
"Invalid options found: {}".format(invalid_opts)
|
||||
)
|
||||
raise HomeAssistantError(f"Invalid options found: {invalid_opts}")
|
||||
options_key = ctypes.c_size_t(hash(frozenset(options))).value
|
||||
else:
|
||||
options_key = "-"
|
||||
@ -330,7 +326,7 @@ class SpeechManager:
|
||||
engine, key, message, use_cache, language, options
|
||||
)
|
||||
|
||||
return "{}/api/tts_proxy/{}".format(self.base_url, filename)
|
||||
return f"{self.base_url}/api/tts_proxy/{filename}"
|
||||
|
||||
async def async_get_tts_audio(self, engine, key, message, cache, language, options):
|
||||
"""Receive TTS and store for view in cache.
|
||||
@ -341,10 +337,10 @@ class SpeechManager:
|
||||
extension, data = await provider.async_get_tts_audio(message, language, options)
|
||||
|
||||
if data is None or extension is None:
|
||||
raise HomeAssistantError("No TTS from {} for '{}'".format(engine, message))
|
||||
raise HomeAssistantError(f"No TTS from {engine} for '{message}'")
|
||||
|
||||
# Create file infos
|
||||
filename = ("{}.{}".format(key, extension)).lower()
|
||||
filename = (f"{key}.{extension}").lower()
|
||||
|
||||
data = self.write_tags(filename, data, provider, message, language, options)
|
||||
|
||||
@ -381,7 +377,7 @@ class SpeechManager:
|
||||
"""
|
||||
filename = self.file_cache.get(key)
|
||||
if not filename:
|
||||
raise HomeAssistantError("Key {} not in file cache!".format(key))
|
||||
raise HomeAssistantError(f"Key {key} not in file cache!")
|
||||
|
||||
voice_file = os.path.join(self.cache_dir, filename)
|
||||
|
||||
@ -394,7 +390,7 @@ class SpeechManager:
|
||||
data = await self.hass.async_add_job(load_speech)
|
||||
except OSError:
|
||||
del self.file_cache[key]
|
||||
raise HomeAssistantError("Can't read {}".format(voice_file))
|
||||
raise HomeAssistantError(f"Can't read {voice_file}")
|
||||
|
||||
self._async_store_to_memcache(key, filename, data)
|
||||
|
||||
@ -425,7 +421,7 @@ class SpeechManager:
|
||||
|
||||
if key not in self.mem_cache:
|
||||
if key not in self.file_cache:
|
||||
raise HomeAssistantError("{} not in cache!".format(key))
|
||||
raise HomeAssistantError(f"{key} not in cache!")
|
||||
await self.async_file_to_mem(key)
|
||||
|
||||
content, _ = mimetypes.guess_type(filename)
|
||||
|
@ -98,7 +98,7 @@ async def async_setup(hass, config):
|
||||
tariff_confs.append(
|
||||
{
|
||||
CONF_METER: meter,
|
||||
CONF_NAME: "{} {}".format(meter, tariff),
|
||||
CONF_NAME: f"{meter} {tariff}",
|
||||
CONF_TARIFF: tariff,
|
||||
}
|
||||
)
|
||||
|
@ -107,7 +107,7 @@ class UtilityMeterSensor(RestoreEntity):
|
||||
if name:
|
||||
self._name = name
|
||||
else:
|
||||
self._name = "{} meter".format(source_entity)
|
||||
self._name = f"{source_entity} meter"
|
||||
self._unit_of_measurement = None
|
||||
self._period = meter_type
|
||||
self._period_offset = meter_offset
|
||||
|
@ -33,7 +33,7 @@ CONFIG_SCHEMA = vol.Schema({DOMAIN: vol.Schema({})}, extra=vol.ALLOW_EXTRA)
|
||||
|
||||
def setup(hass, config):
|
||||
"""Set up Zeroconf and make Home Assistant discoverable."""
|
||||
zeroconf_name = "{}.{}".format(hass.config.location_name, ZEROCONF_TYPE)
|
||||
zeroconf_name = f"{hass.config.location_name}.{ZEROCONF_TYPE}"
|
||||
|
||||
params = {
|
||||
"version": __version__,
|
||||
|
@ -317,7 +317,7 @@ async def async_hass_config_yaml(hass: HomeAssistant) -> Dict:
|
||||
path = find_config_file(hass.config.config_dir)
|
||||
if path is None:
|
||||
raise HomeAssistantError(
|
||||
"Config file not found in: {}".format(hass.config.config_dir)
|
||||
f"Config file not found in: {hass.config.config_dir}"
|
||||
)
|
||||
config = load_yaml_config_file(path)
|
||||
return config
|
||||
@ -443,7 +443,7 @@ def _format_config_error(ex: vol.Invalid, domain: str, config: Dict) -> str:
|
||||
|
||||
This method must be run in the event loop.
|
||||
"""
|
||||
message = "Invalid config for [{}]: ".format(domain)
|
||||
message = f"Invalid config for [{domain}]: "
|
||||
if "extra keys not allowed" in ex.error_message:
|
||||
message += (
|
||||
"[{option}] is an invalid option for [{domain}]. "
|
||||
@ -705,7 +705,7 @@ async def merge_packages_config(
|
||||
error = _recursive_merge(conf=config[comp_name], package=comp_conf)
|
||||
if error:
|
||||
_log_pkg_error(
|
||||
pack_name, comp_name, config, "has duplicate key '{}'".format(error)
|
||||
pack_name, comp_name, config, f"has duplicate key '{error}'"
|
||||
)
|
||||
|
||||
return config
|
||||
@ -777,7 +777,7 @@ async def async_process_component_config(
|
||||
p_config
|
||||
)
|
||||
except vol.Invalid as ex:
|
||||
async_log_exception(ex, "{}.{}".format(domain, p_name), p_config, hass)
|
||||
async_log_exception(ex, f"{domain}.{p_name}", p_config, hass)
|
||||
continue
|
||||
|
||||
platforms.append(p_validated)
|
||||
@ -836,7 +836,7 @@ def async_notify_setup_error(
|
||||
else:
|
||||
part = name
|
||||
|
||||
message += " - {}\n".format(part)
|
||||
message += f" - {part}\n"
|
||||
|
||||
message += "\nPlease check your config."
|
||||
|
||||
|
@ -1365,7 +1365,7 @@ class Config:
|
||||
self.time_zone = time_zone
|
||||
dt_util.set_default_time_zone(time_zone)
|
||||
else:
|
||||
raise ValueError("Received invalid time zone {}".format(time_zone_str))
|
||||
raise ValueError(f"Received invalid time zone {time_zone_str}")
|
||||
|
||||
@callback
|
||||
def _update(
|
||||
|
@ -126,7 +126,7 @@ class FlowManager:
|
||||
self, flow: Any, step_id: str, user_input: Optional[Dict]
|
||||
) -> Dict:
|
||||
"""Handle a step of a flow."""
|
||||
method = "async_step_{}".format(step_id)
|
||||
method = f"async_step_{step_id}"
|
||||
|
||||
if not hasattr(flow, method):
|
||||
self._progress.pop(flow.flow_id)
|
||||
|
@ -25,7 +25,7 @@ class TemplateError(HomeAssistantError):
|
||||
|
||||
def __init__(self, exception: jinja2.TemplateError) -> None:
|
||||
"""Init the error."""
|
||||
super().__init__("{}: {}".format(exception.__class__.__name__, exception))
|
||||
super().__init__(f"{exception.__class__.__name__}: {exception}")
|
||||
|
||||
|
||||
class PlatformNotReady(HomeAssistantError):
|
||||
@ -73,10 +73,10 @@ class ServiceNotFound(HomeAssistantError):
|
||||
|
||||
def __init__(self, domain: str, service: str) -> None:
|
||||
"""Initialize error."""
|
||||
super().__init__(self, "Service {}.{} not found".format(domain, service))
|
||||
super().__init__(self, f"Service {domain}.{service} not found")
|
||||
self.domain = domain
|
||||
self.service = service
|
||||
|
||||
def __str__(self) -> str:
|
||||
"""Return string representation."""
|
||||
return "Unable to find service {}/{}".format(self.domain, self.service)
|
||||
return f"Unable to find service {self.domain}/{self.service}"
|
||||
|
@ -62,7 +62,7 @@ async def async_check_ha_config_file(hass: HomeAssistant) -> HomeAssistantConfig
|
||||
message = "Package {} setup failed. Component {} {}".format(
|
||||
package, component, message
|
||||
)
|
||||
domain = "homeassistant.packages.{}.{}".format(package, component)
|
||||
domain = f"homeassistant.packages.{package}.{component}"
|
||||
pack_config = core_config[CONF_PACKAGES].get(package, config)
|
||||
result.add_error(message, domain, pack_config)
|
||||
|
||||
@ -77,9 +77,9 @@ async def async_check_ha_config_file(hass: HomeAssistant) -> HomeAssistantConfig
|
||||
return result.add_error("File configuration.yaml not found.")
|
||||
config = await hass.async_add_executor_job(load_yaml_config_file, config_path)
|
||||
except FileNotFoundError:
|
||||
return result.add_error("File not found: {}".format(config_path))
|
||||
return result.add_error(f"File not found: {config_path}")
|
||||
except HomeAssistantError as err:
|
||||
return result.add_error("Error loading {}: {}".format(config_path, err))
|
||||
return result.add_error(f"Error loading {config_path}: {err}")
|
||||
finally:
|
||||
yaml_loader.clear_secret_cache()
|
||||
|
||||
@ -106,13 +106,13 @@ async def async_check_ha_config_file(hass: HomeAssistant) -> HomeAssistantConfig
|
||||
try:
|
||||
integration = await async_get_integration_with_requirements(hass, domain)
|
||||
except (RequirementsNotFound, loader.IntegrationNotFound) as ex:
|
||||
result.add_error("Component error: {} - {}".format(domain, ex))
|
||||
result.add_error(f"Component error: {domain} - {ex}")
|
||||
continue
|
||||
|
||||
try:
|
||||
component = integration.get_component()
|
||||
except ImportError as ex:
|
||||
result.add_error("Component error: {} - {}".format(domain, ex))
|
||||
result.add_error(f"Component error: {domain} - {ex}")
|
||||
continue
|
||||
|
||||
config_schema = getattr(component, "CONFIG_SCHEMA", None)
|
||||
@ -159,7 +159,7 @@ async def async_check_ha_config_file(hass: HomeAssistant) -> HomeAssistantConfig
|
||||
RequirementsNotFound,
|
||||
ImportError,
|
||||
) as ex:
|
||||
result.add_error("Platform error {}.{} - {}".format(domain, p_name, ex))
|
||||
result.add_error(f"Platform error {domain}.{p_name} - {ex}")
|
||||
continue
|
||||
|
||||
# Validate platform specific schema
|
||||
@ -168,7 +168,7 @@ async def async_check_ha_config_file(hass: HomeAssistant) -> HomeAssistantConfig
|
||||
try:
|
||||
p_validated = platform_schema(p_validated)
|
||||
except vol.Invalid as ex:
|
||||
_comp_error(ex, "{}.{}".format(domain, p_name), p_validated)
|
||||
_comp_error(ex, f"{domain}.{p_name}", p_validated)
|
||||
continue
|
||||
|
||||
platforms.append(p_validated)
|
||||
|
@ -243,11 +243,11 @@ class Entity:
|
||||
This method must be run in the event loop.
|
||||
"""
|
||||
if self.hass is None:
|
||||
raise RuntimeError("Attribute hass is None for {}".format(self))
|
||||
raise RuntimeError(f"Attribute hass is None for {self}")
|
||||
|
||||
if self.entity_id is None:
|
||||
raise NoEntitySpecifiedError(
|
||||
"No entity id specified for entity {}".format(self.name)
|
||||
f"No entity id specified for entity {self.name}"
|
||||
)
|
||||
|
||||
# update entity data
|
||||
@ -264,11 +264,11 @@ class Entity:
|
||||
def async_write_ha_state(self):
|
||||
"""Write the state to the state machine."""
|
||||
if self.hass is None:
|
||||
raise RuntimeError("Attribute hass is None for {}".format(self))
|
||||
raise RuntimeError(f"Attribute hass is None for {self}")
|
||||
|
||||
if self.entity_id is None:
|
||||
raise NoEntitySpecifiedError(
|
||||
"No entity id specified for entity {}".format(self.name)
|
||||
f"No entity id specified for entity {self.name}"
|
||||
)
|
||||
|
||||
self._async_write_ha_state()
|
||||
|
@ -205,7 +205,7 @@ class EntityComponent:
|
||||
|
||||
async def handle_service(call):
|
||||
"""Handle the service."""
|
||||
service_name = "{}.{}".format(self.domain, name)
|
||||
service_name = f"{self.domain}.{name}"
|
||||
await self.hass.helpers.service.entity_service_call(
|
||||
self._platforms.values(), func, call, service_name, required_features
|
||||
)
|
||||
|
@ -133,7 +133,7 @@ class EntityPlatform:
|
||||
current_platform.set(self)
|
||||
logger = self.logger
|
||||
hass = self.hass
|
||||
full_name = "{}.{}".format(self.domain, self.platform_name)
|
||||
full_name = f"{self.domain}.{self.platform_name}"
|
||||
|
||||
logger.info("Setting up %s", full_name)
|
||||
warn_task = hass.loop.call_later(
|
||||
@ -357,7 +357,7 @@ class EntityPlatform:
|
||||
"Not adding entity %s because it's disabled",
|
||||
entry.name
|
||||
or entity.name
|
||||
or '"{} {}"'.format(self.platform_name, entity.unique_id),
|
||||
or f'"{self.platform_name} {entity.unique_id}"',
|
||||
)
|
||||
return
|
||||
|
||||
@ -386,12 +386,12 @@ class EntityPlatform:
|
||||
|
||||
# Make sure it is valid in case an entity set the value themselves
|
||||
if not valid_entity_id(entity.entity_id):
|
||||
raise HomeAssistantError("Invalid entity id: {}".format(entity.entity_id))
|
||||
raise HomeAssistantError(f"Invalid entity id: {entity.entity_id}")
|
||||
if (
|
||||
entity.entity_id in self.entities
|
||||
or entity.entity_id in self.hass.states.async_entity_ids(self.domain)
|
||||
):
|
||||
msg = "Entity id already exists: {}".format(entity.entity_id)
|
||||
msg = f"Entity id already exists: {entity.entity_id}"
|
||||
if entity.unique_id is not None:
|
||||
msg += ". Platform {} does not generate unique IDs".format(
|
||||
self.platform_name
|
||||
|
@ -166,9 +166,7 @@ class EntityRegistry:
|
||||
)
|
||||
|
||||
entity_id = self.async_generate_entity_id(
|
||||
domain,
|
||||
suggested_object_id or "{}_{}".format(platform, unique_id),
|
||||
known_object_ids,
|
||||
domain, suggested_object_id or f"{platform}_{unique_id}", known_object_ids
|
||||
)
|
||||
|
||||
if (
|
||||
|
@ -58,7 +58,7 @@ async def async_handle(
|
||||
handler = hass.data.get(DATA_KEY, {}).get(intent_type) # type: IntentHandler
|
||||
|
||||
if handler is None:
|
||||
raise UnknownIntent("Unknown intent {}".format(intent_type))
|
||||
raise UnknownIntent(f"Unknown intent {intent_type}")
|
||||
|
||||
intent = Intent(hass, platform, intent_type, slots or {}, text_input)
|
||||
|
||||
@ -68,13 +68,11 @@ async def async_handle(
|
||||
return result
|
||||
except vol.Invalid as err:
|
||||
_LOGGER.warning("Received invalid slot info for %s: %s", intent_type, err)
|
||||
raise InvalidSlotInfo(
|
||||
"Received invalid slot info for {}".format(intent_type)
|
||||
) from err
|
||||
raise InvalidSlotInfo(f"Received invalid slot info for {intent_type}") from err
|
||||
except IntentHandleError:
|
||||
raise
|
||||
except Exception as err:
|
||||
raise IntentUnexpectedError("Error handling {}".format(intent_type)) from err
|
||||
raise IntentUnexpectedError(f"Error handling {intent_type}") from err
|
||||
|
||||
|
||||
class IntentError(HomeAssistantError):
|
||||
@ -109,7 +107,7 @@ def async_match_state(
|
||||
state = _fuzzymatch(name, states, lambda state: state.name)
|
||||
|
||||
if state is None:
|
||||
raise IntentHandleError("Unable to find an entity called {}".format(name))
|
||||
raise IntentHandleError(f"Unable to find an entity called {name}")
|
||||
|
||||
return state
|
||||
|
||||
@ -118,9 +116,7 @@ def async_match_state(
|
||||
def async_test_feature(state: State, feature: int, feature_name: str) -> None:
|
||||
"""Test is state supports a feature."""
|
||||
if state.attributes.get(ATTR_SUPPORTED_FEATURES, 0) & feature == 0:
|
||||
raise IntentHandleError(
|
||||
"Entity {} does not support {}".format(state.name, feature_name)
|
||||
)
|
||||
raise IntentHandleError(f"Entity {state.name} does not support {feature_name}")
|
||||
|
||||
|
||||
class IntentHandler:
|
||||
|
@ -20,7 +20,7 @@ def display_temp(
|
||||
# If the temperature is not a number this can cause issues
|
||||
# with Polymer components, so bail early there.
|
||||
if not isinstance(temperature, Number):
|
||||
raise TypeError("Temperature is not a number: {}".format(temperature))
|
||||
raise TypeError(f"Temperature is not a number: {temperature}")
|
||||
|
||||
# type ignore: https://github.com/python/mypy/issues/7207
|
||||
if temperature_unit != ha_unit: # type: ignore
|
||||
|
@ -320,10 +320,10 @@ class AllStates:
|
||||
"""Return the domain state."""
|
||||
if "." in name:
|
||||
if not valid_entity_id(name):
|
||||
raise TemplateError("Invalid entity ID '{}'".format(name))
|
||||
raise TemplateError(f"Invalid entity ID '{name}'")
|
||||
return _get_state(self._hass, name)
|
||||
if not valid_entity_id(name + ".entity"):
|
||||
raise TemplateError("Invalid domain name '{}'".format(name))
|
||||
raise TemplateError(f"Invalid domain name '{name}'")
|
||||
return DomainStates(self._hass, name)
|
||||
|
||||
def _collect_all(self):
|
||||
@ -367,9 +367,9 @@ class DomainStates:
|
||||
|
||||
def __getattr__(self, name):
|
||||
"""Return the states."""
|
||||
entity_id = "{}.{}".format(self._domain, name)
|
||||
entity_id = f"{self._domain}.{name}"
|
||||
if not valid_entity_id(entity_id):
|
||||
raise TemplateError("Invalid entity ID '{}'".format(entity_id))
|
||||
raise TemplateError(f"Invalid entity ID '{entity_id}'")
|
||||
return _get_state(self._hass, entity_id)
|
||||
|
||||
def _collect_domain(self):
|
||||
@ -399,7 +399,7 @@ class DomainStates:
|
||||
|
||||
def __repr__(self):
|
||||
"""Representation of Domain States."""
|
||||
return "<template DomainStates('{}')>".format(self._domain)
|
||||
return f"<template DomainStates('{self._domain}')>"
|
||||
|
||||
|
||||
class TemplateState(State):
|
||||
@ -426,7 +426,7 @@ class TemplateState(State):
|
||||
unit = state.attributes.get(ATTR_UNIT_OF_MEASUREMENT)
|
||||
if unit is None:
|
||||
return state.state
|
||||
return "{} {}".format(state.state, unit)
|
||||
return f"{state.state} {unit}"
|
||||
|
||||
def __getattribute__(self, name):
|
||||
"""Return an attribute of the state."""
|
||||
|
@ -20,9 +20,9 @@ def recursive_flatten(prefix: Any, data: Dict) -> Dict[str, Any]:
|
||||
output = {}
|
||||
for key, value in data.items():
|
||||
if isinstance(value, dict):
|
||||
output.update(recursive_flatten("{}{}.".format(prefix, key), value))
|
||||
output.update(recursive_flatten(f"{prefix}{key}.", value))
|
||||
else:
|
||||
output["{}{}".format(prefix, key)] = value
|
||||
output[f"{prefix}{key}"] = value
|
||||
return output
|
||||
|
||||
|
||||
@ -60,7 +60,7 @@ async def component_translation_file(
|
||||
if integration.file_path.name != domain:
|
||||
return None
|
||||
|
||||
filename = "{}.json".format(language)
|
||||
filename = f"{language}.json"
|
||||
return str(integration.file_path / ".translations" / filename)
|
||||
|
||||
|
||||
|
@ -165,10 +165,7 @@ class Integration:
|
||||
continue
|
||||
|
||||
return cls(
|
||||
hass,
|
||||
"{}.{}".format(root_module.__name__, domain),
|
||||
manifest_path.parent,
|
||||
manifest,
|
||||
hass, f"{root_module.__name__}.{domain}", manifest_path.parent, manifest
|
||||
)
|
||||
|
||||
return None
|
||||
@ -229,16 +226,16 @@ class Integration:
|
||||
def get_platform(self, platform_name: str) -> ModuleType:
|
||||
"""Return a platform for an integration."""
|
||||
cache = self.hass.data.setdefault(DATA_COMPONENTS, {})
|
||||
full_name = "{}.{}".format(self.domain, platform_name)
|
||||
full_name = f"{self.domain}.{platform_name}"
|
||||
if full_name not in cache:
|
||||
cache[full_name] = importlib.import_module(
|
||||
"{}.{}".format(self.pkg_path, platform_name)
|
||||
f"{self.pkg_path}.{platform_name}"
|
||||
)
|
||||
return cache[full_name] # type: ignore
|
||||
|
||||
def __repr__(self) -> str:
|
||||
"""Text representation of class."""
|
||||
return "<Integration {}: {}>".format(self.domain, self.pkg_path)
|
||||
return f"<Integration {self.domain}: {self.pkg_path}>"
|
||||
|
||||
|
||||
async def async_get_integration(hass: "HomeAssistant", domain: str) -> Integration:
|
||||
@ -312,7 +309,7 @@ class IntegrationNotFound(LoaderError):
|
||||
|
||||
def __init__(self, domain: str) -> None:
|
||||
"""Initialize a component not found error."""
|
||||
super().__init__("Integration {} not found.".format(domain))
|
||||
super().__init__(f"Integration {domain} not found.")
|
||||
self.domain = domain
|
||||
|
||||
|
||||
@ -321,9 +318,7 @@ class CircularDependency(LoaderError):
|
||||
|
||||
def __init__(self, from_domain: str, to_domain: str) -> None:
|
||||
"""Initialize circular dependency error."""
|
||||
super().__init__(
|
||||
"Circular dependency detected: {} -> {}.".format(from_domain, to_domain)
|
||||
)
|
||||
super().__init__(f"Circular dependency detected: {from_domain} -> {to_domain}.")
|
||||
self.from_domain = from_domain
|
||||
self.to_domain = to_domain
|
||||
|
||||
@ -350,7 +345,7 @@ def _load_file(
|
||||
return None
|
||||
cache = hass.data[DATA_COMPONENTS] = {}
|
||||
|
||||
for path in ("{}.{}".format(base, comp_or_platform) for base in base_paths):
|
||||
for path in (f"{base}.{comp_or_platform}" for base in base_paths):
|
||||
try:
|
||||
module = importlib.import_module(path)
|
||||
|
||||
@ -439,7 +434,7 @@ class Components:
|
||||
component = _load_file(self._hass, comp_name, LOOKUP_PATHS)
|
||||
|
||||
if component is None:
|
||||
raise ImportError("Unable to load {}".format(comp_name))
|
||||
raise ImportError(f"Unable to load {comp_name}")
|
||||
|
||||
wrapped = ModuleWrapper(self._hass, component)
|
||||
setattr(self, comp_name, wrapped)
|
||||
@ -457,7 +452,7 @@ class Helpers:
|
||||
|
||||
def __getattr__(self, helper_name: str) -> ModuleWrapper:
|
||||
"""Fetch a helper."""
|
||||
helper = importlib.import_module("homeassistant.helpers.{}".format(helper_name))
|
||||
helper = importlib.import_module(f"homeassistant.helpers.{helper_name}")
|
||||
wrapped = ModuleWrapper(self._hass, helper)
|
||||
setattr(self, helper_name, wrapped)
|
||||
return wrapped
|
||||
|
@ -22,9 +22,7 @@ class RequirementsNotFound(HomeAssistantError):
|
||||
|
||||
def __init__(self, domain: str, requirements: List) -> None:
|
||||
"""Initialize a component not found error."""
|
||||
super().__init__(
|
||||
"Requirements for {} not found: {}.".format(domain, requirements)
|
||||
)
|
||||
super().__init__(f"Requirements for {domain} not found: {requirements}.")
|
||||
self.domain = domain
|
||||
self.requirements = requirements
|
||||
|
||||
|
@ -39,7 +39,7 @@ def run(args):
|
||||
hass = core.HomeAssistant(loop)
|
||||
hass.async_stop_track_tasks()
|
||||
runtime = loop.run_until_complete(bench(hass))
|
||||
print("Benchmark {} done in {}s".format(bench.__name__, runtime))
|
||||
print(f"Benchmark {bench.__name__} done in {runtime}s")
|
||||
loop.run_until_complete(hass.async_stop())
|
||||
loop.close()
|
||||
|
||||
|
@ -58,20 +58,18 @@ def run(args):
|
||||
if args.value:
|
||||
the_secret = args.value
|
||||
else:
|
||||
the_secret = getpass.getpass(
|
||||
"Please enter the secret for {}: ".format(args.name)
|
||||
)
|
||||
the_secret = getpass.getpass(f"Please enter the secret for {args.name}: ")
|
||||
current_version = credstash.getHighestVersion(args.name, table=table)
|
||||
credstash.putSecret(
|
||||
args.name, the_secret, version=int(current_version) + 1, table=table
|
||||
)
|
||||
print("Secret {} put successfully".format(args.name))
|
||||
print(f"Secret {args.name} put successfully")
|
||||
elif args.action == "get":
|
||||
the_secret = credstash.getSecret(args.name, table=table)
|
||||
if the_secret is None:
|
||||
print("Secret {} not found".format(args.name))
|
||||
print(f"Secret {args.name} not found")
|
||||
else:
|
||||
print("Secret {}={}".format(args.name, the_secret))
|
||||
print(f"Secret {args.name}={the_secret}")
|
||||
elif args.action == "del":
|
||||
credstash.deleteSecrets(args.name, table=table)
|
||||
print("Deleted secret {}".format(args.name))
|
||||
print(f"Deleted secret {args.name}")
|
||||
|
@ -36,29 +36,27 @@ def run(args):
|
||||
if args.action == "info":
|
||||
keyr = keyring.get_keyring()
|
||||
print("Keyring version {}\n".format(REQUIREMENTS[0].split("==")[1]))
|
||||
print("Active keyring : {}".format(keyr.__module__))
|
||||
print(f"Active keyring : {keyr.__module__}")
|
||||
config_name = os.path.join(platform.config_root(), "keyringrc.cfg")
|
||||
print("Config location : {}".format(config_name))
|
||||
print(f"Config location : {config_name}")
|
||||
print("Data location : {}\n".format(platform.data_root()))
|
||||
elif args.name is None:
|
||||
parser.print_help()
|
||||
return 1
|
||||
|
||||
if args.action == "set":
|
||||
entered_secret = getpass.getpass(
|
||||
"Please enter the secret for {}: ".format(args.name)
|
||||
)
|
||||
entered_secret = getpass.getpass(f"Please enter the secret for {args.name}: ")
|
||||
keyring.set_password(_SECRET_NAMESPACE, args.name, entered_secret)
|
||||
print("Secret {} set successfully".format(args.name))
|
||||
print(f"Secret {args.name} set successfully")
|
||||
elif args.action == "get":
|
||||
the_secret = keyring.get_password(_SECRET_NAMESPACE, args.name)
|
||||
if the_secret is None:
|
||||
print("Secret {} not found".format(args.name))
|
||||
print(f"Secret {args.name} not found")
|
||||
else:
|
||||
print("Secret {}={}".format(args.name, the_secret))
|
||||
print(f"Secret {args.name}={the_secret}")
|
||||
elif args.action == "del":
|
||||
try:
|
||||
keyring.delete_password(_SECRET_NAMESPACE, args.name)
|
||||
print("Deleted secret {}".format(args.name))
|
||||
print(f"Deleted secret {args.name}")
|
||||
except keyring.errors.PasswordDeleteError:
|
||||
print("Secret {} not found".format(args.name))
|
||||
print(f"Secret {args.name} not found")
|
||||
|
@ -240,7 +240,7 @@ async def async_prepare_setup_platform(
|
||||
try:
|
||||
platform = integration.get_platform(domain)
|
||||
except ImportError as exc:
|
||||
log_error("Platform not found ({}).".format(exc))
|
||||
log_error(f"Platform not found ({exc}).")
|
||||
return None
|
||||
|
||||
# Already loaded
|
||||
@ -253,7 +253,7 @@ async def async_prepare_setup_platform(
|
||||
try:
|
||||
component = integration.get_component()
|
||||
except ImportError as exc:
|
||||
log_error("Unable to import the component ({}).".format(exc))
|
||||
log_error(f"Unable to import the component ({exc}).")
|
||||
return None
|
||||
|
||||
if hasattr(component, "setup") or hasattr(component, "async_setup"):
|
||||
|
@ -86,7 +86,7 @@ def ensure_unique_string(
|
||||
|
||||
while test_string in current_strings_set:
|
||||
tries += 1
|
||||
test_string = "{}_{}".format(preferred_string, tries)
|
||||
test_string = f"{preferred_string}_{tries}"
|
||||
|
||||
return test_string
|
||||
|
||||
|
@ -25,7 +25,7 @@ def convert(value: float, unit_1: str, unit_2: str) -> float:
|
||||
raise ValueError(UNIT_NOT_RECOGNIZED_TEMPLATE.format(unit_2, LENGTH))
|
||||
|
||||
if not isinstance(value, Number):
|
||||
raise TypeError("{} is not of numeric type".format(value))
|
||||
raise TypeError(f"{value} is not of numeric type")
|
||||
|
||||
# type ignore: https://github.com/python/mypy/issues/7207
|
||||
if unit_1 == unit_2 or unit_1 not in VALID_UNITS: # type: ignore
|
||||
|
@ -193,8 +193,8 @@ def get_age(date: dt.datetime) -> str:
|
||||
def formatn(number: int, unit: str) -> str:
|
||||
"""Add "unit" if it's plural."""
|
||||
if number == 1:
|
||||
return "1 {}".format(unit)
|
||||
return "{:d} {}s".format(number, unit)
|
||||
return f"1 {unit}"
|
||||
return f"{number:d} {unit}s"
|
||||
|
||||
def q_n_r(first: int, second: int) -> Tuple[int, int]:
|
||||
"""Return quotient and remaining."""
|
||||
|
@ -34,7 +34,7 @@ def convert(value: float, unit_1: str, unit_2: str) -> float:
|
||||
raise ValueError(UNIT_NOT_RECOGNIZED_TEMPLATE.format(unit_2, PRESSURE))
|
||||
|
||||
if not isinstance(value, Number):
|
||||
raise TypeError("{} is not of numeric type".format(value))
|
||||
raise TypeError(f"{value} is not of numeric type")
|
||||
|
||||
# type ignore: https://github.com/python/mypy/issues/7207
|
||||
if unit_1 == unit_2 or unit_1 not in VALID_UNITS: # type: ignore
|
||||
|
@ -34,7 +34,7 @@ def convert(volume: float, from_unit: str, to_unit: str) -> float:
|
||||
raise ValueError(UNIT_NOT_RECOGNIZED_TEMPLATE.format(to_unit, VOLUME))
|
||||
|
||||
if not isinstance(volume, Number):
|
||||
raise TypeError("{} is not of numeric type".format(volume))
|
||||
raise TypeError(f"{volume} is not of numeric type")
|
||||
|
||||
# type ignore: https://github.com/python/mypy/issues/7207
|
||||
if from_unit == to_unit: # type: ignore
|
||||
|
@ -207,7 +207,7 @@ def _ordered_dict(loader: SafeLineLoader, node: yaml.nodes.MappingNode) -> Order
|
||||
except TypeError:
|
||||
fname = getattr(loader.stream, "name", "")
|
||||
raise yaml.MarkedYAMLError(
|
||||
context='invalid key: "{}"'.format(key),
|
||||
context=f'invalid key: "{key}"',
|
||||
context_mark=yaml.Mark(fname, 0, line, -1, None, None),
|
||||
)
|
||||
|
||||
@ -314,7 +314,7 @@ def secret_yaml(loader: SafeLineLoader, node: yaml.nodes.Node) -> JSON_TYPE:
|
||||
# Catch if package installed and no config
|
||||
credstash = None
|
||||
|
||||
raise HomeAssistantError("Secret {} not defined".format(node.value))
|
||||
raise HomeAssistantError(f"Secret {node.value} not defined")
|
||||
|
||||
|
||||
yaml.SafeLoader.add_constructor("!include", _include_yaml)
|
||||
|
@ -230,9 +230,7 @@ def gather_recursive_requirements(domain, seen=None):
|
||||
seen = set()
|
||||
|
||||
seen.add(domain)
|
||||
integration = Integration(
|
||||
pathlib.Path("homeassistant/components/{}".format(domain))
|
||||
)
|
||||
integration = Integration(pathlib.Path(f"homeassistant/components/{domain}"))
|
||||
integration.load_manifest()
|
||||
reqs = set(integration.manifest["requirements"])
|
||||
for dep_domain in integration.manifest["dependencies"]:
|
||||
@ -272,13 +270,13 @@ def gather_requirements_from_manifests(errors, reqs):
|
||||
integration = integrations[domain]
|
||||
|
||||
if not integration.manifest:
|
||||
errors.append("The manifest for integration {} is invalid.".format(domain))
|
||||
errors.append(f"The manifest for integration {domain} is invalid.")
|
||||
continue
|
||||
|
||||
process_requirements(
|
||||
errors,
|
||||
integration.manifest["requirements"],
|
||||
"homeassistant.components.{}".format(domain),
|
||||
f"homeassistant.components.{domain}",
|
||||
reqs,
|
||||
)
|
||||
|
||||
@ -306,13 +304,9 @@ def process_requirements(errors, module_requirements, package, reqs):
|
||||
if req in IGNORE_REQ:
|
||||
continue
|
||||
if "://" in req:
|
||||
errors.append(
|
||||
"{}[Only pypi dependencies are allowed: {}]".format(package, req)
|
||||
)
|
||||
errors.append(f"{package}[Only pypi dependencies are allowed: {req}]")
|
||||
if req.partition("==")[1] == "" and req not in IGNORE_PIN:
|
||||
errors.append(
|
||||
"{}[Please pin requirement {}, see {}]".format(package, req, URL_PIN)
|
||||
)
|
||||
errors.append(f"{package}[Please pin requirement {req}, see {URL_PIN}]")
|
||||
reqs.setdefault(req, []).append(package)
|
||||
|
||||
|
||||
@ -321,12 +315,12 @@ def generate_requirements_list(reqs):
|
||||
output = []
|
||||
for pkg, requirements in sorted(reqs.items(), key=lambda item: item[0]):
|
||||
for req in sorted(requirements):
|
||||
output.append("\n# {}".format(req))
|
||||
output.append(f"\n# {req}")
|
||||
|
||||
if comment_requirement(pkg):
|
||||
output.append("\n# {}\n".format(pkg))
|
||||
output.append(f"\n# {pkg}\n")
|
||||
else:
|
||||
output.append("\n{}\n".format(pkg))
|
||||
output.append(f"\n{pkg}\n")
|
||||
return "".join(output)
|
||||
|
||||
|
||||
|
@ -68,7 +68,7 @@ def main():
|
||||
print()
|
||||
|
||||
for integration in sorted(invalid_itg, key=lambda itg: itg.domain):
|
||||
print("Integration {}:".format(integration.domain))
|
||||
print(f"Integration {integration.domain}:")
|
||||
for error in integration.errors:
|
||||
print("*", error)
|
||||
print()
|
||||
|
@ -67,5 +67,5 @@ def validate(integrations: Dict[str, Integration], config):
|
||||
for dep in integration.manifest["dependencies"]:
|
||||
if dep not in integrations:
|
||||
integration.add_error(
|
||||
"dependencies", "Dependency {} does not exist".format(dep)
|
||||
"dependencies", f"Dependency {dep} does not exist"
|
||||
)
|
||||
|
@ -79,20 +79,20 @@ class Integration:
|
||||
"""Load manifest."""
|
||||
manifest_path = self.path / "manifest.json"
|
||||
if not manifest_path.is_file():
|
||||
self.add_error("model", "Manifest file {} not found".format(manifest_path))
|
||||
self.add_error("model", f"Manifest file {manifest_path} not found")
|
||||
return
|
||||
|
||||
try:
|
||||
manifest = json.loads(manifest_path.read_text())
|
||||
except ValueError as err:
|
||||
self.add_error("model", "Manifest contains invalid JSON: {}".format(err))
|
||||
self.add_error("model", f"Manifest contains invalid JSON: {err}")
|
||||
return
|
||||
|
||||
self.manifest = manifest
|
||||
|
||||
def import_pkg(self, platform=None):
|
||||
"""Import the Python file."""
|
||||
pkg = "homeassistant.components.{}".format(self.domain)
|
||||
pkg = f"homeassistant.components.{self.domain}"
|
||||
if platform is not None:
|
||||
pkg += ".{}".format(platform)
|
||||
pkg += f".{platform}"
|
||||
return importlib.import_module(pkg)
|
||||
|
@ -34,7 +34,7 @@ def printc(the_color, *args):
|
||||
print(escape_codes[the_color] + msg + escape_codes["reset"])
|
||||
except KeyError:
|
||||
print(msg)
|
||||
raise ValueError("Invalid color {}".format(the_color))
|
||||
raise ValueError(f"Invalid color {the_color}")
|
||||
|
||||
|
||||
def validate_requirements_ok():
|
||||
@ -145,7 +145,7 @@ async def lint(files):
|
||||
|
||||
lint_ok = True
|
||||
for err in res:
|
||||
err_msg = "{} {}:{} {}".format(err.file, err.line, err.col, err.msg)
|
||||
err_msg = f"{err.file} {err.line}:{err.col} {err.msg}"
|
||||
|
||||
# tests/* does not have to pass lint
|
||||
if err.skip:
|
||||
|
@ -40,18 +40,11 @@ def get_component_path(lang, component):
|
||||
"""Get the component translation path."""
|
||||
if os.path.isdir(os.path.join("homeassistant", "components", component)):
|
||||
return os.path.join(
|
||||
"homeassistant",
|
||||
"components",
|
||||
component,
|
||||
".translations",
|
||||
"{}.json".format(lang),
|
||||
"homeassistant", "components", component, ".translations", f"{lang}.json"
|
||||
)
|
||||
else:
|
||||
return os.path.join(
|
||||
"homeassistant",
|
||||
"components",
|
||||
".translations",
|
||||
"{}.{}.json".format(component, lang),
|
||||
"homeassistant", "components", ".translations", f"{component}.{lang}.json"
|
||||
)
|
||||
|
||||
|
||||
@ -64,7 +57,7 @@ def get_platform_path(lang, component, platform):
|
||||
component,
|
||||
platform,
|
||||
".translations",
|
||||
"{}.json".format(lang),
|
||||
f"{lang}.json",
|
||||
)
|
||||
else:
|
||||
return os.path.join(
|
||||
@ -72,7 +65,7 @@ def get_platform_path(lang, component, platform):
|
||||
"components",
|
||||
component,
|
||||
".translations",
|
||||
"{}.{}.json".format(platform, lang),
|
||||
f"{platform}.{lang}.json",
|
||||
)
|
||||
|
||||
|
||||
|
@ -35,7 +35,7 @@ def save_json(filename: str, data: Union[List, Dict]):
|
||||
def find_strings_files():
|
||||
"""Return the paths of the strings source files."""
|
||||
return itertools.chain(
|
||||
glob.iglob("strings*.json"), glob.iglob("*{}strings*.json".format(os.sep))
|
||||
glob.iglob("strings*.json"), glob.iglob(f"*{os.sep}strings*.json")
|
||||
)
|
||||
|
||||
|
||||
|
@ -81,7 +81,7 @@ def bump_version(version, bump_type):
|
||||
to_change["pre"] = ("b", 0)
|
||||
|
||||
else:
|
||||
assert False, "Unsupported type: {}".format(bump_type)
|
||||
assert False, f"Unsupported type: {bump_type}"
|
||||
|
||||
temp = Version("0")
|
||||
temp._version = version._version._replace(**to_change)
|
||||
@ -95,15 +95,9 @@ def write_version(version):
|
||||
|
||||
major, minor, patch = str(version).split(".", 2)
|
||||
|
||||
content = re.sub(
|
||||
"MAJOR_VERSION = .*\n", "MAJOR_VERSION = {}\n".format(major), content
|
||||
)
|
||||
content = re.sub(
|
||||
"MINOR_VERSION = .*\n", "MINOR_VERSION = {}\n".format(minor), content
|
||||
)
|
||||
content = re.sub(
|
||||
"PATCH_VERSION = .*\n", "PATCH_VERSION = '{}'\n".format(patch), content
|
||||
)
|
||||
content = re.sub("MAJOR_VERSION = .*\n", f"MAJOR_VERSION = {major}\n", content)
|
||||
content = re.sub("MINOR_VERSION = .*\n", f"MINOR_VERSION = {minor}\n", content)
|
||||
content = re.sub("PATCH_VERSION = .*\n", f"PATCH_VERSION = '{patch}'\n", content)
|
||||
|
||||
with open("homeassistant/const.py", "wt") as fil:
|
||||
content = fil.write(content)
|
||||
@ -129,7 +123,7 @@ def main():
|
||||
if not arguments.commit:
|
||||
return
|
||||
|
||||
subprocess.run(["git", "commit", "-am", "Bumped version to {}".format(bumped)])
|
||||
subprocess.run(["git", "commit", "-am", f"Bumped version to {bumped}"])
|
||||
|
||||
|
||||
def test_bump_version():
|
||||
|
Loading…
x
Reference in New Issue
Block a user