Skip to content

Commit dea245a

Browse files
irvanalhaq9chopan050pre-commit-ci[bot]
authored
Fix duplicate references in Scene.mobjects after ReplacementTransform with existing target mobject (#4242)
Co-authored-by: Francisco Manríquez Novoa <[email protected]> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent a8c16fb commit dea245a

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

manim/scene/scene.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,19 @@ def replace(self, old_mobject: Mobject, new_mobject: Mobject) -> None:
592592
def replace_in_list(
593593
mobj_list: list[Mobject], old_m: Mobject, new_m: Mobject
594594
) -> bool:
595+
# Avoid duplicate references to the same object in self.mobjects
596+
if new_m in mobj_list:
597+
if old_m is new_m:
598+
# In this case, one could say that the old Mobject was already found.
599+
# No replacement is needed, since old_m is new_m, so no action is required.
600+
# This might be unexpected, so raise a warning.
601+
logger.warning(
602+
f"Attempted to replace {type(old_m).__name__} "
603+
"with itself in Scene.mobjects."
604+
)
605+
return True
606+
mobj_list.remove(new_m)
607+
595608
# We use breadth-first search because some Mobjects get very deep and
596609
# we expect top-level elements to be the most common targets for replace.
597610
for i in range(0, len(mobj_list)):
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from __future__ import annotations
2+
3+
from manim import Circle, ReplacementTransform, Scene, Square, VGroup
4+
5+
6+
def test_no_duplicate_references():
7+
scene = Scene()
8+
c = Circle()
9+
sq = Square()
10+
scene.add(c, sq)
11+
12+
scene.play(ReplacementTransform(c, sq))
13+
assert len(scene.mobjects) == 1
14+
assert scene.mobjects[0] is sq
15+
16+
17+
def test_duplicate_references_in_group():
18+
scene = Scene()
19+
c = Circle()
20+
sq = Square()
21+
vg = VGroup(c, sq)
22+
scene.add(vg)
23+
24+
scene.play(ReplacementTransform(c, sq))
25+
submobs = vg.submobjects
26+
assert len(submobs) == 1
27+
assert submobs[0] is sq

0 commit comments

Comments
 (0)