Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: Pyright strict 模式检查不通过 #2855

Closed
luochen1990 opened this issue Aug 5, 2024 · 11 comments · Fixed by #2856
Closed

Bug: Pyright strict 模式检查不通过 #2855

luochen1990 opened this issue Aug 5, 2024 · 11 comments · Fixed by #2856
Labels
enhancement New feature or request wontfix This will not be worked on

Comments

@luochen1990
Copy link

操作系统

Linux

Python 版本

3.12

NoneBot 版本

2.3.2

适配器

无关

协议端

无关

描述问题

Pylance严格模式下类型错误:

Type of "on_message" is partially unknown
Type of "get_message" is partially unknown
Type of "send" is partially unknown

复现步骤

  1. 在vscode 中添加插件 python
  2. 设置严格模式
 "python.languageServer": "Pylance",
 "python.analysis.typeCheckingMode": "strict",
  1. 编写以下代码
from nonebot.plugin import on_command, on_message
from nonebot.adapters import Bot, Event
from nonebot.rule import to_me

#Doc: https://nonebot.dev/docs/advanced/matcher
echo_cmd = on_command("echo",to_me())
echo_msg = on_message(to_me())

@echo_msg.handle()
async def echo_escape(bot: Bot, event: Event):
    await bot.send(event, event.get_message())
  1. 观察编辑器报错

期望的结果

类型检查正确,没有类型错误

截图或日志

image
@luochen1990 luochen1990 added the bug Something isn't working label Aug 5, 2024
@yanyongyu
Copy link
Member

yanyongyu commented Aug 5, 2024

nb 目前仅支持 standard 模式类型检查,该模式也是 pyright 默认模式,在 strict 模式下,你使用的大部分库(包括标准库)都无法通过检查。

如果有空的话,nb 也可以针对 strict 模式做一些补充,但不能保证做到 0 error。

@yanyongyu yanyongyu added enhancement New feature or request wontfix This will not be worked on and removed bug Something isn't working labels Aug 5, 2024
@yanyongyu yanyongyu changed the title Bug: 类型错误 Bug: Pyright strict 模式检查不通过 Aug 5, 2024
@luochen1990
Copy link
Author

用严格模式对开发效率是很有帮助的,建议试一试,标准库及大部分流行第三方库的类型问题都可以通过安装额外的stubs文件解决

@luochen1990
Copy link
Author

如果认为有必要的话,我很乐意贡献一些 PR,但我需要先确认项目的 owner 认为这是有价值的。 另外过程中可能会需要一些讨论以了解 nb 库的设计思路,因为加类型的过程中会需要对这些细节了解地很透彻。 比如 Message 为什么设计为泛型(但引用处又存在未指定泛型参数的情形)

@RF-Tar-Railt
Copy link
Member

如果认为有必要的话,我很乐意贡献一些 PR,但我需要先确认项目的 owner 认为这是有价值的。 另外过程中可能会需要一些讨论以了解 nb 库的设计思路,因为加类型的过程中会需要对这些细节了解地很透彻。 比如 Message 为什么设计为泛型(但引用处又存在未指定泛型参数的情形)

这个问题有点舍本逐末了,类型是提升开发效率的,而不应作为主要内容。作为开发者,过分纠结类型问题并不能解决实际问题

@yanyongyu
Copy link
Member

用严格模式对开发效率是很有帮助的,建议试一试,标准库及大部分流行第三方库的类型问题都可以通过安装额外的stubs文件解决

大部分库均采用 mypy 或 pyright standard/basic 模式进行检查,目前我认为 strict 模式无必要,因为他会 forbid 任何 unknown,要做到这一点首先需要要求所有的 depends (包括标准库和第三方库)均以 strict 模式通过检查,我认为这个目前是不可能的,需要为所有上游依赖进行修改。

比如 Message 为什么设计为泛型

由于 Message 是一个抽象类,具体实现由适配器决定,所以这些类型均为泛型。

@littleblacklb
Copy link

将类型检查简单的设置为strict我认为并非明智之举。
诚然,严格的类型在长期上来说必然是有益的。但是也应考虑到社区开发者们是否有精力付出此决策的代价,因此应当合理的对项目进行分析后再设定合理的检查标准。

《Robust Python》一书对此有所见解:

Developer time is expensive, and it is easy to focus on what else those developers could be doing. Adopting type annotations is not free. Worse, with large enough codebase, these cost can easily dwarf the initial benefits you get from type checking.

@luochen1990
Copy link
Author

Message 是一个抽象类,具体实现由适配器决定,所以这些类型均为泛型

泛型没问题,我理解这里 Message 是 MessageFragment 的一个多态列表也没问题,但是,至少我们可以用 Message[Any] 来引用它以确保至少这个类型引用是 full applied 的?

@yanyongyu
Copy link
Member

@luochen1990 并不可以,可以看到 Message 泛型的 TypeVar 具有 bounded type 限制,为了确保元素类型必须为 MessageSegment 的子类型。而 MessageSegment 也为泛型,python 并不支持 HKT。

@luochen1990
Copy link
Author

并不可以

我是指,从 kind 层面 ,Message* -> * 不是 *, 至少 Message[Any]* 。当然它丢失了一些精度(指 Any 没有捕获它必须是 MessageSegment 的子类型这一事实)

@yanyongyu
Copy link
Member

Dependent 那边遗漏的类型在 #2856 里补全。

Message 泛型我不认为用 Any 是一个好的做法,这同样是在隐蔽式产生错误。当然这个问题在适配器的子类实现上并不存在,你依然可以正确使用子类型。如果你对于 Message 基类的 type hint 有更好的做法,欢迎 PR 来解决这个问题。

@yanyongyu
Copy link
Member

如果有遗漏的类型欢迎提交 Issue 或者 PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request wontfix This will not be worked on
Development

Successfully merging a pull request may close this issue.

4 participants