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. converters (~collections.abc.Iterable[typing.C
(*converters)
| 3347 | |
| 3348 | |
| 3349 | def pipe(*converters): |
| 3350 | """ |
| 3351 | A converter that composes multiple converters into one. |
| 3352 | |
| 3353 | When called on a value, it runs all wrapped converters, returning the |
| 3354 | *last* value. |
| 3355 | |
| 3356 | Type annotations will be inferred from the wrapped converters', if they |
| 3357 | have any. |
| 3358 | |
| 3359 | converters (~collections.abc.Iterable[typing.Callable]): |
| 3360 | Arbitrary number of converters. |
| 3361 | |
| 3362 | .. versionadded:: 20.1.0 |
| 3363 | """ |
| 3364 | |
| 3365 | return_instance = any(isinstance(c, Converter) for c in converters) |
| 3366 | |
| 3367 | if return_instance: |
| 3368 | |
| 3369 | def pipe_converter(val, inst, field): |
| 3370 | for c in converters: |
| 3371 | val = ( |
| 3372 | c(val, inst, field) if isinstance(c, Converter) else c(val) |
| 3373 | ) |
| 3374 | |
| 3375 | return val |
| 3376 | |
| 3377 | else: |
| 3378 | |
| 3379 | def pipe_converter(val): |
| 3380 | for c in converters: |
| 3381 | val = c(val) |
| 3382 | |
| 3383 | return val |
| 3384 | |
| 3385 | if not converters: |
| 3386 | # If the converter list is empty, pipe_converter is the identity. |
| 3387 | A = TypeVar("A") |
| 3388 | pipe_converter.__annotations__.update({"val": A, "return": A}) |
| 3389 | else: |
| 3390 | # Get parameter type from first converter. |
| 3391 | t = _AnnotationExtractor(converters[0]).get_first_param_type() |
| 3392 | if t: |
| 3393 | pipe_converter.__annotations__["val"] = t |
| 3394 | |
| 3395 | last = converters[-1] |
| 3396 | if not PY_3_11_PLUS and isinstance(last, Converter): |
| 3397 | last = last.__call__ |
| 3398 | |
| 3399 | # Get return type from last converter. |
| 3400 | rt = _AnnotationExtractor(last).get_return_type() |
| 3401 | if rt: |
| 3402 | pipe_converter.__annotations__["return"] = rt |
| 3403 | |
| 3404 | if return_instance: |
| 3405 | return Converter(pipe_converter, takes_self=True, takes_field=True) |
| 3406 | return pipe_converter |