Dedupe discovery and entity boilerplate #95
Loading…
Reference in a new issue
No description provided.
Delete branch "refactor/dedupe-discovery-entity"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Collapses the triplicated
Endpointfield lists indiscovery.py(thewith_*methods,Inventory.describe/present, andDiscovery._described/_presentedall re-spelled the same keywords), inlines a few trivial one-line wrappers, and removes the duplicated assignments between__init__andasync_redescribedinentity.py.No behavioural change; the existing discovery and entity test suites are the gate.
describe/presentnow take**fieldstyped with aTypedDict/Unpackpair so mypy can still check thedataclasses.replace()call.Tested with
tools/check(lint, format, mypy, full pytest run).Checked this against
refactor/code-hygienein a worktree.tools/checkis green (lint, format, mypy strict, full pytest run, 1218 passed).Traced the two things most likely to hide a behavioural change in a "pure refactor" like this:
CampervanNodeEntity.__init__now callsasync_redescribed(node), whose early-return becameif node == getattr(self, "node", None): return. On first constructionself.nodedoesn't exist yet,getattrreturnsNone, the dataclass__eq__safely returnsFalseagainstNone(noAttributeError, no exception), so init falls through and setsnode/device_infoexactly as before. Theif self.hass is not None: self.async_write_ha_state()guard beneath it (unchanged) is alsoFalseat construction time, sinceEntity.hassdefaults toNonebeforeadd_to_hass. So no spuriousasync_write_ha_state()call on construction, and later calls fromplatforms.py'sfollow_the_inventory()still skip the rebuild when the node hasn't actually changed, same as pre-refactor. This all matches howplatforms.pydrives it (construct once per node, cache inheld, thencarried.async_redescribed(node)on every subsequent announce).@callbackin this codebase (homeassistant.core.callback) just sets a_hass_callbackmarker attribute and returns the function unchanged — it isn't enforced anywherecoordinator.py'ssubscribe/notifytouches. Callingasync_redescribedsynchronously from__init__is no different fromplatforms.pyalready calling it synchronously post-construction, so no issue there either.Also checked the
TypedDict/Unpackfield names in_DescriptorFields/_MetaFieldsagainst every keywordDiscovery._described/_presentedpass intodescribe()/present()— they match exactly, and it's the minimal fix for the mypy-strictreplace(**dict)problem (two small TypedDicts, used only where needed, nothing speculative).No behavioural drift found, no dead code left behind (
with_descriptor/with_meta/with_label/_forget_label_pieces/query_frame/_bus_changed/_notifyare all gone with no remaining references), and the moved comment inInventory.describekeeps the one load-bearing sentence from the deleted_forget_label_piecesdocstring. Nothing to change.