From 276fd4f42ce1cdbf5cc8ce25e8c034b88d6da5ca Mon Sep 17 00:00:00 2001
From: Franck Nijhof <git@frenck.dev>
Date: Thu, 17 Feb 2022 14:58:24 +0100
Subject: [PATCH] Add Python 3.10 to CI (#59729)

---
 .github/workflows/ci.yaml                     |  10 +-
 .github/workflows/wheels.yml                  |   1 +
 Dockerfile                                    |   3 +-
 homeassistant/components/apcupsd/__init__.py  |   1 +
 .../components/apcupsd/manifest.json          |   1 +
 homeassistant/components/apcupsd/sensor.py    |   1 +
 homeassistant/components/apns/manifest.json   |   1 +
 homeassistant/components/apns/notify.py       |   1 +
 homeassistant/components/xbee/__init__.py     |   1 +
 homeassistant/components/xbee/manifest.json   |   1 +
 homeassistant/components/xbee/sensor.py       |   1 +
 homeassistant/components/zwave/__init__.py    |   3 +-
 homeassistant/components/zwave/config_flow.py |   1 +
 homeassistant/components/zwave/node_entity.py |   1 +
 homeassistant/package_constraints.txt         |   8 +-
 requirements_all.txt                          |  11 +-
 requirements_test_all.txt                     |   5 +-
 script/gen_requirements_all.py                |   9 +-
 tests/components/apns/__init__.py             |   1 -
 tests/components/apns/test_notify.py          | 395 ------------------
 ...g_flow.py => disabled_test_config_flow.py} |   9 +-
 tests/components/zwave/test_binary_sensor.py  |   5 +
 tests/components/zwave/test_climate.py        |   3 +
 tests/components/zwave/test_cover.py          |   5 +
 tests/components/zwave/test_fan.py            |   5 +
 tests/components/zwave/test_init.py           |   3 +
 tests/components/zwave/test_light.py          |   5 +
 tests/components/zwave/test_lock.py           |   5 +
 tests/components/zwave/test_node_entity.py    |   5 +
 tests/components/zwave/test_sensor.py         |   5 +
 tests/components/zwave/test_switch.py         |   5 +
 tests/components/zwave/test_websocket_api.py  |   6 +
 tests/components/zwave/test_workaround.py     |   5 +
 tests/components/zwave_js/test_migrate.py     |   1 +
 tests/mock/zwave.py                           |   4 +-
 35 files changed, 99 insertions(+), 428 deletions(-)
 delete mode 100644 tests/components/apns/__init__.py
 delete mode 100644 tests/components/apns/test_notify.py
 rename tests/components/icloud/{test_config_flow.py => disabled_test_config_flow.py} (98%)

diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 321cb7f622b..a2345081b50 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -10,8 +10,8 @@ on:
   pull_request: ~
 
 env:
-  CACHE_VERSION: 7
-  PIP_CACHE_VERSION: 1
+  CACHE_VERSION: 9
+  PIP_CACHE_VERSION: 3
   HA_SHORT_VERSION: 2022.3
   DEFAULT_PYTHON: 3.9
   PRE_COMMIT_CACHE: ~/.cache/pre-commit
@@ -524,10 +524,10 @@ jobs:
   prepare-tests:
     name: Prepare tests for Python ${{ matrix.python-version }}
     runs-on: ubuntu-latest
-    timeout-minutes: 30
+    timeout-minutes: 60
     strategy:
       matrix:
-        python-version: [3.9]
+        python-version: ["3.9", "3.10"]
     outputs:
       python-key: ${{ steps.generate-python-key.outputs.key }}
     container: homeassistant/ci-azure:${{ matrix.python-version }}
@@ -721,7 +721,7 @@ jobs:
       fail-fast: false
       matrix:
         group: ${{ fromJson(needs.changes.outputs.test_groups) }}
-        python-version: [3.9]
+        python-version: ["3.9", "3.10"]
     name: >-
       Run tests Python ${{ matrix.python-version }} (${{ matrix.group }})
     container: homeassistant/ci-azure:${{ matrix.python-version }}
diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml
index 6c9a7759c3d..a60ac651e31 100644
--- a/.github/workflows/wheels.yml
+++ b/.github/workflows/wheels.yml
@@ -154,6 +154,7 @@ jobs:
             sed -i "s|# face_recognition|face_recognition|g" ${requirement_file}
             sed -i "s|# bme680|bme680|g" ${requirement_file}
             sed -i "s|# python-gammu|python-gammu|g" ${requirement_file}
+            sed -i "s|# homeassistant-pyozw|homeassistant-pyozw|g" ${requirement_file}
           done
 
       - name: Build wheels
diff --git a/Dockerfile b/Dockerfile
index 1d6ce675e74..7193d706b89 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -15,7 +15,8 @@ RUN \
     -r homeassistant/requirements.txt --use-deprecated=legacy-resolver
 COPY requirements_all.txt homeassistant/
 RUN \
-    pip3 install --no-cache-dir --no-index --only-binary=:all: --find-links "${WHEELS_LINKS}" \
+    sed -i "s|# homeassistant-pyozw|homeassistant-pyozw|g" homeassistant/requirements_all.txt \
+    && pip3 install --no-cache-dir --no-index --only-binary=:all: --find-links "${WHEELS_LINKS}" \
     -r homeassistant/requirements_all.txt --use-deprecated=legacy-resolver
 
 ## Setup Home Assistant Core
diff --git a/homeassistant/components/apcupsd/__init__.py b/homeassistant/components/apcupsd/__init__.py
index 7cbf33f8b47..a032430e1bc 100644
--- a/homeassistant/components/apcupsd/__init__.py
+++ b/homeassistant/components/apcupsd/__init__.py
@@ -1,4 +1,5 @@
 """Support for APCUPSd via its Network Information Server (NIS)."""
+# pylint: disable=import-error
 from datetime import timedelta
 import logging
 
diff --git a/homeassistant/components/apcupsd/manifest.json b/homeassistant/components/apcupsd/manifest.json
index 13a08685c68..18d5549ef9a 100644
--- a/homeassistant/components/apcupsd/manifest.json
+++ b/homeassistant/components/apcupsd/manifest.json
@@ -1,4 +1,5 @@
 {
+  "disabled": "Integration library not compatible with Python 3.10",
   "domain": "apcupsd",
   "name": "apcupsd",
   "documentation": "https://www.home-assistant.io/integrations/apcupsd",
diff --git a/homeassistant/components/apcupsd/sensor.py b/homeassistant/components/apcupsd/sensor.py
index b7e7366796b..2fae17ac922 100644
--- a/homeassistant/components/apcupsd/sensor.py
+++ b/homeassistant/components/apcupsd/sensor.py
@@ -1,4 +1,5 @@
 """Support for APCUPSd sensors."""
+# pylint: disable=import-error
 from __future__ import annotations
 
 import logging
diff --git a/homeassistant/components/apns/manifest.json b/homeassistant/components/apns/manifest.json
index 2ea4e495a2b..bcefdcf0639 100644
--- a/homeassistant/components/apns/manifest.json
+++ b/homeassistant/components/apns/manifest.json
@@ -1,4 +1,5 @@
 {
+  "disabled": "Integration library not compatible with Python 3.10",
   "domain": "apns",
   "name": "Apple Push Notification Service (APNS)",
   "documentation": "https://www.home-assistant.io/integrations/apns",
diff --git a/homeassistant/components/apns/notify.py b/homeassistant/components/apns/notify.py
index 4cc13a3057f..8d0dcc334e9 100644
--- a/homeassistant/components/apns/notify.py
+++ b/homeassistant/components/apns/notify.py
@@ -1,4 +1,5 @@
 """APNS Notification platform."""
+# pylint: disable=import-error
 from contextlib import suppress
 import logging
 
diff --git a/homeassistant/components/xbee/__init__.py b/homeassistant/components/xbee/__init__.py
index 17d861d6432..6a7aba16b95 100644
--- a/homeassistant/components/xbee/__init__.py
+++ b/homeassistant/components/xbee/__init__.py
@@ -1,4 +1,5 @@
 """Support for XBee Zigbee devices."""
+# pylint: disable=import-error
 from binascii import hexlify, unhexlify
 import logging
 
diff --git a/homeassistant/components/xbee/manifest.json b/homeassistant/components/xbee/manifest.json
index bd1a0d2a1e1..150036129d2 100644
--- a/homeassistant/components/xbee/manifest.json
+++ b/homeassistant/components/xbee/manifest.json
@@ -1,4 +1,5 @@
 {
+  "disabled": "Integration library not compatible with Python 3.10",
   "domain": "xbee",
   "name": "XBee",
   "documentation": "https://www.home-assistant.io/integrations/xbee",
diff --git a/homeassistant/components/xbee/sensor.py b/homeassistant/components/xbee/sensor.py
index 1d1a4b99705..9cea60ade8c 100644
--- a/homeassistant/components/xbee/sensor.py
+++ b/homeassistant/components/xbee/sensor.py
@@ -1,4 +1,5 @@
 """Support for XBee Zigbee sensors."""
+# pylint: disable=import-error
 from __future__ import annotations
 
 from binascii import hexlify
diff --git a/homeassistant/components/zwave/__init__.py b/homeassistant/components/zwave/__init__.py
index cd0bda6735f..3424aa11a87 100644
--- a/homeassistant/components/zwave/__init__.py
+++ b/homeassistant/components/zwave/__init__.py
@@ -1,4 +1,5 @@
 """Support for Z-Wave."""
+# pylint: disable=import-error
 # pylint: disable=import-outside-toplevel
 from __future__ import annotations
 
@@ -355,8 +356,6 @@ async def async_setup_entry(  # noqa: C901
     from openzwave.group import ZWaveGroup
     from openzwave.network import ZWaveNetwork
     from openzwave.option import ZWaveOption
-
-    # pylint: enable=import-error
     from pydispatch import dispatcher
 
     if async_is_ozw_migrated(hass) or async_is_zwave_js_migrated(hass):
diff --git a/homeassistant/components/zwave/config_flow.py b/homeassistant/components/zwave/config_flow.py
index ce7aebd801a..f29f2e6f6d0 100644
--- a/homeassistant/components/zwave/config_flow.py
+++ b/homeassistant/components/zwave/config_flow.py
@@ -1,4 +1,5 @@
 """Config flow to configure Z-Wave."""
+# pylint: disable=import-error
 # pylint: disable=import-outside-toplevel
 from collections import OrderedDict
 
diff --git a/homeassistant/components/zwave/node_entity.py b/homeassistant/components/zwave/node_entity.py
index b17034e0e8a..ade68284313 100644
--- a/homeassistant/components/zwave/node_entity.py
+++ b/homeassistant/components/zwave/node_entity.py
@@ -1,4 +1,5 @@
 """Entity class that represents Z-Wave node."""
+# pylint: disable=import-error
 # pylint: disable=import-outside-toplevel
 from itertools import count
 
diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt
index e26dcbe925a..4d3670ac9b4 100644
--- a/homeassistant/package_constraints.txt
+++ b/homeassistant/package_constraints.txt
@@ -67,10 +67,6 @@ enum34==1000000000.0.0
 typing==1000000000.0.0
 uuid==1000000000.0.0
 
-# Temporary constraint on pandas, to unblock 2021.7 releases
-# until we have fixed the wheels builds for newer versions.
-pandas==1.3.0
-
 # regex causes segfault with version 2021.8.27
 # https://bitbucket.org/mrabarnett/mrab-regex/issues/421/2021827-results-in-fatal-python-error
 # This is fixed in 2021.8.28
@@ -84,6 +80,10 @@ anyio==3.5.0
 h11==0.12.0
 httpcore==0.14.5
 
+# Ensure we have a hyperframe version that works in Python 3.10
+# 5.2.0 fixed a collections abc deprecation
+hyperframe>=5.2.0
+
 # pytest_asyncio breaks our test suite. We rely on pytest-aiohttp instead
 pytest_asyncio==1000000000.0.0
 
diff --git a/requirements_all.txt b/requirements_all.txt
index 150d7b28949..e0c0e4c960c 100644
--- a/requirements_all.txt
+++ b/requirements_all.txt
@@ -319,12 +319,6 @@ anel_pwrctrl-homeassistant==0.0.1.dev2
 # homeassistant.components.anthemav
 anthemav==1.2.0
 
-# homeassistant.components.apcupsd
-apcaccess==0.0.13
-
-# homeassistant.components.apns
-apns2==0.3.0
-
 # homeassistant.components.apprise
 apprise==0.9.7
 
@@ -842,7 +836,7 @@ holidays==0.12
 home-assistant-frontend==20220214.0
 
 # homeassistant.components.zwave
-homeassistant-pyozw==0.1.10
+# homeassistant-pyozw==0.1.10
 
 # homeassistant.components.home_connect
 homeconnect==0.6.3
@@ -2493,9 +2487,6 @@ wled==0.13.0
 # homeassistant.components.wolflink
 wolf_smartset==0.1.11
 
-# homeassistant.components.xbee
-xbee-helper==0.0.7
-
 # homeassistant.components.xbox
 xbox-webapi==2.0.11
 
diff --git a/requirements_test_all.txt b/requirements_test_all.txt
index 8f10a13b145..f6d7d898eb3 100644
--- a/requirements_test_all.txt
+++ b/requirements_test_all.txt
@@ -239,9 +239,6 @@ ambiclimate==0.2.1
 # homeassistant.components.androidtv
 androidtv[async]==0.0.63
 
-# homeassistant.components.apns
-apns2==0.3.0
-
 # homeassistant.components.apprise
 apprise==0.9.7
 
@@ -552,7 +549,7 @@ holidays==0.12
 home-assistant-frontend==20220214.0
 
 # homeassistant.components.zwave
-homeassistant-pyozw==0.1.10
+# homeassistant-pyozw==0.1.10
 
 # homeassistant.components.home_connect
 homeconnect==0.6.3
diff --git a/script/gen_requirements_all.py b/script/gen_requirements_all.py
index 872f2d0c7a8..eed5a5a5946 100755
--- a/script/gen_requirements_all.py
+++ b/script/gen_requirements_all.py
@@ -27,6 +27,7 @@ COMMENT_REQUIREMENTS = (
     "envirophat",
     "evdev",
     "face_recognition",
+    "homeassistant-pyozw",
     "i2csense",
     "opencv-python-headless",
     "pybluez",
@@ -94,10 +95,6 @@ enum34==1000000000.0.0
 typing==1000000000.0.0
 uuid==1000000000.0.0
 
-# Temporary constraint on pandas, to unblock 2021.7 releases
-# until we have fixed the wheels builds for newer versions.
-pandas==1.3.0
-
 # regex causes segfault with version 2021.8.27
 # https://bitbucket.org/mrabarnett/mrab-regex/issues/421/2021827-results-in-fatal-python-error
 # This is fixed in 2021.8.28
@@ -111,6 +108,10 @@ anyio==3.5.0
 h11==0.12.0
 httpcore==0.14.5
 
+# Ensure we have a hyperframe version that works in Python 3.10
+# 5.2.0 fixed a collections abc deprecation
+hyperframe>=5.2.0
+
 # pytest_asyncio breaks our test suite. We rely on pytest-aiohttp instead
 pytest_asyncio==1000000000.0.0
 
diff --git a/tests/components/apns/__init__.py b/tests/components/apns/__init__.py
deleted file mode 100644
index 42c980a62a7..00000000000
--- a/tests/components/apns/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-"""Tests for the apns component."""
diff --git a/tests/components/apns/test_notify.py b/tests/components/apns/test_notify.py
deleted file mode 100644
index ad55a5697ad..00000000000
--- a/tests/components/apns/test_notify.py
+++ /dev/null
@@ -1,395 +0,0 @@
-"""The tests for the APNS component."""
-import io
-from unittest.mock import Mock, mock_open, patch
-
-from apns2.errors import Unregistered
-import pytest
-import yaml
-
-import homeassistant.components.apns.notify as apns
-import homeassistant.components.notify as notify
-from homeassistant.core import State
-from homeassistant.setup import async_setup_component
-
-from tests.common import assert_setup_component
-
-CONFIG = {
-    notify.DOMAIN: {
-        "platform": "apns",
-        "name": "test_app",
-        "topic": "testapp.appname",
-        "cert_file": "test_app.pem",
-    }
-}
-
-
-@pytest.fixture(scope="module", autouse=True)
-def mock_apns_notify_open():
-    """Mock builtins.open for apns.notify."""
-    with patch("homeassistant.components.apns.notify.open", mock_open(), create=True):
-        yield
-
-
-@patch("os.path.isfile", Mock(return_value=True))
-@patch("os.access", Mock(return_value=True))
-async def _setup_notify(hass_):
-    assert isinstance(apns.load_yaml_config_file, Mock), "Found unmocked load_yaml"
-
-    with assert_setup_component(1) as handle_config:
-        assert await async_setup_component(hass_, notify.DOMAIN, CONFIG)
-    assert handle_config[notify.DOMAIN]
-
-
-@patch("os.path.isfile", return_value=True)
-@patch("os.access", return_value=True)
-async def test_apns_setup_full(mock_access, mock_isfile, hass):
-    """Test setup with all data."""
-    config = {
-        "notify": {
-            "platform": "apns",
-            "name": "test_app",
-            "sandbox": "True",
-            "topic": "testapp.appname",
-            "cert_file": "test_app.pem",
-        }
-    }
-
-    with assert_setup_component(1) as handle_config:
-        assert await async_setup_component(hass, notify.DOMAIN, config)
-    assert handle_config[notify.DOMAIN]
-
-
-async def test_apns_setup_missing_name(hass):
-    """Test setup with missing name."""
-    config = {
-        "notify": {
-            "platform": "apns",
-            "topic": "testapp.appname",
-            "cert_file": "test_app.pem",
-        }
-    }
-    with assert_setup_component(0) as handle_config:
-        assert await async_setup_component(hass, notify.DOMAIN, config)
-    assert not handle_config[notify.DOMAIN]
-
-
-async def test_apns_setup_missing_certificate(hass):
-    """Test setup with missing certificate."""
-    config = {
-        "notify": {
-            "platform": "apns",
-            "name": "test_app",
-            "topic": "testapp.appname",
-        }
-    }
-    with assert_setup_component(0) as handle_config:
-        assert await async_setup_component(hass, notify.DOMAIN, config)
-    assert not handle_config[notify.DOMAIN]
-
-
-async def test_apns_setup_missing_topic(hass):
-    """Test setup with missing topic."""
-    config = {
-        "notify": {
-            "platform": "apns",
-            "name": "test_app",
-            "cert_file": "test_app.pem",
-        }
-    }
-    with assert_setup_component(0) as handle_config:
-        assert await async_setup_component(hass, notify.DOMAIN, config)
-    assert not handle_config[notify.DOMAIN]
-
-
-@patch("homeassistant.components.apns.notify._write_device")
-async def test_register_new_device(mock_write, hass):
-    """Test registering a new device with a name."""
-    yaml_file = {5678: {"name": "test device 2"}}
-
-    written_devices = []
-
-    def fake_write(_out, device):
-        """Fake write_device."""
-        written_devices.append(device)
-
-    mock_write.side_effect = fake_write
-
-    with patch(
-        "homeassistant.components.apns.notify.load_yaml_config_file",
-        Mock(return_value=yaml_file),
-    ):
-        await _setup_notify(hass)
-
-    assert await hass.services.async_call(
-        apns.DOMAIN,
-        "apns_test_app",
-        {"push_id": "1234", "name": "test device"},
-        blocking=True,
-    )
-
-    assert len(written_devices) == 1
-    assert written_devices[0].name == "test device"
-
-
-@patch("homeassistant.components.apns.notify._write_device")
-async def test_register_device_without_name(mock_write, hass):
-    """Test registering a without a name."""
-    yaml_file = {
-        1234: {"name": "test device 1", "tracking_device_id": "tracking123"},
-        5678: {"name": "test device 2", "tracking_device_id": "tracking456"},
-    }
-
-    written_devices = []
-
-    def fake_write(_out, device):
-        """Fake write_device."""
-        written_devices.append(device)
-
-    mock_write.side_effect = fake_write
-
-    with patch(
-        "homeassistant.components.apns.notify.load_yaml_config_file",
-        Mock(return_value=yaml_file),
-    ):
-        await _setup_notify(hass)
-
-    assert await hass.services.async_call(
-        apns.DOMAIN, "apns_test_app", {"push_id": "1234"}, blocking=True
-    )
-
-    devices = {dev.push_id: dev for dev in written_devices}
-
-    test_device = devices.get("1234")
-
-    assert test_device is not None
-    assert test_device.name is None
-
-
-@patch("homeassistant.components.apns.notify._write_device")
-async def test_update_existing_device(mock_write, hass):
-    """Test updating an existing device."""
-    yaml_file = {1234: {"name": "test device 1"}, 5678: {"name": "test device 2"}}
-
-    written_devices = []
-
-    def fake_write(_out, device):
-        """Fake write_device."""
-        written_devices.append(device)
-
-    mock_write.side_effect = fake_write
-
-    with patch(
-        "homeassistant.components.apns.notify.load_yaml_config_file",
-        Mock(return_value=yaml_file),
-    ):
-        await _setup_notify(hass)
-
-    assert await hass.services.async_call(
-        apns.DOMAIN,
-        "apns_test_app",
-        {"push_id": "1234", "name": "updated device 1"},
-        blocking=True,
-    )
-
-    devices = {dev.push_id: dev for dev in written_devices}
-
-    test_device_1 = devices.get("1234")
-    test_device_2 = devices.get("5678")
-
-    assert test_device_1 is not None
-    assert test_device_2 is not None
-
-    assert test_device_1.name == "updated device 1"
-
-
-@patch("homeassistant.components.apns.notify._write_device")
-async def test_update_existing_device_with_tracking_id(mock_write, hass):
-    """Test updating an existing device that has a tracking id."""
-    yaml_file = {
-        1234: {"name": "test device 1", "tracking_device_id": "tracking123"},
-        5678: {"name": "test device 2", "tracking_device_id": "tracking456"},
-    }
-
-    written_devices = []
-
-    def fake_write(_out, device):
-        """Fake write_device."""
-        written_devices.append(device)
-
-    mock_write.side_effect = fake_write
-
-    with patch(
-        "homeassistant.components.apns.notify.load_yaml_config_file",
-        Mock(return_value=yaml_file),
-    ):
-        await _setup_notify(hass)
-
-    assert await hass.services.async_call(
-        apns.DOMAIN,
-        "apns_test_app",
-        {"push_id": "1234", "name": "updated device 1"},
-        blocking=True,
-    )
-
-    devices = {dev.push_id: dev for dev in written_devices}
-
-    test_device_1 = devices.get("1234")
-    test_device_2 = devices.get("5678")
-
-    assert test_device_1 is not None
-    assert test_device_2 is not None
-
-    assert test_device_1.tracking_device_id == "tracking123"
-    assert test_device_2.tracking_device_id == "tracking456"
-
-
-@patch("homeassistant.components.apns.notify.APNsClient")
-async def test_send(mock_client, hass):
-    """Test updating an existing device."""
-    send = mock_client.return_value.send_notification
-
-    yaml_file = {1234: {"name": "test device 1"}}
-
-    with patch(
-        "homeassistant.components.apns.notify.load_yaml_config_file",
-        Mock(return_value=yaml_file),
-    ):
-        await _setup_notify(hass)
-
-    assert await hass.services.async_call(
-        "notify",
-        "test_app",
-        {
-            "message": "Hello",
-            "data": {"badge": 1, "sound": "test.mp3", "category": "testing"},
-        },
-        blocking=True,
-    )
-
-    assert send.called
-    assert len(send.mock_calls) == 1
-
-    target = send.mock_calls[0][1][0]
-    payload = send.mock_calls[0][1][1]
-
-    assert target == "1234"
-    assert payload.alert == "Hello"
-    assert payload.badge == 1
-    assert payload.sound == "test.mp3"
-    assert payload.category == "testing"
-
-
-@patch("homeassistant.components.apns.notify.APNsClient")
-async def test_send_when_disabled(mock_client, hass):
-    """Test updating an existing device."""
-    send = mock_client.return_value.send_notification
-
-    yaml_file = {1234: {"name": "test device 1", "disabled": True}}
-
-    with patch(
-        "homeassistant.components.apns.notify.load_yaml_config_file",
-        Mock(return_value=yaml_file),
-    ):
-        await _setup_notify(hass)
-
-    assert await hass.services.async_call(
-        "notify",
-        "test_app",
-        {
-            "message": "Hello",
-            "data": {"badge": 1, "sound": "test.mp3", "category": "testing"},
-        },
-        blocking=True,
-    )
-
-    assert not send.called
-
-
-@patch("homeassistant.components.apns.notify.APNsClient")
-async def test_send_with_state(mock_client, hass):
-    """Test updating an existing device."""
-    send = mock_client.return_value.send_notification
-
-    yaml_file = {
-        1234: {"name": "test device 1", "tracking_device_id": "tracking123"},
-        5678: {"name": "test device 2", "tracking_device_id": "tracking456"},
-    }
-
-    with patch(
-        "homeassistant.components.apns.notify.load_yaml_config_file",
-        Mock(return_value=yaml_file),
-    ), patch("os.path.isfile", Mock(return_value=True)):
-        notify_service = await hass.async_add_executor_job(
-            apns.ApnsNotificationService,
-            hass,
-            "test_app",
-            "testapp.appname",
-            False,
-            "test_app.pem",
-        )
-
-    notify_service.device_state_changed_listener(
-        "device_tracker.tracking456",
-        State("device_tracker.tracking456", None),
-        State("device_tracker.tracking456", "home"),
-    )
-
-    notify_service.send_message(message="Hello", target="home")
-
-    assert send.called
-    assert len(send.mock_calls) == 1
-
-    target = send.mock_calls[0][1][0]
-    payload = send.mock_calls[0][1][1]
-
-    assert target == "5678"
-    assert payload.alert == "Hello"
-
-
-@patch("homeassistant.components.apns.notify.APNsClient")
-@patch("homeassistant.components.apns.notify._write_device")
-async def test_disable_when_unregistered(mock_write, mock_client, hass):
-    """Test disabling a device when it is unregistered."""
-    send = mock_client.return_value.send_notification
-    send.side_effect = Unregistered()
-
-    yaml_file = {
-        1234: {"name": "test device 1", "tracking_device_id": "tracking123"},
-        5678: {"name": "test device 2", "tracking_device_id": "tracking456"},
-    }
-
-    written_devices = []
-
-    def fake_write(_out, device):
-        """Fake write_device."""
-        written_devices.append(device)
-
-    mock_write.side_effect = fake_write
-
-    with patch(
-        "homeassistant.components.apns.notify.load_yaml_config_file",
-        Mock(return_value=yaml_file),
-    ):
-        await _setup_notify(hass)
-
-    assert await hass.services.async_call(
-        "notify", "test_app", {"message": "Hello"}, blocking=True
-    )
-
-    devices = {dev.push_id: dev for dev in written_devices}
-
-    test_device_1 = devices.get("1234")
-    assert test_device_1 is not None
-    assert test_device_1.disabled is True
-
-
-async def test_write_device():
-    """Test writing device."""
-    out = io.StringIO()
-    device = apns.ApnsDevice("123", "name", "track_id", True)
-
-    apns._write_device(out, device)
-    data = yaml.safe_load(out.getvalue())
-    assert data == {
-        123: {"name": "name", "tracking_device_id": "track_id", "disabled": True}
-    }
diff --git a/tests/components/icloud/test_config_flow.py b/tests/components/icloud/disabled_test_config_flow.py
similarity index 98%
rename from tests/components/icloud/test_config_flow.py
rename to tests/components/icloud/disabled_test_config_flow.py
index 59c5ebf24a9..1f7e411003a 100644
--- a/tests/components/icloud/test_config_flow.py
+++ b/tests/components/icloud/disabled_test_config_flow.py
@@ -1,4 +1,11 @@
-"""Tests for the iCloud config flow."""
+"""Tests for the iCloud config flow.
+
+This integration is temporary disabled, as the library is incompatible
+with the Python versions we currently support.
+
+This file has been renamed (instead of skipped), simply because its easier
+to prevent library imports from happening that way.
+"""
 from unittest.mock import MagicMock, Mock, patch
 
 from pyicloud.exceptions import PyiCloudFailedLoginException
diff --git a/tests/components/zwave/test_binary_sensor.py b/tests/components/zwave/test_binary_sensor.py
index 731e413caf8..265ec6f2d1e 100644
--- a/tests/components/zwave/test_binary_sensor.py
+++ b/tests/components/zwave/test_binary_sensor.py
@@ -2,10 +2,15 @@
 import datetime
 from unittest.mock import patch
 
+import pytest
+
 from homeassistant.components.zwave import binary_sensor, const
 
 from tests.mock.zwave import MockEntityValues, MockNode, MockValue, value_changed
 
+# Integration is disabled
+pytest.skip("Integration has been disabled in the manifest", allow_module_level=True)
+
 
 def test_get_device_detects_none(mock_openzwave):
     """Test device is not returned."""
diff --git a/tests/components/zwave/test_climate.py b/tests/components/zwave/test_climate.py
index 1afe9617097..a9ad182c4b1 100644
--- a/tests/components/zwave/test_climate.py
+++ b/tests/components/zwave/test_climate.py
@@ -31,6 +31,9 @@ from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS, TEMP_FAHRENHEIT
 
 from tests.mock.zwave import MockEntityValues, MockNode, MockValue, value_changed
 
+# Integration is disabled
+pytest.skip("Integration has been disabled in the manifest", allow_module_level=True)
+
 
 @pytest.fixture
 def device(hass, mock_openzwave):
diff --git a/tests/components/zwave/test_cover.py b/tests/components/zwave/test_cover.py
index e8b784feefe..e7283de25b4 100644
--- a/tests/components/zwave/test_cover.py
+++ b/tests/components/zwave/test_cover.py
@@ -1,6 +1,8 @@
 """Test Z-Wave cover devices."""
 from unittest.mock import MagicMock
 
+import pytest
+
 from homeassistant.components.cover import SUPPORT_CLOSE, SUPPORT_OPEN
 from homeassistant.components.zwave import (
     CONF_INVERT_OPENCLOSE_BUTTONS,
@@ -11,6 +13,9 @@ from homeassistant.components.zwave import (
 
 from tests.mock.zwave import MockEntityValues, MockNode, MockValue, value_changed
 
+# Integration is disabled
+pytest.skip("Integration has been disabled in the manifest", allow_module_level=True)
+
 
 def test_get_device_detects_none(hass, mock_openzwave):
     """Test device returns none."""
diff --git a/tests/components/zwave/test_fan.py b/tests/components/zwave/test_fan.py
index 18188cefcd6..d71ba0713d2 100644
--- a/tests/components/zwave/test_fan.py
+++ b/tests/components/zwave/test_fan.py
@@ -1,4 +1,6 @@
 """Test Z-Wave fans."""
+import pytest
+
 from homeassistant.components.fan import (
     SPEED_HIGH,
     SPEED_LOW,
@@ -10,6 +12,9 @@ from homeassistant.components.zwave import fan
 
 from tests.mock.zwave import MockEntityValues, MockNode, MockValue, value_changed
 
+# Integration is disabled
+pytest.skip("Integration has been disabled in the manifest", allow_module_level=True)
+
 
 def test_get_device_detects_fan(mock_openzwave):
     """Test get_device returns a zwave fan."""
diff --git a/tests/components/zwave/test_init.py b/tests/components/zwave/test_init.py
index b0114d087ad..745d6d8ce57 100644
--- a/tests/components/zwave/test_init.py
+++ b/tests/components/zwave/test_init.py
@@ -22,6 +22,9 @@ from homeassistant.util import dt as dt_util
 from tests.common import async_fire_time_changed, mock_registry
 from tests.mock.zwave import MockEntityValues, MockNetwork, MockNode, MockValue
 
+# Integration is disabled
+pytest.skip("Integration has been disabled in the manifest", allow_module_level=True)
+
 
 @pytest.fixture(autouse=True)
 def mock_storage(hass_storage):
diff --git a/tests/components/zwave/test_light.py b/tests/components/zwave/test_light.py
index 74c541f4d5a..87bfb1ec726 100644
--- a/tests/components/zwave/test_light.py
+++ b/tests/components/zwave/test_light.py
@@ -1,6 +1,8 @@
 """Test Z-Wave lights."""
 from unittest.mock import MagicMock, patch
 
+import pytest
+
 from homeassistant.components import zwave
 from homeassistant.components.light import (
     ATTR_BRIGHTNESS,
@@ -18,6 +20,9 @@ from homeassistant.components.zwave import const, light
 
 from tests.mock.zwave import MockEntityValues, MockNode, MockValue, value_changed
 
+# Integration is disabled
+pytest.skip("Integration has been disabled in the manifest", allow_module_level=True)
+
 
 class MockLightValues(MockEntityValues):
     """Mock Z-Wave light values."""
diff --git a/tests/components/zwave/test_lock.py b/tests/components/zwave/test_lock.py
index 04d46620013..575df9491ad 100644
--- a/tests/components/zwave/test_lock.py
+++ b/tests/components/zwave/test_lock.py
@@ -1,11 +1,16 @@
 """Test Z-Wave locks."""
 from unittest.mock import MagicMock, patch
 
+import pytest
+
 from homeassistant import config_entries
 from homeassistant.components.zwave import const, lock
 
 from tests.mock.zwave import MockEntityValues, MockNode, MockValue, value_changed
 
+# Integration is disabled
+pytest.skip("Integration has been disabled in the manifest", allow_module_level=True)
+
 
 def test_get_device_detects_lock(mock_openzwave):
     """Test get_device returns a Z-Wave lock."""
diff --git a/tests/components/zwave/test_node_entity.py b/tests/components/zwave/test_node_entity.py
index c47201fb168..56ae0d61d41 100644
--- a/tests/components/zwave/test_node_entity.py
+++ b/tests/components/zwave/test_node_entity.py
@@ -1,11 +1,16 @@
 """Test Z-Wave node entity."""
 from unittest.mock import MagicMock, patch
 
+import pytest
+
 from homeassistant.components.zwave import const, node_entity
 from homeassistant.const import ATTR_ENTITY_ID
 
 import tests.mock.zwave as mock_zwave
 
+# Integration is disabled
+pytest.skip("Integration has been disabled in the manifest", allow_module_level=True)
+
 
 async def test_maybe_schedule_update(hass, mock_openzwave):
     """Test maybe schedule update."""
diff --git a/tests/components/zwave/test_sensor.py b/tests/components/zwave/test_sensor.py
index 83ebcaa3a4a..21944fe8f7e 100644
--- a/tests/components/zwave/test_sensor.py
+++ b/tests/components/zwave/test_sensor.py
@@ -1,10 +1,15 @@
 """Test Z-Wave sensor."""
+import pytest
+
 from homeassistant.components.sensor import SensorDeviceClass
 from homeassistant.components.zwave import const, sensor
 import homeassistant.const
 
 from tests.mock.zwave import MockEntityValues, MockNode, MockValue, value_changed
 
+# Integration is disabled
+pytest.skip("Integration has been disabled in the manifest", allow_module_level=True)
+
 
 def test_get_device_detects_none(mock_openzwave):
     """Test get_device returns None."""
diff --git a/tests/components/zwave/test_switch.py b/tests/components/zwave/test_switch.py
index 4293a4a23fd..4c3efbe61fd 100644
--- a/tests/components/zwave/test_switch.py
+++ b/tests/components/zwave/test_switch.py
@@ -1,10 +1,15 @@
 """Test Z-Wave switches."""
 from unittest.mock import patch
 
+import pytest
+
 from homeassistant.components.zwave import switch
 
 from tests.mock.zwave import MockEntityValues, MockNode, MockValue, value_changed
 
+# Integration is disabled
+pytest.skip("Integration has been disabled in the manifest", allow_module_level=True)
+
 
 def test_get_device_detects_switch(mock_openzwave):
     """Test get_device returns a Z-Wave switch."""
diff --git a/tests/components/zwave/test_websocket_api.py b/tests/components/zwave/test_websocket_api.py
index 2ad94d29b0e..2ffe5d61715 100644
--- a/tests/components/zwave/test_websocket_api.py
+++ b/tests/components/zwave/test_websocket_api.py
@@ -1,6 +1,8 @@
 """Test Z-Wave Websocket API."""
 from unittest.mock import call, patch
 
+import pytest
+
 from homeassistant import config_entries
 from homeassistant.bootstrap import async_setup_component
 from homeassistant.components.zwave.const import (
@@ -14,6 +16,10 @@ from homeassistant.components.zwave.websocket_api import ID, TYPE
 NETWORK_KEY = "0xTE, 0xST, 0xTE, 0xST, 0xTE, 0xST, 0xTE, 0xST, 0xTE, 0xST, 0xTE, 0xST, 0xTE, 0xST, 0xTE, 0xST"
 
 
+# Integration is disabled
+pytest.skip("Integration has been disabled in the manifest", allow_module_level=True)
+
+
 async def test_zwave_ws_api(hass, mock_openzwave, hass_ws_client):
     """Test Z-Wave websocket API."""
 
diff --git a/tests/components/zwave/test_workaround.py b/tests/components/zwave/test_workaround.py
index ec708d38e43..8f84fd6b949 100644
--- a/tests/components/zwave/test_workaround.py
+++ b/tests/components/zwave/test_workaround.py
@@ -1,8 +1,13 @@
 """Test Z-Wave workarounds."""
+import pytest
+
 from homeassistant.components.zwave import const, workaround
 
 from tests.mock.zwave import MockNode, MockValue
 
+# Integration is disabled
+pytest.skip("Integration has been disabled in the manifest", allow_module_level=True)
+
 
 def test_get_device_no_component_mapping():
     """Test that None is returned."""
diff --git a/tests/components/zwave_js/test_migrate.py b/tests/components/zwave_js/test_migrate.py
index ff3712b607e..3479638b387 100644
--- a/tests/components/zwave_js/test_migrate.py
+++ b/tests/components/zwave_js/test_migrate.py
@@ -317,6 +317,7 @@ async def test_migrate_zwave(
     assert not await hass.config_entries.async_setup(zwave_config_entry.entry_id)
 
 
+@pytest.mark.skip(reason="The old zwave integration has been disabled.")
 async def test_migrate_zwave_dry_run(
     hass,
     zwave_integration,
diff --git a/tests/mock/zwave.py b/tests/mock/zwave.py
index 5565b43a78e..89c70eaf83c 100644
--- a/tests/mock/zwave.py
+++ b/tests/mock/zwave.py
@@ -1,7 +1,9 @@
 """Mock helpers for Z-Wave component."""
 from unittest.mock import MagicMock
 
-from pydispatch import dispatcher
+# Integration & integration tests are disabled
+# from pydispatch import dispatcher
+dispatcher = MagicMock()
 
 
 def value_changed(value):
-- 
GitLab