diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 4a7ad03f218..ba4a37fda14 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -39,7 +39,7 @@ env: BLACK_CACHE_VERSION: 1 HA_SHORT_VERSION: "2023.11" DEFAULT_PYTHON: "3.11" - ALL_PYTHON_VERSIONS: "['3.11']" + ALL_PYTHON_VERSIONS: "['3.11', '3.12']" # 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 diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index 83f81b0cd4a..f3bab1872c7 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -82,7 +82,7 @@ jobs: strategy: fail-fast: false matrix: - abi: ["cp311"] + abi: ["cp311", "cp312"] arch: ${{ fromJson(needs.init.outputs.architectures) }} steps: - name: Checkout the repository @@ -112,7 +112,7 @@ jobs: requirements-diff: "requirements_diff.txt" requirements: "requirements.txt" - integrations_cp311: + integrations: name: Build wheels ${{ matrix.abi }} for ${{ matrix.arch }} if: github.repository_owner == 'home-assistant' needs: init @@ -120,7 +120,7 @@ jobs: strategy: fail-fast: false matrix: - abi: ["cp311"] + abi: ["cp311", "cp312"] arch: ${{ fromJson(needs.init.outputs.architectures) }} steps: - name: Checkout the repository diff --git a/homeassistant/components/apache_kafka/__init__.py b/homeassistant/components/apache_kafka/__init__.py index 38a70b450ab..c974735791e 100644 --- a/homeassistant/components/apache_kafka/__init__.py +++ b/homeassistant/components/apache_kafka/__init__.py @@ -1,8 +1,8 @@ """Support for Apache Kafka.""" from datetime import datetime import json +import sys -from aiokafka import AIOKafkaProducer import voluptuous as vol from homeassistant.const import ( @@ -16,11 +16,16 @@ from homeassistant.const import ( STATE_UNKNOWN, ) from homeassistant.core import HomeAssistant +from homeassistant.exceptions import HomeAssistantError import homeassistant.helpers.config_validation as cv from homeassistant.helpers.entityfilter import FILTER_SCHEMA from homeassistant.helpers.typing import ConfigType from homeassistant.util import ssl as ssl_util +if sys.version_info < (3, 12): + from aiokafka import AIOKafkaProducer + + DOMAIN = "apache_kafka" CONF_FILTER = "filter" @@ -49,6 +54,10 @@ CONFIG_SCHEMA = vol.Schema( async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Activate the Apache Kafka integration.""" + if sys.version_info >= (3, 12): + raise HomeAssistantError( + "Apache Kafka is not supported on Python 3.12. Please use Python 3.11." + ) conf = config[DOMAIN] kafka = hass.data[DOMAIN] = KafkaManager( diff --git a/homeassistant/components/brother/__init__.py b/homeassistant/components/brother/__init__.py index 27ac97a27dc..0f8f94c73c4 100644 --- a/homeassistant/components/brother/__init__.py +++ b/homeassistant/components/brother/__init__.py @@ -4,18 +4,23 @@ from __future__ import annotations from asyncio import timeout from datetime import timedelta import logging - -from brother import Brother, BrotherSensors, SnmpError, UnsupportedModelError +import sys +from typing import Any from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_HOST, CONF_TYPE, Platform from homeassistant.core import HomeAssistant -from homeassistant.exceptions import ConfigEntryNotReady +from homeassistant.exceptions import ConfigEntryNotReady, HomeAssistantError from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from .const import DATA_CONFIG_ENTRY, DOMAIN, SNMP from .utils import get_snmp_engine +if sys.version_info < (3, 12): + from brother import Brother, BrotherSensors, SnmpError, UnsupportedModelError +else: + BrotherSensors = Any + PLATFORMS = [Platform.SENSOR] SCAN_INTERVAL = timedelta(seconds=30) @@ -25,6 +30,10 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up Brother from a config entry.""" + if sys.version_info >= (3, 12): + raise HomeAssistantError( + "Brother Printer is not supported on Python 3.12. Please use Python 3.11." + ) host = entry.data[CONF_HOST] printer_type = entry.data[CONF_TYPE] diff --git a/homeassistant/components/brother/utils.py b/homeassistant/components/brother/utils.py index e421be52154..cd472b9b754 100644 --- a/homeassistant/components/brother/utils.py +++ b/homeassistant/components/brother/utils.py @@ -1,8 +1,8 @@ """Brother helpers functions.""" -import logging +from __future__ import annotations -import pysnmp.hlapi.asyncio as hlapi -from pysnmp.hlapi.asyncio.cmdgen import lcd +import logging +import sys from homeassistant.const import EVENT_HOMEASSISTANT_STOP from homeassistant.core import Event, HomeAssistant, callback @@ -10,6 +10,10 @@ from homeassistant.helpers import singleton from .const import DOMAIN, SNMP +if sys.version_info < (3, 12): + import pysnmp.hlapi.asyncio as hlapi + from pysnmp.hlapi.asyncio.cmdgen import lcd + _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/cisco_webex_teams/manifest.json b/homeassistant/components/cisco_webex_teams/manifest.json index 4fe333f40a5..6f4e1ead956 100644 --- a/homeassistant/components/cisco_webex_teams/manifest.json +++ b/homeassistant/components/cisco_webex_teams/manifest.json @@ -5,5 +5,5 @@ "documentation": "https://www.home-assistant.io/integrations/cisco_webex_teams", "iot_class": "cloud_push", "loggers": ["webexteamssdk"], - "requirements": ["webexteamssdk==1.1.1"] + "requirements": ["webexteamssdk==1.1.1;python_version<'3.12'"] } diff --git a/homeassistant/components/cisco_webex_teams/notify.py b/homeassistant/components/cisco_webex_teams/notify.py index be8710c7096..d2c75d78390 100644 --- a/homeassistant/components/cisco_webex_teams/notify.py +++ b/homeassistant/components/cisco_webex_teams/notify.py @@ -2,9 +2,9 @@ from __future__ import annotations import logging +import sys import voluptuous as vol -from webexteamssdk import ApiError, WebexTeamsAPI, exceptions from homeassistant.components.notify import ( ATTR_TITLE, @@ -13,9 +13,14 @@ from homeassistant.components.notify import ( ) from homeassistant.const import CONF_TOKEN from homeassistant.core import HomeAssistant +from homeassistant.exceptions import HomeAssistantError import homeassistant.helpers.config_validation as cv from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType +if sys.version_info < (3, 12): + from webexteamssdk import ApiError, WebexTeamsAPI, exceptions + + _LOGGER = logging.getLogger(__name__) CONF_ROOM_ID = "room_id" @@ -31,6 +36,10 @@ def get_service( discovery_info: DiscoveryInfoType | None = None, ) -> CiscoWebexTeamsNotificationService | None: """Get the CiscoWebexTeams notification service.""" + if sys.version_info >= (3, 12): + raise HomeAssistantError( + "Cisco Webex Teams is not supported on Python 3.12. Please use Python 3.11." + ) client = WebexTeamsAPI(access_token=config[CONF_TOKEN]) try: diff --git a/homeassistant/components/metoffice/__init__.py b/homeassistant/components/metoffice/__init__.py index a658de9a024..e00215f6073 100644 --- a/homeassistant/components/metoffice/__init__.py +++ b/homeassistant/components/metoffice/__init__.py @@ -4,10 +4,9 @@ from __future__ import annotations import asyncio import logging import re +import sys from typing import Any -import datapoint - from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( CONF_API_KEY, @@ -17,7 +16,7 @@ from homeassistant.const import ( Platform, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.exceptions import ConfigEntryNotReady +from homeassistant.exceptions import ConfigEntryNotReady, HomeAssistantError from homeassistant.helpers import device_registry as dr, entity_registry as er from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.update_coordinator import TimestampDataUpdateCoordinator @@ -35,6 +34,9 @@ from .const import ( from .data import MetOfficeData from .helpers import fetch_data, fetch_site +if sys.version_info < (3, 12): + import datapoint + _LOGGER = logging.getLogger(__name__) PLATFORMS = [Platform.SENSOR, Platform.WEATHER] @@ -42,6 +44,10 @@ PLATFORMS = [Platform.SENSOR, Platform.WEATHER] async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up a Met Office entry.""" + if sys.version_info >= (3, 12): + raise HomeAssistantError( + "Met Office is not supported on Python 3.12. Please use Python 3.11." + ) latitude = entry.data[CONF_LATITUDE] longitude = entry.data[CONF_LONGITUDE] diff --git a/homeassistant/components/metoffice/data.py b/homeassistant/components/metoffice/data.py index 4b2741ce0fb..8512dd4c7a6 100644 --- a/homeassistant/components/metoffice/data.py +++ b/homeassistant/components/metoffice/data.py @@ -1,11 +1,13 @@ """Common Met Office Data class used by both sensor and entity.""" - +from __future__ import annotations from dataclasses import dataclass +import sys -from datapoint.Forecast import Forecast -from datapoint.Site import Site -from datapoint.Timestep import Timestep +if sys.version_info < (3, 12): + from datapoint.Forecast import Forecast + from datapoint.Site import Site + from datapoint.Timestep import Timestep @dataclass diff --git a/homeassistant/components/metoffice/helpers.py b/homeassistant/components/metoffice/helpers.py index cdd506790ef..389462d573a 100644 --- a/homeassistant/components/metoffice/helpers.py +++ b/homeassistant/components/metoffice/helpers.py @@ -2,9 +2,7 @@ from __future__ import annotations import logging - -import datapoint -from datapoint.Site import Site +import sys from homeassistant.helpers.update_coordinator import UpdateFailed from homeassistant.util.dt import utcnow @@ -12,6 +10,11 @@ from homeassistant.util.dt import utcnow from .const import MODE_3HOURLY from .data import MetOfficeData +if sys.version_info < (3, 12): + import datapoint + from datapoint.Site import Site + + _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/metoffice/manifest.json b/homeassistant/components/metoffice/manifest.json index cfe6e6de9cd..9291f22f3b7 100644 --- a/homeassistant/components/metoffice/manifest.json +++ b/homeassistant/components/metoffice/manifest.json @@ -6,5 +6,5 @@ "documentation": "https://www.home-assistant.io/integrations/metoffice", "iot_class": "cloud_polling", "loggers": ["datapoint"], - "requirements": ["datapoint==0.9.8"] + "requirements": ["datapoint==0.9.8;python_version<'3.12'"] } diff --git a/homeassistant/components/profiler/__init__.py b/homeassistant/components/profiler/__init__.py index 8c5c206ae9f..8b0252e7fa7 100644 --- a/homeassistant/components/profiler/__init__.py +++ b/homeassistant/components/profiler/__init__.py @@ -402,6 +402,11 @@ 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, 12): + raise HomeAssistantError( + "Memory profiling is not supported on Python 3.12. Please use Python 3.11." + ) + from guppy import hpy # pylint: disable=import-outside-toplevel start_time = int(time.time() * 1000000) diff --git a/homeassistant/components/profiler/manifest.json b/homeassistant/components/profiler/manifest.json index 1b33c778843..eeb0a182ee3 100644 --- a/homeassistant/components/profiler/manifest.json +++ b/homeassistant/components/profiler/manifest.json @@ -5,5 +5,9 @@ "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/profiler", "quality_scale": "internal", - "requirements": ["pyprof2calltree==1.4.5", "guppy3==3.1.3", "objgraph==3.5.0"] + "requirements": [ + "pyprof2calltree==1.4.5", + "guppy3==3.1.3;python_version<'3.12'", + "objgraph==3.5.0" + ] } diff --git a/homeassistant/components/python_script/manifest.json b/homeassistant/components/python_script/manifest.json index 80ed6164e74..bd034053a34 100644 --- a/homeassistant/components/python_script/manifest.json +++ b/homeassistant/components/python_script/manifest.json @@ -5,5 +5,8 @@ "documentation": "https://www.home-assistant.io/integrations/python_script", "loggers": ["RestrictedPython"], "quality_scale": "internal", - "requirements": ["RestrictedPython==6.2"] + "requirements": [ + "RestrictedPython==6.2;python_version<'3.12'", + "RestrictedPython==7.0a1.dev0;python_version>='3.12'" + ] } diff --git a/homeassistant/components/snmp/device_tracker.py b/homeassistant/components/snmp/device_tracker.py index 696b079fd5e..7ca31bae618 100644 --- a/homeassistant/components/snmp/device_tracker.py +++ b/homeassistant/components/snmp/device_tracker.py @@ -3,9 +3,8 @@ from __future__ import annotations import binascii import logging +import sys -from pysnmp.entity import config as cfg -from pysnmp.entity.rfc3413.oneliner import cmdgen import voluptuous as vol from homeassistant.components.device_tracker import ( @@ -15,6 +14,7 @@ from homeassistant.components.device_tracker import ( ) from homeassistant.const import CONF_HOST from homeassistant.core import HomeAssistant +from homeassistant.exceptions import HomeAssistantError import homeassistant.helpers.config_validation as cv from homeassistant.helpers.typing import ConfigType @@ -26,6 +26,11 @@ from .const import ( DEFAULT_COMMUNITY, ) +if sys.version_info < (3, 12): + from pysnmp.entity import config as cfg + from pysnmp.entity.rfc3413.oneliner import cmdgen + + _LOGGER = logging.getLogger(__name__) PLATFORM_SCHEMA = PARENT_PLATFORM_SCHEMA.extend( @@ -41,6 +46,10 @@ PLATFORM_SCHEMA = PARENT_PLATFORM_SCHEMA.extend( def get_scanner(hass: HomeAssistant, config: ConfigType) -> SnmpScanner | None: """Validate the configuration and return an SNMP scanner.""" + if sys.version_info >= (3, 12): + raise HomeAssistantError( + "SNMP is not supported on Python 3.12. Please use Python 3.11." + ) scanner = SnmpScanner(config[DOMAIN]) return scanner if scanner.success_init else None diff --git a/homeassistant/components/snmp/sensor.py b/homeassistant/components/snmp/sensor.py index a5915183ad0..58cd12d611f 100644 --- a/homeassistant/components/snmp/sensor.py +++ b/homeassistant/components/snmp/sensor.py @@ -3,20 +3,8 @@ from __future__ import annotations from datetime import timedelta import logging +import sys -from pysnmp.error import PySnmpError -import pysnmp.hlapi.asyncio as hlapi -from pysnmp.hlapi.asyncio import ( - CommunityData, - ContextData, - ObjectIdentity, - ObjectType, - SnmpEngine, - Udp6TransportTarget, - UdpTransportTarget, - UsmUserData, - getCmd, -) import voluptuous as vol from homeassistant.components.sensor import CONF_STATE_CLASS, PLATFORM_SCHEMA @@ -33,6 +21,7 @@ from homeassistant.const import ( STATE_UNKNOWN, ) from homeassistant.core import HomeAssistant +from homeassistant.exceptions import HomeAssistantError import homeassistant.helpers.config_validation as cv from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.template import Template @@ -67,6 +56,21 @@ from .const import ( SNMP_VERSIONS, ) +if sys.version_info < (3, 12): + from pysnmp.error import PySnmpError + import pysnmp.hlapi.asyncio as hlapi + from pysnmp.hlapi.asyncio import ( + CommunityData, + ContextData, + ObjectIdentity, + ObjectType, + SnmpEngine, + Udp6TransportTarget, + UdpTransportTarget, + UsmUserData, + getCmd, + ) + _LOGGER = logging.getLogger(__name__) SCAN_INTERVAL = timedelta(seconds=10) @@ -111,6 +115,10 @@ async def async_setup_platform( discovery_info: DiscoveryInfoType | None = None, ) -> None: """Set up the SNMP sensor.""" + if sys.version_info >= (3, 12): + raise HomeAssistantError( + "SNMP is not supported on Python 3.12. Please use Python 3.11." + ) host = config.get(CONF_HOST) port = config.get(CONF_PORT) community = config.get(CONF_COMMUNITY) diff --git a/homeassistant/components/snmp/switch.py b/homeassistant/components/snmp/switch.py index d0fe393d550..e94c6991601 100644 --- a/homeassistant/components/snmp/switch.py +++ b/homeassistant/components/snmp/switch.py @@ -2,34 +2,9 @@ from __future__ import annotations import logging +import sys from typing import Any -import pysnmp.hlapi.asyncio as hlapi -from pysnmp.hlapi.asyncio import ( - CommunityData, - ContextData, - ObjectIdentity, - ObjectType, - SnmpEngine, - UdpTransportTarget, - UsmUserData, - getCmd, - setCmd, -) -from pysnmp.proto.rfc1902 import ( - Counter32, - Counter64, - Gauge32, - Integer, - Integer32, - IpAddress, - Null, - ObjectIdentifier, - OctetString, - Opaque, - TimeTicks, - Unsigned32, -) import voluptuous as vol from homeassistant.components.switch import PLATFORM_SCHEMA, SwitchEntity @@ -42,6 +17,7 @@ from homeassistant.const import ( CONF_USERNAME, ) from homeassistant.core import HomeAssistant +from homeassistant.exceptions import HomeAssistantError import homeassistant.helpers.config_validation as cv from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType @@ -67,6 +43,34 @@ from .const import ( SNMP_VERSIONS, ) +if sys.version_info < (3, 12): + import pysnmp.hlapi.asyncio as hlapi + from pysnmp.hlapi.asyncio import ( + CommunityData, + ContextData, + ObjectIdentity, + ObjectType, + SnmpEngine, + UdpTransportTarget, + UsmUserData, + getCmd, + setCmd, + ) + from pysnmp.proto.rfc1902 import ( + Counter32, + Counter64, + Gauge32, + Integer, + Integer32, + IpAddress, + Null, + ObjectIdentifier, + OctetString, + Opaque, + TimeTicks, + Unsigned32, + ) + _LOGGER = logging.getLogger(__name__) CONF_COMMAND_OID = "command_oid" @@ -77,21 +81,22 @@ DEFAULT_COMMUNITY = "private" DEFAULT_PAYLOAD_OFF = 0 DEFAULT_PAYLOAD_ON = 1 -MAP_SNMP_VARTYPES = { - "Counter32": Counter32, - "Counter64": Counter64, - "Gauge32": Gauge32, - "Integer32": Integer32, - "Integer": Integer, - "IpAddress": IpAddress, - "Null": Null, - # some work todo to support tuple ObjectIdentifier, this just supports str - "ObjectIdentifier": ObjectIdentifier, - "OctetString": OctetString, - "Opaque": Opaque, - "TimeTicks": TimeTicks, - "Unsigned32": Unsigned32, -} +if sys.version_info < (3, 12): + MAP_SNMP_VARTYPES = { + "Counter32": Counter32, + "Counter64": Counter64, + "Gauge32": Gauge32, + "Integer32": Integer32, + "Integer": Integer, + "IpAddress": IpAddress, + "Null": Null, + # some work todo to support tuple ObjectIdentifier, this just supports str + "ObjectIdentifier": ObjectIdentifier, + "OctetString": OctetString, + "Opaque": Opaque, + "TimeTicks": TimeTicks, + "Unsigned32": Unsigned32, + } PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { @@ -127,6 +132,10 @@ async def async_setup_platform( discovery_info: DiscoveryInfoType | None = None, ) -> None: """Set up the SNMP switch.""" + if sys.version_info >= (3, 12): + raise HomeAssistantError( + "SNMP is not supported on Python 3.12. Please use Python 3.11." + ) name = config.get(CONF_NAME) host = config.get(CONF_HOST) port = config.get(CONF_PORT) diff --git a/homeassistant/components/vulcan/__init__.py b/homeassistant/components/vulcan/__init__.py index 0bfd09d590d..b52b4181510 100644 --- a/homeassistant/components/vulcan/__init__.py +++ b/homeassistant/components/vulcan/__init__.py @@ -1,21 +1,32 @@ """The Vulcan component.""" +import sys from aiohttp import ClientConnectorError -from vulcan import Account, Keystore, UnauthorizedCertificateException, Vulcan from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady +from homeassistant.exceptions import ( + ConfigEntryAuthFailed, + ConfigEntryNotReady, + HomeAssistantError, +) from homeassistant.helpers.aiohttp_client import async_get_clientsession from .const import DOMAIN +if sys.version_info < (3, 12): + from vulcan import Account, Keystore, UnauthorizedCertificateException, Vulcan + PLATFORMS = [Platform.CALENDAR] async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up Uonet+ Vulcan integration.""" + if sys.version_info >= (3, 12): + raise HomeAssistantError( + "Uonet+ Vulcan is not supported on Python 3.12. Please use Python 3.11." + ) hass.data.setdefault(DOMAIN, {}) try: keystore = Keystore.load(entry.data["keystore"]) diff --git a/pyproject.toml b/pyproject.toml index 9b8642172ce..15a33f2cbf3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -439,6 +439,8 @@ filterwarnings = [ "ignore:ssl.TLSVersion.TLSv1 is deprecated:DeprecationWarning:elkm1_lib.util", # https://github.com/michaeldavie/env_canada/blob/v0.5.37/env_canada/ec_cache.py "ignore:Inheritance class CacheClientSession from ClientSession is discouraged:DeprecationWarning:env_canada.ec_cache", + # https://github.com/allenporter/ical/pull/215 - v5.0.0 + "ignore:datetime.*utcnow\\(\\) is deprecated and scheduled for removal:DeprecationWarning:ical.util", # https://github.com/bachya/regenmaschine/blob/2023.08.0/regenmaschine/client.py#L51 "ignore:ssl.TLSVersion.SSLv3 is deprecated:DeprecationWarning:regenmaschine.client", @@ -451,6 +453,13 @@ filterwarnings = [ # -- tracked upstream / open PRs # https://github.com/caronc/apprise/issues/659 - v1.4.5 "ignore:Use setlocale\\(\\), getencoding\\(\\) and getlocale\\(\\) instead:DeprecationWarning:apprise.AppriseLocal", + # https://github.com/kiorky/croniter/issues/49 - v1.4.1 + "ignore:datetime.*utcfromtimestamp\\(\\) is deprecated and scheduled for removal:DeprecationWarning:croniter.croniter", + # https://github.com/spulec/freezegun/issues/508 - v1.2.2 + # https://github.com/spulec/freezegun/pull/511 + "ignore:datetime.*utcnow\\(\\) is deprecated and scheduled for removal:DeprecationWarning:freezegun.api", + # https://github.com/influxdata/influxdb-client-python/issues/603 - v1.37.0 + "ignore:datetime.*utcfromtimestamp\\(\\) is deprecated and scheduled for removal:DeprecationWarning:influxdb_client.client.write.point", # https://github.com/beetbox/mediafile/issues/67 - v0.12.0 "ignore:'imghdr' is deprecated and slated for removal in Python 3.13:DeprecationWarning:mediafile", # https://github.com/eclipse/paho.mqtt.python/issues/653 - v1.6.1 @@ -458,6 +467,8 @@ filterwarnings = [ "ignore:ssl.PROTOCOL_TLS is deprecated:DeprecationWarning:paho.mqtt.client", # https://github.com/PythonCharmers/python-future/issues/488 - v0.18.3 "ignore:the imp module is deprecated in favour of importlib and slated for removal in Python 3.12:DeprecationWarning:future.standard_library", + # https://github.com/frenck/python-toonapi/pull/9 - v0.2.1 - 2021-09-23 + "ignore:datetime.*utcnow\\(\\) is deprecated and scheduled for removal:DeprecationWarning:toonapi.models", # https://github.com/foxel/python_ndms2_client/issues/6 - v0.1.2 "ignore:'telnetlib' is deprecated and slated for removal in Python 3.13:DeprecationWarning:ndms2_client.connection", # https://github.com/pytest-dev/pytest-cov/issues/557 - v4.1.0 @@ -465,14 +476,40 @@ filterwarnings = [ "ignore:The --rsyncdir command line argument and rsyncdirs config variable are deprecated:DeprecationWarning:xdist.plugin", # -- fixed, waiting for release / update + # https://github.com/ludeeus/aiogithubapi/pull/208 - >=23.9.0 + "ignore:datetime.*utcnow\\(\\) is deprecated and scheduled for removal:DeprecationWarning:aiogithubapi.namespaces.events", + # https://github.com/bachya/aiopurpleair/pull/200 - >2023.08.0 + "ignore:datetime.*utcfromtimestamp\\(\\) is deprecated and scheduled for removal:DeprecationWarning:aiopurpleair.helpers.validators", + # https://github.com/scrapinghub/dateparser/pull/1179 - >1.1.8 + "ignore:datetime.*utcnow\\(\\) is deprecated and scheduled for removal:DeprecationWarning:dateparser.timezone_parser", + # https://github.com/zopefoundation/DateTime/pull/55 - >5.2 + "ignore:datetime.*utcfromtimestamp\\(\\) is deprecated and scheduled for removal:DeprecationWarning:DateTime.pytz_support", # https://github.com/kurtmckee/feedparser/issues/330 - >6.0.10 "ignore:'cgi' is deprecated and slated for removal in Python 3.13:DeprecationWarning:feedparser.encodings", # https://github.com/jaraco/jaraco.abode/commit/9e3e789efc96cddcaa15f920686bbeb79a7469e0 - update jaraco.abode to >=5.1.0 "ignore:`jaraco.functools.call_aside` is deprecated, use `jaraco.functools.invoke` instead:DeprecationWarning:jaraco.abode.helpers.timeline", # https://github.com/nextcord/nextcord/pull/1095 - >2.6.1 "ignore:pkg_resources is deprecated as an API:DeprecationWarning:nextcord.health_check", + # https://github.com/pytest-dev/pytest/pull/10894 - >=7.4.0 + "ignore:ast.(Str|Num|NameConstant) is deprecated and will be removed in Python 3.14:DeprecationWarning:_pytest.assertion.rewrite", + "ignore:Attribute s is deprecated and will be removed in Python 3.14:DeprecationWarning:_pytest.assertion.rewrite", + # https://github.com/bachya/pytile/pull/280 - >2023.08.0 + "ignore:datetime.*utcfromtimestamp\\(\\) is deprecated and scheduled for removal:DeprecationWarning:pytile.tile", + # https://github.com/rytilahti/python-miio/pull/1809 - >0.5.12 + "ignore:datetime.*utcnow\\(\\) is deprecated and scheduled for removal:DeprecationWarning:miio.protocol", + "ignore:datetime.*utcnow\\(\\) is deprecated and scheduled for removal:DeprecationWarning:miio.miioprotocol", + # https://github.com/hunterjm/python-onvif-zeep-async/pull/51 - >3.1.12 + "ignore:datetime.*utcnow\\(\\) is deprecated and scheduled for removal:DeprecationWarning:onvif.client", + # Fixed upstream in python-telegram-bot - >=20.0 + "ignore:python-telegram-bot is using upstream urllib3:UserWarning:telegram.utils.request", + # https://github.com/ludeeus/pytraccar/pull/15 - >1.0.0 + "ignore:datetime.*utcnow\\(\\) is deprecated and scheduled for removal:DeprecationWarning:pytraccar.client", + # https://github.com/zopefoundation/RestrictedPython/pull/259 - >7.0a1.dev0 + "ignore:ast\\.(Str|Num) is deprecated and will be removed in Python 3.14:DeprecationWarning:RestrictedPython.transformer", # https://github.com/grahamwetzler/smart-meter-texas/pull/143 - >0.5.3 "ignore:ssl.OP_NO_SSL\\*/ssl.OP_NO_TLS\\* options are deprecated:DeprecationWarning:smart_meter_texas", + # https://github.com/Bluetooth-Devices/xiaomi-ble/pull/59 - >0.21.1 + "ignore:datetime.*utcfromtimestamp\\(\\) is deprecated and scheduled for removal:DeprecationWarning:xiaomi_ble.parser", # -- not helpful # pyatmo.__init__ imports deprecated moduls from itself - v7.5.0 @@ -482,6 +519,17 @@ filterwarnings = [ # Locale changes might take some time to resolve upstream "ignore:Use setlocale\\(\\), getencoding\\(\\) and getlocale\\(\\) instead:DeprecationWarning:homematicip.base.base_connection", "ignore:Use setlocale\\(\\), getencoding\\(\\) and getlocale\\(\\) instead:DeprecationWarning:micloud.micloud", + # https://github.com/protocolbuffers/protobuf - v4.24.4 + "ignore:datetime.*utcfromtimestamp\\(\\) is deprecated and scheduled for removal:DeprecationWarning:google.protobuf.internal.well_known_types", + "ignore:Type google._upb._message.(Message|Scalar)MapContainer uses PyType_Spec with a metaclass that has custom tp_new. .* Python 3.14:DeprecationWarning", + # https://github.com/googleapis/google-auth-library-python/blob/v2.23.3/google/auth/_helpers.py#L95 - v2.23.3 + "ignore:datetime.*utcnow\\(\\) is deprecated:DeprecationWarning:google.auth._helpers", + # https://github.com/googleapis/proto-plus-python/blob/v1.22.3/proto/datetime_helpers.py#L24 - v1.22.3 + "ignore:datetime.*utcfromtimestamp\\(\\) is deprecated:DeprecationWarning:proto.datetime_helpers", + # https://github.com/MatsNl/pyatag/issues/11 - v0.3.7.1 + "ignore:datetime.*utcnow\\(\\) is deprecated and scheduled for removal:DeprecationWarning:pyatag.gateway", + # https://github.com/Python-MyQ/Python-MyQ - v3.1.11 + "ignore:datetime.*utcnow\\(\\) is deprecated and scheduled for removal:DeprecationWarning:pymyq.(api|account)", # Wrong stacklevel # https://bugs.launchpad.net/beautifulsoup/+bug/2034451 "ignore:It looks like you're parsing an XML document using an HTML parser:UserWarning:bs4.builder", @@ -495,10 +543,13 @@ filterwarnings = [ "ignore:with timeout\\(\\) is deprecated:DeprecationWarning:aiomodernforms.modernforms", # https://pypi.org/project/directv/ - v0.4.0 - 2020-09-12 "ignore:with timeout\\(\\) is deprecated:DeprecationWarning:directv.directv", + "ignore:datetime.*utcnow\\(\\) is deprecated and scheduled for removal:DeprecationWarning:directv.models", # https://pypi.org/project/emulated-roku/ - v0.2.1 - 2020-01-23 (archived) "ignore:loop argument is deprecated:DeprecationWarning:emulated_roku", # https://pypi.org/project/foobot_async/ - v1.0.0 - 2020-11-24 "ignore:with timeout\\(\\) is deprecated:DeprecationWarning:foobot_async", + # https://pypi.org/project/influxdb/ - v5.3.1 - 2020-11-11 (archived) + "ignore:datetime.*utcfromtimestamp\\(\\) is deprecated and scheduled for removal:DeprecationWarning:influxdb.line_protocol", # https://pypi.org/project/lark-parser/ - v0.12.0 - 2021-08-30 -> moved to `lark` # https://pypi.org/project/commentjson/ - v0.9.0 - 2020-10-05 # https://github.com/vaidik/commentjson/issues/51 @@ -507,11 +558,17 @@ filterwarnings = [ "ignore:module '(sre_parse|sre_constants)' is deprecate:DeprecationWarning:lark.utils", # https://pypi.org/project/lomond/ - v0.3.3 - 2018-09-21 "ignore:ssl.PROTOCOL_TLS is deprecated:DeprecationWarning:lomond.session", + # https://pypi.org/project/oauth2client/ - v4.1.3 - 2018-09-07 (archived) + "ignore:datetime.*utcnow\\(\\) is deprecated and scheduled for removal:DeprecationWarning:oauth2client.client", # https://pypi.org/project/passlib/ - v1.7.4 - 2020-10-08 "ignore:'crypt' is deprecated and slated for removal in Python 3.13:DeprecationWarning:passlib.utils", + # https://pypi.org/project/PyMetEireann/ - v2021.8.0 - 2021-08-16 + "ignore:datetime.*utcnow\\(\\) is deprecated and scheduled for removal:DeprecationWarning:meteireann", # https://pypi.org/project/pyqwikswitch/ - v0.94 - 2019-08-19 "ignore:client.loop property is deprecated:DeprecationWarning:pyqwikswitch.async_", "ignore:with timeout\\(\\) is deprecated:DeprecationWarning:pyqwikswitch.async_", + # https://pypi.org/project/Rx/ - v3.2.0 - 2021-04-25 + "ignore:datetime.*utcfromtimestamp\\(\\) is deprecated and scheduled for removal:DeprecationWarning:rx.internal.constants", # https://pypi.org/project/rxv/ - v0.7.0 - 2021-10-10 "ignore:defusedxml.cElementTree is deprecated, import from defusedxml.ElementTree instead:DeprecationWarning:rxv.ssdp", # https://pypi.org/project/vilfo-api-client/ - v0.4.1 - 2021-11-06 diff --git a/requirements_all.txt b/requirements_all.txt index a18c5f19d75..16538b82fb8 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -122,7 +122,10 @@ PyXiaomiGateway==0.14.3 RachioPy==1.0.3 # homeassistant.components.python_script -RestrictedPython==6.2 +RestrictedPython==6.2;python_version<'3.12' + +# homeassistant.components.python_script +RestrictedPython==7.0a1.dev0;python_version>='3.12' # homeassistant.components.remember_the_milk RtmAPI==0.7.2 @@ -642,7 +645,7 @@ crownstone-uart==2.1.0 datadog==0.15.0 # homeassistant.components.metoffice -datapoint==0.9.8 +datapoint==0.9.8;python_version<'3.12' # homeassistant.components.bluetooth dbus-fast==2.11.1 @@ -939,7 +942,7 @@ gspread==5.5.0 gstreamer-player==1.1.2 # homeassistant.components.profiler -guppy3==3.1.3 +guppy3==3.1.3;python_version<'3.12' # homeassistant.components.iaqualink h2==4.1.0 @@ -2697,7 +2700,7 @@ watchdog==2.3.1 waterfurnace==1.1.0 # homeassistant.components.cisco_webex_teams -webexteamssdk==1.1.1 +webexteamssdk==1.1.1;python_version<'3.12' # homeassistant.components.assist_pipeline webrtc-noise-gain==1.2.3 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 84419d16cc1..14e933c08e2 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -109,7 +109,10 @@ PyXiaomiGateway==0.14.3 RachioPy==1.0.3 # homeassistant.components.python_script -RestrictedPython==6.2 +RestrictedPython==6.2;python_version<'3.12' + +# homeassistant.components.python_script +RestrictedPython==7.0a1.dev0;python_version>='3.12' # homeassistant.components.remember_the_milk RtmAPI==0.7.2 @@ -525,7 +528,7 @@ crownstone-uart==2.1.0 datadog==0.15.0 # homeassistant.components.metoffice -datapoint==0.9.8 +datapoint==0.9.8;python_version<'3.12' # homeassistant.components.bluetooth dbus-fast==2.11.1 @@ -740,7 +743,7 @@ growattServer==1.3.0 gspread==5.5.0 # homeassistant.components.profiler -guppy3==3.1.3 +guppy3==3.1.3;python_version<'3.12' # homeassistant.components.iaqualink h2==4.1.0 diff --git a/tests/components/apache_kafka/conftest.py b/tests/components/apache_kafka/conftest.py new file mode 100644 index 00000000000..9391ccdd380 --- /dev/null +++ b/tests/components/apache_kafka/conftest.py @@ -0,0 +1,5 @@ +"""Skip test collection.""" +import sys + +if sys.version_info >= (3, 12): + collect_ignore_glob = ["test_*.py"] diff --git a/tests/components/brother/__init__.py b/tests/components/brother/__init__.py index 8e24c2d8058..3176fa7fc28 100644 --- a/tests/components/brother/__init__.py +++ b/tests/components/brother/__init__.py @@ -1,13 +1,16 @@ """Tests for Brother Printer integration.""" import json +import sys from unittest.mock import patch -from homeassistant.components.brother.const import DOMAIN from homeassistant.const import CONF_HOST, CONF_TYPE from homeassistant.core import HomeAssistant from tests.common import MockConfigEntry, load_fixture +if sys.version_info < (3, 12): + from homeassistant.components.brother.const import DOMAIN + async def init_integration( hass: HomeAssistant, skip_setup: bool = False diff --git a/tests/components/brother/conftest.py b/tests/components/brother/conftest.py index 9e81cce9d12..558b3b8ac3e 100644 --- a/tests/components/brother/conftest.py +++ b/tests/components/brother/conftest.py @@ -1,9 +1,13 @@ """Test fixtures for brother.""" from collections.abc import Generator +import sys from unittest.mock import AsyncMock, patch import pytest +if sys.version_info >= (3, 12): + collect_ignore_glob = ["test_*.py"] + @pytest.fixture def mock_setup_entry() -> Generator[AsyncMock, None, None]: diff --git a/tests/components/metoffice/conftest.py b/tests/components/metoffice/conftest.py index b1d1c9f508e..1633fae5ee8 100644 --- a/tests/components/metoffice/conftest.py +++ b/tests/components/metoffice/conftest.py @@ -1,9 +1,14 @@ """Fixtures for Met Office weather integration tests.""" +import sys from unittest.mock import patch -from datapoint.exceptions import APIException import pytest +if sys.version_info < (3, 12): + from datapoint.exceptions import APIException +else: + collect_ignore_glob = ["test_*.py"] + @pytest.fixture def mock_simple_manager_fail(): diff --git a/tests/components/profiler/test_init.py b/tests/components/profiler/test_init.py index 7c2aeb2a29a..01f4c4ff510 100644 --- a/tests/components/profiler/test_init.py +++ b/tests/components/profiler/test_init.py @@ -3,6 +3,7 @@ from datetime import timedelta from functools import lru_cache import os from pathlib import Path +import sys from unittest.mock import patch from lru import LRU # pylint: disable=no-name-in-module @@ -63,6 +64,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, 12), reason="not yet available on Python 3.12" +) 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" @@ -94,6 +98,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, 12), reason="still works on python 3.11") +async def test_memory_usage_py312(hass: HomeAssistant, tmp_path: Path) -> None: + """Test raise an error on python3.11.""" + 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.12. Please use Python 3.11.", + ): + 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 ) -> None: diff --git a/tests/components/snmp/conftest.py b/tests/components/snmp/conftest.py new file mode 100644 index 00000000000..05a518ad7f3 --- /dev/null +++ b/tests/components/snmp/conftest.py @@ -0,0 +1,5 @@ +"""Skip test collection for Python 3.12.""" +import sys + +if sys.version_info >= (3, 12): + collect_ignore_glob = ["test_*.py"] diff --git a/tests/components/vulcan/conftest.py b/tests/components/vulcan/conftest.py new file mode 100644 index 00000000000..05a518ad7f3 --- /dev/null +++ b/tests/components/vulcan/conftest.py @@ -0,0 +1,5 @@ +"""Skip test collection for Python 3.12.""" +import sys + +if sys.version_info >= (3, 12): + collect_ignore_glob = ["test_*.py"]