Skip to content

Commit

Permalink
Switch formatting from black to ruff-format (home-assistant#102893)
Browse files Browse the repository at this point in the history
Co-authored-by: Franck Nijhof <[email protected]>
  • Loading branch information
akx and frenck authored Nov 27, 2023
1 parent cf9b0e8 commit 706add4
Show file tree
Hide file tree
Showing 161 changed files with 531 additions and 608 deletions.
7 changes: 5 additions & 2 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"customizations": {
"vscode": {
"extensions": [
"ms-python.black-formatter",
"charliermarsh.ruff",
"ms-python.pylint",
"ms-python.vscode-pylance",
"visualstudioexptteam.vscodeintellicode",
Expand Down Expand Up @@ -39,7 +39,10 @@
"!include_dir_list scalar",
"!include_dir_merge_list scalar",
"!include_dir_merge_named scalar"
]
],
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff"
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
- [ ] There is no commented out code in this PR.
- [ ] I have followed the [development checklist][dev-checklist]
- [ ] I have followed the [perfect PR recommendations][perfect-pr]
- [ ] The code has been formatted using Black (`black --fast homeassistant tests`)
- [ ] The code has been formatted using Ruff (`ruff format homeassistant tests`)
- [ ] Tests have been added to verify that the new code works.

If user exposed functionality or configuration variables are added/changed:
Expand Down
37 changes: 6 additions & 31 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ env:
CACHE_VERSION: 5
PIP_CACHE_VERSION: 4
MYPY_CACHE_VERSION: 6
BLACK_CACHE_VERSION: 1
HA_SHORT_VERSION: "2023.12"
DEFAULT_PYTHON: "3.11"
ALL_PYTHON_VERSIONS: "['3.11', '3.12']"
Expand All @@ -58,7 +57,6 @@ env:
POSTGRESQL_VERSIONS: "['postgres:12.14','postgres:15.2']"
PRE_COMMIT_CACHE: ~/.cache/pre-commit
PIP_CACHE: /tmp/pip-cache
BLACK_CACHE: /tmp/black-cache
SQLALCHEMY_WARN_20: 1
PYTHONASYNCIODEBUG: 1
HASS_CI: 1
Expand Down Expand Up @@ -261,8 +259,8 @@ jobs:
. venv/bin/activate
pre-commit install-hooks
lint-black:
name: Check black
lint-ruff-format:
name: Check ruff-format
runs-on: ubuntu-22.04
needs:
- info
Expand All @@ -276,13 +274,6 @@ jobs:
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
- name: Generate partial black restore key
id: generate-black-key
run: |
black_version=$(cat requirements_test_pre_commit.txt | grep black | cut -d '=' -f 3)
echo "version=$black_version" >> $GITHUB_OUTPUT
echo "key=black-${{ env.BLACK_CACHE_VERSION }}-$black_version-${{
env.HA_SHORT_VERSION }}-$(date -u '+%Y-%m-%dT%H:%M:%s')" >> $GITHUB_OUTPUT
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache/[email protected]
Expand All @@ -301,33 +292,17 @@ jobs:
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
needs.info.outputs.pre-commit_cache_key }}
- name: Restore black cache
uses: actions/[email protected]
with:
path: ${{ env.BLACK_CACHE }}
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
steps.generate-black-key.outputs.key }}
restore-keys: |
${{ runner.os }}-${{ steps.python.outputs.python-version }}-black-${{
env.BLACK_CACHE_VERSION }}-${{ steps.generate-black-key.outputs.version }}-${{
env.HA_SHORT_VERSION }}-
- name: Run black (fully)
if: needs.info.outputs.test_full_suite == 'true'
env:
BLACK_CACHE_DIR: ${{ env.BLACK_CACHE }}
- name: Run ruff-format (fully)
run: |
. venv/bin/activate
pre-commit run --hook-stage manual black --all-files --show-diff-on-failure
- name: Run black (partially)
pre-commit run --hook-stage manual ruff-format --all-files --show-diff-on-failure
- name: Run ruff-format (partially)
if: needs.info.outputs.test_full_suite == 'false'
shell: bash
env:
BLACK_CACHE_DIR: ${{ env.BLACK_CACHE }}
run: |
. venv/bin/activate
shopt -s globstar
pre-commit run --hook-stage manual black --files {homeassistant,tests}/components/${{ needs.info.outputs.integrations_glob }}/{*,**/*} --show-diff-on-failure
pre-commit run --hook-stage manual ruff-format --files {homeassistant,tests}/components/${{ needs.info.outputs.integrations_glob }}/{*,**/*} --show-diff-on-failure
lint-ruff:
name: Check ruff
Expand Down
9 changes: 2 additions & 7 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.1
rev: v0.1.6
hooks:
- id: ruff
args:
- --fix
- repo: https://github.com/psf/black-pre-commit-mirror
rev: 23.11.0
hooks:
- id: black
args:
- --quiet
- id: ruff-format
files: ^((homeassistant|pylint|script|tests)/.+)?[^/]+\.py$
- repo: https://github.com/codespell-project/codespell
rev: v2.2.2
Expand Down
6 changes: 5 additions & 1 deletion .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
{
"recommendations": ["esbenp.prettier-vscode", "ms-python.python"]
"recommendations": [
"charliermarsh.ruff",
"esbenp.prettier-vscode",
"ms-python.python"
]
}
3 changes: 1 addition & 2 deletions Dockerfile.dev
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ SHELL ["/bin/bash", "-o", "pipefail", "-c"]
# Uninstall pre-installed formatting and linting tools
# They would conflict with our pinned versions
RUN \
pipx uninstall black \
&& pipx uninstall pydocstyle \
pipx uninstall pydocstyle \
&& pipx uninstall pycodestyle \
&& pipx uninstall mypy \
&& pipx uninstall pylint
Expand Down
4 changes: 1 addition & 3 deletions homeassistant/auth/permissions/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@

ValueType = (
# Example: entities.all = { read: true, control: true }
Mapping[str, bool]
| bool
| None
Mapping[str, bool] | bool | None
)

# Example: entities.domains = { light: … }
Expand Down
6 changes: 3 additions & 3 deletions homeassistant/components/assist_pipeline/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -1315,9 +1315,9 @@ async def execute(self) -> None:
if stt_audio_buffer:
# Send audio in the buffer first to speech-to-text, then move on to stt_stream.
# This is basically an async itertools.chain.
async def buffer_then_audio_stream() -> AsyncGenerator[
ProcessedAudioChunk, None
]:
async def buffer_then_audio_stream() -> (
AsyncGenerator[ProcessedAudioChunk, None]
):
# Buffered audio
for chunk in stt_audio_buffer:
yield chunk
Expand Down
3 changes: 1 addition & 2 deletions homeassistant/components/assist_pipeline/websocket_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -417,8 +417,7 @@ async def websocket_device_capture(
# single sample (16 bits) per queue item.
max_queue_items = (
# +1 for None to signal end
int(math.ceil(timeout_seconds * CAPTURE_RATE))
+ 1
int(math.ceil(timeout_seconds * CAPTURE_RATE)) + 1
)

audio_queue = DeviceAudioQueue(queue=asyncio.Queue(maxsize=max_queue_items))
Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/bmw_connected_drive/select.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ class BMWSelectEntityDescription(SelectEntityDescription, BMWRequiredKeysMixin):
translation_key="ac_limit",
is_available=lambda v: v.is_remote_set_ac_limit_enabled,
dynamic_options=lambda v: [
str(lim) for lim in v.charging_profile.ac_available_limits # type: ignore[union-attr]
str(lim)
for lim in v.charging_profile.ac_available_limits # type: ignore[union-attr]
],
current_option=lambda v: str(v.charging_profile.ac_current_limit), # type: ignore[union-attr]
remote_service=lambda v, o: v.remote_services.trigger_charging_settings_update(
Expand Down
9 changes: 6 additions & 3 deletions homeassistant/components/cloud/http_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ def _ws_handle_cloud_errors(
handler: Callable[
[HomeAssistant, websocket_api.ActiveConnection, dict[str, Any]],
Coroutine[None, None, None],
]
],
) -> Callable[
[HomeAssistant, websocket_api.ActiveConnection, dict[str, Any]],
Coroutine[None, None, None],
Expand Down Expand Up @@ -362,8 +362,11 @@ def _require_cloud_login(
handler: Callable[
[HomeAssistant, websocket_api.ActiveConnection, dict[str, Any]],
None,
]
) -> Callable[[HomeAssistant, websocket_api.ActiveConnection, dict[str, Any]], None,]:
],
) -> Callable[
[HomeAssistant, websocket_api.ActiveConnection, dict[str, Any]],
None,
]:
"""Websocket decorator that requires cloud to be logged in."""

@wraps(handler)
Expand Down
5 changes: 2 additions & 3 deletions homeassistant/components/deconz/deconz_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,8 @@ def async_update_callback(self) -> None:
if self.gateway.ignore_state_updates:
return

if (
self._update_keys is not None
and not self._device.changed_keys.intersection(self._update_keys)
if self._update_keys is not None and not self._device.changed_keys.intersection(
self._update_keys
):
return

Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/devolo_home_network/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ async def async_setup_entry( # noqa: C901
)
await device.async_connect(session_instance=async_client)
device.password = entry.data.get(
CONF_PASSWORD, "" # This key was added in HA Core 2022.6
CONF_PASSWORD,
"", # This key was added in HA Core 2022.6
)
except DeviceNotFound as err:
raise ConfigEntryNotReady(
Expand Down
7 changes: 3 additions & 4 deletions homeassistant/components/dlna_dmr/media_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -453,10 +453,9 @@ def _on_event(
for state_variable in state_variables:
# Force a state refresh when player begins or pauses playback
# to update the position info.
if (
state_variable.name == "TransportState"
and state_variable.value
in (TransportState.PLAYING, TransportState.PAUSED_PLAYBACK)
if state_variable.name == "TransportState" and state_variable.value in (
TransportState.PLAYING,
TransportState.PAUSED_PLAYBACK,
):
force_refresh = True

Expand Down
4 changes: 1 addition & 3 deletions homeassistant/components/dsmr/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -441,9 +441,7 @@ def device_class_and_uom(
description,
entry,
telegram,
*device_class_and_uom(
telegram, description
), # type: ignore[arg-type]
*device_class_and_uom(telegram, description), # type: ignore[arg-type]
)
for description in all_sensors
if (
Expand Down
12 changes: 5 additions & 7 deletions homeassistant/components/elmax/cover.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,11 @@

_LOGGER = logging.getLogger(__name__)

_COMMAND_BY_MOTION_STATUS = (
{ # Maps the stop command to use for every cover motion status
CoverStatus.DOWN: CoverCommand.DOWN,
CoverStatus.UP: CoverCommand.UP,
CoverStatus.IDLE: None,
}
)
_COMMAND_BY_MOTION_STATUS = { # Maps the stop command to use for every cover motion status
CoverStatus.DOWN: CoverCommand.DOWN,
CoverStatus.UP: CoverCommand.UP,
CoverStatus.IDLE: None,
}


async def async_setup_entry(
Expand Down
4 changes: 1 addition & 3 deletions homeassistant/components/esphome/enum_mapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ class EsphomeEnumMapper(Generic[_EnumT, _ValT]):
def __init__(self, mapping: dict[_EnumT, _ValT]) -> None:
"""Construct a EsphomeEnumMapper."""
# Add none mapping
augmented_mapping: dict[
_EnumT | None, _ValT | None
] = mapping # type: ignore[assignment]
augmented_mapping: dict[_EnumT | None, _ValT | None] = mapping # type: ignore[assignment]
augmented_mapping[None] = None

self._mapping = augmented_mapping
Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/esphome/fan.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ def percentage(self) -> int | None:
"""Return the current speed percentage."""
if not self._supports_speed_levels:
return ordered_list_item_to_percentage(
ORDERED_NAMED_FAN_SPEEDS, self._state.speed # type: ignore[misc]
ORDERED_NAMED_FAN_SPEEDS,
self._state.speed, # type: ignore[misc]
)

return ranged_value_to_percentage(
Expand Down
11 changes: 7 additions & 4 deletions homeassistant/components/evohome/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,13 @@ def convert_dict(dictionary: dict[str, Any]) -> dict[str, Any]:
def convert_key(key: str) -> str:
"""Convert a string to snake_case."""
string = re.sub(r"[\-\.\s]", "_", str(key))
return (string[0]).lower() + re.sub(
r"[A-Z]",
lambda matched: f"_{matched.group(0).lower()}", # type:ignore[str-bytes-safe]
string[1:],
return (
(string[0]).lower()
+ re.sub(
r"[A-Z]",
lambda matched: f"_{matched.group(0).lower()}", # type:ignore[str-bytes-safe]
string[1:],
)
)

return {
Expand Down
12 changes: 6 additions & 6 deletions homeassistant/components/goodwe/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,12 @@
class GoodweSensorEntityDescription(SensorEntityDescription):
"""Class describing Goodwe sensor entities."""

value: Callable[
[GoodweUpdateCoordinator, str], Any
] = lambda coordinator, sensor: coordinator.sensor_value(sensor)
available: Callable[
[GoodweUpdateCoordinator], bool
] = lambda coordinator: coordinator.last_update_success
value: Callable[[GoodweUpdateCoordinator, str], Any] = (
lambda coordinator, sensor: coordinator.sensor_value(sensor)
)
available: Callable[[GoodweUpdateCoordinator], bool] = (
lambda coordinator: coordinator.last_update_success
)


_DESCRIPTIONS: dict[str, GoodweSensorEntityDescription] = {
Expand Down
6 changes: 5 additions & 1 deletion homeassistant/components/google_assistant/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,11 @@
@callback
def _get_registry_entries(
hass: HomeAssistant, entity_id: str
) -> tuple[er.RegistryEntry | None, dr.DeviceEntry | None, ar.AreaEntry | None,]:
) -> tuple[
er.RegistryEntry | None,
dr.DeviceEntry | None,
ar.AreaEntry | None,
]:
"""Get registry entries."""
ent_reg = er.async_get(hass)
dev_reg = dr.async_get(hass)
Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/google_tasks/todo.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ def todo_items(self) -> list[TodoItem] | None:
summary=item["title"],
uid=item["id"],
status=TODO_STATUS_MAP.get(
item.get("status"), TodoItemStatus.NEEDS_ACTION # type: ignore[arg-type]
item.get("status"), # type: ignore[arg-type]
TodoItemStatus.NEEDS_ACTION,
),
)
for item in _order_tasks(self.coordinator.data)
Expand Down
4 changes: 1 addition & 3 deletions homeassistant/components/hdmi_cec/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,7 @@ def setup(hass: HomeAssistant, base_config: ConfigType) -> bool: # noqa: C901

loop = (
# Create own thread if more than 1 CPU
hass.loop
if multiprocessing.cpu_count() < 2
else None
hass.loop if multiprocessing.cpu_count() < 2 else None
)
host = base_config[DOMAIN].get(CONF_HOST)
display_name = base_config[DOMAIN].get(CONF_DISPLAY_NAME, DEFAULT_DISPLAY_NAME)
Expand Down
9 changes: 6 additions & 3 deletions homeassistant/components/homekit/type_fans.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,15 @@ def __init__(self, *args: Any) -> None:
),
)

setter_callback = (
lambda value, preset_mode=preset_mode: self.set_preset_mode(
value, preset_mode
)
)
self.preset_mode_chars[preset_mode] = preset_serv.configure_char(
CHAR_ON,
value=False,
setter_callback=lambda value, preset_mode=preset_mode: self.set_preset_mode(
value, preset_mode
),
setter_callback=setter_callback,
)

if CHAR_SWING_MODE in self.chars:
Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/hunterdouglas_powerview/select.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,5 +116,6 @@ def current_option(self) -> str | None:
async def async_select_option(self, option: str) -> None:
"""Change the selected option."""
await self.entity_description.select_fn(self._shade, option)
await self._shade.refresh() # force update data to ensure new info is in coordinator
# force update data to ensure new info is in coordinator
await self._shade.refresh()
self.async_write_ha_state()
Loading

0 comments on commit 706add4

Please sign in to comment.