[core] Lint duplicate UNIT_/CONF_ constants against both const homes (#19422)

This commit is contained in:
Jesse Hills
2026-09-24 14:21:32 +01:00
committed by GitHub
parent 22177680c4
commit b0c9a7d5bd
15 changed files with 157 additions and 24 deletions
+76
View File
@@ -151,6 +151,82 @@ def test_nolint_on_control_line_suppresses() -> None:
assert not _lint("if (x) // NOLINT\n ESP_LOGD(t);\n")
# --- rule: UNIT_ constants must not be redefined (mirror of the CONF_ check) ---
# Real UNIT_ constants that live in each canonical home.
UNIT_IN_CONST_PY = ci_custom.UNIT_CONSTANTS[0]
UNIT_IN_COMPONENT_CONST = ci_custom.COMPONENT_UNIT_CONSTANTS[0]
def _unit_def(fname: str, content: str) -> list:
return ci_custom.lint_unit_from_const_py(fname, content)
def test_unit_already_in_const_py_is_flagged() -> None:
errs = _unit_def("esphome/components/x/sensor.py", f'{UNIT_IN_CONST_PY} = "x"\n')
assert errs
assert "const.py" in errs[0][2]
def test_unit_already_in_component_const_is_flagged() -> None:
errs = _unit_def(
"esphome/components/x/sensor.py", f'{UNIT_IN_COMPONENT_CONST} = "x"\n'
)
assert errs
assert "esphome.components.const" in errs[0][2]
def test_unit_not_in_const_py_is_tracked_not_flagged() -> None:
ci_custom.UNIT_CONSTANTS_USES.clear()
assert _unit_def("a.py", 'UNIT_FOO_BAR = "fb"\n') == []
assert ci_custom.UNIT_CONSTANTS_USES["UNIT_FOO_BAR"] == ["a.py"]
def test_unit_defined_in_three_files_is_flagged() -> None:
ci_custom.UNIT_CONSTANTS_USES.clear()
for fname in ("a.py", "b.py", "c.py"):
_unit_def(fname, 'UNIT_FOO_BAR = "fb"\n')
errs = ci_custom.lint_unit_constants_usage()
assert any("UNIT_FOO_BAR" in e and "3 files" in e for e in errs)
def test_unit_defined_in_two_files_is_not_flagged() -> None:
ci_custom.UNIT_CONSTANTS_USES.clear()
for fname in ("a.py", "b.py"):
_unit_def(fname, 'UNIT_FOO_BAR = "fb"\n')
assert ci_custom.lint_unit_constants_usage() == []
# --- same rule for CONF_, now also recognising the components/const home ---
CONF_IN_CONST_PY = ci_custom.CONSTANTS[0]
CONF_IN_COMPONENT_CONST = ci_custom.COMPONENT_CONSTANTS[0]
def _conf_def(fname: str, content: str) -> list:
return ci_custom.lint_conf_from_const_py(fname, content)
def test_conf_already_in_const_py_is_flagged() -> None:
errs = _conf_def("esphome/components/x/sensor.py", f'{CONF_IN_CONST_PY} = "x"\n')
assert errs
assert "const.py" in errs[0][2]
def test_conf_already_in_component_const_is_flagged() -> None:
errs = _conf_def(
"esphome/components/x/sensor.py", f'{CONF_IN_COMPONENT_CONST} = "x"\n'
)
assert errs
assert "esphome.components.const" in errs[0][2]
def test_conf_not_in_a_const_home_is_tracked_not_flagged() -> None:
ci_custom.CONSTANTS_USES.pop("CONF_FOO_BAR", None)
assert _conf_def("a.py", 'CONF_FOO_BAR = "foo_bar"\n') == []
assert ci_custom.CONSTANTS_USES["CONF_FOO_BAR"] == ["a.py"]
# --- ESP_LOG call scanner and bare-literal-ternary lint ---