Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

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

Aperta
#1,692 1 commento 3 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
5/5
Tempo stimato
Più di una settimana
Idoneità per principianti
35/100
Tipo di issue
Funzionalità
Chiarezza
Abbastanza chiara
Stato di attività
Ferma
Stack tecnologico
python

Direzione di ricerca

Inizia con returns/_internal/pipeline/pipe.py e il relativo pipe.pyi, quindi riproduci gli esempi con la configurazione di controllo dei tipi del progetto. Definisci come più argomenti posizionali debbano passare attraverso la prima funzione, preservando gli errori di tipo per le pipeline incompatibili; il lavoro è completato quando l'esempio bazz viene eseguito senza un TypeError e le composizioni non valide continuano a essere rifiutate.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

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

Lingua principale
Python
Stelle
4.4k
Fork
154
Merge medio
3h 5m
PR unite (30g)
22

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di dry-python/returns

Tutte le issue di dry-python/returns

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.