mirror of
https://github.com/home-assistant/core.git
synced 2025-08-05 11:38:21 +00:00
Add linter to check correct microchar use
This commit is contained in:
parent
7b607a2c1b
commit
eaf536b52e
48
pylint/plugins/hass_enforce_greek_micro_char.py
Normal file
48
pylint/plugins/hass_enforce_greek_micro_char.py
Normal file
@ -0,0 +1,48 @@
|
||||
"""Plugin for checking correct micro unicode card is used."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from astroid import nodes
|
||||
from pylint.checkers import BaseChecker
|
||||
from pylint.lint import PyLinter
|
||||
|
||||
|
||||
class HassEnforceGreekMicroCharChecker(BaseChecker):
|
||||
"""Checker for micro char."""
|
||||
|
||||
name = "hass-enforce-greek-micro-char"
|
||||
priority = -1
|
||||
msgs = {
|
||||
"W7452": (
|
||||
"Constants with the mico sign must be encoded as U+03BC (\u03bc), not as U+00B5 (\u00b5)",
|
||||
"hass-enforce-greek-micro-char",
|
||||
"According to [The Unicode Consortium](https://en.wikipedia.org/wiki/Unicode_Consortium), the Greek letter character is preferred [10].",
|
||||
),
|
||||
}
|
||||
options = ()
|
||||
|
||||
def visit_annassign(self, node: nodes.AnnAssign) -> None:
|
||||
"""Check for sorted PLATFORMS const with type annotations."""
|
||||
self._do_micro_check(node.target, node)
|
||||
|
||||
def visit_assign(self, node: nodes.Assign) -> None:
|
||||
"""Check for sorted PLATFORMS const without type annotations."""
|
||||
for target in node.targets:
|
||||
self._do_micro_check(target, node)
|
||||
|
||||
def _do_micro_check(
|
||||
self, target: nodes.NodeNG, node: nodes.Assign | nodes.AnnAssign
|
||||
) -> None:
|
||||
"""Check const assignment is not containing ANSI micro char."""
|
||||
if (
|
||||
isinstance(target, nodes.AssignName)
|
||||
and isinstance(node.value, nodes.Const)
|
||||
and isinstance(node.value.value, str)
|
||||
and "\u00b5" in node.value.value
|
||||
):
|
||||
self.add_message(self.name, node=node)
|
||||
|
||||
|
||||
def register(linter: PyLinter) -> None:
|
||||
"""Register the checker."""
|
||||
linter.register_checker(HassEnforceGreekMicroCharChecker(linter))
|
@ -121,6 +121,7 @@ load-plugins = [
|
||||
"hass_async_load_fixtures",
|
||||
"hass_decorator",
|
||||
"hass_enforce_class_module",
|
||||
"hass_enforce_greek_micro_char",
|
||||
"hass_enforce_sorted_platforms",
|
||||
"hass_enforce_super_call",
|
||||
"hass_enforce_type_hints",
|
||||
|
@ -138,3 +138,24 @@ def decorator_checker_fixture(hass_decorator, linter) -> BaseChecker:
|
||||
type_hint_checker = hass_decorator.HassDecoratorChecker(linter)
|
||||
type_hint_checker.module = "homeassistant.components.pylint_test"
|
||||
return type_hint_checker
|
||||
|
||||
|
||||
@pytest.fixture(name="hass_enforce_greek_micro_char", scope="package")
|
||||
def hass_enforce_greek_micro_checker_fixture() -> ModuleType:
|
||||
"""Fixture to the content for the hass_enforce_greek_micro_char check."""
|
||||
return _load_plugin_from_file(
|
||||
"hass_enforce_greek_micro_char",
|
||||
"pylint/plugins/hass_enforce_greek_micro_char.py",
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(name="enforce_greek_micro_char_checker")
|
||||
def enforce_greek_micro_char_checker_fixture(
|
||||
hass_enforce_greek_micro_char, linter
|
||||
) -> BaseChecker:
|
||||
"""Fixture to provide a hass_enforce_greek_micro_char checker."""
|
||||
enforce_greek_micro_char_checker = (
|
||||
hass_enforce_greek_micro_char.HassEnforceGreekMicroCharChecker(linter)
|
||||
)
|
||||
enforce_greek_micro_char_checker.module = "homeassistant.components.pylint_test"
|
||||
return enforce_greek_micro_char_checker
|
||||
|
114
tests/pylint/test_enforce_greek_micro_char.py
Normal file
114
tests/pylint/test_enforce_greek_micro_char.py
Normal file
@ -0,0 +1,114 @@
|
||||
"""Tests for pylint hass_enforce_greek_micro_char plugin."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import astroid
|
||||
from pylint.checkers import BaseChecker
|
||||
from pylint.testutils.unittest_linter import UnittestLinter
|
||||
from pylint.utils.ast_walker import ASTWalker
|
||||
import pytest
|
||||
|
||||
from . import assert_no_messages
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"code",
|
||||
[
|
||||
pytest.param(
|
||||
"""
|
||||
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER: Final = "μg/m³" # "μ" == "\u03bc"
|
||||
""",
|
||||
id="good_const_with_annotation",
|
||||
),
|
||||
pytest.param(
|
||||
"""
|
||||
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER: Final = "\u03bcg/m³" # "μ" == "\u03bc"
|
||||
""",
|
||||
id="good_unicode_const_with_annotation",
|
||||
),
|
||||
pytest.param(
|
||||
"""
|
||||
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER = "μg/m³" # "μ" == "\u03bc"
|
||||
""",
|
||||
id="good_const_without_annotation",
|
||||
),
|
||||
pytest.param(
|
||||
"""
|
||||
class UnitOfElectricPotential(StrEnum):
|
||||
\"\"\"Electric potential units.\"\"\"
|
||||
|
||||
MICROVOLT = "μV" # "μ" == "\u03bc"
|
||||
MILLIVOLT = "mV"
|
||||
VOLT = "V"
|
||||
KILOVOLT = "kV"
|
||||
MEGAVOLT = "MV"
|
||||
""",
|
||||
id="good_str_enum",
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_enforce_greek_micro_char(
|
||||
linter: UnittestLinter,
|
||||
enforce_greek_micro_char_checker: BaseChecker,
|
||||
code: str,
|
||||
) -> None:
|
||||
"""Good test cases."""
|
||||
root_node = astroid.parse(code, "homeassistant.components.pylint_test")
|
||||
walker = ASTWalker(linter)
|
||||
walker.add_checker(enforce_greek_micro_char_checker)
|
||||
|
||||
with assert_no_messages(linter):
|
||||
walker.walk(root_node)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"code",
|
||||
[
|
||||
pytest.param(
|
||||
"""
|
||||
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER: Final = "µg/m³" # "μ" != "\u03bc"
|
||||
""",
|
||||
id="bad_const_with_annotation",
|
||||
),
|
||||
pytest.param(
|
||||
"""
|
||||
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER: Final = "\u00b5g/m³" # "μ" != "\u03bc"
|
||||
""",
|
||||
id="bad_unicode_const_with_annotation",
|
||||
),
|
||||
pytest.param(
|
||||
"""
|
||||
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER = "µg/m³" # "μ" != "\u03bc"
|
||||
""",
|
||||
id="bad_const_without_annotation",
|
||||
),
|
||||
pytest.param(
|
||||
"""
|
||||
class UnitOfElectricPotential(StrEnum):
|
||||
\"\"\"Electric potential units.\"\"\"
|
||||
|
||||
MICROVOLT = "µV" # "μ" != "\u03bc"
|
||||
MILLIVOLT = "mV"
|
||||
VOLT = "V"
|
||||
KILOVOLT = "kV"
|
||||
MEGAVOLT = "MV"
|
||||
""",
|
||||
id="bad_str_enum",
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_enforce_greek_micro_char_assign_bad(
|
||||
linter: UnittestLinter,
|
||||
enforce_greek_micro_char_checker: BaseChecker,
|
||||
code: str,
|
||||
) -> None:
|
||||
"""Bad assignment test cases."""
|
||||
root_node = astroid.parse(code, "homeassistant.components.pylint_test")
|
||||
walker = ASTWalker(linter)
|
||||
walker.add_checker(enforce_greek_micro_char_checker)
|
||||
|
||||
walker.walk(root_node)
|
||||
messages = linter.release_messages()
|
||||
assert len(messages) == 1
|
||||
message = next(iter(messages))
|
||||
assert message.msg_id == "hass-enforce-greek-micro-char"
|
Loading…
x
Reference in New Issue
Block a user