From 77283704a54b6aa8d0456d7217b07c52d73970c7 Mon Sep 17 00:00:00 2001 From: Maciej Bieniek Date: Tue, 12 Dec 2023 22:36:11 +0100 Subject: [PATCH] Bump `brother` library, use `pysnmp-lextudio` with SNMP integration (#105591) --- homeassistant/components/brother/__init__.py | 15 +-- .../components/brother/manifest.json | 2 +- homeassistant/components/brother/utils.py | 8 +- .../components/snmp/device_tracker.py | 13 +-- homeassistant/components/snmp/manifest.json | 2 +- homeassistant/components/snmp/sensor.py | 34 +++---- homeassistant/components/snmp/switch.py | 91 +++++++++---------- requirements_all.txt | 4 +- requirements_test_all.txt | 4 +- tests/components/brother/__init__.py | 5 +- tests/components/brother/conftest.py | 4 - tests/components/snmp/conftest.py | 5 - 12 files changed, 69 insertions(+), 118 deletions(-) delete mode 100644 tests/components/snmp/conftest.py diff --git a/homeassistant/components/brother/__init__.py b/homeassistant/components/brother/__init__.py index 0f8f94c73c4..27ac97a27dc 100644 --- a/homeassistant/components/brother/__init__.py +++ b/homeassistant/components/brother/__init__.py @@ -4,23 +4,18 @@ from __future__ import annotations from asyncio import timeout from datetime import timedelta import logging -import sys -from typing import Any + +from brother import Brother, BrotherSensors, SnmpError, UnsupportedModelError 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, HomeAssistantError +from homeassistant.exceptions import ConfigEntryNotReady 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) @@ -30,10 +25,6 @@ _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/manifest.json b/homeassistant/components/brother/manifest.json index cba44b68c6a..06b8574dbb4 100644 --- a/homeassistant/components/brother/manifest.json +++ b/homeassistant/components/brother/manifest.json @@ -8,7 +8,7 @@ "iot_class": "local_polling", "loggers": ["brother", "pyasn1", "pysmi", "pysnmp"], "quality_scale": "platinum", - "requirements": ["brother==2.3.0"], + "requirements": ["brother==3.0.0"], "zeroconf": [ { "type": "_printer._tcp.local.", diff --git a/homeassistant/components/brother/utils.py b/homeassistant/components/brother/utils.py index cd472b9b754..47b7ae31a67 100644 --- a/homeassistant/components/brother/utils.py +++ b/homeassistant/components/brother/utils.py @@ -2,7 +2,9 @@ from __future__ import annotations import logging -import sys + +import pysnmp.hlapi.asyncio as hlapi +from pysnmp.hlapi.asyncio.cmdgen import lcd from homeassistant.const import EVENT_HOMEASSISTANT_STOP from homeassistant.core import Event, HomeAssistant, callback @@ -10,10 +12,6 @@ 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/snmp/device_tracker.py b/homeassistant/components/snmp/device_tracker.py index 7ca31bae618..696b079fd5e 100644 --- a/homeassistant/components/snmp/device_tracker.py +++ b/homeassistant/components/snmp/device_tracker.py @@ -3,8 +3,9 @@ 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 ( @@ -14,7 +15,6 @@ 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,11 +26,6 @@ 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( @@ -46,10 +41,6 @@ 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/manifest.json b/homeassistant/components/snmp/manifest.json index 324a1e49366..2756b97157c 100644 --- a/homeassistant/components/snmp/manifest.json +++ b/homeassistant/components/snmp/manifest.json @@ -5,5 +5,5 @@ "documentation": "https://www.home-assistant.io/integrations/snmp", "iot_class": "local_polling", "loggers": ["pyasn1", "pysmi", "pysnmp"], - "requirements": ["pysnmplib==5.0.21"] + "requirements": ["pysnmp-lextudio==5.0.31"] } diff --git a/homeassistant/components/snmp/sensor.py b/homeassistant/components/snmp/sensor.py index 58cd12d611f..a5915183ad0 100644 --- a/homeassistant/components/snmp/sensor.py +++ b/homeassistant/components/snmp/sensor.py @@ -3,8 +3,20 @@ 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 @@ -21,7 +33,6 @@ 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 @@ -56,21 +67,6 @@ 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) @@ -115,10 +111,6 @@ 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 e94c6991601..d0fe393d550 100644 --- a/homeassistant/components/snmp/switch.py +++ b/homeassistant/components/snmp/switch.py @@ -2,9 +2,34 @@ 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 @@ -17,7 +42,6 @@ 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 @@ -43,34 +67,6 @@ 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" @@ -81,22 +77,21 @@ DEFAULT_COMMUNITY = "private" DEFAULT_PAYLOAD_OFF = 0 DEFAULT_PAYLOAD_ON = 1 -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, - } +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( { @@ -132,10 +127,6 @@ 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/requirements_all.txt b/requirements_all.txt index 573d51cb43a..010d6bbc799 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -583,7 +583,7 @@ boto3==1.28.17 broadlink==0.18.3 # homeassistant.components.brother -brother==2.3.0 +brother==3.0.0 # homeassistant.components.brottsplatskartan brottsplatskartan==0.0.1 @@ -2089,7 +2089,7 @@ pysmartthings==0.7.8 pysml==0.0.12 # homeassistant.components.snmp -pysnmplib==5.0.21 +pysnmp-lextudio==5.0.31 # homeassistant.components.snooz pysnooz==0.8.6 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 6e61b196514..daabb5e343c 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -491,7 +491,7 @@ boschshcpy==0.2.75 broadlink==0.18.3 # homeassistant.components.brother -brother==2.3.0 +brother==3.0.0 # homeassistant.components.brottsplatskartan brottsplatskartan==0.0.1 @@ -1588,7 +1588,7 @@ pysmartthings==0.7.8 pysml==0.0.12 # homeassistant.components.snmp -pysnmplib==5.0.21 +pysnmp-lextudio==5.0.31 # homeassistant.components.snooz pysnooz==0.8.6 diff --git a/tests/components/brother/__init__.py b/tests/components/brother/__init__.py index 3176fa7fc28..8e24c2d8058 100644 --- a/tests/components/brother/__init__.py +++ b/tests/components/brother/__init__.py @@ -1,16 +1,13 @@ """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 558b3b8ac3e..9e81cce9d12 100644 --- a/tests/components/brother/conftest.py +++ b/tests/components/brother/conftest.py @@ -1,13 +1,9 @@ """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/snmp/conftest.py b/tests/components/snmp/conftest.py deleted file mode 100644 index 05a518ad7f3..00000000000 --- a/tests/components/snmp/conftest.py +++ /dev/null @@ -1,5 +0,0 @@ -"""Skip test collection for Python 3.12.""" -import sys - -if sys.version_info >= (3, 12): - collect_ignore_glob = ["test_*.py"]