Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Feature Request: Let Pipe function take more than 1 positional argument.

Abierto
#1,692 1 comentario 3 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
5/5
Tiempo estimado
Más de una semana
Aptitud para principiantes
35/100
Tipo de issue
Nueva funcionalidad
Claridad
Bastante claro
Estado de actividad
Estancado
Stack tecnológico
python

Línea de trabajo

Empieza con returns/_internal/pipeline/pipe.py y su pipe.pyi correspondiente; después, reproduce los ejemplos con la configuración de comprobación de tipos del proyecto. Define cómo deben pasar varios argumentos posicionales a través de la primera función, conservando los errores de tipo para pipelines incompatibles; se considera terminado cuando el ejemplo bazz se ejecuta sin un TypeError y las composiciones no válidas siguen siendo rechazadas.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Feature Request/Enhancement

I stumbled upon this post a while ago:

https://github.com/python/typing/discussions/1245?sort=top#discussioncomment-3454192

It was pretty neat, and wanted to try it out for functions that take more than 1 positional argument. Sadly, it does not seem to work.

What's wrong

When trying to run the following code:

from returns._internal.pipeline.pipe import pipe


def one_arg_only(num1: float) -> int:
    return int(num1)


def two_args(num1: float, num2: int) -> int:
    return int(num1 + num2)


def to_string(f: float) -> str:
    return str(f)


def to_float(s: str) -> float:
    return float(s)


if __name__ == "__main__":
    fizz = pipe(one_arg_only, to_string, to_float)
    print(fizz(1))  # Trivial example

    buzz = pipe(to_string, to_float)
    print(buzz(two_args(1, 2)))  # This works, but is not ideal

    bazz = pipe(two_args, to_string, to_float)
    try:
        print(bazz(1, 2))  # Too many arguments for "__call__" of "_Pipe" [call-arg]
    except TypeError as e:
        print(
            "Cannot pass two arguments even though first function requires 2 positional arguments"
        )
        raise e

you would get the following exception:

Cannot pass two arguments even though first function requires 2 positional arguments
Traceback (most recent call last):
  File "/home/pratik/workplace/dry-python-returns/problem.py", line 21, in <module>
    raise e
  File "/home/pratik/workplace/dry-python-returns/problem.py", line 16, in <module>
    print(fizz(1, 2))
          ^^^^^^^^^^
TypeError: pipe.<locals>.<lambda>() takes 1 positional argument but 2 were given

How is that should be

Invoking bazz should not throw a TypeError.

What I have tried

The following works if and only if the types are all correct.

from functools import reduce
from typing import overload, ParamSpec, TypeVar, Callable


_P = ParamSpec("_P")
_T1 = TypeVar("_T1")
_T2 = TypeVar("_T2")
_T3 = TypeVar("_T3")

@overload
def pipe(f1: Callable[_P, _T1]) -> Callable[_P, _T1]: ...
@overload
def pipe(
    f1: Callable[_P, _T1],
    f2: Callable[[_T1], _T2],
) -> Callable[_P, _T2]: ...
@overload
def pipe(
    f1: Callable[_P, _T1],
    f2: Callable[[_T1], _T2],
    f3: Callable[[_T2], _T3],
) -> Callable[_P, _T3]: ...

def pipe(*functions):
    def compose2(f, g):
        return lambda *args, **kwargs: g(f(*args, **kwargs))

    return reduce(compose2, functions)

When the types are not correct, mypy throws the following error message:

# Mypy error says: Cannot infer type argument 3 of "pipe"
fizz = pipe(one_arg_only, to_string, to_string)

I toyed around with typing.ParamSpec within returns/_internal/pipeline/pipe.pyi to see if that would do the trick, but I couldn't after a couple of hours of getting the above example to have mypy return no errors. Maybe I missed something, or I just have mind block.

Related issue: https://github.com/python/typing/discussions/1289

Lenguaje dominante
Python
Estrellas
4.4k
Forks
154
Merge medio
3 h 5 min
PR fusionados (30 d)
22

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de dry-python/returns

Todos los issues de dry-python/returns

Issues similares

Más issues de Python

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.