Repository: ManimCommunity/manim

Issue:
The Wait animation cannot be added to an AnimationGroup
An AnimationGroup expects each animation to have a mobject attribute.  The Wait animation does not have a mobject.

Steps to reproduce:
Compile:
```
class animgrouptest(Scene):
  def construct(self):
    anim = AnimationGroup(Write(Text("a")), Wait(3))
    self.play(anim)
```
Result:
```
  File "/manim/script.py", line 4, in construct
    anim = AnimationGroup(Write(Text("a")), Wait(3))
  File "/usr/local/lib/python3.8/site-packages/manim/animation/composition.py", line 35, in __init__
    self.group = Group(
  File "/usr/local/lib/python3.8/site-packages/manim/mobject/mobject.py", line 1628, in __init__
    self.add(*mobjects)
  File "/usr/local/lib/python3.8/site-packages/manim/mobject/mobject.py", line 198, in add
    raise TypeError("All submobjects must be of type Mobject")
TypeError: All submobjects must be of type Mobject
```

Either we give the Wait animation a dummy (empty) mobject, or we fix the AnimationGroup? I'm not really sure I understand the underlying logic.


Discussion:

Resolving patch:
diff --git a/manim/animation/animation.py b/manim/animation/animation.py
--- a/manim/animation/animation.py
+++ b/manim/animation/animation.py
@@ -196,6 +196,9 @@ def set_name(self, name: str) -> "Animation":
     def is_remover(self) -> bool:
         return self.remover
 
+    def is_dummy(self) -> bool:
+        return self.mobject is None
+
 
 def prepare_animation(
     anim: Union["Animation", "mobject._AnimationBuilder"]
diff --git a/manim/animation/composition.py b/manim/animation/composition.py
--- a/manim/animation/composition.py
+++ b/manim/animation/composition.py
@@ -33,7 +33,9 @@ def __init__(
         self.group = group
         if self.group is None:
             self.group = Group(
-                *remove_list_redundancies([anim.mobject for anim in animations])
+                *remove_list_redundancies(
+                    [anim.mobject for anim in self.animations if not anim.is_dummy()]
+                )
             )
         super().__init__(self.group, rate_func=rate_func, lag_ratio=lag_ratio, **kwargs)
         self.run_time = run_time


Test patch:
diff --git a/tests/test_composition.py b/tests/test_composition.py
--- a/tests/test_composition.py
+++ b/tests/test_composition.py
@@ -1,4 +1,4 @@
-from manim.animation.animation import Animation
+from manim.animation.animation import Animation, Wait
 from manim.animation.composition import AnimationGroup, Succession
 from manim.animation.fading import FadeIn, FadeInFrom, FadeOutAndShift
 from manim.constants import DOWN
@@ -85,3 +85,15 @@ def test_animationbuilder_in_group():
     assert all(isinstance(anim, Animation) for anim in animation_group.animations)
     succession = Succession(sqr.animate.shift(DOWN).scale(2), FadeIn(circ))
     assert all(isinstance(anim, Animation) for anim in succession.animations)
+
+
+def test_animationgroup_with_wait():
+    sqr = Square()
+    sqr_anim = FadeIn(sqr)
+    wait = Wait()
+    animation_group = AnimationGroup(wait, sqr_anim, lag_ratio=1)
+
+    animation_group.begin()
+    timings = animation_group.anims_with_timings
+
+    assert timings == [(wait, 0.0, 1.0), (sqr_anim, 1.0, 2.0)]