mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-04 21:58:56 +00:00
Stage 1 of #780 — the data model. A space carries an optional `led_strips: [{id, points, marker, active?}]` (custom_components/houseplan/ led_strips.py, pure, strict mypy). - Type schema inside SPACE_SCHEMA: 2–50 finite numeric points (no strings, booleans, NaN or off-canvas values), ≤50 strips per space including hidden shapes, strict boolean `active`, marker = non-empty string or null. - A config-level step after coordinate canonicalisation judges the shape (two distinct points, non-zero length, a closed strip needs three distinct vertices, a hidden shape needs a marker, unique ids per space) and the links in the order the spec fixes: duplicates are rejected before any normalisation (two links to the same missing id still conflict); a link to a marker that is not live becomes an unbound strip (marker null, active true, id and points kept), so a client that does not know strips can delete a bound marker without its save failing; a live marker with an empty space adopts the strip's space; a non-empty foreign space rejects the write. - config/set answers with `led_strips: {unbound, space_adopted}` when the write was normalised, so a new client re-reads; old clients ignore it. - Space import remaps links through the marker id map; a skipped or virtualised duplicate leaves the strip unbound; a coinciding old id never binds. Plan-only export keeps geometry and nulls every link. Import details report `unbound_led_strips`, computed by the server, never read from the file. - Coordinates get JSON-noise cleanup only, like stairs (face contacts are off-lattice), in both canonicalisers with a shared fixture case. - Support package: counters only (total/unbound/hidden), no coordinates or ids. Tests: tests_backend/test_led_strips.py (41, pure), test_ha_import_export (6 cases: full round trip with a hidden shape, orphan count, remap against a coinciding id, skip and virtual duplicates, plan-only), test_ha_websocket (old client deletes a bound marker → save stands, counters, foreign space rejects without a new revision). Full backend with the HA harness: 969 passed. Mutating the shape check, the duplicate check, the orphan normalisation or the space adoption each turns the pure suite red. Issue: #780 User-Visible: no
48 lines
2.5 KiB
TOML
48 lines
2.5 KiB
TOML
# #42: tool configuration only — the integration itself ships via HACS, not pip.
|
|
|
|
[tool.ruff]
|
|
target-version = "py313"
|
|
# Скоуп ОБЪЯВЛЕННЫЙ равен проверяемому (#399). Раньше здесь стояли три
|
|
# дерева, а CI линтил одно — читающий конфиг делал неверный вывод, и в
|
|
# tests_backend уже проехали F401/F811, которых на v1.69.0 не было.
|
|
#
|
|
# Сужение, а не расширение: разбор долга в scripts/ и tests_backend/ (56
|
|
# находок, в основном E402 и I001 в тестах, плюс 7 B023 и 5 B017) — работа
|
|
# со своей ценой и своими решениями, её место в отдельной задаче, а не в
|
|
# правке видимости. Расширять этот список можно только вместе со шагом
|
|
# «Линт бэкенда» в validate.yml — за этим следит test/lint-scope.test.mjs.
|
|
include = ["custom_components/houseplan/**/*.py"]
|
|
|
|
[tool.ruff.lint]
|
|
# Narrow on purpose (#42: no mass rewrite): errors, pyflakes, bugbear, imports.
|
|
select = ["E", "F", "B", "I"]
|
|
# E501: 291 legacy long lines are NOT rewritten wholesale; length is not a gate.
|
|
ignore = ["E501"]
|
|
|
|
[tool.mypy]
|
|
# 3.14, как и раннер после #392: mypy разбирает исходники установленного
|
|
# homeassistant, а тот уже написан на синтаксисе 3.14 (`except` без скобок) —
|
|
# на более низком python_version проверка падает синтаксической ошибкой в
|
|
# чужом файле, не дойдя до наших модулей.
|
|
python_version = "3.14"
|
|
explicit_package_bases = true
|
|
mypy_path = "."
|
|
# Strict is opt-in per module (#42): the allowlist below only ever GROWS —
|
|
# test/config-schema-parity guards live elsewhere; the backend guard is
|
|
# tests_backend/test_backend_quality.py which fails when a module leaves.
|
|
ignore_missing_imports = true
|
|
follow_imports = "silent"
|
|
no_site_packages = false
|
|
|
|
[[tool.mypy.overrides]]
|
|
module = [
|
|
"custom_components.houseplan.const",
|
|
"custom_components.houseplan.projection",
|
|
"custom_components.houseplan.coordinate_canonicalization",
|
|
"custom_components.houseplan.frontend_asset_manifest",
|
|
"custom_components.houseplan.junction_limits",
|
|
"custom_components.houseplan.plans",
|
|
"custom_components.houseplan.led_strips",
|
|
]
|
|
strict = true
|