#5018·manim

Use overrides of children in family operations

Author: GniLudioCreated Sep 15, 2026Updated Sep 16, 2026

Currently, operations that work on family members don't take overidden methods of children into account. So the result can be quite different when children implement custom logic.

This is quite prominent with the Arrow.scale method:

python
def construct(self) -> None:
    mob1 = VGroup(Arrow().scale(3))
    mob2 = VGroup(Arrow()).scale(3)
    self.add(VGroup(mob1, mob2).arrange(DOWN))
Image

Ideally, when calling an operation on a parent, it should still use the overridden methods of children.

Aditional things to consider:

  • the submobject tree can contain loops and/or duplicates
  • parents should have control over how the operation is applied to children
  • overrides should be able to have custom logic before and/or after the operation
  • parents should be able to have custom logic before and/or after the operation is applied to their children
  • users should be able to pass (custom) parameters to all members

Some ideas and their ad-/disadvantages were already discussed in #4994. See here

Ideas

Dump recursion

Assumes no duplicates and/or loops.

python
def some_operation(...):
    ... # apply to self
    for sub in self.submobjects:
        sub.some_operation(...)

Internal method for self

python
def some_operation(...):
    for mob in self.get_family():
        mob._some_operation(...)
    
def _some_operation(...):
    ... # apply to self

apply_to_family

python
def some_operation(..., apply_to_family=True):
    ... # logic for self
    if apply to family:
        for mob in self.get_family():
            mob.some_operation(..., apply_to_family=False)

already_seen

python
def some_operation(..., already_seen= None):
    ... # apply to self
    if already_seen is None:
        already_seen = {self}
    for sub in self.submobjects:
        if sub not in already_seen:
            already_seen.add(sub)
            sub.some_operation(..., already_seen=already_seen)

apply_to_family internally

python
def some_operation(...):
    return self._some_operation(...)

def _some_operation(..., apply_to_family=True):
    ... # apply to self
    if apply to family:
        for mob in self.get_family():
            mob.some_operation(..., apply_to_family=False)

already_seen internally

python
def some_operation(...):
    return self._some_operation(...)

def _some_operation(..., already_seen= None):
    ... # apply to self
    if already_seen is None:
        already_seen = {self}
    for sub in self.submobjects:
        if sub not in already_seen:
            already_seen.add(sub)
            sub.some_operation(..., already_seen=already_seen)