mirror of
https://github.com/home-assistant/core.git
synced 2026-01-22 15:46:58 +01:00
Compare commits
5 Commits
dev
...
edenhaus-3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1780477655 | ||
|
|
34fd679f2c | ||
|
|
4dbe42213c | ||
|
|
4fb0d99964 | ||
|
|
cd01e623ff |
2
.github/workflows/builder.yml
vendored
2
.github/workflows/builder.yml
vendored
@@ -10,7 +10,7 @@ on:
|
||||
|
||||
env:
|
||||
BUILD_TYPE: core
|
||||
DEFAULT_PYTHON: "3.13"
|
||||
DEFAULT_PYTHON: "3.14.2"
|
||||
PIP_TIMEOUT: 60
|
||||
UV_HTTP_TIMEOUT: 60
|
||||
UV_SYSTEM_PYTHON: "true"
|
||||
|
||||
4
.github/workflows/ci.yaml
vendored
4
.github/workflows/ci.yaml
vendored
@@ -41,8 +41,8 @@ env:
|
||||
UV_CACHE_VERSION: 1
|
||||
MYPY_CACHE_VERSION: 1
|
||||
HA_SHORT_VERSION: "2026.2"
|
||||
DEFAULT_PYTHON: "3.13.11"
|
||||
ALL_PYTHON_VERSIONS: "['3.13.11', '3.14.2']"
|
||||
DEFAULT_PYTHON: "3.14.2"
|
||||
ALL_PYTHON_VERSIONS: "['3.14.2']"
|
||||
# 10.3 is the oldest supported version
|
||||
# - 10.3.32 is the version currently shipped with Synology (as of 17 Feb 2022)
|
||||
# 10.6 is the current long-term-support
|
||||
|
||||
2
.github/workflows/translations.yml
vendored
2
.github/workflows/translations.yml
vendored
@@ -10,7 +10,7 @@ on:
|
||||
- "**strings.json"
|
||||
|
||||
env:
|
||||
DEFAULT_PYTHON: "3.13"
|
||||
DEFAULT_PYTHON: "3.14.2"
|
||||
|
||||
jobs:
|
||||
upload:
|
||||
|
||||
2
.github/workflows/wheels.yml
vendored
2
.github/workflows/wheels.yml
vendored
@@ -17,7 +17,7 @@ on:
|
||||
- "script/gen_requirements_all.py"
|
||||
|
||||
env:
|
||||
DEFAULT_PYTHON: "3.13"
|
||||
DEFAULT_PYTHON: "3.14.2"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref_name}}
|
||||
|
||||
@@ -1 +1 @@
|
||||
3.13
|
||||
3.14
|
||||
|
||||
@@ -4,7 +4,6 @@ from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
from concurrent.futures.thread import _threads_queues, _worker
|
||||
import sys
|
||||
import threading
|
||||
from typing import Any
|
||||
import weakref
|
||||
@@ -54,17 +53,10 @@ class DBInterruptibleThreadPoolExecutor(InterruptibleThreadPoolExecutor):
|
||||
) -> None:
|
||||
q.put(None)
|
||||
|
||||
if sys.version_info >= (3, 14):
|
||||
additional_args = (
|
||||
self._create_worker_context(),
|
||||
self._work_queue,
|
||||
)
|
||||
else:
|
||||
additional_args = (
|
||||
self._work_queue,
|
||||
self._initializer,
|
||||
self._initargs,
|
||||
)
|
||||
additional_args = (
|
||||
self._create_worker_context(),
|
||||
self._work_queue,
|
||||
)
|
||||
|
||||
num_threads = len(self._threads)
|
||||
if num_threads < self._max_workers:
|
||||
|
||||
@@ -253,7 +253,7 @@ async def get_coap_context(hass: HomeAssistant) -> COAP:
|
||||
ipv4: list[IPv4Address] = []
|
||||
if not network.async_only_default_interface_enabled(adapters):
|
||||
ipv4.extend(
|
||||
address
|
||||
cast(IPv4Address, address)
|
||||
for address in await network.async_get_enabled_source_ips(hass)
|
||||
if address.version == 4
|
||||
and not (
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from ipaddress import IPv4Address, IPv6Address
|
||||
from typing import cast
|
||||
|
||||
from homeassistant.components import network
|
||||
from homeassistant.core import HomeAssistant
|
||||
@@ -15,5 +16,8 @@ async def async_build_source_set(hass: HomeAssistant) -> set[IPv4Address | IPv6A
|
||||
for source_ip in await network.async_get_enabled_source_ips(hass)
|
||||
if not source_ip.is_loopback
|
||||
and not source_ip.is_global
|
||||
and ((source_ip.version == 6 and source_ip.scope_id) or source_ip.version == 4)
|
||||
and (
|
||||
(source_ip.version == 6 and cast(IPv6Address, source_ip).scope_id)
|
||||
or source_ip.version == 4
|
||||
)
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@ import asyncio
|
||||
from collections.abc import Callable, Coroutine, Mapping
|
||||
from datetime import timedelta
|
||||
from enum import Enum
|
||||
from ipaddress import IPv4Address
|
||||
from ipaddress import IPv4Address, IPv6Address
|
||||
import logging
|
||||
from typing import TYPE_CHECKING, Any
|
||||
from typing import TYPE_CHECKING, Any, cast
|
||||
|
||||
from async_upnp_client.aiohttp import AiohttpSessionRequester
|
||||
from async_upnp_client.const import AddressTupleVXType, DeviceOrServiceType, SsdpSource
|
||||
@@ -260,6 +260,7 @@ class Scanner:
|
||||
for source_ip in await async_build_source_set(self.hass):
|
||||
source_ip_str = str(source_ip)
|
||||
if source_ip.version == 6:
|
||||
source_ip = cast(IPv6Address, source_ip)
|
||||
assert source_ip.scope_id is not None
|
||||
source_tuple: AddressTupleVXType = (
|
||||
source_ip_str,
|
||||
|
||||
@@ -4,10 +4,11 @@ from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from contextlib import ExitStack
|
||||
from ipaddress import IPv6Address
|
||||
import logging
|
||||
import socket
|
||||
from time import time
|
||||
from typing import Any
|
||||
from typing import Any, cast
|
||||
from urllib.parse import urljoin
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
@@ -171,6 +172,7 @@ class Server:
|
||||
for source_ip in await async_build_source_set(self.hass):
|
||||
source_ip_str = str(source_ip)
|
||||
if source_ip.version == 6:
|
||||
source_ip = cast(IPv6Address, source_ip)
|
||||
assert source_ip.scope_id is not None
|
||||
source_tuple: AddressTupleVXType = (
|
||||
source_ip_str,
|
||||
|
||||
@@ -165,7 +165,7 @@ def number(
|
||||
attribute: str,
|
||||
minimum: float | None = None,
|
||||
maximum: float | None = None,
|
||||
return_type: type[float] | type[int] = float,
|
||||
return_type: type[float | int] = float,
|
||||
**kwargs: Any,
|
||||
) -> Callable[[Any], float | int | None]:
|
||||
"""Convert the result to a number (float or int).
|
||||
|
||||
@@ -47,7 +47,7 @@ class VeluxEntity(Entity):
|
||||
|
||||
_attr_should_poll = False
|
||||
_attr_has_entity_name = True
|
||||
update_callback: Callable[["Node"], Awaitable[None]] | None = None
|
||||
update_callback: Callable[[Node], Awaitable[None]] | None = None
|
||||
_attr_available = True
|
||||
_unavailable_logged = False
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@ MINOR_VERSION: Final = 2
|
||||
PATCH_VERSION: Final = "0.dev0"
|
||||
__short_version__: Final = f"{MAJOR_VERSION}.{MINOR_VERSION}"
|
||||
__version__: Final = f"{__short_version__}.{PATCH_VERSION}"
|
||||
REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 13, 2)
|
||||
REQUIRED_NEXT_PYTHON_VER: Final[tuple[int, int, int]] = (3, 13, 2)
|
||||
REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 14, 2)
|
||||
REQUIRED_NEXT_PYTHON_VER: Final[tuple[int, int, int]] = (3, 14, 2)
|
||||
# Truthy date string triggers showing related deprecation warning messages.
|
||||
REQUIRED_NEXT_PYTHON_HA_RELEASE: Final = ""
|
||||
|
||||
|
||||
@@ -173,7 +173,7 @@ class RuntimeConfig:
|
||||
safe_mode: bool = False
|
||||
|
||||
|
||||
class HassEventLoopPolicy(asyncio.DefaultEventLoopPolicy):
|
||||
class HassEventLoopPolicy(asyncio.DefaultEventLoopPolicy): # type: ignore[name-defined,misc]
|
||||
"""Event loop policy for Home Assistant."""
|
||||
|
||||
def __init__(self, debug: bool) -> None:
|
||||
@@ -184,7 +184,7 @@ class HassEventLoopPolicy(asyncio.DefaultEventLoopPolicy):
|
||||
@property
|
||||
def loop_name(self) -> str:
|
||||
"""Return name of the loop."""
|
||||
return self._loop_factory.__name__ # type: ignore[no-any-return,attr-defined]
|
||||
return self._loop_factory.__name__ # type: ignore[no-any-return]
|
||||
|
||||
def new_event_loop(self) -> asyncio.AbstractEventLoop:
|
||||
"""Get the event loop."""
|
||||
@@ -281,7 +281,7 @@ def run(runtime_config: RuntimeConfig) -> int:
|
||||
"""Run Home Assistant."""
|
||||
_enable_posix_spawn()
|
||||
set_open_file_descriptor_limit()
|
||||
asyncio.set_event_loop_policy(HassEventLoopPolicy(runtime_config.debug))
|
||||
asyncio.set_event_loop_policy(HassEventLoopPolicy(runtime_config.debug)) # type: ignore[deprecated]
|
||||
# Backport of cpython 3.9 asyncio.run with a _cancel_all_tasks that times out
|
||||
loop = asyncio.new_event_loop()
|
||||
try:
|
||||
|
||||
@@ -61,7 +61,7 @@ def run(args: list[str]) -> int:
|
||||
print("Aborting script, could not install dependency", req)
|
||||
return 1
|
||||
|
||||
asyncio.set_event_loop_policy(runner.HassEventLoopPolicy(False))
|
||||
asyncio.set_event_loop_policy(runner.HassEventLoopPolicy(False)) # type: ignore[deprecated]
|
||||
|
||||
return script.run(args[1:])
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ def run(args: Sequence[str] | None) -> None:
|
||||
parser_change_pw.add_argument("new_password", type=str)
|
||||
parser_change_pw.set_defaults(func=change_password)
|
||||
|
||||
asyncio.set_event_loop_policy(runner.HassEventLoopPolicy(False))
|
||||
asyncio.set_event_loop_policy(runner.HassEventLoopPolicy(False)) # type: ignore[deprecated]
|
||||
asyncio.run(run_command(parser.parse_args(args)))
|
||||
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ def run(args):
|
||||
args = parser.parse_args()
|
||||
|
||||
bench = BENCHMARKS[args.name]
|
||||
print("Using event loop:", asyncio.get_event_loop_policy().loop_name)
|
||||
print("Using event loop:", asyncio.get_event_loop_policy().loop_name) # type: ignore[deprecated]
|
||||
|
||||
with suppress(KeyboardInterrupt):
|
||||
while True:
|
||||
|
||||
@@ -6,15 +6,11 @@ derived from EntityDescription and sub classes thereof.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from annotationlib import Format, get_annotations
|
||||
import dataclasses
|
||||
import sys
|
||||
from typing import TYPE_CHECKING, Any, cast, dataclass_transform
|
||||
|
||||
if sys.version_info >= (3, 14):
|
||||
from annotationlib import Format, get_annotations
|
||||
else:
|
||||
from typing_extensions import Format, get_annotations
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from _typeshed import DataclassInstance
|
||||
|
||||
@@ -103,7 +99,7 @@ class FrozenOrThawed(type):
|
||||
continue
|
||||
annotations |= get_annotations(parent, format=Format.FORWARDREF)
|
||||
|
||||
if "__annotations__" in cls.__dict__ or sys.version_info < (3, 14):
|
||||
if "__annotations__" in cls.__dict__:
|
||||
cls.__annotations__ = annotations
|
||||
else:
|
||||
|
||||
|
||||
2
mypy.ini
generated
2
mypy.ini
generated
@@ -3,7 +3,7 @@
|
||||
# To update, run python3 -m script.hassfest -p mypy_config
|
||||
|
||||
[mypy]
|
||||
python_version = 3.13
|
||||
python_version = 3.14
|
||||
platform = linux
|
||||
plugins = pydantic.mypy, pydantic.v1.mypy
|
||||
show_error_codes = true
|
||||
|
||||
@@ -18,11 +18,10 @@ classifiers = [
|
||||
"Intended Audience :: End Users/Desktop",
|
||||
"Intended Audience :: Developers",
|
||||
"Operating System :: OS Independent",
|
||||
"Programming Language :: Python :: 3.13",
|
||||
"Programming Language :: Python :: 3.14",
|
||||
"Topic :: Home Automation",
|
||||
]
|
||||
requires-python = ">=3.13.2"
|
||||
requires-python = ">=3.14.2"
|
||||
dependencies = [
|
||||
"aiodns==4.0.0",
|
||||
# Integrations may depend on hassio integration without listing it to
|
||||
@@ -102,7 +101,7 @@ include-package-data = true
|
||||
include = ["homeassistant*"]
|
||||
|
||||
[tool.pylint.MAIN]
|
||||
py-version = "3.13"
|
||||
py-version = "3.14"
|
||||
# Use a conservative default here; 2 should speed up most setups and not hurt
|
||||
# any too bad. Override on command line as appropriate.
|
||||
jobs = 2
|
||||
|
||||
@@ -80,7 +80,7 @@ WORKDIR /config
|
||||
_HASSFEST_TEMPLATE = r"""# Automatically generated by hassfest.
|
||||
#
|
||||
# To update, run python3 -m script.hassfest -p docker
|
||||
FROM python:3.13-alpine
|
||||
FROM python:3.14-alpine
|
||||
|
||||
ENV \
|
||||
UV_SYSTEM_PYTHON=true \
|
||||
|
||||
2
script/hassfest/docker/Dockerfile
generated
2
script/hassfest/docker/Dockerfile
generated
@@ -1,7 +1,7 @@
|
||||
# Automatically generated by hassfest.
|
||||
#
|
||||
# To update, run python3 -m script.hassfest -p docker
|
||||
FROM python:3.13-alpine
|
||||
FROM python:3.14-alpine
|
||||
|
||||
ENV \
|
||||
UV_SYSTEM_PYTHON=true \
|
||||
|
||||
@@ -380,7 +380,7 @@ async def test_cloud_heater(
|
||||
before_attrs: dict,
|
||||
service_name: str,
|
||||
service_params: dict,
|
||||
effect: "contextlib.AbstractContextManager",
|
||||
effect: contextlib.AbstractContextManager,
|
||||
heater_control_calls: list,
|
||||
heater_set_temp_calls: list,
|
||||
after_state: HVACMode,
|
||||
@@ -533,7 +533,7 @@ async def test_local_heater(
|
||||
before_attrs: dict,
|
||||
service_name: str,
|
||||
service_params: dict,
|
||||
effect: "contextlib.AbstractContextManager",
|
||||
effect: contextlib.AbstractContextManager,
|
||||
heater_mode_set_individually_calls: list,
|
||||
heater_mode_set_off_calls: list,
|
||||
heater_set_target_temperature_calls: list,
|
||||
|
||||
@@ -139,7 +139,7 @@ async def test_sensors(hass: HomeAssistant) -> None:
|
||||
class CoordinatorStub:
|
||||
"""Coordinator stub for testing entity restoration behavior."""
|
||||
|
||||
instances: list["CoordinatorStub"] = []
|
||||
instances: list[CoordinatorStub] = []
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
|
||||
Reference in New Issue
Block a user