Skip to content

Commit dd259bb

Browse files
RickyC0626kolibril13behackl
authored
Added sanity checks to :meth:~.Mobject.add_to_back for Mobjects (#1220)
* Add Mobject add_to_back sanity checks - Raises ValueError when Mobject tries to add itself - Raises TypeError when a non-Mobject is added - Filters out incoming duplicate submobjects if at least one instance of that submobject exists in the list * Filter incoming Mobjects into a set before adding First, incoming list of Mobjects will be filtered into a set with no duplicates. Then, any mobject in submobjects that is a duplicate of an incoming mobject will be removed. The filtered set of mobjects will be added to back and the remaining submobjects are appended. * Add isort to pre-commit config * Isort test_vectorized_mobject.py * Was already added * Update .pre-commit-config.yaml Co-authored-by: kolibril13 <[email protected]> Co-authored-by: Benjamin Hackl <[email protected]>
1 parent 053e400 commit dd259bb

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

manim/mobject/mobject.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,9 +353,36 @@ def add_to_back(self, *mobjects: "Mobject") -> "Mobject":
353353
the head of :attr:`submobjects`. The head of this list is rendered
354354
first, which places the corresponding mobjects behind the
355355
subsequent list members.
356+
357+
Raises
358+
------
359+
:class:`ValueError`
360+
When a mobject tries to add itself.
361+
:class:`TypeError`
362+
When trying to add an object that is not an instance of :class:`Mobject`.
363+
364+
Notes
365+
-----
366+
A mobject cannot contain itself, and it cannot contain a submobject
367+
more than once. If the parent mobject is displayed, the newly-added
368+
submobjects will also be displayed (i.e. they are automatically added
369+
to the parent Scene).
370+
371+
See Also
372+
--------
373+
:meth:`remove`
374+
:meth:`add`
375+
356376
"""
377+
for mobject in mobjects:
378+
if self in mobjects:
379+
raise ValueError("Mobject cannot contain self")
380+
if not isinstance(mobject, Mobject):
381+
raise TypeError("All submobjects must be of type Mobject")
382+
383+
filtered = list_update(mobjects, self.submobjects)
357384
self.remove(*mobjects)
358-
self.submobjects = list(mobjects) + self.submobjects
385+
self.submobjects = list(filtered) + self.submobjects
359386
return self
360387

361388
def remove(self, *mobjects: "Mobject") -> "Mobject":

tests/test_vectorized_mobject.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import pytest
22

3-
from manim import Mobject, VDict, VGroup, VMobject
3+
from manim import Line, Mobject, VDict, VGroup, VMobject
44

55

66
def test_vgroup_init():
@@ -86,6 +86,24 @@ def test_vgroup_remove_dunder():
8686
assert len(obj.submobjects) == 0
8787

8888

89+
def test_vmob_add_to_back():
90+
"""Test the Mobject add_to_back method."""
91+
a = VMobject()
92+
b = Line()
93+
c = "text"
94+
with pytest.raises(ValueError):
95+
# Mobject cannot contain self
96+
a.add_to_back(a)
97+
with pytest.raises(TypeError):
98+
# All submobjects must be of type Mobject
99+
a.add_to_back(c)
100+
101+
# No submobject gets added twice
102+
a.add_to_back(b)
103+
a.add_to_back(b, b)
104+
assert len(a.submobjects) == 1
105+
106+
89107
def test_vdict_init():
90108
"""Test the VDict instantiation."""
91109
# Test empty VDict

0 commit comments

Comments
 (0)