MLP203: family-walk query of a confirmed-large mobject in a per-frame callback¶
qual reports MLP203 when a family-walk / geometry query
(get_family, family_members_with_points, get_all_points,
get_arc_length, proportion_from_point) runs inside a per-frame
callback on a receiver whose family is confirmed large: every call
recomputes its result from all family members, multiplying that walk by
the frame count.
- Default severity:
info - Minimum confidence:
high - Implementation phase:
3 - Fix: none
- Superseded by
MLP224forpoint_from_proportion(DESIGN §7.3 specificity: those entries are routed to the long-path rule and never reported here)
Emission gate (cited in evidence): N_family >= 32 (large-family-gate)
— once the large family is confirmed, no repeated-query analysis is
required (DESIGN §7.3). A single next_to / get_center on a small
Dot — the catalog near-miss — never fires: those methods are not
family-walk queries, and small or unproven families never confirm the
gate. Receiver resolution uses the updater-lambda-host contract (see
MLP202); other receivers stay silent.
Proven execution (liveness)¶
A hot context only proves the call is reachable from a per-frame entry point. The diagnostic additionally requires at least one play where the callback provably executes per frame (DESIGN 3.2/3.3):
- the registration is active at the play (registered on every path and not removed before it),
- the host is in the scene family there,
- the host is not suspended:
Animation.begin()suspends the animated mobject's updaters — recursively over its family — for the whole play (animation.py), unless the animation was constructed withsuspend_mobject_updating=False, - the play actually runs callbacks: a
play(...), or a wait that is provably dynamic (scene.pyshould_update_mobjects). A one-argument updater leaves the defaultwait()a static frame.
self.add(label); self.play(FadeIn(label), run_time=2); self.wait(3)
therefore stays silent: the only play suspends the updater and the wait
is static, so the callback runs about once — never once per frame.
Evidence lists the counted plays (execution) so the claim is
auditable; quantities sum over the proven plays only, and only-maybe
evidence (a branch-dependent registration, an unknown animation that may
suspend the host) never reaches this rule's high confidence.
Wrong¶
class Demo(Scene):
def construct(self):
anchor = Square()
group = VGroup(*[Square() for _ in range(40)])
group.add_updater(lambda m: m.move_to(m.get_family()[0])) # full walk per frame
self.add(group, anchor)
self.play(FadeIn(anchor), run_time=2) # group stays live: its updater runs