[docs]classEntity(Unstructurable,HasIdentity,HasNamespace):"""Canonical concrete core entity composed from identity + constructor-form traits. Why --- :class:`Entity` is intentionally minimal. It adds no persistent fields beyond :class:`Unstructurable` and :class:`HasIdentity` and exists mainly to: - fix the default trait composition order for core entities, and - inject lifecycle dispatch hooks during creation paths. Notes ----- Inheritance order is ``(Unstructurable, HasNamespace, HasIdentity)``. ``HasNamespace`` adds namespace contribution behavior, while ``__eq__`` still compares by value via :meth:`Unstructurable.eq_by_value`. - Two entities with the same ``uid`` but different constructor-form values are not equal under ``==``. - Use :meth:`HasIdentity.eq_by_id` when you need identity-only comparison. **Dispatch hook control signal** Pass ``_ctx`` to ``__init__`` or :meth:`structure` to activate dispatch hooks. The underscore prefix means this is a control argument and is not stored as model data. If a subclass also has a ``ctx`` data field, both can coexist: .. code-block:: python CallReceipt(result=5, ctx=context, _ctx=context) Example: >>> e = Entity(label="abc") >>> f = Entity(uid=e.uid, label=e.label) >>> e is not f and e.eq_by_value(f) and e == f True >>> e.eq_by_id(f) True >>> g = Entity(uid=e.uid, label="different") >>> e.eq_by_id(g) and e != g True See Also -------- :mod:`tangl.core.dispatch` Hook registration and execution behavior. :mod:`tangl.core.ctx` Ambient context helpers for hook propagation. """templ_hash:Hash|None=Field(default=None,json_schema_extra={"is_identifier":True})"""Optional provenance hash of the template used to materialize this entity."""defis_instance(self,kind:type|tuple[type,...])->bool:"""Legacy alias for ``has_kind``."""ifisinstance(kind,tuple):returnall(isinstance(c,type)forcinkind)andisinstance(self,kind)returnisinstance(kind,type)andisinstance(self,kind)def__init__(self,_ctx:Any=None,**kwargs:Any)->None:"""Construct the entity and optionally run ``on_init`` dispatch hooks."""super().__init__(**kwargs)from.ctximportresolve_ctx_ctx=resolve_ctx(_ctx)if_ctxisnotNone:from.dispatchimportdo_initdo_init(caller=self,ctx=_ctx)@classmethoddefstructure(cls,data:Any,_ctx:Any=None)->Self:"""Structure from constructor-form data and optionally run ``on_create`` hooks."""from.ctximportresolve_ctx_ctx=resolve_ctx(_ctx)if_ctxisnotNone:# chance to modify kind-hint or construction kwargsfrom.dispatchimportdo_createdata=do_create(data=data,ctx=_ctx)returnsuper().structure(data)