Skip to content

MLR102: Bare .animate without a method call is played

qual reports MLR102 when a .animate builder with no chained method is passed to Scene.play, the target is provably unchanged between builder creation and the play, and the target is already displayed. The resulting animation interpolates the mobject to its own current state, so every rendered frame is identical.

  • Default severity: warning
  • Minimum confidence: high
  • Implementation phase: 2
  • Fix: deleting the argument is suggested as UNSAFE (the play's run_time currently acts as an implicit pause, and only offered when another animation remains in the play)

Accessing .animate runs generate_target() immediately; chained methods mutate that target copy, and the play interpolates the live object toward it. The rule stays silent when:

  • any method is chained (the normal use);
  • the builder is never played;
  • the target is not yet displayed (the play's auto-add is an effect);
  • the live object changed between builder creation and the play (a stale target snaps the object back — see MLC117);
  • the play only happens on some branches (a Maybe fact).

Wrong:

square = Square()
self.add(square)
self.play(square.animate)  # renders run_time of identical frames

Right:

square = Square()
self.add(square)
self.play(square.animate.shift(RIGHT))
# or, if a pause was intended:
self.wait()