def pipe(*converters):
    """
    A converter that composes multiple converters into one.

    When called on a value, it runs all wrapped converters, returning the
    *last* value.

    Type annotations will be inferred from the wrapped converters', if
    they have any.

    :param callables converters: Arbitrary number of converters.

    .. versionadded:: 20.1.0
    """

    def pipe_converter(val):
        for converter in converters:
            val = converter(val)

        return val

    if not converters:
        # If the converter list is empty, pipe_converter is the identity.
        A = typing.TypeVar("A")
        pipe_converter.__annotations__ = {"val": A, "return": A}
    else:
        # Get parameter type from first converter.
        t = _AnnotationExtractor(converters[0]).get_first_param_type()
        if t:
            pipe_converter.__annotations__["val"] = t

        # Get return type from last converter.
        rt = _AnnotationExtractor(converters[-1]).get_return_type()
        if rt:
            pipe_converter.__annotations__["return"] = rt

    return pipe_converter

    A converter that composes multiple converters into one.

    When called on a value, it runs all wrapped converters, returning the
    *last* value.

    Type annotations will be inferred from the wrapped converters', if
    they have any.

    :param callables converters: Arbitrary number of converters.

    .. versionadded:: 20.1.0
    
product/gradle-plugin/src/main/python/attr/_make.py