mirror of
https://github.com/home-assistant/core.git
synced 2026-05-08 17:49:37 +01:00
Add support for Python 3.14 (#153939)
This commit is contained in:
@@ -42,7 +42,7 @@ env:
|
||||
MYPY_CACHE_VERSION: 1
|
||||
HA_SHORT_VERSION: "2025.11"
|
||||
DEFAULT_PYTHON: "3.13"
|
||||
ALL_PYTHON_VERSIONS: "['3.13']"
|
||||
ALL_PYTHON_VERSIONS: "['3.13', '3.14']"
|
||||
# 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
|
||||
|
||||
@@ -5,14 +5,9 @@ from __future__ import annotations
|
||||
import asyncio
|
||||
import logging
|
||||
from random import randrange
|
||||
import sys
|
||||
from typing import Any, cast
|
||||
|
||||
from pyatv import connect, exceptions, scan
|
||||
from pyatv.conf import AppleTV
|
||||
from pyatv.const import DeviceModel, Protocol
|
||||
from pyatv.convert import model_str
|
||||
from pyatv.interface import AppleTV as AppleTVInterface, DeviceListener
|
||||
|
||||
from homeassistant.components import zeroconf
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import (
|
||||
@@ -29,7 +24,11 @@ from homeassistant.const import (
|
||||
Platform,
|
||||
)
|
||||
from homeassistant.core import Event, HomeAssistant, callback
|
||||
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
|
||||
from homeassistant.exceptions import (
|
||||
ConfigEntryAuthFailed,
|
||||
ConfigEntryNotReady,
|
||||
HomeAssistantError,
|
||||
)
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||
@@ -43,6 +42,18 @@ from .const import (
|
||||
SIGNAL_DISCONNECTED,
|
||||
)
|
||||
|
||||
if sys.version_info < (3, 14):
|
||||
from pyatv import connect, exceptions, scan
|
||||
from pyatv.conf import AppleTV
|
||||
from pyatv.const import DeviceModel, Protocol
|
||||
from pyatv.convert import model_str
|
||||
from pyatv.interface import AppleTV as AppleTVInterface, DeviceListener
|
||||
else:
|
||||
|
||||
class DeviceListener:
|
||||
"""Dummy class."""
|
||||
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DEFAULT_NAME_TV = "Apple TV"
|
||||
@@ -53,31 +64,41 @@ BACKOFF_TIME_UPPER_LIMIT = 300 # Five minutes
|
||||
|
||||
PLATFORMS = [Platform.MEDIA_PLAYER, Platform.REMOTE]
|
||||
|
||||
AUTH_EXCEPTIONS = (
|
||||
exceptions.AuthenticationError,
|
||||
exceptions.InvalidCredentialsError,
|
||||
exceptions.NoCredentialsError,
|
||||
)
|
||||
CONNECTION_TIMEOUT_EXCEPTIONS = (
|
||||
OSError,
|
||||
asyncio.CancelledError,
|
||||
TimeoutError,
|
||||
exceptions.ConnectionLostError,
|
||||
exceptions.ConnectionFailedError,
|
||||
)
|
||||
DEVICE_EXCEPTIONS = (
|
||||
exceptions.ProtocolError,
|
||||
exceptions.NoServiceError,
|
||||
exceptions.PairingError,
|
||||
exceptions.BackOffError,
|
||||
exceptions.DeviceIdMissingError,
|
||||
)
|
||||
if sys.version_info < (3, 14):
|
||||
AUTH_EXCEPTIONS = (
|
||||
exceptions.AuthenticationError,
|
||||
exceptions.InvalidCredentialsError,
|
||||
exceptions.NoCredentialsError,
|
||||
)
|
||||
CONNECTION_TIMEOUT_EXCEPTIONS = (
|
||||
OSError,
|
||||
asyncio.CancelledError,
|
||||
TimeoutError,
|
||||
exceptions.ConnectionLostError,
|
||||
exceptions.ConnectionFailedError,
|
||||
)
|
||||
DEVICE_EXCEPTIONS = (
|
||||
exceptions.ProtocolError,
|
||||
exceptions.NoServiceError,
|
||||
exceptions.PairingError,
|
||||
exceptions.BackOffError,
|
||||
exceptions.DeviceIdMissingError,
|
||||
)
|
||||
else:
|
||||
AUTH_EXCEPTIONS = ()
|
||||
CONNECTION_TIMEOUT_EXCEPTIONS = ()
|
||||
DEVICE_EXCEPTIONS = ()
|
||||
|
||||
|
||||
type AppleTvConfigEntry = ConfigEntry[AppleTVManager]
|
||||
|
||||
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: AppleTvConfigEntry) -> bool:
|
||||
"""Set up a config entry for Apple TV."""
|
||||
if sys.version_info >= (3, 14):
|
||||
raise HomeAssistantError(
|
||||
"Apple TV is not supported on Python 3.14. Please use Python 3.13."
|
||||
)
|
||||
manager = AppleTVManager(hass, entry)
|
||||
|
||||
if manager.is_on:
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"documentation": "https://www.home-assistant.io/integrations/apple_tv",
|
||||
"iot_class": "local_push",
|
||||
"loggers": ["pyatv", "srptools"],
|
||||
"requirements": ["pyatv==0.16.1"],
|
||||
"requirements": ["pyatv==0.16.1;python_version<'3.14'"],
|
||||
"zeroconf": [
|
||||
"_mediaremotetv._tcp.local.",
|
||||
"_companion-link._tcp.local.",
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
"""The Logitech Harmony Hub integration."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import sys
|
||||
|
||||
from homeassistant.components.remote import ATTR_ACTIVITY, ATTR_DELAY_SECS
|
||||
from homeassistant.const import CONF_HOST, CONF_NAME, EVENT_HOMEASSISTANT_STOP
|
||||
from homeassistant.core import Event, HomeAssistant, callback
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||
|
||||
from .const import HARMONY_OPTIONS_UPDATE, PLATFORMS
|
||||
from .data import HarmonyConfigEntry, HarmonyData
|
||||
if sys.version_info < (3, 14):
|
||||
from .const import HARMONY_OPTIONS_UPDATE, PLATFORMS
|
||||
from .data import HarmonyConfigEntry, HarmonyData
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@@ -20,6 +25,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: HarmonyConfigEntry) -> b
|
||||
# when setting up a config entry, we fallback to adding
|
||||
# the options to the config entry and pull them out here if
|
||||
# they are missing from the options
|
||||
if sys.version_info >= (3, 14):
|
||||
raise HomeAssistantError(
|
||||
"Logitech Harmony Hub is not supported on Python 3.14. Please use Python 3.13."
|
||||
)
|
||||
_async_import_options_from_data_if_missing(hass, entry)
|
||||
|
||||
address = entry.data[CONF_HOST]
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"documentation": "https://www.home-assistant.io/integrations/harmony",
|
||||
"iot_class": "local_push",
|
||||
"loggers": ["aioharmony", "slixmpp"],
|
||||
"requirements": ["aioharmony==0.5.3"],
|
||||
"requirements": ["aioharmony==0.5.3;python_version<'3.14'"],
|
||||
"ssdp": [
|
||||
{
|
||||
"manufacturer": "Logitech",
|
||||
|
||||
@@ -453,6 +453,10 @@ async def _async_generate_memory_profile(hass: HomeAssistant, call: ServiceCall)
|
||||
# Imports deferred to avoid loading modules
|
||||
# in memory since usually only one part of this
|
||||
# integration is used at a time
|
||||
if sys.version_info >= (3, 14):
|
||||
raise HomeAssistantError(
|
||||
"Memory profiling is not supported on Python 3.14. Please use Python 3.13."
|
||||
)
|
||||
from guppy import hpy # noqa: PLC0415
|
||||
|
||||
start_time = int(time.time() * 1000000)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"quality_scale": "internal",
|
||||
"requirements": [
|
||||
"pyprof2calltree==1.4.5",
|
||||
"guppy3==3.1.5",
|
||||
"guppy3==3.1.5;python_version<'3.14'",
|
||||
"objgraph==3.5.0"
|
||||
],
|
||||
"single_config_entry": true
|
||||
|
||||
@@ -5,5 +5,8 @@
|
||||
"documentation": "https://www.home-assistant.io/integrations/python_script",
|
||||
"loggers": ["RestrictedPython"],
|
||||
"quality_scale": "internal",
|
||||
"requirements": ["RestrictedPython==8.0"]
|
||||
"requirements": [
|
||||
"RestrictedPython==8.0;python_version<'3.14'",
|
||||
"RestrictedPython==8.1a1.dev0;python_version>='3.14'"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ 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
|
||||
@@ -53,6 +54,18 @@ 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,
|
||||
)
|
||||
|
||||
num_threads = len(self._threads)
|
||||
if num_threads < self._max_workers:
|
||||
thread_name = f"{self._thread_name_prefix or self}_{num_threads}"
|
||||
@@ -63,9 +76,7 @@ class DBInterruptibleThreadPoolExecutor(InterruptibleThreadPoolExecutor):
|
||||
self._shutdown_hook,
|
||||
self.recorder_and_worker_thread_ids,
|
||||
weakref.ref(self, weakref_cb),
|
||||
self._work_queue,
|
||||
self._initializer,
|
||||
self._initargs,
|
||||
*(additional_args),
|
||||
),
|
||||
)
|
||||
executor_thread.start()
|
||||
|
||||
@@ -6,5 +6,8 @@
|
||||
"iot_class": "cloud_push",
|
||||
"loggers": ["pyasn1", "slixmpp"],
|
||||
"quality_scale": "legacy",
|
||||
"requirements": ["slixmpp==1.10.0", "emoji==2.8.0"]
|
||||
"requirements": [
|
||||
"slixmpp==1.10.0;python_version<'3.14'",
|
||||
"emoji==2.8.0;python_version<'3.14'"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -9,16 +9,9 @@ import mimetypes
|
||||
import pathlib
|
||||
import random
|
||||
import string
|
||||
import sys
|
||||
|
||||
import requests
|
||||
import slixmpp
|
||||
from slixmpp.exceptions import IqError, IqTimeout, XMPPError
|
||||
from slixmpp.plugins.xep_0363.http_upload import (
|
||||
FileTooBig,
|
||||
FileUploadError,
|
||||
UploadServiceNotFound,
|
||||
)
|
||||
from slixmpp.xmlstream.xmlstream import NotConnectedError
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.notify import (
|
||||
@@ -35,9 +28,20 @@ from homeassistant.const import (
|
||||
CONF_SENDER,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers import config_validation as cv, template as template_helper
|
||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||
|
||||
if sys.version_info < (3, 14):
|
||||
import slixmpp
|
||||
from slixmpp.exceptions import IqError, IqTimeout, XMPPError
|
||||
from slixmpp.plugins.xep_0363.http_upload import (
|
||||
FileTooBig,
|
||||
FileUploadError,
|
||||
UploadServiceNotFound,
|
||||
)
|
||||
from slixmpp.xmlstream.xmlstream import NotConnectedError
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
ATTR_DATA = "data"
|
||||
@@ -74,6 +78,10 @@ async def async_get_service(
|
||||
discovery_info: DiscoveryInfoType | None = None,
|
||||
) -> XmppNotificationService:
|
||||
"""Get the Jabber (XMPP) notification service."""
|
||||
if sys.version_info >= (3, 14):
|
||||
raise HomeAssistantError(
|
||||
"Jabber (XMPP) is not supported on Python 3.14. Please use Python 3.13."
|
||||
)
|
||||
return XmppNotificationService(
|
||||
config.get(CONF_SENDER),
|
||||
config.get(CONF_RESOURCE),
|
||||
|
||||
@@ -132,8 +132,8 @@ backoff>=2.0
|
||||
# ensure pydantic version does not float since it might have breaking changes
|
||||
pydantic==2.12.2
|
||||
|
||||
# Required for Python 3.12.4 compatibility (#119223).
|
||||
mashumaro>=3.13.1
|
||||
# Required for Python 3.14.0 compatibility (#119223).
|
||||
mashumaro>=3.17.0
|
||||
|
||||
# Breaks asyncio
|
||||
# https://github.com/pubnub/python/issues/130
|
||||
|
||||
@@ -10,6 +10,11 @@ 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
|
||||
|
||||
@@ -19,7 +24,7 @@ def _class_fields(cls: type, kw_only: bool) -> list[tuple[str, Any, Any]]:
|
||||
|
||||
Extracted from dataclasses._process_class.
|
||||
"""
|
||||
cls_annotations = cls.__dict__.get("__annotations__", {})
|
||||
cls_annotations = get_annotations(cls, format=Format.FORWARDREF)
|
||||
|
||||
cls_fields: list[dataclasses.Field[Any]] = []
|
||||
|
||||
@@ -96,8 +101,16 @@ class FrozenOrThawed(type):
|
||||
for parent in cls.__mro__[::-1]:
|
||||
if parent is object:
|
||||
continue
|
||||
annotations |= parent.__annotations__
|
||||
cls.__annotations__ = annotations
|
||||
annotations |= get_annotations(parent, format=Format.FORWARDREF)
|
||||
|
||||
if "__annotations__" in cls.__dict__ or sys.version_info < (3, 14):
|
||||
cls.__annotations__ = annotations
|
||||
else:
|
||||
|
||||
def wrapped_annotate(format: Format) -> dict:
|
||||
return annotations
|
||||
|
||||
cls.__annotate__ = wrapped_annotate
|
||||
return
|
||||
|
||||
# First try without setting the kw_only flag, and if that fails, try setting it
|
||||
|
||||
@@ -19,6 +19,7 @@ classifiers = [
|
||||
"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"
|
||||
@@ -569,6 +570,11 @@ filterwarnings = [
|
||||
# https://pypi.org/project/opuslib/ - v3.0.1 - 2018-01-16
|
||||
# https://pypi.org/project/pyiss/ - v1.0.1 - 2016-12-19
|
||||
"ignore:\"is.*\" with '.*' literal:SyntaxWarning:importlib._bootstrap",
|
||||
# - SyntaxWarning - return in finally
|
||||
# https://github.com/nextcord/nextcord/pull/1268 - v3.1.1 - 2025-08-16
|
||||
# https://github.com/Python-roborock/python-roborock/ - >=2.50.4
|
||||
# https://pypi.org/project/sleekxmppfs/ - v1.4.1 - 2022-08-18
|
||||
"ignore:'return' in a 'finally' block:SyntaxWarning:importlib._bootstrap",
|
||||
|
||||
# -- New in Python 3.13
|
||||
# https://github.com/youknowone/python-deadlib - Backports for aifc, telnetlib
|
||||
@@ -577,6 +583,28 @@ filterwarnings = [
|
||||
"ignore:telnetlib was removed in Python 3.13.*'standard-telnetlib':DeprecationWarning:ndms2_client.connection",
|
||||
"ignore:telnetlib was removed in Python 3.13.*'standard-telnetlib':DeprecationWarning:pyws66i",
|
||||
|
||||
# -- New in Python 3.14
|
||||
# https://github.com/kumaraditya303/aioshutil - v1.5 - 2024-07-20
|
||||
"ignore:'shutil.ExecError' is deprecated and slated for removal in Python 3.16:DeprecationWarning:aioshutil",
|
||||
# https://github.com/litl/backoff/pull/220 - v2.2.1 - 2022-10-05 (archived)
|
||||
"ignore:'asyncio.iscoroutinefunction' is deprecated and slated for removal in Python 3.16:DeprecationWarning:(backoff._decorator|backoff._async)",
|
||||
# https://github.com/albertogeniola/elmax-api - v0.0.6.3 - 2024-11-30
|
||||
"ignore:'asyncio.iscoroutinefunction' is deprecated and slated for removal in Python 3.16:DeprecationWarning:elmax_api.http",
|
||||
# https://github.com/py-mine/mcstatus - v12.0.5 - 2025-08-13
|
||||
"ignore:'asyncio.iscoroutinefunction' is deprecated and slated for removal in Python 3.16:DeprecationWarning:mcstatus.utils",
|
||||
# https://github.com/nextcord/nextcord/pull/1269 - v3.1.1 - 2025-08-16
|
||||
"ignore:'asyncio.iscoroutinefunction' is deprecated and slated for removal in Python 3.16:DeprecationWarning:nextcord.member",
|
||||
# https://github.com/andrewsayre/pyheos/pull/124 - >1.0.5
|
||||
"ignore:'asyncio.iscoroutinefunction' is deprecated and slated for removal in Python 3.16:DeprecationWarning:pyheos.dispatch",
|
||||
# https://github.com/SteveEasley/pykaleidescape/pull/7 - v2022.2.6 - 2022-03-07
|
||||
"ignore:'asyncio.iscoroutinefunction' is deprecated and slated for removal in Python 3.16:DeprecationWarning:kaleidescape.dispatcher",
|
||||
# https://github.com/svinota/pyroute2
|
||||
"ignore:Due to '_pack_', the '.*' Structure will use memory layout compatible with MSVC:DeprecationWarning:pyroute2.ethtool.ioctl",
|
||||
# https://github.com/googleapis/python-genai
|
||||
"ignore:'_UnionGenericAlias' is deprecated and slated for removal in Python 3.17:DeprecationWarning:google.genai.types",
|
||||
# https://github.com/pyusb/pyusb
|
||||
"ignore:Due to '_pack_', the '.*' Structure will use memory layout compatible with MSVC:DeprecationWarning:usb.backend.libusb0",
|
||||
|
||||
# -- Websockets 14.1
|
||||
# https://websockets.readthedocs.io/en/stable/howto/upgrade.html
|
||||
"ignore:websockets.legacy is deprecated:DeprecationWarning:websockets.legacy",
|
||||
|
||||
Generated
+9
-6
@@ -109,7 +109,10 @@ PyXiaomiGateway==0.14.3
|
||||
RachioPy==1.1.0
|
||||
|
||||
# homeassistant.components.python_script
|
||||
RestrictedPython==8.0
|
||||
RestrictedPython==8.0;python_version<'3.14'
|
||||
|
||||
# homeassistant.components.python_script
|
||||
RestrictedPython==8.1a1.dev0;python_version>='3.14'
|
||||
|
||||
# homeassistant.components.remember_the_milk
|
||||
RtmAPI==0.7.2
|
||||
@@ -268,7 +271,7 @@ aiogithubapi==24.6.0
|
||||
aioguardian==2022.07.0
|
||||
|
||||
# homeassistant.components.harmony
|
||||
aioharmony==0.5.3
|
||||
aioharmony==0.5.3;python_version<'3.14'
|
||||
|
||||
# homeassistant.components.hassio
|
||||
aiohasupervisor==0.3.3
|
||||
@@ -883,7 +886,7 @@ elmax-api==0.0.6.4rc0
|
||||
elvia==0.1.0
|
||||
|
||||
# homeassistant.components.xmpp
|
||||
emoji==2.8.0
|
||||
emoji==2.8.0;python_version<'3.14'
|
||||
|
||||
# homeassistant.components.emulated_roku
|
||||
emulated-roku==0.3.0
|
||||
@@ -1127,7 +1130,7 @@ gspread==5.5.0
|
||||
gstreamer-player==1.1.2
|
||||
|
||||
# homeassistant.components.profiler
|
||||
guppy3==3.1.5
|
||||
guppy3==3.1.5;python_version<'3.14'
|
||||
|
||||
# homeassistant.components.iaqualink
|
||||
h2==4.3.0
|
||||
@@ -1885,7 +1888,7 @@ pyatag==0.3.5.3
|
||||
pyatmo==9.2.3
|
||||
|
||||
# homeassistant.components.apple_tv
|
||||
pyatv==0.16.1
|
||||
pyatv==0.16.1;python_version<'3.14'
|
||||
|
||||
# homeassistant.components.aussie_broadband
|
||||
pyaussiebb==0.1.5
|
||||
@@ -2846,7 +2849,7 @@ skyboxremote==0.0.6
|
||||
slack_sdk==3.33.4
|
||||
|
||||
# homeassistant.components.xmpp
|
||||
slixmpp==1.10.0
|
||||
slixmpp==1.10.0;python_version<'3.14'
|
||||
|
||||
# homeassistant.components.smart_meter_texas
|
||||
smart-meter-texas==0.5.5
|
||||
|
||||
Generated
+7
-4
@@ -103,7 +103,10 @@ PyXiaomiGateway==0.14.3
|
||||
RachioPy==1.1.0
|
||||
|
||||
# homeassistant.components.python_script
|
||||
RestrictedPython==8.0
|
||||
RestrictedPython==8.0;python_version<'3.14'
|
||||
|
||||
# homeassistant.components.python_script
|
||||
RestrictedPython==8.1a1.dev0;python_version>='3.14'
|
||||
|
||||
# homeassistant.components.remember_the_milk
|
||||
RtmAPI==0.7.2
|
||||
@@ -253,7 +256,7 @@ aiogithubapi==24.6.0
|
||||
aioguardian==2022.07.0
|
||||
|
||||
# homeassistant.components.harmony
|
||||
aioharmony==0.5.3
|
||||
aioharmony==0.5.3;python_version<'3.14'
|
||||
|
||||
# homeassistant.components.hassio
|
||||
aiohasupervisor==0.3.3
|
||||
@@ -988,7 +991,7 @@ gspread==5.5.0
|
||||
gstreamer-player==1.1.2
|
||||
|
||||
# homeassistant.components.profiler
|
||||
guppy3==3.1.5
|
||||
guppy3==3.1.5;python_version<'3.14'
|
||||
|
||||
# homeassistant.components.iaqualink
|
||||
h2==4.3.0
|
||||
@@ -1593,7 +1596,7 @@ pyatag==0.3.5.3
|
||||
pyatmo==9.2.3
|
||||
|
||||
# homeassistant.components.apple_tv
|
||||
pyatv==0.16.1
|
||||
pyatv==0.16.1;python_version<'3.14'
|
||||
|
||||
# homeassistant.components.aussie_broadband
|
||||
pyaussiebb==0.1.5
|
||||
|
||||
@@ -157,8 +157,8 @@ backoff>=2.0
|
||||
# ensure pydantic version does not float since it might have breaking changes
|
||||
pydantic==2.12.2
|
||||
|
||||
# Required for Python 3.12.4 compatibility (#119223).
|
||||
mashumaro>=3.13.1
|
||||
# Required for Python 3.14.0 compatibility (#119223).
|
||||
mashumaro>=3.17.0
|
||||
|
||||
# Breaks asyncio
|
||||
# https://github.com/pubnub/python/issues/130
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
"""Tests for Apple TV."""
|
||||
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
# Make asserts in the common module display differences
|
||||
pytest.register_assert_rewrite("tests.components.apple_tv.common")
|
||||
if sys.version_info < (3, 14):
|
||||
# Make asserts in the common module display differences
|
||||
pytest.register_assert_rewrite("tests.components.apple_tv.common")
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
"""Fixtures for component."""
|
||||
|
||||
from collections.abc import Generator
|
||||
import sys
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
from pyatv import conf
|
||||
from pyatv.const import PairingRequirement, Protocol
|
||||
from pyatv.support import http
|
||||
import pytest
|
||||
|
||||
from .common import MockPairingHandler, airplay_service, create_conf, mrp_service
|
||||
if sys.version_info < (3, 14):
|
||||
from pyatv import conf
|
||||
from pyatv.const import PairingRequirement, Protocol
|
||||
from pyatv.support import http
|
||||
|
||||
from .common import MockPairingHandler, airplay_service, create_conf, mrp_service
|
||||
|
||||
if sys.version_info >= (3, 14):
|
||||
collect_ignore_glob = ["test_*.py"]
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True, name="mock_scan")
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
"""Fixtures for harmony tests."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Generator
|
||||
import sys
|
||||
from unittest.mock import AsyncMock, MagicMock, PropertyMock, patch
|
||||
|
||||
from aioharmony.const import ClientCallbackType
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.harmony.const import ACTIVITY_POWER_OFF, DOMAIN
|
||||
@@ -18,6 +20,13 @@ from .const import (
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
if sys.version_info < (3, 14):
|
||||
from aioharmony.const import ClientCallbackType
|
||||
|
||||
if sys.version_info >= (3, 14):
|
||||
collect_ignore_glob = ["test_*.py"]
|
||||
|
||||
|
||||
ACTIVITIES_TO_IDS = {
|
||||
ACTIVITY_POWER_OFF: -1,
|
||||
"Watch TV": WATCH_TV_ACTIVITY_ID,
|
||||
|
||||
@@ -6,6 +6,7 @@ import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
import socket
|
||||
import sys
|
||||
from unittest.mock import patch
|
||||
|
||||
from freezegun.api import FrozenDateTimeFactory
|
||||
@@ -72,6 +73,9 @@ async def test_basic_usage(hass: HomeAssistant, tmp_path: Path) -> None:
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
sys.version_info >= (3, 14), reason="not yet available on Python 3.14"
|
||||
)
|
||||
async def test_memory_usage(hass: HomeAssistant, tmp_path: Path) -> None:
|
||||
"""Test we can setup and the service is registered."""
|
||||
test_dir = tmp_path / "profiles"
|
||||
@@ -103,6 +107,24 @@ async def test_memory_usage(hass: HomeAssistant, tmp_path: Path) -> None:
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
||||
@pytest.mark.skipif(sys.version_info < (3, 14), reason="still works on python 3.13")
|
||||
async def test_memory_usage_py313(hass: HomeAssistant, tmp_path: Path) -> None:
|
||||
"""Test raise an error on python3.13."""
|
||||
entry = MockConfigEntry(domain=DOMAIN)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
assert await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
assert hass.services.has_service(DOMAIN, SERVICE_MEMORY)
|
||||
with pytest.raises(
|
||||
HomeAssistantError,
|
||||
match="Memory profiling is not supported on Python 3.14. Please use Python 3.13.",
|
||||
):
|
||||
await hass.services.async_call(
|
||||
DOMAIN, SERVICE_MEMORY, {CONF_SECONDS: 0.000001}, blocking=True
|
||||
)
|
||||
|
||||
|
||||
async def test_object_growth_logging(
|
||||
hass: HomeAssistant,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
|
||||
Reference in New Issue
Block a user