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
This commit is contained in:
Sid 2024-03-18 13:26:14 +01:00 committed by GitHub
parent 8f33bad4ef
commit 727581eea3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 60 additions and 102 deletions

View file

@ -645,7 +645,7 @@ def retryable_database_job(
return job(instance, *args, **kwargs) return job(instance, *args, **kwargs)
except OperationalError as err: except OperationalError as err:
if _is_retryable_error(instance, err): if _is_retryable_error(instance, err):
assert isinstance(err.orig, BaseException) assert isinstance(err.orig, BaseException) # noqa: PT017
_LOGGER.info( _LOGGER.info(
"%s; %s not completed, retrying", err.orig.args[1], description "%s; %s not completed, retrying", err.orig.args[1], description
) )
@ -691,7 +691,7 @@ def database_job_retry_wrapper(
instance, err instance, err
): ):
raise raise
assert isinstance(err.orig, BaseException) assert isinstance(err.orig, BaseException) # noqa: PT017
_LOGGER.info( _LOGGER.info(
"%s; %s failed, retrying", err.orig.args[1], description "%s; %s failed, retrying", err.orig.args[1], description
) )

View file

@ -609,6 +609,7 @@ select = [
"PGH004", # Use specific rule codes when using noqa "PGH004", # Use specific rule codes when using noqa
"PIE", # flake8-pie "PIE", # flake8-pie
"PL", # pylint "PL", # pylint
"PT", # flake8-pytest-style
"RSE", # flake8-raise "RSE", # flake8-raise
"RUF005", # Consider iterable unpacking instead of concatenation "RUF005", # Consider iterable unpacking instead of concatenation
"RUF006", # Store a reference to the return value of asyncio.create_task "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 # Disabled because ruff does not understand type of __all__ generated by a function
"PLE0605", "PLE0605",
# temporarily disabled
"PT004",
"PT007",
"PT011",
"PT018",
"PT012",
"PT023",
"PT019"
] ]
[tool.ruff.lint.flake8-import-conventions.extend-aliases] [tool.ruff.lint.flake8-import-conventions.extend-aliases]

View file

@ -49,7 +49,7 @@ async def test_get_actions(
@pytest.mark.parametrize( @pytest.mark.parametrize(
"hidden_by,entity_category", ("hidden_by", "entity_category"),
( (
(er.RegistryEntryHider.INTEGRATION, None), (er.RegistryEntryHider.INTEGRATION, None),
(er.RegistryEntryHider.USER, None), (er.RegistryEntryHider.USER, None),

View file

@ -90,7 +90,7 @@ def bump_version(version, bump_type):
to_change["dev"] = ("dev", dt_util.utcnow().strftime("%Y%m%d")) to_change["dev"] = ("dev", dt_util.utcnow().strftime("%Y%m%d"))
else: else:
assert False, f"Unsupported type: {bump_type}" raise ValueError(f"Unsupported type: {bump_type}")
temp = Version("0") temp = Version("0")
temp._version = version._version._replace(**to_change) temp._version = version._version._replace(**to_change)

View file

@ -176,7 +176,7 @@ async def setup_blackbird(hass, mock_blackbird):
"""Set up blackbird.""" """Set up blackbird."""
with mock.patch( with mock.patch(
"homeassistant.components.blackbird.media_player.get_blackbird", "homeassistant.components.blackbird.media_player.get_blackbird",
new=lambda *a: mock_blackbird, return_value=mock_blackbird,
): ):
await hass.async_add_executor_job( await hass.async_add_executor_job(
setup_platform, setup_platform,

View file

@ -78,7 +78,6 @@ from tests.common import MockConfigEntry
("5B", "1234_Max_current_per_phase", "1234_belgium_max_current_per_phase"), ("5B", "1234_Max_current_per_phase", "1234_belgium_max_current_per_phase"),
("5L", "1234_Energy_Consumption_(total)", "1234_electricity_imported_total"), ("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"),
("5L", "1234_Energy_Production_(total)", "1234_electricity_exported_total"),
("5", "1234_Gas_Consumption", "1234_hourly_gas_meter_reading"), ("5", "1234_Gas_Consumption", "1234_hourly_gas_meter_reading"),
("5B", "1234_Gas_Consumption", "1234_belgium_5min_gas_meter_reading"), ("5B", "1234_Gas_Consumption", "1234_belgium_5min_gas_meter_reading"),
("2.2", "1234_Gas_Consumption", "1234_gas_meter_reading"), ("2.2", "1234_Gas_Consumption", "1234_gas_meter_reading"),

View file

@ -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) mode_calls = async_mock_service(hass, DOMAIN, SERVICE_SET_MODE)
await intent.async_setup_intents(hass) await intent.async_setup_intents(hass)
try: with pytest.raises(IntentHandleError) as excinfo:
await async_handle( await async_handle(
hass, hass,
"test", "test",
intent.INTENT_MODE, intent.INTENT_MODE,
{"name": {"value": "Bedroom humidifier"}, "mode": {"value": "away"}}, {"name": {"value": "Bedroom humidifier"}, "mode": {"value": "away"}},
) )
pytest.fail("handling intent should have raised") assert str(excinfo.value) == "Entity bedroom humidifier does not support modes"
except IntentHandleError as err:
assert str(err) == "Entity bedroom humidifier does not support modes"
assert len(mode_calls) == 0 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) mode_calls = async_mock_service(hass, DOMAIN, SERVICE_SET_MODE)
await intent.async_setup_intents(hass) await intent.async_setup_intents(hass)
try: with pytest.raises(IntentHandleError) as excinfo:
await async_handle( await async_handle(
hass, hass,
"test", "test",
intent.INTENT_MODE, intent.INTENT_MODE,
{"name": {"value": "Bedroom humidifier"}, "mode": {"value": "eco"}}, {"name": {"value": "Bedroom humidifier"}, "mode": {"value": "eco"}},
) )
pytest.fail("handling intent should have raised") assert str(excinfo.value) == "Entity bedroom humidifier does not support eco mode"
except IntentHandleError as err:
assert str(err) == "Entity bedroom humidifier does not support eco mode"
assert len(mode_calls) == 0 assert len(mode_calls) == 0

View file

@ -329,11 +329,6 @@ async def test_ok_struct_validator(do_config) -> None:
CONF_VIRTUAL_COUNT: 2, CONF_VIRTUAL_COUNT: 2,
CONF_DATA_TYPE: DataType.INT32, 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_NAME: TEST_ENTITY_NAME,
CONF_DATA_TYPE: DataType.INT16, 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_TYPE: TCP,
CONF_HOST: TEST_MODBUS_HOST, CONF_HOST: TEST_MODBUS_HOST,

View file

@ -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: [ CONF_SENSORS: [
{ {

View file

@ -5,6 +5,7 @@ import logging
import socket import socket
from unittest.mock import patch from unittest.mock import patch
import pytest
from voluptuous import MultipleInvalid from voluptuous import MultipleInvalid
from homeassistant.components import pilight 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: {}}) assert await async_setup_component(hass, pilight.DOMAIN, {pilight.DOMAIN: {}})
# Call without protocol info, should raise an error # Call without protocol info, should raise an error
try: with pytest.raises(MultipleInvalid) as excinfo:
await hass.services.async_call( await hass.services.async_call(
pilight.DOMAIN, pilight.DOMAIN,
pilight.SERVICE_NAME, pilight.SERVICE_NAME,
@ -112,8 +113,7 @@ async def test_send_code_no_protocol(hass: HomeAssistant) -> None:
blocking=True, blocking=True,
) )
await hass.async_block_till_done() await hass.async_block_till_done()
except MultipleInvalid as error: assert "required key not provided @ data['protocol']" in str(excinfo.value)
assert "required key not provided @ data['protocol']" in str(error)
@patch("homeassistant.components.pilight._LOGGER.error") @patch("homeassistant.components.pilight._LOGGER.error")

View file

@ -512,7 +512,8 @@ async def _check_local_state(
@pytest.fixture @pytest.fixture
def _mock_partition_handler(): def mock_partition_handler():
"""Create a mock for add_partition_handler."""
with patch( with patch(
"homeassistant.components.risco.RiscoLocal.add_partition_handler" "homeassistant.components.risco.RiscoLocal.add_partition_handler"
) as mock: ) as mock:
@ -523,11 +524,11 @@ def _mock_partition_handler():
async def test_local_states( async def test_local_states(
hass: HomeAssistant, hass: HomeAssistant,
two_part_local_alarm, two_part_local_alarm,
_mock_partition_handler, mock_partition_handler,
setup_risco_local, setup_risco_local,
) -> None: ) -> None:
"""Test the various alarm states.""" """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 assert callback is not None

View file

@ -134,16 +134,17 @@ async def _check_local_state(
@pytest.fixture @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: with patch("homeassistant.components.risco.RiscoLocal.add_zone_handler") as mock:
yield mock yield mock
async def test_local_states( 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: ) -> None:
"""Test the various zone states.""" """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 assert callback is not None
@ -162,10 +163,10 @@ async def test_local_states(
async def test_alarmed_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: ) -> None:
"""Test the various zone alarmed states.""" """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 assert callback is not None
@ -184,10 +185,10 @@ async def test_alarmed_local_states(
async def test_armed_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: ) -> None:
"""Test the various zone armed states.""" """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 assert callback is not None

View file

@ -163,7 +163,8 @@ def _set_utc_time_zone(hass):
@pytest.fixture @pytest.fixture
def _save_mock(): def save_mock():
"""Create a mock for async_save."""
with patch( with patch(
"homeassistant.components.risco.Store.async_save", "homeassistant.components.risco.Store.async_save",
) as save_mock: ) as save_mock:
@ -175,7 +176,7 @@ async def test_cloud_setup(
hass: HomeAssistant, hass: HomeAssistant,
two_zone_cloud, two_zone_cloud,
_set_utc_time_zone, _set_utc_time_zone,
_save_mock, save_mock,
setup_risco_cloud, setup_risco_cloud,
) -> None: ) -> None:
"""Test entity setup.""" """Test entity setup."""
@ -183,7 +184,7 @@ async def test_cloud_setup(
for id in ENTITY_IDS.values(): for id in ENTITY_IDS.values():
assert registry.async_is_registered(id) 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(): for category, entity_id in ENTITY_IDS.items():
_check_state(hass, category, entity_id) _check_state(hass, category, entity_id)

View file

@ -124,16 +124,17 @@ async def _check_local_state(hass, zones, bypassed, entity_id, zone_id, callback
@pytest.fixture @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: with patch("homeassistant.components.risco.RiscoLocal.add_zone_handler") as mock:
yield mock yield mock
async def test_local_states( 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: ) -> None:
"""Test the various alarm states.""" """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 assert callback is not None

View file

@ -25,7 +25,8 @@ TEST_DATA = {
@pytest.fixture @pytest.fixture
def _config_entry(hass): def config_entry(hass: HomeAssistant) -> MockConfigEntry:
"""Create a mock config entry."""
config_entry = MockConfigEntry( config_entry = MockConfigEntry(
domain=DOMAIN, domain=DOMAIN,
data=TEST_DATA, 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 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.""" """Test that a flow with an existing account aborts."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER} 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" 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.""" """Test reauthentication."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, DOMAIN,
context={ context={
"source": config_entries.SOURCE_REAUTH, "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["type"] == "form"
assert result["errors"] is None 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["type"] == "abort"
assert result2["reason"] == "reauth_successful" 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 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.""" """Test reauthentication with new account."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, DOMAIN,
context={ context={
"source": config_entries.SOURCE_REAUTH, "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["type"] == "form"
assert result["errors"] is None 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["type"] == "abort"
assert result2["reason"] == "reauth_successful" assert result2["reason"] == "reauth_successful"
assert _config_entry.data[CONF_UNIQUE_ID] == "new-account-number" assert config_entry.data[CONF_UNIQUE_ID] == "new-account-number"
assert _config_entry.unique_id == "new-account-number" assert config_entry.unique_id == "new-account-number"
assert len(mock_setup_entry.mock_calls) == 1 assert len(mock_setup_entry.mock_calls) == 1

View file

@ -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: async def test_wrong_template_config(hass: HomeAssistant, start_ha) -> None:

View file

@ -257,10 +257,12 @@ async def test_temperature_no_unit(
) )
@pytest.mark.parametrize("native_unit", (UnitOfPressure.INHG, UnitOfPressure.INHG))
@pytest.mark.parametrize( @pytest.mark.parametrize(
("state_unit", "unit_system"), ("state_unit", "unit_system", "native_unit"),
((UnitOfPressure.HPA, METRIC_SYSTEM), (UnitOfPressure.INHG, US_CUSTOMARY_SYSTEM)), (
(UnitOfPressure.HPA, METRIC_SYSTEM, UnitOfPressure.INHG),
(UnitOfPressure.INHG, US_CUSTOMARY_SYSTEM, UnitOfPressure.INHG),
),
) )
async def test_pressure( async def test_pressure(
hass: HomeAssistant, hass: HomeAssistant,

View file

@ -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.AnalogInput.cluster_id, 1, {"present_value"}),
(zigpy.zcl.clusters.general.AnalogOutput.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.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.BinaryOutput.cluster_id, 1, {"present_value"}),
(zigpy.zcl.clusters.general.BinaryValue.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"}), (zigpy.zcl.clusters.general.MultistateInput.cluster_id, 1, {"present_value"}),

View file

@ -1775,8 +1775,7 @@ async def test_async_migrate_entry_delete_other(
entity_registry.async_remove(entry2.entity_id) entity_registry.async_remove(entry2.entity_id)
return None return None
if entity_entry == entry2: if entity_entry == entry2:
# We should not get here pytest.fail("We should not get here")
pytest.fail()
return None return None
entries = set() entries = set()