mirror of
https://github.com/home-assistant/core.git
synced 2025-08-07 04:28:19 +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_async_load_fixtures",
|
||||||
"hass_decorator",
|
"hass_decorator",
|
||||||
"hass_enforce_class_module",
|
"hass_enforce_class_module",
|
||||||
|
"hass_enforce_greek_micro_char",
|
||||||
"hass_enforce_sorted_platforms",
|
"hass_enforce_sorted_platforms",
|
||||||
"hass_enforce_super_call",
|
"hass_enforce_super_call",
|
||||||
"hass_enforce_type_hints",
|
"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 = hass_decorator.HassDecoratorChecker(linter)
|
||||||
type_hint_checker.module = "homeassistant.components.pylint_test"
|
type_hint_checker.module = "homeassistant.components.pylint_test"
|
||||||
return type_hint_checker
|
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