我正在尝试创建一个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,但它并没有真正起作用。我有什么选择?
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 …
我一直在努力编写"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) 我想开始在团队的项目中使用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?
我有一个大致如下所示的函数:
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) 想象一下,我有一组如下所示的功能。foo有很多不同类型的参数,bar并将所有参数传递给另一个函数。有什么方法可以让 mypy 理解bar与foo不显式复制整个参数列表的类型相同?
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 3.7
我有一个这样的数据类:
@dataclass
class Action:
action: str
Run Code Online (Sandbox Code Playgroud)
但 action 实际上仅限于值“bla”和“foo”。有没有一种明智的方式来表达这一点?
当不可能使用 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 抱怨以下内容:
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). 但是,我选择这个例子更多是为了说明目的。
我正在尝试向文件系统相关库添加类型提示,其中许多函数采用 ofstr或bytestype的路径。我可以通过使用重载来处理我自己的函数,但我很难处理简单的操作或内部调用的标准库函数,这些函数是使用任一类型的参数调用的。这是一个简化的示例:
@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 ×10
python-typing ×10
mypy ×5
python-3.x ×2
enums ×1
pyright ×1
type-hinting ×1
typechecking ×1
typeddict ×1
types ×1
typing ×1