标签: python-typing

使用枚举键创建 TypedDict

我正在尝试创建一个TypedDict更好的代码完成功能,但遇到了问题。

我想要有一组固定的键(枚举)和值来根据键匹配特定的对象列表。

例如:

from enum import Enum


class OneObject:
    pass

class TwoObject:
    pass

class MyEnum(Enum):
    ONE: 1
    TWO: 2
Run Code Online (Sandbox Code Playgroud)

我希望有这样的东西:

from typing import TypedDict


class CustomDict(TypedDict):
    MyEnum.ONE: list[OneObject]
    MyEnum.TWO: list[TwoObject]

Run Code Online (Sandbox Code Playgroud)

然而,我得到了Non-self attribute could not be type hinted,但它并没有真正起作用。我有什么选择?

python enums type-hinting python-typing typeddict

5
推荐指数
1
解决办法
1003
查看次数

Using a pipe symbol in typing.Literal string

I have a function that accepts certain literals for a specific argument:

from typing import Literal

def fn(x: Literal["foo", "bar", "foo|bar"]) -> None:
    reveal_type(x)
Run Code Online (Sandbox Code Playgroud)

The third contains a pipe symbol (|), "foo|bar". This is interpreted by mypy as an error, as the name foo is not defined.

I guess this happens due to how forward references are evaluated? I use Python 3.8 with:

from __future__ import annotations
Run Code Online (Sandbox Code Playgroud)

Is there a way to make this work? I can …

python typechecking mypy python-typing

5
推荐指数
0
解决办法
192
查看次数

python 3键入varadic"apply"样式定义

我一直在努力编写"varadic"参数列表类型定义.

例如,给出类型:

def foo(fn, *args):
    return fn(*args)
Run Code Online (Sandbox Code Playgroud)

我能做的最好的就是使用这里的建议:

from typing import overload, Callable, TypeVar

A = TypeVar('A')
B = TypeVar('B')
C = TypeVar('C')
R = TypeVar('R')

@overload
def foo(fn: Callable[[A], R], a: A) -> R: ...
@overload
def foo(fn: Callable[[A, B], R], a: A, b: B) -> R: ...
@overload
def foo(fn: Callable[[A, B, C], R], a: A, b: B, c: C) -> R: ...

def foo(fn, *args):
    return fn(*args)
Run Code Online (Sandbox Code Playgroud)

这主要是做正确的事情...例如,给定:

def bar(i: int, j: int) …
Run Code Online (Sandbox Code Playgroud)

python types typing python-3.x python-typing

4
推荐指数
1
解决办法
146
查看次数

如何从CLI而不是使用VS Code安装和运行Pyright?

我想开始在团队的项目中使用Pyright。我已经安装了Visual Studio Code插件,并且在工作时可以在编辑器中看到类型错误。但是我希望能够在我们的测试套件中(包括在CI服务器上)自动运行它,而VS Code插件无法做到这一点。我需要将其安装并用作独立的命令行工具。

Pyright的文档说它具有命令行界面,但是唯一的安装和构建说明是针对Visual Studio Code扩展的,而安装并没有添加pyright可执行文件:

$ pyright
-bash: pyright: command not found
Run Code Online (Sandbox Code Playgroud)

如何从命令行在Python项目上安装和运行Pyright?

python python-typing pyright

4
推荐指数
1
解决办法
378
查看次数

使用 mypy 处理条件逻辑 + 哨兵值

我有一个大致如下所示的函数:

import datetime
from typing import Union

class Sentinel(object): pass
sentinel = Sentinel()

def func(
    dt: datetime.datetime,
    as_tz: Union[datetime.tzinfo, None, Sentinel] = sentinel,
) -> str:

    if as_tz is not sentinel:
        # Never reached if as_tz has wrong type (Sentinel)
        dt = dt.astimezone(as_tz)
    # ...
    # do other meaningful stuff
    # ...
    return "foo"
Run Code Online (Sandbox Code Playgroud)

sentinel此处使用该值是因为None它已经是 的有效参数.astimezone(),因此目的是正确识别用户根本不想调用的.astimezone()情况。

但是,mypy抱怨这种模式:

错误:“datetime”的“astimezone”的参数 1 具有不兼容的类型“Union[tzinfo, None, Sentinel]”;预期“可选[tzinfo]”

似乎这是因为datetime存根(理所当然)使用:

def astimezone(self, tz: Optional[_tzinfo] = …
Run Code Online (Sandbox Code Playgroud)

python python-3.x mypy python-typing

4
推荐指数
2
解决办法
758
查看次数

从另一个函数复制类型签名

想象一下,我有一组如下所示的功能。foo有很多不同类型的参数,bar并将所有参数传递给另一个函数。有什么方法可以让 mypy 理解barfoo不显式复制整个参数列表的类型相同?

def foo(a: int, b: float, c: str, d: bool, *e: str, f: str = "a", g: str = "b") -> str:
    ...

def bar(*args, **kwargs):
    val = foo(*args, **kwargs)
    ...
    return val
Run Code Online (Sandbox Code Playgroud)

python mypy python-typing

4
推荐指数
1
解决办法
371
查看次数

键入:限制为字符串列表

这是 Python 3.7

我有一个这样的数据类:

@dataclass
class Action:
   action: str
Run Code Online (Sandbox Code Playgroud)

但 action 实际上仅限于值“bla”和“foo”。有没有一种明智的方式来表达这一点?

python python-dataclasses python-typing

4
推荐指数
2
解决办法
336
查看次数

为什么 mypy 在无法注释时抱怨列表理解?

当不可能使用 MyPy 注释这样的变量时,为什么 Mypy 抱怨它需要对列表理解变量进行类型注释?

具体来说,我该如何解决以下错误:

from enum import EnumMeta

def spam( y: EnumMeta ):
    return [[x.value] for x in y]  Mypy: Need type annotation for 'x' 
Run Code Online (Sandbox Code Playgroud)

cast不起作用

return [[cast(Enum, x).value] for x in y]  Mypy: Need type annotation for 'x'  
Run Code Online (Sandbox Code Playgroud)

即使Mypy不支持注释(x:Enum)在这种情况下,我看到了使用的变量可以使用注释的cast看到这个帖子)。但是,这cast(Enum, x) 并不能阻止 Mypy 抱怨变量没有首先被注释。

#type:不起作用

return [[x.value] for x in y] # type: Enum  Mypy: Misplaced type annotation
Run Code Online (Sandbox Code Playgroud)

我还看到for可以使用注释对循环变量进行注释,# type:参见这篇文章 …

python mypy python-typing

4
推荐指数
2
解决办法
917
查看次数

Python 类型:连接序列

在 python 中,两个序列的连接通常由+操作符完成。但是,mypy 抱怨以下内容:

from typing import Sequence

def concat1(a: Sequence, b: Sequence) -> Sequence:
    return a + b
Run Code Online (Sandbox Code Playgroud)

没错:Sequence没有__add__. 但是,该函数对于“通常的”序列类型list, str,工作得非常好tuple。显然,还有其他序列类型不起作用(例如numpy.ndarray)。解决方案可能是以下内容:

from itertools import chain

def concat2(a: Sequence, b: Sequence) -> Sequence:
    return list(chain(a, b))
Run Code Online (Sandbox Code Playgroud)

现在,mypy 没有抱怨。但是连接字符串或元组总是给出一个列表。似乎有一个简单的解决方法:

def concat3(a: Sequence, b: Sequence) -> Sequence:
    T = type(a)
    return T(chain(a, b))
Run Code Online (Sandbox Code Playgroud)

但是现在 mypy 不高兴了,因为 T get 的构造函数参数太多。更糟糕的是,该函数不再返回序列,而是返回一个生成器。

这样做的正确方法是什么?我觉得问题的一部分是 a 和 b 应该具有相同的类型,并且输出也将是相同的类型,但是类型注释并没有传达它。

注意:我知道使用''.join(a, b). 但是,我选择这个例子更多是为了说明目的。

python mypy python-typing

4
推荐指数
2
解决办法
544
查看次数

如何使用变量类型正确地对函数进行类型注释?

我正在尝试向文件系统相关库添加类型提示,其中许多函数采用 ofstrbytestype的路径。我可以通过使用重载来处理我自己的函数,但我很难处理简单的操作或内部调用的标准库函数,这些函数是使用任一类型的参数调用的。这是一个简化的示例:

@overload
def join_paths(s1: str, s2: str) -> str: ...


@overload
def join_paths(s1: bytes, s2: bytes) -> bytes: ...


def join_paths(s1: Union[str, bytes],
               s2: Union[str, bytes]) -> Union[str, bytes]:
    return s1 + s2
Run Code Online (Sandbox Code Playgroud)

如果我想从其他地方调用这个函数,重载工作正常,但我的问题在于s1 + s2语句,这会导致mypy发出警告:

example.py:74: error: Unsupported operand types for + ("str" and "bytes")  [operator]
example.py:74: error: Unsupported operand types for + ("bytes" and "str")  [operator]
Run Code Online (Sandbox Code Playgroud)

我想表达的是,无论是两个操作数是类型str或两者的bytes类型,类似于做是为了使用重载我自己的函数。

我没有太多打字经验,所以我可能只是错过了明显的解决方案,但到目前为止我还没有找到如何调整它以避免警告。

python python-typing

4
推荐指数
1
解决办法
46
查看次数