From 2e8a1e7813ada641c982fd59f033586be85f11f9 Mon Sep 17 00:00:00 2001 From: Lasath Fernando Date: Fri, 27 Jun 2025 06:23:15 +0000 Subject: [PATCH] Make pytest-socket optional That way, this library can be used for integration/end-to-end tests. --- README.md | 15 +++++++++++++++ setup.py | 12 ++++++++++-- .../plugins.py | 19 ++++++++++++++++--- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ecefcba..6294469 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,21 @@ tests/ return snapshot.use_extension(HomeAssistantSnapshotExtension) ``` +## Installation + +### Basic Installation +```bash +pip install pytest-homeassistant-custom-component +``` + +### With Socket Testing Support +If you need network socket testing capabilities (using pytest-socket), install with the socket extra: +```bash +pip install pytest-homeassistant-custom-component[socket] +``` + +The pytest-socket plugin helps prevent tests from making real network calls by blocking socket access. This is optional and only needed if you want to ensure your tests don't accidentally make network connections. + ## Examples: * See [list of custom components](https://github.com/MatthewFlamm/pytest-homeassistant-custom-component/network/dependents) as examples that use this package. * Also see tests for `simple_integration` in this repository. diff --git a/setup.py b/setup.py index ce1650f..85c050a 100644 --- a/setup.py +++ b/setup.py @@ -5,10 +5,15 @@ requirements = [ "sqlalchemy", ] +optional_requirements = [] with open("requirements_test.txt","r") as f: for line in f: - if "txt" not in line and "#" not in line: - requirements.append(line) + line = line.strip() + if "txt" not in line and "#" not in line and line: + if line.startswith("pytest-socket"): + optional_requirements.append(line) + else: + requirements.append(line) with open("version", "r") as f: __version__ = f.read() @@ -21,6 +26,9 @@ package_dir={"": "src"}, python_requires=">=3.13", install_requires=requirements, + extras_require={ + "socket": optional_requirements, + }, license="MIT license", url="https://github.com/MatthewFlamm/pytest-homeassistant-custom-component", author_email="matthewflamm0@gmail.com", diff --git a/src/pytest_homeassistant_custom_component/plugins.py b/src/pytest_homeassistant_custom_component/plugins.py index 4112eee..63eb1ca 100644 --- a/src/pytest_homeassistant_custom_component/plugins.py +++ b/src/pytest_homeassistant_custom_component/plugins.py @@ -40,7 +40,10 @@ import multidict import pytest import pytest_asyncio -import pytest_socket +try: + import pytest_socket +except ImportError: + pytest_socket = None import requests_mock import respx from syrupy.assertion import SnapshotAssertion @@ -191,8 +194,9 @@ def pytest_runtest_setup() -> None: freezegun: Modified to include https://github.com/spulec/freezegun/pull/424 """ - pytest_socket.socket_allow_hosts(["127.0.0.1"]) - pytest_socket.disable_socket(allow_unix_socket=True) + if pytest_socket is not None: + pytest_socket.socket_allow_hosts(["127.0.0.1"]) + pytest_socket.disable_socket(allow_unix_socket=True) freezegun.api.datetime_to_fakedatetime = patch_time.ha_datetime_to_fakedatetime # type: ignore[attr-defined] freezegun.api.FakeDatetime = patch_time.HAFakeDatetime # type: ignore[attr-defined] @@ -2093,6 +2097,15 @@ def snapshot(snapshot: SnapshotAssertion) -> SnapshotAssertion: return snapshot.use_extension(HomeAssistantSnapshotExtension) +# Only define socket_enabled fixture if pytest-socket is not available +# When pytest-socket is installed, it provides its own socket_enabled fixture +if pytest_socket is None: + @pytest.fixture + def socket_enabled() -> None: + """Fixture to enable socket (no-op when pytest-socket is not installed).""" + return None + + @pytest.fixture def disable_block_async_io() -> Generator[None]: """Fixture to disable the loop protection from block_async_io."""