用于修改功能签名的注释

发布于 2025-01-23 01:22:51 字数 1609 浏览 0 评论 0原文

我想编写一个python装饰仪,该装饰符,并返回一个修改的功能,该功能采用相同的参数,但要修改参数的所需类型以及返回类型。我希望能够以允许呼叫代码中的错误或类似方式中的错误表达这些类型的更改。

一个示例是以下内容:

from typing import Callable, Optional, TypeVar
from typing_extensions import ParamSpec

P = ParamSpec('P')
R = TypeVar('R')

def preserve_nulls(f: Callable[P, R]) -> Callable[???, Optional[R]]:
    
    def inner(*args, **kwargs):
        if any(value is None for value in args):
            return None
        elif any(value is None for value in kwargs.values()):
            return None
        else:
            return f(*args, **kwargs)

    return inner

在这种情况下,给定一个函数f,带有签名(foo:int,bar:str,bar:str,baz:list [str]) - > int,然后装饰的函数preserve_nulls(f)应具有签名(foo:可选[int],bar:optional [str],str],baz:baz:otarional [list [list [str] ]) - >可选[int]

表达新的返回类型很简单,因为我只能做可选[R]。但是我不知道在上面的示例中替换??? /代码>“。

最终,我的目标是为preserve_nulls找到合适的注释,以便给定以下内容,

def f(foo: int, bar: str, baz: list[str]) -> int:
    return 0

wrapped_f = preserve_nulls(f)

correct = wrapped_f(foo=1, bar=None, baz=None)

incorrect = wrapped_f(foo='one', bar=None, baz=[None])

然后如果我通过mypy(或其他类型的检查器)运行,则很高兴> >正确调用是有效的,但抱怨foobaz不正确调用中的类型错误。

理想情况下,该解决方案应适用于其他“修改”,而不仅仅是可选,例如说用tcallable [[],t],t] t代码>或列表[T]或其他。

我已经准备好以目前不可能的可能性,但是如果可以做到,那么任何帮助将受到赞赏。

I'd like to write a Python decorator which takes a function, and returns a modified function which takes the same arguments, but modifies the required types of the arguments, as well as the return type. I would like to be able to express these type changes in a manner that allows mistakes in calling code to be detected by MyPy or similar.

An example would be something like the following:

from typing import Callable, Optional, TypeVar
from typing_extensions import ParamSpec

P = ParamSpec('P')
R = TypeVar('R')

def preserve_nulls(f: Callable[P, R]) -> Callable[???, Optional[R]]:
    
    def inner(*args, **kwargs):
        if any(value is None for value in args):
            return None
        elif any(value is None for value in kwargs.values()):
            return None
        else:
            return f(*args, **kwargs)

    return inner

In this case, given a function f with signature (foo: int, bar: str, baz: List[str]) -> int, then the decorated function preserve_nulls(f) should have signature (foo: Optional[int], bar: Optional[str], baz: Optional[List[str]]) -> Optional[int].

Expressing the new return type is simple, since I can just do Optional[R]. But I don't know what to replace the ??? in my above example with to essentially express "the result of applying Optional to every argument in P".

Ultimately, my goal is to find a suitable annotation for preserve_nulls such that given something like the following,

def f(foo: int, bar: str, baz: list[str]) -> int:
    return 0

wrapped_f = preserve_nulls(f)

correct = wrapped_f(foo=1, bar=None, baz=None)

incorrect = wrapped_f(foo='one', bar=None, baz=[None])

Then if I run it through MyPy (or another type checker), it will be happy that the correct call is valid, but complain that foo and baz have the wrong type in the incorrect call.

Ideally the solution should be adaptable to other 'modifications' other than just Optional, like say replacing each argument type T with Callable[[], T] or List[T] or whatever.

I am prepared for the possibility that this is simply not currently possible, but if it can be done then any help is much appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文