PaddlePaddle / Paddle

PArallel Distributed Deep LEarning: Machine Learning Framework from Industrial Practice (『飞桨』核心框架,深度学习&机器学习高性能单机、分布式训练和跨平台部署)
http://www.paddlepaddle.org/
Apache License 2.0
21.63k stars 5.44k forks source link

【Type Hints】Paddle 的 CI 中引入 mypy 对于 API 中 docstring 的示例代码的类型检查 #63901

Open megemini opened 1 week ago

megemini commented 1 week ago

PR Category

User Experience

PR Types

Others

Description

关联 PR : https://github.com/PaddlePaddle/Paddle/issues/63597

任务:1-4

在 CI 中引入 mypy 对 docstring 中示例代码的检查。与 xdoctest 的检查项共用一个 CI: PR-CI-Static-Check。如果后续有必要的话可以单独开一个 CI 。

涉及文件:

用于 type hint 检查的文件:

另外,修改一个文件用于验证:

paddle-bot[bot] commented 1 week ago

你的PR提交成功,感谢你对开源项目的贡献! 请关注后续CI自动化测试结果,详情请参考Paddle-CI手册。 Your PR has been submitted. Thanks for your contribution! Please wait for the result of CI firstly. See Paddle CI Manual for details.

megemini commented 2 days ago

Update 20240505

将 mypy 的检查引入 PR-CI-Static-Check,通过修改 api 的 annotation 可以触发 mypy 检查 ~

这里需要

配合检查 ~

math.py 中修改两个 api

另外,tools/mypy.ini 还只是最基础的配置,后面应该需要不断更新 ~

@SigureMo 请评审 ~

megemini commented 19 hours ago

在 CI 标题里加 [typing_checking=all](后缀形式),则检查全部示例文档

嗯,确实需要,torch 是把所有示例代码抓出来测试的 ~

这个任务可以放到 代码标注 完成之后,目前 get_docstring 可以获取全量 docstring,在 CI 里面加个标记,然后脚本执行的时候把 full_test=True 代进去应该就可以~

def get_docstring(full_test=False):
    '''
    this function will get the docstring for test.
    '''
    import paddle
    import paddle.static.quantization  # noqa: F401

    if full_test:
        get_full_api_from_pr_spec()
    else:
        get_incrementapi()

我加个子任务吧?~ https://github.com/PaddlePaddle/Paddle/issues/63597 任务 3-1

另外有一个问题就是,现在这样的话,对于其他不知情的同学来说,在一个示例代码里改了一个 typo CI 是会通过的吗?是否会导致现存的示例代码就通不过呢?

嗯,肯定会有这样的情况 ~

这个 type checking 比之前的示例代码那个任务还麻烦 ~ 其中应该会有一些依赖关系,在没有完成基础标注的情况下,type checking 可能出问题 ~

目前能做的:

暂时想到这些,@SigureMo 帮忙看看这样行不行?

SigureMo commented 14 hours ago

其余暂时没什么大问题,等 CI 跑完我看下效果~

其实之前就发现一个体验比较差的问题就是,log 太多了,包括示例代码检查,对于大多数工具来说,默认行为是如果 success,那么是静默的,不会在成功的那些 case 上打印过多 log(除非开 --verbose),只有 fail 才会打印详细日志,对于这一点来说我们的日志对于用户是不友好的,之前示例代码还好些吧,加上类型检查就不太可读了,这个可以之后专门优化一下(体验优化,单独 PR)

这个任务可以放到 代码标注 完成之后

诶?会不会有点晚?按我理解这个功能可以用来摸底和统计 API 支持情况,感觉可以在批量任务的同时做?

这个 type checking 比之前的示例代码那个任务还麻烦 ~ 其中应该会有一些依赖关系,在没有完成基础标注的情况下,type checking 可能出问题 ~

这样的话,那我们的任务划分也是需要考虑这一点的

这个 CI 要等到 _typing 和 tensor.pyi 那两个任务,以及《Paddle 类型提示》这个文档都完成后才能合入,相当于设定一个 milestone,后续 api 修改的时候要添加 type annotation ~

喔喔,我以为这个想先合呢 :joy:

在类型提示都标注完之前,PR-CI-Static-Check 如果出现 type checking 的 error,可以先找地方(比如之前提到的 辅助管理文档或工具)记录下来,然后赦免,最后查缺补漏的时候(或者后面全量检查)再修改 ~

唔,鉴于这个周期比较长,这会极大影响其他开发者(包括内部的)在这段时间的体验的,而且这会非常麻烦 CI 管理人员,豁免不太合适,是否可以有黑白名单机制呢?比如通过标记

.. code-block:: python

    :type-checking: true

但这有一个缺点就是,前期默认是 false,后期默认就是 true 了,后期 true 切默认后最好统一清理掉 :type-checking: true 标记

或者干脆维护一个黑名单,即 API 列表,每完成一个删掉一个,也能根据这个名单直接反映完成情况(不过要做好频繁冲突的准备)

不过两者的话,感觉前者会更灵活些,因为大概率,我们总有一些就是需要禁掉的,这样的 case 直接 :type-checking: false 就好了

megemini commented 4 hours ago

其实之前就发现一个体验比较差的问题就是,log 太多了,包括示例代码检查,对于大多数工具来说,默认行为是如果 success,那么是静默的,不会在成功的那些 case 上打印过多 log(除非开 --verbose),只有 fail 才会打印详细日志,对于这一点来说我们的日志对于用户是不友好的,之前示例代码还好些吧,加上类型检查就不太可读了,这个可以之后专门优化一下(体验优化,单独 PR)

现在脚本里是用的 debug,比如 : python sampcd_processor.py --debug --mode cpu; example_error=$?,所以日志比较多 ~

最早之前就这么写,所以示例代码和 type checking 沿用了 ~

那么,去掉 debug?

另外,关于全量 docstring 和黑白名单的问题,昨晚想了想,能不能这样:

如果这样:

看看这样如何?

megemini commented 4 hours ago

另外话说这个是否可以放到根目录的 pyproject.toml 呢?现代 python 工具大多配置是放在 pyproject.toml 里的

可以啊 ~ 我试试看 ~

SigureMo commented 2 hours ago

那么,去掉 debug?

嗯,可以之后试一下

另外,关于全量 docstring 和黑白名单的问题,昨晚想了想,能不能这样:

嗯嗯,不过之后是否有一些情况确实需要禁用掉呢?就像我上面说的「因为大概率,我们总有一些就是需要禁掉的」,是否有方式灵活禁用某些 case 呢?(比如 cpplint 的 // NOLINT、ruff 的 # noqa

[typing_checking]

喔喔才发现上面写错了 :joy:,应该是 [type_checking]typing_checking 怪怪的

megemini commented 2 hours ago

嗯嗯,不过之后是否有一些情况确实需要禁用掉呢?就像我上面说的「因为大概率,我们总有一些就是需要禁掉的」,是否有方式灵活禁用某些 case 呢?(比如 cpplint 的 // NOLINT、ruff 的 # noqa

# type: ignore ?比如:

import paddle
a = paddle.aaa # type: ignore

如果不写 # type: ignore,则检查出错:

/home/shun/Documents/Projects/data-projects/paddle_typehint/test_mypy_ignore.py:2: error: Module has no attribute "aaa"  [attr-defined]
Found 1 error in 1 file (checked 1 source file)

标记 # type: ignore,则检查成功

Success: no issues found in 1 source file
SigureMo commented 2 hours ago

用 # type: ignore ?比如:

喔喔,局部的这种,可以的,这里说的是整个 case 的情形,如果不至于写太多 type: ignore 的话就没问题

另外可以考虑下示例代码展示时是否要将 type: ignore 删掉~