From e60f9ca3928aef9f546a1ecd70fa525a306a1f5c Mon Sep 17 00:00:00 2001 From: Andrey <andrey-git@users.noreply.github.com> Date: Fri, 13 Jul 2018 20:14:45 +0300 Subject: [PATCH] More typing (#15449) ## Description: More typing improvements. Switch to using `mypy.ini` for flexibility Add `warn_return_any` check except in `homeassistant.util.yaml` that does typing hacks. Fix some type annotations as resulting from this check and ignore others were fixing is hard. ## Checklist: - [x] The code change is tested and works locally. - [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass** --- homeassistant/config.py | 13 ++++++------- homeassistant/core.py | 11 ++++++----- homeassistant/loader.py | 2 +- homeassistant/remote.py | 2 +- homeassistant/setup.py | 6 +++--- homeassistant/util/json.py | 2 +- mypy.ini | 11 +++++++++++ tox.ini | 2 +- 8 files changed, 30 insertions(+), 19 deletions(-) create mode 100644 mypy.ini diff --git a/homeassistant/config.py b/homeassistant/config.py index 48632ccab83..2afa943ee50 100644 --- a/homeassistant/config.py +++ b/homeassistant/config.py @@ -171,7 +171,8 @@ def get_default_config_dir() -> str: return os.path.join(data_dir, CONFIG_DIR_NAME) # type: ignore -def ensure_config_exists(config_dir: str, detect_location: bool = True) -> str: +def ensure_config_exists(config_dir: str, detect_location: bool = True)\ + -> Optional[str]: """Ensure a configuration file exists in given configuration directory. Creating a default one if needed. @@ -187,7 +188,8 @@ def ensure_config_exists(config_dir: str, detect_location: bool = True) -> str: return config_path -def create_default_config(config_dir, detect_location=True): +def create_default_config(config_dir: str, detect_location=True)\ + -> Optional[str]: """Create a default configuration file in given configuration directory. Return path to new config file if success, None if failed. @@ -286,11 +288,8 @@ async def async_hass_config_yaml(hass): return conf -def find_config_file(config_dir): - """Look in given directory for supported configuration files. - - Async friendly. - """ +def find_config_file(config_dir: str) -> Optional[str]: + """Look in given directory for supported configuration files.""" config_path = os.path.join(config_dir, YAML_CONFIG_FILE) return config_path if os.path.isfile(config_path) else None diff --git a/homeassistant/core.py b/homeassistant/core.py index c7aa04910bd..8b534bf1731 100644 --- a/homeassistant/core.py +++ b/homeassistant/core.py @@ -106,7 +106,7 @@ class CoreState(enum.Enum): def __str__(self) -> str: """Return the event.""" - return self.value + return self.value # type: ignore class HomeAssistant(object): @@ -137,7 +137,7 @@ class HomeAssistant(object): # This is a dictionary that any component can store any data on. self.data = {} self.state = CoreState.not_running - self.exit_code = None + self.exit_code = 0 # type: int self.config_entries = None @property @@ -239,7 +239,7 @@ class HomeAssistant(object): target: target to call. """ - task = self.loop.create_task(target) + task = self.loop.create_task(target) # type: asyncio.tasks.Task if self._track_task: self._pending_tasks.append(task) @@ -252,7 +252,8 @@ class HomeAssistant(object): target: Callable[..., Any], *args: Any) -> asyncio.Future: """Add an executor job from within the event loop.""" - task = self.loop.run_in_executor(None, target, *args) + task = self.loop.run_in_executor( + None, target, *args) # type: asyncio.Future # If a task is scheduled if self._track_task: @@ -307,7 +308,7 @@ class HomeAssistant(object): """Stop Home Assistant and shuts down all threads.""" fire_coroutine_threadsafe(self.async_stop(), self.loop) - async def async_stop(self, exit_code=0) -> None: + async def async_stop(self, exit_code: int = 0) -> None: """Stop Home Assistant and shuts down all threads. This method is a coroutine. diff --git a/homeassistant/loader.py b/homeassistant/loader.py index b22271d6eb5..52e6b1e7703 100644 --- a/homeassistant/loader.py +++ b/homeassistant/loader.py @@ -67,7 +67,7 @@ def get_component(hass, comp_or_platform) -> Optional[ModuleType]: Async friendly. """ try: - return hass.data[DATA_KEY][comp_or_platform] + return hass.data[DATA_KEY][comp_or_platform] # type: ignore except KeyError: pass diff --git a/homeassistant/remote.py b/homeassistant/remote.py index b3e5f417618..ae932b7d955 100644 --- a/homeassistant/remote.py +++ b/homeassistant/remote.py @@ -38,7 +38,7 @@ class APIStatus(enum.Enum): def __str__(self) -> str: """Return the state.""" - return self.value + return self.value # type: ignore class API(object): diff --git a/homeassistant/setup.py b/homeassistant/setup.py index 5398cfde963..478320dca27 100644 --- a/homeassistant/setup.py +++ b/homeassistant/setup.py @@ -26,7 +26,7 @@ SLOW_SETUP_WARNING = 10 def setup_component(hass: core.HomeAssistant, domain: str, config: Optional[Dict] = None) -> bool: """Set up a component and all its dependencies.""" - return run_coroutine_threadsafe( + return run_coroutine_threadsafe( # type: ignore async_setup_component(hass, domain, config), loop=hass.loop).result() @@ -42,7 +42,7 @@ async def async_setup_component(hass: core.HomeAssistant, domain: str, setup_tasks = hass.data.get(DATA_SETUP) if setup_tasks is not None and domain in setup_tasks: - return await setup_tasks[domain] + return await setup_tasks[domain] # type: ignore if config is None: config = {} @@ -53,7 +53,7 @@ async def async_setup_component(hass: core.HomeAssistant, domain: str, task = setup_tasks[domain] = hass.async_create_task( _async_setup_component(hass, domain, config)) - return await task + return await task # type: ignore async def _async_process_dependencies(hass, config, name, dependencies): diff --git a/homeassistant/util/json.py b/homeassistant/util/json.py index 74feb779dcd..1029e58c118 100644 --- a/homeassistant/util/json.py +++ b/homeassistant/util/json.py @@ -25,7 +25,7 @@ def load_json(filename: str, default: Union[List, Dict, None] = None) \ """ try: with open(filename, encoding='utf-8') as fdesc: - return json.loads(fdesc.read()) + return json.loads(fdesc.read()) # type: ignore except FileNotFoundError: # This is not a fatal error _LOGGER.debug('JSON file not found: %s', filename) diff --git a/mypy.ini b/mypy.ini new file mode 100644 index 00000000000..3970ea72d47 --- /dev/null +++ b/mypy.ini @@ -0,0 +1,11 @@ +[mypy] +warn_redundant_casts = true +warn_unused_configs = true +ignore_missing_imports = true +follow_imports = silent +warn_unused_ignores = true +warn_return_any = true + +[mypy-homeassistant.util.yaml] +warn_return_any = false + diff --git a/tox.ini b/tox.ini index 6e22f2a5e95..fb36ac6511a 100644 --- a/tox.ini +++ b/tox.ini @@ -42,4 +42,4 @@ whitelist_externals=/bin/bash deps = -r{toxinidir}/requirements_test.txt commands = - /bin/bash -c 'mypy --ignore-missing-imports --follow-imports=silent --strict-optional --warn-unused-ignores homeassistant/*.py homeassistant/util/' + /bin/bash -c 'mypy homeassistant/*.py homeassistant/util/' -- GitLab