Repository: ManimCommunity/manim
File: manim/mobject/types/vectorized_mobject.py (Python)

Code before:
                        gr.animate.shift(LEFT),
                        gr2.animate.shift(UP),
                    )
                    self.play( #Animate groups without modification
                        (gr+gr2).animate.shift(RIGHT)
                    )
                    self.play( # Animate group without component
                        (gr-circle_red).animate.shift(RIGHT)
                    )

        A `VGroup` can be created using iterables as well. Keep in mind that all generated values from an
        iterable must be an instance of `VMobject`. This is demonstrated below:

        .. manim:: AddIterableToVGroupExample
            :save_last_frame:

            class AddIterableToVGroupExample(Scene):
                def construct(self):
                    v = VGroup(
                        Square(),               # Singular VMobject instance
                        [Circle(), Triangle()], # List of VMobject instances
                        Dot(),
                        (Dot() for _ in range(2)), # Iterable that generates VMobjects
                    )
                    v.arrange()
                    self.add(v)
        """

        def get_type_error_message(invalid_obj, invalid_indices):
            return (
                f"Only values of type {vmobject_render_type.__name__} can be added "
                "as submobjects of VGroup, but the value "
                f"{repr(invalid_obj)} (at index {invalid_indices[1]} of "
                f"parameter {invalid_indices[0]}) is of type "
                f"{type(invalid_obj).__name__}."
            )

        vmobject_render_type = (
            OpenGLVMobject if config.renderer == RendererType.OPENGL else VMobject
        )
        valid_vmobjects = []

        for i, vmobject in enumerate(vmobjects):
            if isinstance(vmobject, vmobject_render_type):
                valid_vmobjects.append(vmobject)
            elif isinstance(vmobject, Iterable) and not isinstance(
                vmobject, (Mobject, OpenGLMobject)
            ):
                for j, subvmobject in enumerate(vmobject):
                    if not isinstance(subvmobject, vmobject_render_type):
                        raise TypeError(get_type_error_message(subvmobject, (i, j)))

Review comment (suggestion):
Maybe it would be helpful to note after the example that it works by unpacking iterables, so indexing a `VGroup` won't give you an iterable.

Code after:
                        gr.animate.shift(LEFT),
                        gr2.animate.shift(UP),
                    )
                    self.play( #Animate groups without modification
                        (gr+gr2).animate.shift(RIGHT)
                    )
                    self.play( # Animate group without component
                        (gr-circle_red).animate.shift(RIGHT)
                    )

        A `VGroup` can be created using iterables as well. Keep in mind that all generated values from an
        iterable must be an instance of `VMobject`. This is demonstrated below:

        .. manim:: AddIterableToVGroupExample
            :save_last_frame:

            class AddIterableToVGroupExample(Scene):
                def construct(self):
                    v = VGroup(
                        Square(),               # Singular VMobject instance
                        [Circle(), Triangle()], # List of VMobject instances
                        Dot(),
                        (Dot() for _ in range(2)), # Iterable that generates VMobjects
                    )
                    v.arrange()
                    self.add(v)

        To facilitate this, the iterable is unpacked before its individual instances are added to the `VGroup`.
        As a result, when you index a `VGroup`, you will never get back an iterable.
        Instead, you will always receive `VMobject` instances, including those
        that were part of the iterable/s that you originally added to the `VGroup`.
        """

        def get_type_error_message(invalid_obj, invalid_indices):
            return (
                f"Only values of type {vmobject_render_type.__name__} can be added "
                "as submobjects of VGroup, but the value "
                f"{repr(invalid_obj)} (at index {invalid_indices[1]} of "
                f"parameter {invalid_indices[0]}) is of type "
                f"{type(invalid_obj).__name__}."
            )

        vmobject_render_type = (
            OpenGLVMobject if config.renderer == RendererType.OPENGL else VMobject
        )
        valid_vmobjects = []

        for i, vmobject in enumerate(vmobjects):
            if isinstance(vmobject, vmobject_render_type):
                valid_vmobjects.append(vmobject)
            elif isinstance(vmobject, Iterable) and not isinstance(