Skip to content

Commit

Permalink
move to ruff from black (#241)
Browse files Browse the repository at this point in the history
* move to ruff from black

* add setup.cfg back for pytest
  • Loading branch information
marcolivierarsenault authored Dec 7, 2023
1 parent 2e27e66 commit 98b6467
Show file tree
Hide file tree
Showing 32 changed files with 250 additions and 220 deletions.
6 changes: 2 additions & 4 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,13 @@
"extensions": [
"ms-python.python",
"github.vscode-pull-request-github",
"ms-python.black-formatter",
"ms-python.flake8",
"ms-python.isort",
"charliermarsh.ruff",
"ms-python.vscode-pylance",
"ryanluker.vscode-coverage-gutters"
],
"settings": {
"[python]": {
"editor.defaultFormatter": "ms-python.black-formatter"
"editor.defaultFormatter": "charliermarsh.ruff"
},
"files.eol": "\n",
"editor.tabSize": 4,
Expand Down
25 changes: 15 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,24 @@ jobs:
- name: Hassfest validation
uses: "home-assistant/actions/hassfest@master"

style:
ruff:
name: "Ruff"
runs-on: "ubuntu-latest"
name: Check style formatting
steps:
- uses: "actions/checkout@v4"
- uses: "actions/setup-python@v4"
- uses: isort/[email protected]
- uses: jpetrucciani/black-check@master
- name: "Checkout the repository"
uses: "actions/[email protected]"

- name: "Set up Python"
uses: actions/[email protected]
with:
python-version: "3.x"
- run: python3 -m pip install flake8
- run: flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
- run: flake8 . --count --max-complexity=15 --max-line-length=127 --statistics
python-version: "3.11"
cache: "pip"

- name: "Install requirements"
run: python3 -m pip install -r requirements.txt

- name: "Run"
run: python3 -m ruff check .

tests:
runs-on: "ubuntu-latest"
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ secrets.yaml
blueprints
docs/_build
coverage.xml
.ruff_cache
29 changes: 6 additions & 23 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,14 @@ repos:
hooks:
- id: pyupgrade
args: [--py39-plus]
- repo: https://github.com/PyCQA/autoflake
rev: v2.0.0
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.6
hooks:
- id: autoflake
- id: ruff
args:
- --in-place
- --remove-all-unused-imports
- repo: https://github.com/psf/black
rev: 22.12.0
hooks:
- id: black
args:
- --quiet
- repo: https://github.com/PyCQA/flake8
rev: 6.0.0
hooks:
- id: flake8
args:
- --max-complexity=15
- --max-line-length=127
- --select=E9,F63,F7,F82
- repo: https://github.com/PyCQA/isort
rev: 5.12.0
hooks:
- id: isort
- --fix
- id: ruff-format
files: ^((homeassistant|pylint|script|tests)/.+)?[^/]+\.py$
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v2.7.1
hooks:
Expand Down
48 changes: 48 additions & 0 deletions .ruff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# The contents of this file is based on https://github.com/home-assistant/core/blob/dev/pyproject.toml

target-version = "py310"

select = [
"B007", # Loop control variable {name} not used within loop body
"B014", # Exception handler with duplicate exception
"C", # complexity
"D", # docstrings
"E", # pycodestyle
"F", # pyflakes/autoflake
"ICN001", # import concentions; {name} should be imported as {asname}
"PGH004", # Use specific rule codes when using noqa
"PLC0414", # Useless import alias. Import alias does not rename original package.
"SIM105", # Use contextlib.suppress({exception}) instead of try-except-pass
"SIM117", # Merge with-statements that use the same scope
"SIM118", # Use {key} in {dict} instead of {key} in {dict}.keys()
"SIM201", # Use {left} != {right} instead of not {left} == {right}
"SIM212", # Use {a} if {a} else {b} instead of {b} if not {a} else {a}
"SIM300", # Yoda conditions. Use 'age == 42' instead of '42 == age'.
"SIM401", # Use get from dict with default instead of an if block
"T20", # flake8-print
"TRY004", # Prefer TypeError exception for invalid type
"RUF006", # Store a reference to the return value of asyncio.create_task
"UP", # pyupgrade
"W", # pycodestyle
]

ignore = [
"D202", # No blank lines allowed after function docstring
"D203", # 1 blank line required before class docstring
"D213", # Multi-line docstring summary should start at the second line
"D404", # First word of the docstring should not be This
"D406", # Section name should end with a newline
"D407", # Section name underlining
"D411", # Missing blank line before section
"E501", # line too long
"E731", # do not assign a lambda expression, use a def
]

[flake8-pytest-style]
fixture-parentheses = false

[pyupgrade]
keep-runtime-typing = true

[mccabe]
max-complexity = 25
11 changes: 6 additions & 5 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"[python]": {
"editor.defaultFormatter": "ms-python.black-formatter",
"editor.formatOnSave": true
},
"python.formatting.provider": "none"
// Please keep this file in sync with settings in home-assistant/.devcontainer/devcontainer.json
// Added --no-cov to work around TypeError: message must be set
// https://github.com/microsoft/vscode-python/issues/14067
"python.testing.pytestArgs": ["--no-cov"],
// https://code.visualstudio.com/docs/python/testing#_pytest-configuration-settings
"python.testing.pytestEnabled": false
}
37 changes: 14 additions & 23 deletions custom_components/moonraker/__init__.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,22 @@
"""
Moonraker integration for Home Assistant
"""
"""Moonraker integration for Home Assistant."""
import asyncio
from datetime import timedelta
import logging
import os.path
from datetime import timedelta

import async_timeout
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import Config, HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from homeassistant.helpers.update_coordinator import (DataUpdateCoordinator,
UpdateFailed)

from .api import MoonrakerApiClient
from .const import (
CONF_API_KEY,
CONF_PORT,
CONF_PRINTER_NAME,
CONF_TLS,
CONF_URL,
DOMAIN,
HOSTNAME,
METHODS,
OBJ,
PLATFORMS,
TIMEOUT,
)
from .const import (CONF_API_KEY, CONF_PORT, CONF_PRINTER_NAME, CONF_TLS,
CONF_URL, DOMAIN, HOSTNAME, METHODS, OBJ, PLATFORMS,
TIMEOUT)
from .sensor import SENSORS

SCAN_INTERVAL = timedelta(seconds=30)
Expand All @@ -43,6 +32,7 @@ async def async_setup(_hass: HomeAssistant, _config: Config):


def get_user_name(hass: HomeAssistant, entry: ConfigEntry):
"""Get username."""
device_registry = dr.async_get(hass)
device_entries = dr.async_entries_for_config_entry(device_registry, entry.entry_id)

Expand Down Expand Up @@ -159,7 +149,7 @@ def __init__(

async def _async_update_data(self):
"""Update data via library."""
data = dict()
data = {}

for updater in self.updaters:
data.update(await updater(self))
Expand Down Expand Up @@ -256,26 +246,27 @@ async def _async_send_data(self, query_path: METHODS, query_obj) -> None:
async def async_fetch_data(
self, query_path: METHODS, query_obj: dict[str:any] = None, quiet: bool = False
):
"""Fetch data from moonraker"""
"""Fetch data from moonraker."""
return await self._async_fetch_data(query_path, query_obj, quiet=quiet)

async def async_send_data(
self, query_path: METHODS, query_obj: dict[str:any] = None
):
"""Send data to moonraker"""
"""Send data to moonraker."""
return await self._async_send_data(query_path, query_obj)

def add_data_updater(self, updater):
"""Update the data."""
self.updaters.append(updater)

def load_sensor_data(self, sensor_list):
"""Loading sensor data, so we can poll the right object"""
"""Load sensor data, so we can poll the right object."""
for sensor in sensor_list:
for subscriptions in sensor.subscriptions:
self.add_query_objects(subscriptions[0], subscriptions[1])

def add_query_objects(self, query_object: str, result_key: str):
"""Building the list of object we want to retreive from the server"""
"""Build the list of object we want to retreive from the server."""
if query_object not in self.query_obj[OBJ]:
self.query_obj[OBJ][query_object] = []
if result_key not in self.query_obj[OBJ][query_object]:
Expand Down
3 changes: 2 additions & 1 deletion custom_components/moonraker/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@


class MoonrakerApiClient(MoonrakerListener):
"""Moonraker communication API"""
"""Moonraker communication API."""

def __init__(
self, url, session, port: int = 7125, api_key: str = None, tls: bool = False
):
"""Init."""
self.running = False
if api_key == "":
api_key = None
Expand Down
8 changes: 3 additions & 5 deletions custom_components/moonraker/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@
from dataclasses import dataclass

from homeassistant.components.binary_sensor import (
BinarySensorDeviceClass,
BinarySensorEntity,
BinarySensorEntityDescription,
)
BinarySensorDeviceClass, BinarySensorEntity, BinarySensorEntityDescription)

from .const import DOMAIN, METHODS
from .entity import BaseMoonrakerEntity
Expand All @@ -30,7 +27,7 @@ async def async_setup_entry(hass, entry, async_add_devices):


async def async_setup_optional_binary_sensors(coordinator, entry, async_add_entities):
"""Setup optional binary sensor platform."""
"""Set optional binary sensor platform."""

sensors = []
object_list = await coordinator.async_fetch_data(METHODS.PRINTER_OBJECTS_LIST)
Expand Down Expand Up @@ -80,4 +77,5 @@ def __init__(

@property
def is_on(self) -> bool:
"""Return state."""
return self.is_on_fn(self)
10 changes: 6 additions & 4 deletions custom_components/moonraker/button.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
from collections.abc import Callable
from dataclasses import dataclass

from homeassistant.components.button import ButtonEntity, ButtonEntityDescription
from homeassistant.components.button import (ButtonEntity,
ButtonEntityDescription)

from .const import DOMAIN, METHODS
from .entity import BaseMoonrakerEntity
Expand Down Expand Up @@ -88,19 +89,19 @@ class MoonrakerButtonDescription(ButtonEntityDescription):


async def async_setup_entry(hass, entry, async_add_entities):
"""Setup sensor platform."""
"""Set sensor platform."""
coordinator = hass.data[DOMAIN][entry.entry_id]
await async_setup_basic_buttons(coordinator, entry, async_add_entities)
await async_setup_macros(coordinator, entry, async_add_entities)


async def async_setup_basic_buttons(coordinator, entry, async_add_entities):
"""Setup optional button platform."""
"""Set optional button platform."""
async_add_entities([MoonrakerButton(coordinator, entry, desc) for desc in BUTTONS])


async def async_setup_macros(coordinator, entry, async_add_entities):
"""Setup optional button platform."""
"""Set optional button platform."""
cmds = await coordinator.async_fetch_data(METHODS.PRINTER_GCODE_HELP)

macros = []
Expand Down Expand Up @@ -128,6 +129,7 @@ class MoonrakerButton(BaseMoonrakerEntity, ButtonEntity):
"""MoonrakerSensor Sensor class."""

def __init__(self, coordinator, entry, description):
"""Intit."""
super().__init__(coordinator, entry)
self.coordinator = coordinator
self._attr_unique_id = f"{entry.entry_id}_{description.key}"
Expand Down
4 changes: 2 additions & 2 deletions custom_components/moonraker/camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ class PreviewCamera(Camera):
_attr_is_streaming = False

def __init__(self, config_entry, coordinator, session) -> None:
"""Initialize as a subclass of Camera for the Thumbnail Preview"""
"""Initialize as a subclass of Camera for the Thumbnail Preview."""

super().__init__()
self._attr_device_info = DeviceInfo(
Expand All @@ -114,7 +114,7 @@ def __init__(self, config_entry, coordinator, session) -> None:
async def async_camera_image(
self, width: int | None = None, height: int | None = None
) -> bytes | None:
"""Return current camera image"""
"""Return current camera image."""
if (
self.coordinator.data["status"]["print_stats"]["state"]
!= PRINTSTATES.PRINTING.value
Expand Down
17 changes: 5 additions & 12 deletions custom_components/moonraker/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,14 @@
import logging

import async_timeout
import voluptuous as vol
from homeassistant import config_entries
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.util import network, slugify
import voluptuous as vol

from .api import MoonrakerApiClient
from .const import (
CONF_API_KEY,
CONF_PORT,
CONF_PRINTER_NAME,
CONF_TLS,
CONF_URL,
DOMAIN,
TIMEOUT,
)
from .const import (CONF_API_KEY, CONF_PORT, CONF_PRINTER_NAME, CONF_TLS,
CONF_URL, DOMAIN, TIMEOUT)

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -98,13 +91,13 @@ async def _test_host(self, host: str):
return network.is_host_valid(host)

async def _test_port(self, port):
if not port == "":
if port != "":
if not port.isdigit() or int(port) > 65535 or int(port) <= 1:
return False
return True

async def _test_api_key(self, api_key):
if not api_key == "":
if api_key != "":
if not api_key.isalnum() or len(api_key) != 32:
return False
return True
Expand Down
2 changes: 1 addition & 1 deletion custom_components/moonraker/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class ExtendedEnum(Enum):
@classmethod
def list(cls):
"""Return a list of all enum values."""
return list(map(lambda c: c.value, cls))
return [c.value for c in cls]


class PRINTSTATES(ExtendedEnum):
Expand Down
Loading

0 comments on commit 98b6467

Please sign in to comment.