mirror of
https://github.com/home-assistant/core.git
synced 2025-07-16 17:57:11 +00:00
Keep mypy.ini and strict-typing files sorted with hassfest (#81331)
hassfest: keep mypy.ini and .strict-typing sorted
This commit is contained in:
parent
4bf233a4c1
commit
727dcd6df6
@ -5,14 +5,10 @@
|
|||||||
# Strict typing is enabled by default for core files.
|
# Strict typing is enabled by default for core files.
|
||||||
# Add it here to add 'disallow_any_generics'.
|
# Add it here to add 'disallow_any_generics'.
|
||||||
# --- Only for core file! ---
|
# --- Only for core file! ---
|
||||||
homeassistant.exceptions
|
|
||||||
homeassistant.core
|
|
||||||
homeassistant.loader
|
|
||||||
homeassistant.requirements
|
|
||||||
homeassistant.runner
|
|
||||||
homeassistant.setup
|
|
||||||
homeassistant.auth.auth_store
|
homeassistant.auth.auth_store
|
||||||
homeassistant.auth.providers.*
|
homeassistant.auth.providers.*
|
||||||
|
homeassistant.core
|
||||||
|
homeassistant.exceptions
|
||||||
homeassistant.helpers.area_registry
|
homeassistant.helpers.area_registry
|
||||||
homeassistant.helpers.condition
|
homeassistant.helpers.condition
|
||||||
homeassistant.helpers.debounce
|
homeassistant.helpers.debounce
|
||||||
@ -29,6 +25,10 @@ homeassistant.helpers.script_variables
|
|||||||
homeassistant.helpers.singleton
|
homeassistant.helpers.singleton
|
||||||
homeassistant.helpers.sun
|
homeassistant.helpers.sun
|
||||||
homeassistant.helpers.translation
|
homeassistant.helpers.translation
|
||||||
|
homeassistant.loader
|
||||||
|
homeassistant.requirements
|
||||||
|
homeassistant.runner
|
||||||
|
homeassistant.setup
|
||||||
homeassistant.util.async_
|
homeassistant.util.async_
|
||||||
homeassistant.util.color
|
homeassistant.util.color
|
||||||
homeassistant.util.decorator
|
homeassistant.util.decorator
|
||||||
@ -79,9 +79,9 @@ homeassistant.components.button.*
|
|||||||
homeassistant.components.calendar.*
|
homeassistant.components.calendar.*
|
||||||
homeassistant.components.camera.*
|
homeassistant.components.camera.*
|
||||||
homeassistant.components.canary.*
|
homeassistant.components.canary.*
|
||||||
homeassistant.components.cover.*
|
|
||||||
homeassistant.components.clickatell.*
|
homeassistant.components.clickatell.*
|
||||||
homeassistant.components.clicksend.*
|
homeassistant.components.clicksend.*
|
||||||
|
homeassistant.components.cover.*
|
||||||
homeassistant.components.cpuspeed.*
|
homeassistant.components.cpuspeed.*
|
||||||
homeassistant.components.crownstone.*
|
homeassistant.components.crownstone.*
|
||||||
homeassistant.components.deconz.*
|
homeassistant.components.deconz.*
|
||||||
@ -215,9 +215,9 @@ homeassistant.components.prusalink.*
|
|||||||
homeassistant.components.pure_energie.*
|
homeassistant.components.pure_energie.*
|
||||||
homeassistant.components.pvoutput.*
|
homeassistant.components.pvoutput.*
|
||||||
homeassistant.components.qnap_qsw.*
|
homeassistant.components.qnap_qsw.*
|
||||||
|
homeassistant.components.radarr.*
|
||||||
homeassistant.components.rainmachine.*
|
homeassistant.components.rainmachine.*
|
||||||
homeassistant.components.rdw.*
|
homeassistant.components.rdw.*
|
||||||
homeassistant.components.radarr.*
|
|
||||||
homeassistant.components.recollect_waste.*
|
homeassistant.components.recollect_waste.*
|
||||||
homeassistant.components.recorder.*
|
homeassistant.components.recorder.*
|
||||||
homeassistant.components.remote.*
|
homeassistant.components.remote.*
|
||||||
|
74
mypy.ini
74
mypy.ini
@ -28,28 +28,16 @@ warn_unreachable = true
|
|||||||
[mypy-homeassistant.*]
|
[mypy-homeassistant.*]
|
||||||
no_implicit_reexport = true
|
no_implicit_reexport = true
|
||||||
|
|
||||||
[mypy-homeassistant.exceptions]
|
[mypy-homeassistant.auth.auth_store]
|
||||||
|
disallow_any_generics = true
|
||||||
|
|
||||||
|
[mypy-homeassistant.auth.providers.*]
|
||||||
disallow_any_generics = true
|
disallow_any_generics = true
|
||||||
|
|
||||||
[mypy-homeassistant.core]
|
[mypy-homeassistant.core]
|
||||||
disallow_any_generics = true
|
disallow_any_generics = true
|
||||||
|
|
||||||
[mypy-homeassistant.loader]
|
[mypy-homeassistant.exceptions]
|
||||||
disallow_any_generics = true
|
|
||||||
|
|
||||||
[mypy-homeassistant.requirements]
|
|
||||||
disallow_any_generics = true
|
|
||||||
|
|
||||||
[mypy-homeassistant.runner]
|
|
||||||
disallow_any_generics = true
|
|
||||||
|
|
||||||
[mypy-homeassistant.setup]
|
|
||||||
disallow_any_generics = true
|
|
||||||
|
|
||||||
[mypy-homeassistant.auth.auth_store]
|
|
||||||
disallow_any_generics = true
|
|
||||||
|
|
||||||
[mypy-homeassistant.auth.providers.*]
|
|
||||||
disallow_any_generics = true
|
disallow_any_generics = true
|
||||||
|
|
||||||
[mypy-homeassistant.helpers.area_registry]
|
[mypy-homeassistant.helpers.area_registry]
|
||||||
@ -100,6 +88,18 @@ disallow_any_generics = true
|
|||||||
[mypy-homeassistant.helpers.translation]
|
[mypy-homeassistant.helpers.translation]
|
||||||
disallow_any_generics = true
|
disallow_any_generics = true
|
||||||
|
|
||||||
|
[mypy-homeassistant.loader]
|
||||||
|
disallow_any_generics = true
|
||||||
|
|
||||||
|
[mypy-homeassistant.requirements]
|
||||||
|
disallow_any_generics = true
|
||||||
|
|
||||||
|
[mypy-homeassistant.runner]
|
||||||
|
disallow_any_generics = true
|
||||||
|
|
||||||
|
[mypy-homeassistant.setup]
|
||||||
|
disallow_any_generics = true
|
||||||
|
|
||||||
[mypy-homeassistant.util.async_]
|
[mypy-homeassistant.util.async_]
|
||||||
disallow_any_generics = true
|
disallow_any_generics = true
|
||||||
|
|
||||||
@ -543,16 +543,6 @@ disallow_untyped_defs = true
|
|||||||
warn_return_any = true
|
warn_return_any = true
|
||||||
warn_unreachable = true
|
warn_unreachable = true
|
||||||
|
|
||||||
[mypy-homeassistant.components.cover.*]
|
|
||||||
check_untyped_defs = true
|
|
||||||
disallow_incomplete_defs = true
|
|
||||||
disallow_subclassing_any = true
|
|
||||||
disallow_untyped_calls = true
|
|
||||||
disallow_untyped_decorators = true
|
|
||||||
disallow_untyped_defs = true
|
|
||||||
warn_return_any = true
|
|
||||||
warn_unreachable = true
|
|
||||||
|
|
||||||
[mypy-homeassistant.components.clickatell.*]
|
[mypy-homeassistant.components.clickatell.*]
|
||||||
check_untyped_defs = true
|
check_untyped_defs = true
|
||||||
disallow_incomplete_defs = true
|
disallow_incomplete_defs = true
|
||||||
@ -573,6 +563,16 @@ disallow_untyped_defs = true
|
|||||||
warn_return_any = true
|
warn_return_any = true
|
||||||
warn_unreachable = true
|
warn_unreachable = true
|
||||||
|
|
||||||
|
[mypy-homeassistant.components.cover.*]
|
||||||
|
check_untyped_defs = true
|
||||||
|
disallow_incomplete_defs = true
|
||||||
|
disallow_subclassing_any = true
|
||||||
|
disallow_untyped_calls = true
|
||||||
|
disallow_untyped_decorators = true
|
||||||
|
disallow_untyped_defs = true
|
||||||
|
warn_return_any = true
|
||||||
|
warn_unreachable = true
|
||||||
|
|
||||||
[mypy-homeassistant.components.cpuspeed.*]
|
[mypy-homeassistant.components.cpuspeed.*]
|
||||||
check_untyped_defs = true
|
check_untyped_defs = true
|
||||||
disallow_incomplete_defs = true
|
disallow_incomplete_defs = true
|
||||||
@ -1903,6 +1903,16 @@ disallow_untyped_defs = true
|
|||||||
warn_return_any = true
|
warn_return_any = true
|
||||||
warn_unreachable = true
|
warn_unreachable = true
|
||||||
|
|
||||||
|
[mypy-homeassistant.components.radarr.*]
|
||||||
|
check_untyped_defs = true
|
||||||
|
disallow_incomplete_defs = true
|
||||||
|
disallow_subclassing_any = true
|
||||||
|
disallow_untyped_calls = true
|
||||||
|
disallow_untyped_decorators = true
|
||||||
|
disallow_untyped_defs = true
|
||||||
|
warn_return_any = true
|
||||||
|
warn_unreachable = true
|
||||||
|
|
||||||
[mypy-homeassistant.components.rainmachine.*]
|
[mypy-homeassistant.components.rainmachine.*]
|
||||||
check_untyped_defs = true
|
check_untyped_defs = true
|
||||||
disallow_incomplete_defs = true
|
disallow_incomplete_defs = true
|
||||||
@ -1923,16 +1933,6 @@ disallow_untyped_defs = true
|
|||||||
warn_return_any = true
|
warn_return_any = true
|
||||||
warn_unreachable = true
|
warn_unreachable = true
|
||||||
|
|
||||||
[mypy-homeassistant.components.radarr.*]
|
|
||||||
check_untyped_defs = true
|
|
||||||
disallow_incomplete_defs = true
|
|
||||||
disallow_subclassing_any = true
|
|
||||||
disallow_untyped_calls = true
|
|
||||||
disallow_untyped_decorators = true
|
|
||||||
disallow_untyped_defs = true
|
|
||||||
warn_return_any = true
|
|
||||||
warn_unreachable = true
|
|
||||||
|
|
||||||
[mypy-homeassistant.components.recollect_waste.*]
|
[mypy-homeassistant.components.recollect_waste.*]
|
||||||
check_untyped_defs = true
|
check_untyped_defs = true
|
||||||
disallow_incomplete_defs = true
|
disallow_incomplete_defs = true
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
"""Generate mypy config."""
|
"""Generate mypy config."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Iterable
|
||||||
import configparser
|
import configparser
|
||||||
import io
|
import io
|
||||||
import os
|
import os
|
||||||
@ -90,18 +91,48 @@ def _strict_module_in_ignore_list(
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def generate_and_validate(config: Config) -> str:
|
def _sort_within_sections(line_iter: Iterable[str]) -> Iterable[str]:
|
||||||
|
"""
|
||||||
|
Sort lines within sections.
|
||||||
|
|
||||||
|
Sections are defined as anything not delimited by a blank line
|
||||||
|
or an octothorpe-prefixed comment line.
|
||||||
|
"""
|
||||||
|
section: list[str] = []
|
||||||
|
for line in line_iter:
|
||||||
|
if line.startswith("#") or not line.strip():
|
||||||
|
yield from sorted(section)
|
||||||
|
section.clear()
|
||||||
|
yield line
|
||||||
|
continue
|
||||||
|
section.append(line)
|
||||||
|
yield from sorted(section)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_strict_typing_path(config: Config) -> Path:
|
||||||
|
return config.root / ".strict-typing"
|
||||||
|
|
||||||
|
|
||||||
|
def _get_mypy_ini_path(config: Config) -> Path:
|
||||||
|
return config.root / "mypy.ini"
|
||||||
|
|
||||||
|
|
||||||
|
def _generate_and_validate_strict_typing(config: Config) -> str:
|
||||||
|
"""Validate and generate strict_typing."""
|
||||||
|
lines = [
|
||||||
|
line.strip()
|
||||||
|
for line in _get_strict_typing_path(config).read_text().splitlines()
|
||||||
|
]
|
||||||
|
return "\n".join(_sort_within_sections(lines)) + "\n"
|
||||||
|
|
||||||
|
|
||||||
|
def _generate_and_validate_mypy_config(config: Config) -> str:
|
||||||
"""Validate and generate mypy config."""
|
"""Validate and generate mypy config."""
|
||||||
|
|
||||||
config_path = config.root / ".strict-typing"
|
|
||||||
|
|
||||||
with config_path.open() as fp:
|
|
||||||
lines = fp.readlines()
|
|
||||||
|
|
||||||
# Filter empty and commented lines.
|
# Filter empty and commented lines.
|
||||||
parsed_modules: list[str] = [
|
parsed_modules: list[str] = [
|
||||||
line.strip()
|
line.strip()
|
||||||
for line in lines
|
for line in config.cache["strict_typing"].splitlines()
|
||||||
if line.strip() != "" and not line.startswith("#")
|
if line.strip() != "" and not line.startswith("#")
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -210,28 +241,36 @@ def generate_and_validate(config: Config) -> str:
|
|||||||
with io.StringIO() as fp:
|
with io.StringIO() as fp:
|
||||||
mypy_config.write(fp)
|
mypy_config.write(fp)
|
||||||
fp.seek(0)
|
fp.seek(0)
|
||||||
return HEADER + fp.read().strip()
|
return f"{HEADER}{fp.read().strip()}\n"
|
||||||
|
|
||||||
|
|
||||||
def validate(integrations: dict[str, Integration], config: Config) -> None:
|
def validate(integrations: dict[str, Integration], config: Config) -> None:
|
||||||
"""Validate mypy config."""
|
"""Validate strict_typing and mypy config."""
|
||||||
config_path = config.root / "mypy.ini"
|
strict_typing_content = _generate_and_validate_strict_typing(config)
|
||||||
config.cache["mypy_config"] = content = generate_and_validate(config)
|
config.cache["strict_typing"] = strict_typing_content
|
||||||
|
|
||||||
|
mypy_content = _generate_and_validate_mypy_config(config)
|
||||||
|
config.cache["mypy_config"] = mypy_content
|
||||||
|
|
||||||
if any(err.plugin == "mypy_config" for err in config.errors):
|
if any(err.plugin == "mypy_config" for err in config.errors):
|
||||||
return
|
return
|
||||||
|
|
||||||
with open(str(config_path)) as fp:
|
if _get_strict_typing_path(config).read_text() != strict_typing_content:
|
||||||
if fp.read().strip() != content:
|
config.add_error(
|
||||||
config.add_error(
|
"mypy_config",
|
||||||
"mypy_config",
|
"File .strict_typing is not up to date. Run python3 -m script.hassfest",
|
||||||
"File mypy.ini is not up to date. Run python3 -m script.hassfest",
|
fixable=True,
|
||||||
fixable=True,
|
)
|
||||||
)
|
|
||||||
|
if _get_mypy_ini_path(config).read_text() != mypy_content:
|
||||||
|
config.add_error(
|
||||||
|
"mypy_config",
|
||||||
|
"File mypy.ini is not up to date. Run python3 -m script.hassfest",
|
||||||
|
fixable=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def generate(integrations: dict[str, Integration], config: Config) -> None:
|
def generate(integrations: dict[str, Integration], config: Config) -> None:
|
||||||
"""Generate mypy config."""
|
"""Generate strict_typing and mypy config."""
|
||||||
config_path = config.root / "mypy.ini"
|
_get_mypy_ini_path(config).write_text(config.cache["mypy_config"])
|
||||||
with open(str(config_path), "w") as fp:
|
_get_strict_typing_path(config).write_text(config.cache["strict_typing"])
|
||||||
fp.write(f"{config.cache['mypy_config']}\n")
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user