Skip to content

Commit

Permalink
Add support for Python 3.12 (#101651)
Browse files Browse the repository at this point in the history
  • Loading branch information
cdce8p authored Oct 10, 2023
1 parent 535e2b8 commit ba91aaa
Show file tree
Hide file tree
Showing 28 changed files with 296 additions and 93 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -112,15 +112,15 @@ 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
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
abi: ["cp311"]
abi: ["cp311", "cp312"]
arch: ${{ fromJson(needs.init.outputs.architectures) }}
steps:
- name: Checkout the repository
Expand Down
11 changes: 10 additions & 1 deletion homeassistant/components/apache_kafka/__init__.py
Original file line number Diff line number Diff line change
@@ -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 (
Expand All @@ -16,11 +16,16 @@
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"
Expand Down Expand Up @@ -49,6 +54,10 @@

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(
Expand Down
15 changes: 12 additions & 3 deletions homeassistant/components/brother/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,23 @@
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)
Expand All @@ -25,6 +30,10 @@

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]

Expand Down
10 changes: 7 additions & 3 deletions homeassistant/components/brother/utils.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
"""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
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__)


Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/cisco_webex_teams/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -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'"]
}
11 changes: 10 additions & 1 deletion homeassistant/components/cisco_webex_teams/notify.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -13,9 +13,14 @@
)
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"
Expand All @@ -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:
Expand Down
12 changes: 9 additions & 3 deletions homeassistant/components/metoffice/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@
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,
Expand All @@ -17,7 +16,7 @@
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
Expand All @@ -35,13 +34,20 @@
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]


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]
Expand Down
10 changes: 6 additions & 4 deletions homeassistant/components/metoffice/data.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down
9 changes: 6 additions & 3 deletions homeassistant/components/metoffice/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@
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

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


Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/metoffice/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -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'"]
}
5 changes: 5 additions & 0 deletions homeassistant/components/profiler/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
6 changes: 5 additions & 1 deletion homeassistant/components/profiler/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
]
}
5 changes: 4 additions & 1 deletion homeassistant/components/python_script/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -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'"
]
}
13 changes: 11 additions & 2 deletions homeassistant/components/snmp/device_tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@

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 (
Expand All @@ -15,6 +14,7 @@
)
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

Expand All @@ -26,6 +26,11 @@
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(
Expand All @@ -41,6 +46,10 @@

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
Expand Down
Loading

0 comments on commit ba91aaa

Please sign in to comment.