Kivy 贡献指南深度解析:从代码提交流程到图形单元测试体系 📅 发布时间:2026/9/20 17:35:12 👁 浏览次数: 跨平台移动开发桌面应用UI组件【免费下载链接】kivyOpen source UI framework written in Python, running on Windows, Linux, macOS, Android and iOS项目地址https://gitcode.com/gh_mirrors/ki/kivy点击查看免费下载Kivy 是一个用 Python 编写的开源 UI 框架可运行于 Windows、Linux、macOS、Android 与 iOS。它由大量志愿者无偿维护社区贡献是其发展的核心动力。本文以仓库根目录的CONTRIBUTING.md为主线结合Makefile、kivy/tests/common.py、kivy/tools/precommit_hooks/pre-commit-config.yaml、doc/README.md等仓库内真实源码与配置系统梳理 Kivy 生态的贡献方式、代码提交流程、文档规范与单元测试基础设施帮助你以正确的方式加入这个项目。一、贡献的多种形式Kivy 的贡献远不止提交代码。CONTRIBUTING.md将其归纳为以下几大类提交源码变更修复 bug、新增功能、改进文档走 Code Contributions 或 Documentation Contributions 流程。提交 Issue在 Issue 跟踪器中报告 bug 或提交新功能建议。注意如果你的问题属于为什么报这个错怎么实现某个功能这类使用咨询不要直接开 Issue应先走支持渠道见CONTACT.md。协助处理他人 Issue验证错误能否复现相似或不同平台如果问题已被修复而无人注意到及时告知补充最小可复现代码片段、详细日志为模糊的提交者补充线索新手可从Easy或Good First Issue标签入手边学习流程边贡献有经验者可寻找已提出详细方案但未提交 PR的 Issue 快速拿下更高阶的贡献是领养foster陈旧的公开 PR理解其要解决的问题与解决思路自行审查、修复、rebase 后重新提交并推动其合并。代码审查与重构在缺陷变成 bug 前发现它们重构让代码更易读易改。补充单元测试稳定的测试银行能大幅加速后续开发。详见 七、单元测试体系。扩展生态新增 Widget 或 python-for-android recipe 供社区复用第三方 Widget 可通过独立的 Kivy Garden 项目发布推广。非代码贡献在讨论区与支持频道帮助新手、做 Kivy 布道者、投稿到 Kivy 画廊、说服所在组织成为赞助商Open Collective等。若想在动手前讨论方案、获取反馈与建议可加入#dev频道Discord见 chat.kivy.orgGitHub Issue 跟踪器则是更正式的跟踪机制。二、行为准则社区采用《行为准则》CODE_OF_CONDUCT.md来维护开放、友好的氛围。参与任何贡献前请阅读并遵守该准则。三、报告 Issue 的规范流程报告问题Kivy 的 bug、文档缺失、拼写错误或示例不清前若不确定是否为 bug请先走支持渠道。若能提供最小失败示例将极大提高处理效率开启调试日志编辑user_directory/.kivy/config.ini[kivy] log_level debug这一配置项直接由kivy/config.py解析——Kivy 的配置系统支持[kivy]、[graphics]、[input]、[postproc]等多个小节其中log_level控制日志输出级别调试级别会输出更详细的信息便于定位问题。重新执行代码将 Kivy 日志与 Python 回溯完整粘贴到 GitHub Gist。提交 Issue在对应项目的 Issue 数据库提交如 Kivy Framework、Buildozer、python-for-android、kivy-ios 等标题简明扼要地描述问题正文精确说明复现步骤并附上 Gist 链接用 Preview 标签页预览排版直接粘贴日志会造成格式混乱提交即可。四、代码贡献完整工作流4.1 编码风格遵循 PEP8 Python 编码规范。自动化风格检查在 Kivy 源码目录下执行make hook即可把 git 暂存区代码接入 pre-commit 检查器提交时自动校验若引入风格错误提交会被拒绝。仓库根目录Makefile中hook目标的实现为hook: # Install pre-commit git hook to check your changes for styleguide # consistency. pre-commit install -f --configkivy/tools/precommit_hooks/pre-commit-config.yaml实际使用的检查器配置kivy/tools/precommit_hooks/pre-commit-config.yaml包含通用钩子pre-commit/pre-commit-hooks v4.0.1大文件检查、AST 语法检查、大小写冲突检查、可执行文件 shebang、JSON/YAML/TOML 校验、合并冲突检查、符号链接检查、行尾空白修复、禁止提交到分支、JSON 自动格式化等Ruffastral-sh/ruff-pre-commit v0.8.2Python 代码静态检查与 lint行尾规范Lucas-C/pre-commit-hooks v1.1.7禁止/移除 CRLF、禁止/移除 Tab。如需临时跳过某个检查在git commit前加SKIPhookname环境变量即可Linux 下失败的钩子名称会明确显示。4.2 性能要求阅读 Python 性能技巧Kivy 中 CPU 密集部分使用Cython编写如果你的改动涉及大量计算也应考虑使用 Cython。仓库中大量.pyx/.pxd文件如kivy/graphics/*.pyx、kivy/properties.pyx、kivy/_clock.pyx等即印证了这一策略。4.3 Git 与 GitHub 工作流Kivy 使用 git 做版本控制、GitHub 托管代码。初次设置只需一次# 1. 登录 GitHub # 2. Fork 对应仓库如 kivy/kivy点击 Fork 按钮 # 3. 克隆你的 fork远程名 origin分支 master git clone https://github.com/username/kivy.git # 4. 编译并设置 PYTHONPATH 或安装 # 5. 将官方仓库添加为远程源 git remote add kivy https://github.com/kivy/kivy.git此后每次提交补丁的步骤# 1. 在 bug 跟踪器中确认对应 ticket若无人认领则声明你要处理 # 2. 为这个功能/bugfix 创建独立命名的分支 git checkout -b new_feature # 3. 修改代码 # 4. 测试代码并补充自动化单元测试即使小修复也要测试 # 5. 每个修复/功能做一次最小化原子提交保持提交干净必要时用 git add -p # 6. 写合适的提交信息 # 7. 拉取上游并合并 git pull kivy master # 8. 推送到你的 GitHub 远程 git push origin new_feature # 9. 通过 GitHub 界面发送 Pull Request 并描述改动编译注意事项如果改动涉及需要编译的代码Cython 扩展必须重新编译才能生效。make会完成这项工作用make clean清理编译产物make distclean会删除所有不受版本控制的文件警告未纳入版本控制的改动也会被删除。Makefile中distclean目标实际调用git clean -dxf -e debian正是清理全部未跟踪文件这一行为的来源。五、PR 被接受后的流程维护者会检查你的改动是否干净、合理若事先沟通过会更顺利。一旦合并你的名字将永远与这次改动关联在代码历史中可自行选择退出。六、文档贡献文档贡献与代码贡献流程基本一致但更为宽松Fork 仓库 → 克隆 → 添加 kivy 远程源同前安装 Sphinx参见doc/README.md使用ReStructuredText 标记修改docs/sources下的文档。提交文档更新的步骤git checkout -b my_docs_update # 修改文档 make html # 重新生成 HTML 并审查 # 提交信息、保持提交主题聚焦 git push # 发送 Pull Request仅纠正一个错别字不必走完整流程但复杂贡献请遵循上述建议。6.1 构建文档doc/README.md给出了文档构建的实操指引# 安装文档依赖Sphinx 需要 Python 3.12 pip install -e .[docs] # 生成文档 make html文档生成在docs/build/html/本地预览可执行cd build/html/后运行python -m http.server 8000。如果更新了 Kivy 安装后编译文档遇到问题可运行make clean force html。6.2 Docstring 规范每个模块/类/方法/函数都需要 docstring并使用以下 Sphinx 关键字.. versionadded::标注功能添加的版本.. versionchanged::标注行为变化的版本.. note::附加使用说明或相关功能信息.. warning::提示用户可能遇到的潜在问题.. deprecated::标注功能开始废弃的版本。示例def my_new_feature(self, arg): New feature is awesome .. versionadded:: 1.1.4 .. note:: This new feature will likely blow your mind .. warning:: Please take a seat before trying this feature 引用 API 其他部分时使用以下交叉引用指令:mod:~kivy.uix.floatlayout # 引用模块 :class:~kivy.uix.floatlayout.FloatLayout # 引用类 :meth:~kivy.core.window.WindowBase.toggle_fullscreen # 引用方法 :doc:/api-kivy.core.window # 引用模块文档module、class、method替换为真实名称子模块名用.分隔。:doc:与:mod:基本相同区别仅在于 URL 中的锚点因此:doc:因 URL 更干净而更受青睐。七、Kivy 单元测试体系以下内容针对 Kivy 框架本体GitHub 上的 kivy/kivy是CONTRIBUTING.md中技术性最强、与源码结合最紧密的部分。7.1 测试分类单元测试分为两类非图形单元测试标准 unittest可在控制台中直接运行图形单元测试需要 GL 上下文按需通过图像对比工作详见 7.4。运行测试需要安装 pytest 与 coveragesudo pip install kivy[dev]然后在 kivy 目录下make testMakefile中test目标的实际实现为test: # Run tests and print output. -rm -rf kivy/tests/build env KIVY_NO_ARGS1 $(PYTEST) kivy/tests其中PYTEST $(PYTHON) -m pytest即python3 -m pytest kivy/tests并设置KIVY_NO_ARGS1防止 Kivy 解析无关命令行参数。pytest 的 markers 在kivy/tests/pytest.ini中声明如logmodepython、logmodemixed、incremental。7.2 测试组织与编写所有测试位于kivy/tests目录文件名以test_name.py开头pytest 会自动收集。模板如下import unittest class XXXTestCase(unittest.TestCase): def setUp(self): # import class and prepare everything here. pass def test_YYY(self): # place your test case here a 1 self.assertEqual(a, 1)XXX替换为覆盖测试场景的合适名称YYY替换为测试名。运行方式make test # 全部测试 pytest kivy/tests/test_yourtestcase.py # 只跑某个文件或在文件末尾加上if __name__ __main__: unittest.main()后用python test_yourtestcase.py直接运行。仓库现有测试覆盖了从动画、时钟、配置、图形、语言解析到各类 UI 组件accordion、actionbar、boxlayout、textinput、scrollview 等的广阔范围例如kivy/tests/test_clock.py、kivy/tests/test_properties.py、kivy/tests/test_uix_widget.py等可作为编写新测试的参考。7.3 图形单元测试GraphicUnitTest某些测试必须在 GL Window 创建之后进行以交互图形、控件、模块、输入等。这类测试通过kivy.tests.common模块中的GraphicUnitTest基类实现。方式一手动设置 自动清理from kivy.tests.common import GraphicUnitTest class MyTestCase(GraphicUnitTest): def test_runtouchapp(self): # non-integrated approach from kivy.app import runTouchApp from kivy.uix.button import Button button Button() runTouchApp(button) # get your Window instance safely from kivy.base import EventLoop EventLoop.ensure_window() window EventLoop.window # your asserts self.assertEqual(window.children[0], button) self.assertEqual( window.children[0].height, window.height )方式二使用render()自动搭建环境GraphicUnitTest.render()与setUp()/tearDown()配合自动完成以下基础设置源码见kivy/tests/common.py窗口固定为320×240 px仅使用默认配置通过KIVY_USE_DEFAULTCONFIG环境变量限制setUp中执行environ[KIVY_USE_DEFAULTCONFIG] 1并通过Config.set(graphics, width, 320)等设置窗口尺寸移除所有输入鼠标/触摸需要测试时需 mock 或手动添加显示任何控件树前先清空 Window 的 canvasclear_window_and_event_loop中清空before/主/after三层 canvas 与事件循环触摸缓存。示例含触摸模拟from kivy.tests.common import GraphicUnitTest, UnitTestTouch class MyTestCase(GraphicUnitTest): def test_render(self): from kivy.uix.button import Button # with GraphicUnitTest.render() you basically do this: # runTouchApp(Button()) some setup before button Button() self.render(button) # get your Window instance safely from kivy.base import EventLoop EventLoop.ensure_window() window EventLoop.window touch UnitTestTouch( *[s / 2.0 for s in window.size] ) # bind something to test the touch with button.bind( on_releaselambda instance: setattr( instance, test_released, True ) ) # then lets touch the Windows center touch.touch_down() touch.touch_up() self.assertTrue(button.test_released) if __name__ __main__: import unittest unittest.main()UnitTestTouch实现细节源码kivy/tests/common.py它继承kivy.input.motionevent.MotionEvent构造时将像素坐标换算为归一化坐标x / (win.width - 1.0)通过EventLoop.post_dispatch_input(begin/update/end, self)分别实现touch_down、touch_move、touch_up从而模拟真实触摸事件在 Kivy 输入管线中的分发。重要告诫不要在测试中使用绝对数值以免破坏跨分辨率的功能。应使用相对位置/尺寸并乘以Window.size。7.4 GL 单元测试图像对比测试GL 测试比普通图形测试更困难OpenGL 虽是标准但渲染输出并不标准取决于 GPU 与驱动。这类测试的目标是保存第 X 帧的渲染输出并与参考图像对比。图像尺寸固定为320×240 像素 PNG当前图像对比是逐像素per-pixel进行因此你生成的参考图像只对你的 GPU/驱动正确文档注明欢迎实现支持delta容差的图像对比补丁运行方式mkdir kivy/tests/results KIVY_UNITTEST_SCREENSHOTS1 make test第一次运行时若results目录为空不会做对比生成的图像会被用作参考第二次运行起所有图像与参考图像逐一对比。这是通过环境变量KIVY_UNITTEST_SCREENSHOTScommon.py中make_screenshots os.environ.get(KIVY_UNITTEST_SCREENSHOTS)开启截图机制实现的。对比结果生成 HTML 报告含对比前后图像与对应测试代码片段位于kivy/tests/build/index.html。源码中on_window_flip回调在窗口显示一帧后递减framecount归零时用window.screenshot()捕获临时 PNG与results目录中的参考文件逐字节比较_data[0].data并同步生成带高亮源码的 HTML 报告。build目录在每次make test时被清理若不想清理可直接用 pytest 命令。编写 GL 单元测试创建一个根 widget如同App.build或runTouchApp中那样交给渲染函数捕获输出from kivy.tests.common import GraphicUnitTest class VertexInstructionTestCase(GraphicUnitTest): def test_ellipse(self): from kivy.uix.widget import Widget from kivy.graphics import Ellipse, Color r self.render # create a root widget wid Widget() # put some graphics instruction on it with wid.canvas: Color(1, 1, 1) self.e Ellipse(pos(100, 100), size(200, 100)) # render, and capture it directly r(wid) # as alternative, you can capture in 2 frames: r(wid, 2) # or in 10 frames r(wid, 10)每次调用self.render生成的图像命名规则classname_funcname-r-call-count.png其中r-call-count是该测试函数内调用self.render的次数。参考图像命名为ref_classname_funcname-r-call-count.png如需更换参考图直接用新图替换即可。7.5 覆盖率报告基于上述测试执行自动计算覆盖率统计生成 HTML 报告make cover然后用浏览器打开kivy/htmlcov/index.html。Makefile中cover目标执行coverage html --includekivy/*并排除data、lib、tools、tests等目录。八、仓库内的相关辅助设施Makefile常用目标make build可编辑模式安装、make testpytest 测试、make cover覆盖率、make stylepython3 -m ruff check .全库风格检查、make hook安装 pre-commit 钩子、make html构建文档、make clean/make distclean清理产物、make theming重新生成默认主题 atlas等。异步测试kivy/tests/conftest.py与common.py中的async_run装饰器支持 asyncio/trio 事件循环下的异步应用测试由KIVY_EVENTLOOP环境变量控制配合 pytest-asyncio/pytest-trio。Fixtureskivy/tests/fixtures.py提供kivy_app、kivy_clock、kivy_metrics等 pytest fixture供测试复用。结语从一次小小的 Issue 报告到一套 GL 图像对比测试Kivy 社区为不同水平的贡献者设计了完整的参与路径。撰写本文时引用的所有命令、配置与测试基类均可在仓库的CONTRIBUTING.md、Makefile、kivy/tests/common.py、kivy/tests/pytest.ini、kivy/tools/precommit_hooks/pre-commit-config.yaml、doc/README.md中找到并直接使用。无论你选择补充文档、修复 bug 还是完善测试遵循本文梳理的流程都能让贡献被高效接纳并让 Kivy 变得更好、更强。赞分享跨平台移动开发桌面应用UI组件【免费下载链接】kivyOpen source UI framework written in Python, running on Windows, Linux, macOS, Android and iOS项目地址https://gitcode.com/gh_mirrors/ki/kivy点击查看免费下载相关推荐Kivy 开源贡献指南从 Bug 报告、代码工作流到单元测试体系全解析Kivy 开源贡献指南从 Bug 报告、代码工作流到单元测试体系全解析 本文基于 Kivy 仓库中的官方贡献文档 contribute.rst https:/跨平台移动开发桌面应用UI组件Rocket 贡献指南从 PR 流程、测试体系到代码风格与提交规范Rocket 贡献指南从 PR 流程、测试体系到代码风格与提交规范 本篇技术指南以 RocketRust Web 框架仓库根目录下的 CONTRIBUTI后端开发工具pywal开发贡献指南从单元测试到PR提交全流程pywal开发贡献指南从单元测试到PR提交全流程 单元测试编写规范 pywal项目采用Python标准unittest框架进行测试测试文件位于 tests/开发工具上一篇突破10万并发连接gorilla/websocket性能优化实战指南下一篇Hydra游戏启动器下载字体功能异常分析与解决方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考