我最近开始使用 mypy,并遇到了一些奇怪的问题,我似乎一生都无法弄清楚。
我正在使用 mypy 0.950、django-stubs 1.11.0、django 4.0.5 和 python 3.10.2。
通过命令行运行 mypy 将返回以下内容:
project/suppliers/models.py:6: error: Name "Optional" is not defined
project/suppliers/models.py:6: note: Did you forget to import it from "typing"? (Suggestion: "from typing import Optional")
project/users/models.py:6: error: Name "Optional" is not defined
project/users/models.py:6: note: Did you forget to import it from "typing"? (Suggestion: "from typing import Optional")
project/products/models.py:6: error: Name "Optional" is not defined
project/products/models.py:6: note: Did you forget to import it from "typing"? (Suggestion: "from typing import Optional")(Suggestion: "from …Run Code Online (Sandbox Code Playgroud) 有很多关于Cannot find implementation or library stub for module named...错误的线程,但没有关联的错误代码。我想完全禁用此功能。我该怎么做呢?
我稍微修改了记录的 mypy 通用示例,但收到错误:
from typing import Generic, TypeVar, Union
T = TypeVar("T", bound=Union[int, float])
class Person(Generic[T]):
def __init__(self, salary: T) -> None:
self.salary: T = salary
def get_yearly_bonus(self, amount: T) -> None:
self.salary += amount
def __str__(self) -> str:
return f"Person(salary={self.salary})"
p = Person[int](9)
p.get_yearly_bonus(6)
print(p)
Run Code Online (Sandbox Code Playgroud)
看来 mypy未能认识到self.salary和amount 必须
属于同一类型这一事实。
$ mypy test.py
test.py:11: error: Incompatible types in assignment (expression has type "float", variable has type "T")
test.py:11: error: Unsupported operand types …Run Code Online (Sandbox Code Playgroud) 假设我有一个函数foo,允许它接受如下参数
foo(a,b) -> It is OK
foo(None,b) -> It is OK
foo (a, None) -> It is OK
foo(None,None) -> It is NOT OK!!!
Run Code Online (Sandbox Code Playgroud)
如何编写它的签名,包括它的类型提示?
目前我已将类型提示写为
def foo(a:Optional[str], b:Optional[str]) -> str
Run Code Online (Sandbox Code Playgroud)
但这是错误的,因为这样的签名对于调用来说是没问题的foo(None,None)。
我试图引入pre-commit一个相当大的现有项目并将现有的直接调用替换为mypy,pre-commit但是,结果有所不同。试图详细描述我所尝试过的一切或期望得到关于该做什么的明确答案是不合理的。我只是希望得到一些关于如何诊断这种情况的指导或建议。
问题就在这里。当我运行“旧版”mypy 调用时,一切都会过去,但是当我调用 时pre-commit run mypy --all-files,我会收到很多错误,如下所示:
pack_a/pack_b/pack_c/json_formatter.py:171:13: error: Returning
Any from function declared to return "str" [no-any-return]
return orjson.dumps(result, self._default).decode('UTF-8')
Run Code Online (Sandbox Code Playgroud)
有问题的函数确实被声明为 return str,但也是如此orjson.dumps,所以看起来这应该通过(它返回bytes是精确的,但不是Any)。
我得到的另一种错误是Unused "type: ignore" comment
我试图找出配置之间的差异,但找不到。
mypy现在的调用方式如下:
$(VENV)/bin/mypy --install-types --non-interactive $(CODE)
Run Code Online (Sandbox Code Playgroud)
$(CODE)包含“代码”的所有目录的列表在哪里(而不是测试和支持脚本)
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.950
hooks:
- id: mypy
args: [
"--config-file=setup.cfg",
--no-strict-optional,
--ignore-missing-imports,
]
additional_dependencies:
- pydantic
- returns
... (I checked all the types-* files …Run Code Online (Sandbox Code Playgroud) 有什么方法可以将 Numpy 数组键入为通用数组吗?
我目前正在使用 Numpy 1.23.5 和 Python 3.10,并且无法输入以下示例的提示。
import numpy as np
import numpy.typing as npt
E = TypeVar("E") # Should be bounded to a numpy type
def double_arr(arr: npt.NDArray[E]) -> npt.NDArray[E]:
return arr * 2
Run Code Online (Sandbox Code Playgroud)
我的期望是什么
arr = np.array([1, 2, 3], dtype=np.int8)
double_arr(arr) # npt.NDAarray[np.int8]
arr = np.array([1, 2.3, 3], dtype=np.float32)
double_arr(arr) # npt.NDAarray[np.float32]
Run Code Online (Sandbox Code Playgroud)
但我最终遇到以下错误
arr: npt.NDArray[E]
^^^
Could not specialize type "NDArray[ScalarType@NDArray]"
Type "E@double_arr" cannot be assigned to type "generic"
"object*" is incompatible with "generic"
Run Code Online (Sandbox Code Playgroud)
如果我将 E …
我创建了下面的 TypedDict 类;
class Appinfo(TypedDict):
appid: int
extended: dict[str, Any]
config: dict[str, Any]
depots: dict[str, Any]
ufs: dict[str, Any]
class SteamAppInfo(TypedDict):
appid: int
data: dict[str, Appinfo]
Run Code Online (Sandbox Code Playgroud)
在我的应用程序中,我将此类的变量传递给需要字典的函数;
def dict_get_key_list(data: dict[str, Any], key_list: list[str]) -> Any:
"""returns a dict value or None based on list of nested dict keys provided"""
try:
return reduce(operator.getitem, key_list, data)
except KeyError:
return None
Run Code Online (Sandbox Code Playgroud)
代码本身运行良好,就所有意图和目的而言,SteamAppInfo 是一本字典。但是,MyPy 给我以下错误;
error: Argument 1 to "dict_get_key_list" of "Utils" has incompatible type "SteamAppInfo"; expected "Dict[str, Any]"
Run Code Online (Sandbox Code Playgroud)
如何让 MyPy 识别出传递的是字典,而不必列出我创建的所有 TypedDict 作为可能的变量类型或将变量类型设置为 …
我有一个如下所示的功能,
def run_the_f(f):
# run f function after some validation
Run Code Online (Sandbox Code Playgroud)
根据某些条件,f 函数的签名会发生如下变化f(1.0), f(1.0,2.0), f(1.0,2.0,3.0,..)。换句话说,f 中输入参数的数量可以变化,类似于pyspark 中的 udf f。
我正在使用 mypy 并且我在下面尝试了失败,
def run_the_f(f: Callable[[*float],float]):
# run f after some validation
Run Code Online (Sandbox Code Playgroud)
有人可以支持在 Callable 中填写什么吗?
编写类型提示的正确方法是什么defaultdict(lambda: defaultdict(set))?
我使用Python 3.10.5和mypy 0.971,发现mypy返回错误,因为var = defaultdict(lambda: defaultdict(set))没有类型提示。
前提
str。set。(这可能是显而易见的。)示例代码
from collections import defaultdict
var = defaultdict(lambda: defaultdict(set))
Run Code Online (Sandbox Code Playgroud)
输出
test.py:2: error: Need type annotation for "var"
Run Code Online (Sandbox Code Playgroud) 考虑以下代码:
def verify(schema: Type[T], data: T) -> None:
pass
verify(int, "3")
verify(float, "3")
verify(str, "3")
Run Code Online (Sandbox Code Playgroud)
我希望前两个verify()调用显示为类型错误,而最后一个则不会。
然而,在 PyCharm 和 mypy 中,它们都没有出现类型错误。我尝试启用所有可能的严格性标志和错误代码,但什么也没有。
我怎样才能让类型检查器对此进行类型检查?为什么会失败?
库喜欢apischema依赖这样的功能来进行类型检查,例如apischema.serialize(MyDataclass, my_dataclass),但这也不起作用。
def timer(func: Callable[..., Any]) -> Callable[..., Any]:
"""Calculates the runtime of a function, and outputs it to logging.DEBUG."""
@wraps(func)
def wrapper(*args, **kwargs):
start = perf_counter()
value = func(*args, **kwargs)
end = perf_counter()
_logger = logging.getLogger(__name__ + '.' + func.__name__)
_logger.debug(' runtime: {:.4f} seconds'.format(end - start))
return value
return wrapper
Run Code Online (Sandbox Code Playgroud) mypy ×11
python ×10
defaultdict ×1
django ×1
django-stubs ×1
numpy ×1
pycharm ×1
python-3.x ×1
type-hinting ×1
typeddict ×1
typing ×1