资讯动态

Spyder 贡献者开发实战指南:环境搭建、源码运行、测试与 Qt 多继承规范

发布时间:2026/9/25 17:10:31 来源:尧图企业网站定制
开发工具IDE代码编辑器【免费下载链接】spyderOfficial repository for Spyder - The Scientific Python Development Environment项目地址https://gitcode.com/gh_mirrors/sp/spyder点击查看免费下载Spyder 是面向科研计算的 Python 开发环境The Scientific Python Development Environment本文基于仓库根目录的 CONTRIBUTING.md系统梳理向 Spyder 贡献代码的完整流程从提交高质量 Issue、搭建开发环境、通过bootstrap.py从源码运行 Spyder到运行测试套件、发起跨仓库联合 PR涉及 spyder-kernels / python-lsp-server / qtconsole再到 API 变更准则与 Qt 与纯 Python 类混用的多继承规范。读完本文你将具备从零参与 Spyder 开发、调试与提交代码的完整实战能力。参与贡献前的两条铁律在动手之前Spyder 项目对贡献者有两个明确要求先排障再提问提交 Issue 前务必仔细阅读官方的 Troubleshooting Guide并在 issue tracker 中检索自己的错误信息与问题描述。绝大多数 bug 要么是重复报告要么可以通过用户侧的简单步骤自行解决。提交可复现的 Issue除错误信息/traceback 和请求的环境/依赖信息外必须附上逐步触发问题的详细描述。否则维护者大概率无法定位和修复你的 Issue 将在 7 天后被关闭。从仓库结构看Spyder 的测试与配置体系conftest.py、pytest.ini、requirements/非常完善提供可复现的环境信息如 Spyder 版本、Python 版本、Qt 绑定与版本能大幅提升 Issue 被修复的效率。搭建开发环境Fork 与克隆仓库先在浏览器中打开 Spyder 仓库点击Fork按钮在个人 GitHub 账户下创建副本然后复制Clone or Download链接在命令行克隆$ git clone LINK-TO-YOUR-REPO最后将官方仓库设置为 upstream 远程$ git remote add upstream SPYDER-官方仓库地址此后可通过git pull upstream master同步官方最新代码见下文“分支工作流”。用 conda 创建环境并安装依赖Spyder 官方强烈推荐使用 Anaconda 或 Conda-forge 管理开发环境。创建spyder-dev环境并安装主依赖$ conda create -n spyder-dev -c conda-forge python3.11 $ conda activate spyder-dev $ conda env update --file requirements/main.ymlrequirements/main.yml 定义了 Spyder 的核心运行依赖从源码可以看出其精确版本约束例如ipython 9.15.0,10.0.0、jedi 0.17.2,0.21.0、pyqt 5.15,5.16、qtpy 2.4.0、qtconsole 5.7.2,5.8.0、python-lsp-server 1.14.0,1.15.0、spyder-kernels 3.2.0a1,3.2.0a2、pylint 3.1,5、spyder-themes 1.0.13,1.1.0等。该文件同时服务于 mybinder.org 的在线演示其注释说明内容已被复制到 binder/environment.yml因此修改它时需同步更新 binder 配置。安装完主依赖后还需按操作系统安装 Spyder 的特定依赖。macOS 上执行$ conda env update --file requirements/macos.yml从 requirements/macos.yml 可以看到 macOS 特有的依赖是applaunchservices 0.3.0和python.app后者用于以 GUI 方式启动 PythonLinux 的 requirements/linux.yml 则包含fcitx-qt5 1.2.7输入法支持与pyxdg 0.26Windows 对应文件为 requirements/windows.yml。virtualenv 备选方案Linux 上也可以使用virtualenv但 conda 仍是首选$ mkvirtualenv spyder-dev $ workon spyder-dev (spyder-dev) $ pip install -e .pip install -e .以可编辑editable模式安装 Spyder使源码修改即时生效。仓库根目录的 install_dev_repos.py 也提供了类似能力它会扫描external-deps下所有子仓库spyder-kernels、python-lsp-server、qtconsole、spyder-remote-services 等逐一以 editable 模式安装并支持--install/--no-install/--not-editable参数。从源码运行 Spyderbootstrap.py 深度解析克隆仓库后通过根目录的 bootstrap.py 以开发模式启动 Spyder附带额外检查与选项$ python bootstrap.pymacOS 10.15 及更早版本需改用pythonw而非python。bootstrap.py的工作机制值得展开它首先从install_dev_repos导入DEVPATH、REPOS和install_repo在首次运行时检查 Spyder 及其子仓库是否已以可编辑模式安装必要时自动安装并重启自身随后解析命令行参数、设置SPYDER_DEVTrue环境变量、检测/指定 Qt 绑定默认优先探测 PyQt5、调用get_versions()打印版本信息Spyder 版本、Git revision、分支、Python、Qt、系统等并校验 qtpy 版本要求1.1.0最后进入spyder.app.start.main()启动主程序。bootstrap.py 自带参数bootstrap.py拥有自己的命令行选项可用--help查看$ python bootstrap.py --help主要参数及源码语义如下见 bootstrap.py参数含义--gui {pyqt5,pyside2,pyqt6,pyside6}指定 Qt 绑定不指定时默认检测 PyQt5缺失则报错退出--hide-console隐藏父控制台窗口仅 Windows--safe-mode以全新配置目录启动启动前会清空get_conf_path()返回的配置目录用于排查配置损坏问题--debug以调试模式运行设置SPYDER_DEBUG3环境变量--filter-log逗号分隔的模块名层级列表仅显示这些模块的日志例如spyder.plugins.completion,spyder.plugins.editor--no-install跳过 Spyder 及子仓库的自动安装调试模式与日志过滤跟踪某个具体问题时以调试模式启动并配合日志过滤$ python bootstrap.py --debug--debug会设置SPYDER_DEBUG3结合--filter-log可只关注指定模块的日志输出如补全插件、编辑器插件避免日志淹没。切换 Qt 绑定需要测试不同 Qt 绑定如 PySide2 或 PyQt6时$ python bootstrap.py --gui pyqt6该选项对应设置QT_API环境变量--gui的合法取值为pyqt5、pyside2、pyqt6、pyside6。透传 Spyder 主程序参数bootstrap.py与 Spyder 主程序的参数通过--分隔。查看 Spyder 自身命令行选项$ python bootstrap.py -- --help例如python bootstrap.py -- --hide-console。从 bootstrap.py 的实现可见--之后的参数会被提取为spyder_options并替换进sys.argv再交给主入口。多实例运行重要修改 Spyder 源码后需要重启 Spyder 或启动全新实例才能生效。可同时运行多个副本方法是在PreferencesGeneralAdvanced Settings中取消勾选Use a single instance选项。运行测试安装测试依赖Anaconda 环境下安装测试依赖$ conda env update --file requirements/tests.ymlrequirements/tests.yml 包含的测试依赖有pytest 8.0、pytest-cov、pytest-qt、pytest-mock、pytest-timeout、pytest-order、pytest-lazy-fixture、flaky、coverage、cython、matplotlib、pandas、scipy、sympy、pillow、pyyaml等。pip 方式仅限专家$ pip install -e .[test]运行测试套件在spyder根目录执行$ python runtests.py从 runtests.py 源码可以看到更多细节它强制设置SPYDER_PYTESTTrue且必须在任何 import 之前完成默认 pytest 参数包含-vv -rw --durations10 --ignore./external-deps -W ignore::UserWarning即自动忽略 external-deps 子仓库的测试额外支持--run-slow运行标记为 slow 的测试CI 中由RUN_SLOWtrue环境变量控制与--remote-client运行远程客户端测试会加载 pytest_remoteclient.ini 并设置SPYDER_TEST_REMOTE_CLIENTtrue非 CI 场景默认追加--timeout120 --timeout_methodthread防止测试卡死测试结束后会主动断开主 QThread 的信号槽连接并用os._exit()跳过解释器析构避免 PyQt6/PySide6 下“QThread: Destroyed while thread is still running”崩溃。也支持直接透传 pytest 参数给 runtests.py例如只运行单个测试文件。分支工作流开始新 PR 前先同步官方仓库并创建特性分支$ git checkout master $ git pull upstream master $ git checkout -b NAME-NEW-BRANCH即在fix_in_spyder这类分支上进行开发保持master与官方同步。跨仓库联合开发external-deps 与 git-subrepoSpyder 与 spyder-kernels 是联合开发的编辑器中写的代码要发送到 IPython 控制台执行二者之间存在大量通信。同理python-lsp-server提供代码补全、lint 与折叠和 qtconsole提供 IPython 控制台也与 Spyder 深度集成。因此Spyder 仓库在 external-deps/ 下以git subrepo方式嵌入了这些项目的克隆仓库结构中可见 external-deps/spyder-kernels、external-deps/python-lsp-server、external-deps/qtconsole、external-deps/spyder-remote-services。当你的修改同时触及 Spyder 和这些外部仓库时需要按下面的联合 PR 工作流操作。安装 git-subrepogit clone git-subrepo-仓库地址 /path/to/git-subrepo echo source /path/to/git-subrepo/.rc ~/.bashrc source ~/.bashrcWindows 上需使用 Git Bash 执行。针对 spyder-kernels 的联合 PR假设你的 GitHub 用户名是myuser本地有~/spyder和~/spyder-kernels两个克隆分别工作于fix_in_spyder和fix_in_kernel分支在~/spyder中将external-deps/spyder-kernels子仓库替换为你fix_in_kernel分支的克隆$ cd ~/spyder $ git checkout fix_in_spyder $ git subrepo pull external-deps/spyder-kernels -r 你的-spyder-kernels-仓库地址 -b fix_in_kernel -u -f现在可以分别向 Spyder 与 spyder-kernels 两个仓库为各自分支提交 PR。若后续在fix_in_kernel分支新增提交例如添加新文件需要同步到 Spyder 侧$ cd ~/spyder-kernels $ git checkout fix_in_kernel $ touch foo.py $ git add -A $ git commit -m Adding foo.py to the repo $ git push origin fix_in_kernel $ cd ~/spyder $ git checkout fix_in_spyder $ git subrepo pull external-deps/spyder-kernels -r 你的-spyder-kernels-仓库地址 -b fix_in_kernel -u -f $ git push origin fix_in_spyder当fix_in_kernelPR 被合并后必须更新 Spyder 的fix_in_spyder分支让子仓库重新指向 spyder-kernels 官方仓库而非你的克隆$ git subrepo pull external-deps/spyder-kernels -r spyder-kernels-官方仓库地址 -b master -u -f针对 python-lsp-server / qtconsole 的联合 PR流程与 spyder-kernels 类似。假设外部仓库的 PR 分支名为fix_in_external_dep若修改在 python-lsp-server$ git checkout -b fix_in_spyder $ git subrepo pull external-deps/python-lsp-server -r 你的-python-lsp-server-仓库地址 -b fix_in_external_dep -u -f若修改在 qtconsole$ git checkout -b fix_in_spyder $ git subrepo pull external-deps/qtconsole -r 你的-qtconsole-仓库地址 -b fix_in_external_dep -u -f然后提交你在 Spyder 侧所需的改动。向fix_in_external_dep追加提交后同步更新fix_in_spyder分别对应 python-lsp-server / qtconsole$ git checkout fix_in_spyder $ git subrepo pull external-deps/python-lsp-server -r 你的-python-lsp-server-仓库地址 -b fix_in_external_dep -u -f $ git push origin fix_in_spyder$ git checkout fix_in_spyder $ git subrepo pull external-deps/qtconsole -r 你的-qtconsole-仓库地址 -b fix_in_external_dep -u -f $ git push origin fix_in_spyder外部 PR 合并后将子仓库重新指回官方分支python-lsp-server 对应developqtconsole 对应main$ git checkout fix_in_spyder $ git subrepo pull external-deps/python-lsp-server -r python-lsp-server-官方仓库地址 -b develop -u -f$ git checkout fix_in_spyder $ git subrepo pull external-deps/qtconsole -r qtconsole-官方仓库地址 -b main -u -fSpyder API 变更准则如果你的工作改动spyder.api中的公开类、方法或 Qt 信号或改动任意插件的公开接口例如 spyder/plugins/editor/plugin.py必须在当前 Changelog 中登记如 changelogs/Spyder-6.md。若对应版本的条目尚不存在创建一个以Unreleased为日期的条目并添加名为API changes的子章节。API 改动须遵守分级约束bugfix 版本如6.0.3只能新增 Qt 信号、方法或为现有方法增加 kwargsminor 版本如6.1.0尽量与 bugfix 相同除非万不得已才允许以向后不兼容的方式删除或改动 Qt 信号、类、方法major 版本如7.0.0对 API 改动无限制。这套约束保证了稳定分支master上用户升级的平滑性是维护 Spyder 庞大插件生态的基石。混用 Qt 与纯 Python 类多继承的规范这是 CONTRIBUTING.md 中最具技术深度的一节。Spyder 同时运行在 PyQt5/PyQt6基于 SIP和 PySide2/PySide6基于 Shiboken之上而这两个绑定家族对“同时继承 Qt 类与纯 Python 类mixin”的类有着部分相互矛盾的规则SIP要求 Qt 类的__init__在任何其他代码触碰self之前执行否则会抛出RuntimeError: super-class __init__() of type ... was never calledShiboken在 Qt 类的__init__运行时会自动调用 MRO 中紧跟 Qt 类之后那个类的__init__——即使你显式按名称调用了它。若之后又自行调用该类__init__进程会以You cant initialize an object twice中止Shiboken重实现的 Qt 虚方法如mouseDoubleClickEvent会被解析到 MRO 中的第一个命中项。因此若 Qt 类排在 mixin 之前mixin 的覆写会被静默忽略SIP 在搜索时会跳过 C 方法包装器顺序错误时碰巧能工作——但不要依赖这一点。Widget 模式mixin 在前Qt 类殿后对直接继承 Qt 类、或继承PluginMainWidget这类已组合 Qt 类的 widget同时满足上述三条规则的写法是基类列表中mixin 在前、Qt 类最后__init__中先调用 Qt 类的__init__Qt 类在 MRO 末尾Shiboken 的自动调用只会到达object无害然后按名称显式调用每个 mixin 的__init__不要依赖跨越 Qt/mixin 边界的协作式super().__init__()链。若所有 mixin 都未定义__init__例如纯访问器 mixin 如SpyderFontsMixin、SpyderConfigurationAccessor直接写super().__init__(parent)即可它会穿过它们直达 Qt 类。示例class MyWidget(FooMixin, BarMixin, QWidget): def __init__(self, parentNone): QWidget.__init__(self, parent) FooMixin.__init__(self) BarMixin.__init__(self, some_arg)Plugin 模式插件基类在前接口 mixin 在后插件遵循该模式的变体插件基类SpyderPluginV2/SpyderDockablePlugin本身由 QObject 派生且已把QObject放在其自身基类末尾保持在第一位以使其方法优先接口 mixin 跟在后面。__init__顺序相同先插件基类再逐个显式调用 mixinclass MyPlugin(SpyderDockablePlugin, ShellConnectPluginMixin): def __init__(self, parent, configurationNone): SpyderDockablePlugin.__init__(self, parent, configuration) ShellConnectPluginMixin.__init__(self)这是安全的因为这类接口 mixin 不覆写 Qt 虚方法Qt 血统在 MRO 中的位置不会隐藏任何东西。代码库中的规范范例Widget mixinsspyder/plugins/ipythonconsole/widgets/control.py 的ControlWidget与 spyder/plugins/ipythonconsole/widgets/client.py 的ClientWidget源码中可见其基类为SaveHistoryMixin, SpyderWidgetMixin, QWidgetPlugin 接口 mixinsspyder/plugins/plots/plugin.py 的Plots基类为SpyderDockablePlugin, ShellConnectPluginMixin与 spyder/plugins/layout/plugin.py 的LayoutPlugin QObject 派生 mixin状态初始化不能重复触发 QObject 部分spyder/plugins/debugger/plugin.py 的Debugger基类为SpyderDockablePlugin, ShellConnectPluginMixin, RunExecutor它调用RunExecutor._setup_run_executor()——该方法是从RunExecutor.__init__中拆出来的见 spyder/plugins/run/api.py正是为了在不二次执行QObject.__init__的情况下被调用刻意反例Qt 类在前spyder/plugins/projects/utils/watcher.py 的WorkspaceEventHandler基类为QObject, PatternMatchingEventHandler其另一基类是内部会调用super().__init__()的第三方类文件内注释解释了为什么常规顺序会在 Shiboken 下导致进程中止。两个容易踩的坑枚举成员必须在类上访问应写QClipboard.Clipboard而非clipboard_instance.Clipboard——在 PySide6 上实例访问会抛出AttributeError重载信号需逐个连接对Signal((), (object,))这类重载信号槽函数只会绑定到单个重载。PySide 依据槽函数签名选择带可选参数的槽会落到(object,)重载而 PyQt 选择第一个重载。另一重载的发射永远不会到达槽函数。因此应显式连接每个重载并让无参重载使用不接受参数的槽——例如用functools.partial包装参见 spyder/app/mainwindow.py 中sig_unmaximize_plugin_requested信号的连接方式。添加第三方内容许可与流程来自 Spyder 组织之外项目的一切文件无论许可如何包括源码、图片、图标及其他资源必须先经 Spyder 团队批准。在添加外部项目内容前请先在 GitHub、Gitter、Google Group 等渠道确认且仅在必要时引入。许可要求被纳入的代码必须是宽松许可非 copyleft按偏好顺序为MIT (Expat)Public domain首选 CC0ISC licenseBSD 2-clauseSimplified BSDBSD 3-clauseNew 或 Modified BSDApache License 2.0外部资源字体、图标、图片、声音、动画通常可接受以下弱 copyleft 与内容许可Creative Commons Attribution 3.0 或 4.0SIL Open Font License 1.1GNU LGPL 2.1 或 3.0其他许可偶尔可被纳入上述列表但应尽力避免。所有许可必须同时获得 OSI、FSF 与 DSFG 认可且与 GPLv3 兼容以确保 Spyder 最大限度的自由分发使用、并尽量减少歧义与碎片化。操作步骤联系 Spyder 团队确认用途合理且许可兼容添加文件保留原始版权/法律/署名头若做了非平凡修改将.ciocopyright中的标准 Spyder 版权头复制到原始版权头下方若原始头无格式、仅含版权声明和许可提及将其逐字并入 Spyder 版权头中合适位置。始终确保版权声明按时间升序排列并将 Spyder 版权声明中的年份替换为当前年份。修改许可位置为当前目录或 NOTICE.txt在每个模块 docstring 末尾、以空行分隔加入如下行Adapted from path/to/file/in/original/repo.py of the Project Name url-to-original-github-repo_.例如Adapted from qcrash/_dialogs/gh_login.py of the QCrash Project https://github.com/ColinDuquesnoy/QCrash_.按项目标准转换文件若复制文件位于专属目录将源项目的 LICENSE.txt 及其他法律文件放入该目录并在该目录的__init__.py中提及按 NOTICE.txt 的说明与模板添加条目非代码可见资源图标、字体、动画等或使用 Creative Commons 许可的需在 README 相应章节及 Spyder 的 About 对话框中以与现有条目相同的形式提及。进一步了解仓库CONTRIBUTING.md 末尾罗列了官方文档、下载、社区等外部资源对于本文读者仓库内更有价值的第一手资料包括README.md项目总览与安装方式changelogs/各主版本Spyder-2 至 Spyder-6的变更记录是了解 API 演进历史的最佳入口MAINTENANCE.md 与 REVIEW.md维护与评审流程external-deps/spyder-kernels、python-lsp-server、qtconsole、spyder-remote-services 的源码克隆联合开发的核心区域spyder/api/ 与 spyder/plugins/插件化 API 定义与各功能插件实现binder/environment.yml在线演示环境的依赖锁定。掌握本文的环境搭建、bootstrap.py开发启动、runtests.py测试、跨仓库联合 PR 与 Qt 多继承规范你就具备了成为 Spyder 贡献者的完整技能栈——剩下的就是动手打开第一个 Issue或提交第一个 PR。赞分享开发工具IDE代码编辑器【免费下载链接】spyderOfficial repository for Spyder - The Scientific Python Development Environment项目地址https://gitcode.com/gh_mirrors/sp/spyder点击查看免费下载相关推荐Thumbor 源码开发与贡献指南环境搭建、测试运行与代码规范全解析Thumbor 源码开发与贡献指南环境搭建、测试运行与代码规范全解析 Thumbor 是 globo.com 开源的智能图片缩略图服务项目核心代码见 thu后端图像处理计算机视觉thumbor 开发者实战指南环境搭建、运行、测试与代码规范全解析thumbor 开发者实战指南环境搭建、运行、测试与代码规范全解析 thumbor 是一个基于 Python/Tornado 构建的智能成像 HTTP 服务后端图像处理计算机视觉Repomix 开发者贡献实战指南环境搭建、测试、代码规范与发布全流程解析Repomix 开发者贡献实战指南环境搭建、测试、代码规范与发布全流程解析 导读 本文是面向 Repomix 将整个代码仓库打包为单一 AI 友好文件的命令开发工具MCP 服务AI 应用上一篇Backstage v1.29.0-next.2 变更解读Select 可测试性、Catalog 日志模块与 Scaffolder 检查点机制下一篇Research Grant Review Criteria: 逐条拆解 NSF、NIH、DOE、DARPA 与台湾 NSTC 基金评审机制创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑