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**
This commit is contained in:
Andrey 2018-07-13 20:14:45 +03:00 committed by GitHub
parent ae581694ac
commit e60f9ca392
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 30 additions and 19 deletions

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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):

View File

@ -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):

View File

@ -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)

11
mypy.ini Normal file
View File

@ -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

View File

@ -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/'