def cast(obj):
        """Cast a :ref:`shape-like <lang-shapelike>` object to a layout.

        This method performs a subset of the operations done by :meth:`.Shape.cast`; it will
        recursively call :py:`.as_shape()`, but only until a layout is returned.

        Raises
        ------
        TypeError
            If :py:`obj` cannot be converted to a :class:`Layout` instance.
        RecursionError
            If :py:`obj.as_shape()` returns :py:`obj`.
        """
        while isinstance(obj, ShapeCastable):
            if isinstance(obj, Layout):
                return obj
            new_obj = obj.as_shape()
            if new_obj is obj:
                break
            obj = new_obj
        Shape.cast(obj) # delegate non-layout-specific error handling to Shape
        raise TypeError("Object {!r} cannot be converted to a data layout"
                        .format(obj))
Cast a :ref:`shape-like <lang-shapelike>` object to a layout.

        This method performs a subset of the operations done by :meth:`.Shape.cast`; it will
        recursively call :py:`.as_shape()`, but only until a layout is returned.

        Raises
        ------
        TypeError
            If :py:`obj` cannot be converted to a :class:`Layout` instance.
        RecursionError
            If :py:`obj.as_shape()` returns :py:`obj`.
        
amaranth/lib/data.py