From 727581eea3f95faca3d8d1ca40e465e601ed3ade Mon Sep 17 00:00:00 2001 From: Sid <27780930+autinerd@users.noreply.github.com> Date: Mon, 18 Mar 2024 13:26:14 +0100 Subject: [PATCH] Add first batch of Ruff PT rules (#113665) * Add first batch of Ruff PT rules * fix weather test * Fix pilight test * Update test_intent.py * Update pilight test_init.py * Update test_init.py --- homeassistant/components/recorder/util.py | 4 +-- pyproject.toml | 10 +++++++ .../device_action/tests/test_device_action.py | 2 +- script/version_bump.py | 2 +- .../components/blackbird/test_media_player.py | 2 +- tests/components/dsmr/test_init.py | 1 - tests/components/humidifier/test_intent.py | 14 +++------- tests/components/modbus/test_init.py | 27 ------------------- tests/components/modbus/test_sensor.py | 9 ------- tests/components/pilight/test_init.py | 6 ++--- .../risco/test_alarm_control_panel.py | 7 ++--- tests/components/risco/test_binary_sensor.py | 15 ++++++----- tests/components/risco/test_sensor.py | 7 ++--- tests/components/risco/test_switch.py | 7 ++--- tests/components/rympro/test_config_flow.py | 23 ++++++++-------- tests/components/template/test_fan.py | 14 ---------- tests/components/weather/test_init.py | 8 +++--- tests/components/zha/test_cluster_handlers.py | 1 - tests/helpers/test_entity_registry.py | 3 +-- 19 files changed, 60 insertions(+), 102 deletions(-) diff --git a/homeassistant/components/recorder/util.py b/homeassistant/components/recorder/util.py index e92e287d11a..770dc91353c 100644 --- a/homeassistant/components/recorder/util.py +++ b/homeassistant/components/recorder/util.py @@ -645,7 +645,7 @@ def retryable_database_job( return job(instance, *args, **kwargs) except OperationalError as err: if _is_retryable_error(instance, err): - assert isinstance(err.orig, BaseException) + assert isinstance(err.orig, BaseException) # noqa: PT017 _LOGGER.info( "%s; %s not completed, retrying", err.orig.args[1], description ) @@ -691,7 +691,7 @@ def database_job_retry_wrapper( instance, err ): raise - assert isinstance(err.orig, BaseException) + assert isinstance(err.orig, BaseException) # noqa: PT017 _LOGGER.info( "%s; %s failed, retrying", err.orig.args[1], description ) diff --git a/pyproject.toml b/pyproject.toml index 218127ccff0..8c79824a1f6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -609,6 +609,7 @@ select = [ "PGH004", # Use specific rule codes when using noqa "PIE", # flake8-pie "PL", # pylint + "PT", # flake8-pytest-style "RSE", # flake8-raise "RUF005", # Consider iterable unpacking instead of concatenation "RUF006", # Store a reference to the return value of asyncio.create_task @@ -679,6 +680,15 @@ ignore = [ # Disabled because ruff does not understand type of __all__ generated by a function "PLE0605", + + # temporarily disabled + "PT004", + "PT007", + "PT011", + "PT018", + "PT012", + "PT023", + "PT019" ] [tool.ruff.lint.flake8-import-conventions.extend-aliases] diff --git a/script/scaffold/templates/device_action/tests/test_device_action.py b/script/scaffold/templates/device_action/tests/test_device_action.py index cd7adfbc844..f8260a62282 100644 --- a/script/scaffold/templates/device_action/tests/test_device_action.py +++ b/script/scaffold/templates/device_action/tests/test_device_action.py @@ -49,7 +49,7 @@ async def test_get_actions( @pytest.mark.parametrize( - "hidden_by,entity_category", + ("hidden_by", "entity_category"), ( (er.RegistryEntryHider.INTEGRATION, None), (er.RegistryEntryHider.USER, None), diff --git a/script/version_bump.py b/script/version_bump.py index 50f749d6983..da864b45176 100755 --- a/script/version_bump.py +++ b/script/version_bump.py @@ -90,7 +90,7 @@ def bump_version(version, bump_type): to_change["dev"] = ("dev", dt_util.utcnow().strftime("%Y%m%d")) else: - assert False, f"Unsupported type: {bump_type}" + raise ValueError(f"Unsupported type: {bump_type}") temp = Version("0") temp._version = version._version._replace(**to_change) diff --git a/tests/components/blackbird/test_media_player.py b/tests/components/blackbird/test_media_player.py index 5e6ece7d792..3b0465ef208 100644 --- a/tests/components/blackbird/test_media_player.py +++ b/tests/components/blackbird/test_media_player.py @@ -176,7 +176,7 @@ async def setup_blackbird(hass, mock_blackbird): """Set up blackbird.""" with mock.patch( "homeassistant.components.blackbird.media_player.get_blackbird", - new=lambda *a: mock_blackbird, + return_value=mock_blackbird, ): await hass.async_add_executor_job( setup_platform, diff --git a/tests/components/dsmr/test_init.py b/tests/components/dsmr/test_init.py index f87c17f6a19..11487b6b87b 100644 --- a/tests/components/dsmr/test_init.py +++ b/tests/components/dsmr/test_init.py @@ -78,7 +78,6 @@ from tests.common import MockConfigEntry ("5B", "1234_Max_current_per_phase", "1234_belgium_max_current_per_phase"), ("5L", "1234_Energy_Consumption_(total)", "1234_electricity_imported_total"), ("5L", "1234_Energy_Production_(total)", "1234_electricity_exported_total"), - ("5L", "1234_Energy_Production_(total)", "1234_electricity_exported_total"), ("5", "1234_Gas_Consumption", "1234_hourly_gas_meter_reading"), ("5B", "1234_Gas_Consumption", "1234_belgium_5min_gas_meter_reading"), ("2.2", "1234_Gas_Consumption", "1234_gas_meter_reading"), diff --git a/tests/components/humidifier/test_intent.py b/tests/components/humidifier/test_intent.py index 20e23b14605..9ee72baf73b 100644 --- a/tests/components/humidifier/test_intent.py +++ b/tests/components/humidifier/test_intent.py @@ -175,17 +175,14 @@ async def test_intent_set_mode_tests_feature(hass: HomeAssistant) -> None: mode_calls = async_mock_service(hass, DOMAIN, SERVICE_SET_MODE) await intent.async_setup_intents(hass) - try: + with pytest.raises(IntentHandleError) as excinfo: await async_handle( hass, "test", intent.INTENT_MODE, {"name": {"value": "Bedroom humidifier"}, "mode": {"value": "away"}}, ) - pytest.fail("handling intent should have raised") - except IntentHandleError as err: - assert str(err) == "Entity bedroom humidifier does not support modes" - + assert str(excinfo.value) == "Entity bedroom humidifier does not support modes" assert len(mode_calls) == 0 @@ -207,15 +204,12 @@ async def test_intent_set_unknown_mode( mode_calls = async_mock_service(hass, DOMAIN, SERVICE_SET_MODE) await intent.async_setup_intents(hass) - try: + with pytest.raises(IntentHandleError) as excinfo: await async_handle( hass, "test", intent.INTENT_MODE, {"name": {"value": "Bedroom humidifier"}, "mode": {"value": "eco"}}, ) - pytest.fail("handling intent should have raised") - except IntentHandleError as err: - assert str(err) == "Entity bedroom humidifier does not support eco mode" - + assert str(excinfo.value) == "Entity bedroom humidifier does not support eco mode" assert len(mode_calls) == 0 diff --git a/tests/components/modbus/test_init.py b/tests/components/modbus/test_init.py index 44bf089f0d5..b93519c1d05 100644 --- a/tests/components/modbus/test_init.py +++ b/tests/components/modbus/test_init.py @@ -329,11 +329,6 @@ async def test_ok_struct_validator(do_config) -> None: CONF_VIRTUAL_COUNT: 2, CONF_DATA_TYPE: DataType.INT32, }, - { - CONF_NAME: TEST_ENTITY_NAME, - CONF_DATA_TYPE: DataType.INT16, - CONF_SWAP: CONF_SWAP_WORD, - }, { CONF_NAME: TEST_ENTITY_NAME, CONF_DATA_TYPE: DataType.INT16, @@ -981,28 +976,6 @@ async def test_no_duplicate_names(hass: HomeAssistant, do_config) -> None: } ], }, - { - CONF_TYPE: TCP, - CONF_HOST: TEST_MODBUS_HOST, - CONF_PORT: TEST_PORT_TCP, - CONF_SENSORS: [ - { - CONF_NAME: "dummy", - CONF_ADDRESS: 9999, - } - ], - }, - { - CONF_TYPE: TCP, - CONF_HOST: TEST_MODBUS_HOST, - CONF_PORT: TEST_PORT_TCP, - CONF_SENSORS: [ - { - CONF_NAME: "dummy", - CONF_ADDRESS: 9999, - } - ], - }, { CONF_TYPE: TCP, CONF_HOST: TEST_MODBUS_HOST, diff --git a/tests/components/modbus/test_sensor.py b/tests/components/modbus/test_sensor.py index 23347cc56bb..524acc0dabb 100644 --- a/tests/components/modbus/test_sensor.py +++ b/tests/components/modbus/test_sensor.py @@ -116,15 +116,6 @@ SLAVE_UNIQUE_ID = "ground_floor_sensor" } ] }, - { - CONF_SENSORS: [ - { - CONF_NAME: TEST_ENTITY_NAME, - CONF_ADDRESS: 51, - CONF_DATA_TYPE: DataType.INT16, - } - ] - }, { CONF_SENSORS: [ { diff --git a/tests/components/pilight/test_init.py b/tests/components/pilight/test_init.py index 9cbbadfbbc8..e5ff016b5f3 100644 --- a/tests/components/pilight/test_init.py +++ b/tests/components/pilight/test_init.py @@ -5,6 +5,7 @@ import logging import socket from unittest.mock import patch +import pytest from voluptuous import MultipleInvalid from homeassistant.components import pilight @@ -104,7 +105,7 @@ async def test_send_code_no_protocol(hass: HomeAssistant) -> None: assert await async_setup_component(hass, pilight.DOMAIN, {pilight.DOMAIN: {}}) # Call without protocol info, should raise an error - try: + with pytest.raises(MultipleInvalid) as excinfo: await hass.services.async_call( pilight.DOMAIN, pilight.SERVICE_NAME, @@ -112,8 +113,7 @@ async def test_send_code_no_protocol(hass: HomeAssistant) -> None: blocking=True, ) await hass.async_block_till_done() - except MultipleInvalid as error: - assert "required key not provided @ data['protocol']" in str(error) + assert "required key not provided @ data['protocol']" in str(excinfo.value) @patch("homeassistant.components.pilight._LOGGER.error") diff --git a/tests/components/risco/test_alarm_control_panel.py b/tests/components/risco/test_alarm_control_panel.py index 5fc4f40da99..ee8b844c167 100644 --- a/tests/components/risco/test_alarm_control_panel.py +++ b/tests/components/risco/test_alarm_control_panel.py @@ -512,7 +512,8 @@ async def _check_local_state( @pytest.fixture -def _mock_partition_handler(): +def mock_partition_handler(): + """Create a mock for add_partition_handler.""" with patch( "homeassistant.components.risco.RiscoLocal.add_partition_handler" ) as mock: @@ -523,11 +524,11 @@ def _mock_partition_handler(): async def test_local_states( hass: HomeAssistant, two_part_local_alarm, - _mock_partition_handler, + mock_partition_handler, setup_risco_local, ) -> None: """Test the various alarm states.""" - callback = _mock_partition_handler.call_args.args[0] + callback = mock_partition_handler.call_args.args[0] assert callback is not None diff --git a/tests/components/risco/test_binary_sensor.py b/tests/components/risco/test_binary_sensor.py index ce49c1696fd..22f71ead28d 100644 --- a/tests/components/risco/test_binary_sensor.py +++ b/tests/components/risco/test_binary_sensor.py @@ -134,16 +134,17 @@ async def _check_local_state( @pytest.fixture -def _mock_zone_handler(): +def mock_zone_handler(): + """Create a mock for add_zone_handler.""" with patch("homeassistant.components.risco.RiscoLocal.add_zone_handler") as mock: yield mock async def test_local_states( - hass: HomeAssistant, two_zone_local, _mock_zone_handler, setup_risco_local + hass: HomeAssistant, two_zone_local, mock_zone_handler, setup_risco_local ) -> None: """Test the various zone states.""" - callback = _mock_zone_handler.call_args.args[0] + callback = mock_zone_handler.call_args.args[0] assert callback is not None @@ -162,10 +163,10 @@ async def test_local_states( async def test_alarmed_local_states( - hass: HomeAssistant, two_zone_local, _mock_zone_handler, setup_risco_local + hass: HomeAssistant, two_zone_local, mock_zone_handler, setup_risco_local ) -> None: """Test the various zone alarmed states.""" - callback = _mock_zone_handler.call_args.args[0] + callback = mock_zone_handler.call_args.args[0] assert callback is not None @@ -184,10 +185,10 @@ async def test_alarmed_local_states( async def test_armed_local_states( - hass: HomeAssistant, two_zone_local, _mock_zone_handler, setup_risco_local + hass: HomeAssistant, two_zone_local, mock_zone_handler, setup_risco_local ) -> None: """Test the various zone armed states.""" - callback = _mock_zone_handler.call_args.args[0] + callback = mock_zone_handler.call_args.args[0] assert callback is not None diff --git a/tests/components/risco/test_sensor.py b/tests/components/risco/test_sensor.py index a172eb3d650..be909254d70 100644 --- a/tests/components/risco/test_sensor.py +++ b/tests/components/risco/test_sensor.py @@ -163,7 +163,8 @@ def _set_utc_time_zone(hass): @pytest.fixture -def _save_mock(): +def save_mock(): + """Create a mock for async_save.""" with patch( "homeassistant.components.risco.Store.async_save", ) as save_mock: @@ -175,7 +176,7 @@ async def test_cloud_setup( hass: HomeAssistant, two_zone_cloud, _set_utc_time_zone, - _save_mock, + save_mock, setup_risco_cloud, ) -> None: """Test entity setup.""" @@ -183,7 +184,7 @@ async def test_cloud_setup( for id in ENTITY_IDS.values(): assert registry.async_is_registered(id) - _save_mock.assert_awaited_once_with({LAST_EVENT_TIMESTAMP_KEY: TEST_EVENTS[0].time}) + save_mock.assert_awaited_once_with({LAST_EVENT_TIMESTAMP_KEY: TEST_EVENTS[0].time}) for category, entity_id in ENTITY_IDS.items(): _check_state(hass, category, entity_id) diff --git a/tests/components/risco/test_switch.py b/tests/components/risco/test_switch.py index 1d575f4b75b..100796b9ea1 100644 --- a/tests/components/risco/test_switch.py +++ b/tests/components/risco/test_switch.py @@ -124,16 +124,17 @@ async def _check_local_state(hass, zones, bypassed, entity_id, zone_id, callback @pytest.fixture -def _mock_zone_handler(): +def mock_zone_handler(): + """Create a mock for add_zone_handler.""" with patch("homeassistant.components.risco.RiscoLocal.add_zone_handler") as mock: yield mock async def test_local_states( - hass: HomeAssistant, two_zone_local, _mock_zone_handler, setup_risco_local + hass: HomeAssistant, two_zone_local, mock_zone_handler, setup_risco_local ) -> None: """Test the various alarm states.""" - callback = _mock_zone_handler.call_args.args[0] + callback = mock_zone_handler.call_args.args[0] assert callback is not None diff --git a/tests/components/rympro/test_config_flow.py b/tests/components/rympro/test_config_flow.py index 811234dd559..e61384107cb 100644 --- a/tests/components/rympro/test_config_flow.py +++ b/tests/components/rympro/test_config_flow.py @@ -25,7 +25,8 @@ TEST_DATA = { @pytest.fixture -def _config_entry(hass): +def config_entry(hass: HomeAssistant) -> MockConfigEntry: + """Create a mock config entry.""" config_entry = MockConfigEntry( domain=DOMAIN, data=TEST_DATA, @@ -122,7 +123,7 @@ async def test_login_error(hass: HomeAssistant, exception, error) -> None: assert len(mock_setup_entry.mock_calls) == 1 -async def test_form_already_exists(hass: HomeAssistant, _config_entry) -> None: +async def test_form_already_exists(hass: HomeAssistant, config_entry) -> None: """Test that a flow with an existing account aborts.""" result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER} @@ -148,16 +149,16 @@ async def test_form_already_exists(hass: HomeAssistant, _config_entry) -> None: assert result2["reason"] == "already_configured" -async def test_form_reauth(hass: HomeAssistant, _config_entry) -> None: +async def test_form_reauth(hass: HomeAssistant, config_entry) -> None: """Test reauthentication.""" result = await hass.config_entries.flow.async_init( DOMAIN, context={ "source": config_entries.SOURCE_REAUTH, - "entry_id": _config_entry.entry_id, + "entry_id": config_entry.entry_id, }, - data=_config_entry.data, + data=config_entry.data, ) assert result["type"] == "form" assert result["errors"] is None @@ -183,20 +184,20 @@ async def test_form_reauth(hass: HomeAssistant, _config_entry) -> None: assert result2["type"] == "abort" assert result2["reason"] == "reauth_successful" - assert _config_entry.data[CONF_PASSWORD] == "new_password" + assert config_entry.data[CONF_PASSWORD] == "new_password" assert len(mock_setup_entry.mock_calls) == 1 -async def test_form_reauth_with_new_account(hass: HomeAssistant, _config_entry) -> None: +async def test_form_reauth_with_new_account(hass: HomeAssistant, config_entry) -> None: """Test reauthentication with new account.""" result = await hass.config_entries.flow.async_init( DOMAIN, context={ "source": config_entries.SOURCE_REAUTH, - "entry_id": _config_entry.entry_id, + "entry_id": config_entry.entry_id, }, - data=_config_entry.data, + data=config_entry.data, ) assert result["type"] == "form" assert result["errors"] is None @@ -222,6 +223,6 @@ async def test_form_reauth_with_new_account(hass: HomeAssistant, _config_entry) assert result2["type"] == "abort" assert result2["reason"] == "reauth_successful" - assert _config_entry.data[CONF_UNIQUE_ID] == "new-account-number" - assert _config_entry.unique_id == "new-account-number" + assert config_entry.data[CONF_UNIQUE_ID] == "new-account-number" + assert config_entry.unique_id == "new-account-number" assert len(mock_setup_entry.mock_calls) == 1 diff --git a/tests/components/template/test_fan.py b/tests/components/template/test_fan.py index 773c67c39db..93520b0f621 100644 --- a/tests/components/template/test_fan.py +++ b/tests/components/template/test_fan.py @@ -105,20 +105,6 @@ async def test_missing_optional_config(hass: HomeAssistant, start_ha) -> None: }, } }, - { - DOMAIN: { - "platform": "template", - "fans": { - "platform": "template", - "fans": { - "test_fan": { - "value_template": "{{ 'on' }}", - "turn_on": {"service": "script.fan_on"}, - } - }, - }, - } - }, ], ) async def test_wrong_template_config(hass: HomeAssistant, start_ha) -> None: diff --git a/tests/components/weather/test_init.py b/tests/components/weather/test_init.py index cf29c8d62ab..c6f7e6112db 100644 --- a/tests/components/weather/test_init.py +++ b/tests/components/weather/test_init.py @@ -257,10 +257,12 @@ async def test_temperature_no_unit( ) -@pytest.mark.parametrize("native_unit", (UnitOfPressure.INHG, UnitOfPressure.INHG)) @pytest.mark.parametrize( - ("state_unit", "unit_system"), - ((UnitOfPressure.HPA, METRIC_SYSTEM), (UnitOfPressure.INHG, US_CUSTOMARY_SYSTEM)), + ("state_unit", "unit_system", "native_unit"), + ( + (UnitOfPressure.HPA, METRIC_SYSTEM, UnitOfPressure.INHG), + (UnitOfPressure.INHG, US_CUSTOMARY_SYSTEM, UnitOfPressure.INHG), + ), ) async def test_pressure( hass: HomeAssistant, diff --git a/tests/components/zha/test_cluster_handlers.py b/tests/components/zha/test_cluster_handlers.py index fd8ca31fe9f..c081faab010 100644 --- a/tests/components/zha/test_cluster_handlers.py +++ b/tests/components/zha/test_cluster_handlers.py @@ -148,7 +148,6 @@ async def poll_control_device(zha_device_restored, zigpy_device_mock): (zigpy.zcl.clusters.general.AnalogInput.cluster_id, 1, {"present_value"}), (zigpy.zcl.clusters.general.AnalogOutput.cluster_id, 1, {"present_value"}), (zigpy.zcl.clusters.general.AnalogValue.cluster_id, 1, {"present_value"}), - (zigpy.zcl.clusters.general.AnalogOutput.cluster_id, 1, {"present_value"}), (zigpy.zcl.clusters.general.BinaryOutput.cluster_id, 1, {"present_value"}), (zigpy.zcl.clusters.general.BinaryValue.cluster_id, 1, {"present_value"}), (zigpy.zcl.clusters.general.MultistateInput.cluster_id, 1, {"present_value"}), diff --git a/tests/helpers/test_entity_registry.py b/tests/helpers/test_entity_registry.py index b029933ebbe..0974d3bc9de 100644 --- a/tests/helpers/test_entity_registry.py +++ b/tests/helpers/test_entity_registry.py @@ -1775,8 +1775,7 @@ async def test_async_migrate_entry_delete_other( entity_registry.async_remove(entry2.entity_id) return None if entity_entry == entry2: - # We should not get here - pytest.fail() + pytest.fail("We should not get here") return None entries = set()