Feature Request: Let Pipe function take more than 1 positional argument.
まだ誰も着手していません。
評価
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 初心者へのやさしさ
- 35/100
- issue の種類
- 機能追加
- 明瞭さ
- おおむね明確
- 活発さ
- 停滞
- 技術スタック
- python
調査の方向性
returns/_internal/pipeline/pipe.py と対応する pipe.pyi から始め、プロジェクトの型チェック設定で例を再現します。互換性のないパイプラインに対する型エラーを維持しつつ、複数の位置引数を最初の関数に渡す方法を定義します。完了条件は、bazz の例が TypeError なしで実行され、無効な合成が引き続き拒否されることです。
索引モデルが issue の本文から書いたものです。
説明
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
- 主要言語
- Python
- スター
- 4.4k
- フォーク
- 154
- 平均マージ
- 3時間 5分
- マージ済み PR(30日)
- 22
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
dry-python/returns のほかの issue
-
難易度 4/5 3〜5日 初心者へのやさしさ 48/100
dry-python/returns#2394 · リアクション 1 件 ·
-
難易度 4/5 3〜5日 初心者へのやさしさ 52/100
dry-python/returns#2365 ·
-
難易度 5/5 1週間以上 初心者へのやさしさ 25/100
dry-python/returns#2355 · コメント 1 件 ·
-
bug
難易度 4/5 3〜5日 初心者へのやさしさ 45/100
dry-python/returns#2295 · コメント 4 件 · リアクション 1 件 ·
-
bug
難易度 4/5 3〜5日 初心者へのやさしさ 45/100
dry-python/returns#2253 · コメント 2 件 ·
dry-python/returns の issue をすべて見る
似ている issue
-
bug confirmed issue
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
open-webui/open-webui#30750 · コメント 1 件 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
-
enhancement
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
OpenwaterHealth/openmotion-bloodflow-app#604 · コメント 1 件 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
-
good first issue
難易度 1/5 1時間未満 初心者へのやさしさ 90/100