Scrapy 贡献指南Bug 报告、PR 提交与测试、文档规范全解【免费下载链接】scrapyScrapy, a fast high-level web crawling scraping framework for Python.项目地址: https://gitcode.com/GitHub_Trending/sc/scrapy本文基于 Scrapy 官方贡献文档 docs/contributing.rst 整理并深入扩充覆盖从 Bug 报告、选题、编写补丁到提交 Pull Request、运行 tox 测试、遵守文档与代码风格规范的完整贡献工作流。读完后你将知道如何在 Scrapy 仓库中以符合维护者要求的方式提交一个高质量的补丁包括 Ruff 格式化、pre-commit 钩子、coverage_ignore_pyobjects文档覆盖率豁免、versionadded/versionchanged指令的使用以及 mitmproxy 相关测试的运行前提。一、参与 Scrapy 贡献的主要途径Scrapy 接受多种形式的贡献官方文档明确列出以下几类报告 Bug 与功能请求在 issue tracker 中提交遵循下文“报告 Bug 的规范”提交补丁为新功能或 Bug 修复提供代码要求通过全部单元测试并附带测试用例撰写博客分享你在实际项目中使用 Scrapy 的经验为新手提供更多示例在社区交流参与 Scrapy subreddit分享改进想法解答他人问题在 Stack Overflow 上回答带scrapy标签的问题。需要注意的社区约定参与本项目即表示同意遵守 行为准则不可接受的行为应通过 opensourcezyte.com 上报。二、报告 Bug 的规范官方文档强调高质量的 Bug 报告非常有用提交前应遵循以下指南先查 FAQ确认问题是否已有解答一般性使用问题请到 Stack Overflow 提问使用scrapy标签而不是提 issue检查 open issues避免重复报告。若已有人报告不要弃置该工单而是阅读历史记录与评论补充有用信息或直接提交一个包含修复的 Pull Request搜索 scrapy-users 邮件列表与 Scrapy subreddit确认该现象是否已被讨论、是否确属 Bug也可在#scrapyIRC 频道询问写完整、可复现、具体的 Bug 报告——测试用例越小越好。其他开发者没有你的项目环境请附上复现所需的全部相关文件参考 Stack Overflow 的“最小完整可验证示例MCVE”原则最理想的方式是提交一个 PR在 Scrapy 测试套件中加入一个失败failing的测试用例来复现问题——即使你并不打算亲自修复这样做也极有价值附上scrapy version -v的输出让开发者明确知道出错的版本与平台这往往直接决定能否复现或是否已被修复。该命令由 scrapy/commands/version.py 实现。安全类问题有特殊通道安全漏洞只应报告给 scrapy-securitygooglegroups.com。这是一个仅对受信任的 Scrapy 开发者开放的私有列表其存档不公开。三、如何寻找可贡献的工作如果你已决定贡献但不确定做什么官方给出了几条找活的途径GitHub 贡献页查看标记为good first issue的 open issue适合新人入手同时有help wanted标签的 issue但其中一些需要熟悉 Scrapy 代码库此外任何未标记discuss的 issue 都可以认领文档类 issue喜欢写文档的话带docs标签的 issue 同样适合部分同样需要熟悉代码库提升测试覆盖率喜欢写自动化测试的话可以着手提升覆盖率代码清理欢迎修复静态分析工具发现的问题。可查阅 pyproject.toml 中被静默ignore / per-file-ignores的规则——这些是“可能需要处理”的待办。文档特别提示有些被静默的规则是项目刻意不处理的通常附有注释说明原因注意与“仅解释规则含义”的注释区分开。认领工作的规则提问前先读完整个 issue 讨论串包括其中关联的 issue 与 PR项目不做 issue 分配你也不需要公告自己将开始工作某个 issue——直接写补丁即可不要因为某个 issue 已有一个 open PR 就放弃。先检查该 PR 是否活跃即使活跃若你认为有更好的实现方案也可以自由提交自己方案的 PR若要处理一个尚无 open issue 的问题为代码覆盖率或代码清理直接创建 PR不要为此开 issue不要同时立刻开 issue 和 PR。要么先开 issue 获取“这个问题是否值得处理”的反馈反馈积极后再开 PR要么直接开 PR让讨论基于代码进行。不要为了添加 docstring 而添加 docstring也不要仅为解决被静默的 Ruff 规则而补 docstring。docstring 只应在对读者有实质价值时存在解释单看代码不易理解的内容、概括冗长难读的长实现、说明调用方上下文或指出被调用代码中故意不捕获的异常不要写“为了碰到某行代码以提升行覆盖率”而大量 mock 的测试。虽然项目追求高测试覆盖率但测试应面向真实场景、以最少 mock 编写通常更倾向于端到端测试。四、编写补丁Writing patches的关键要求补丁写得越好被接受和合并的概率越高、速度越快。官方列出的要求是最小化改动一个补丁只做一件事小补丁更容易评审和合并。若包含多处改动或修复请每个改动单独提交一个补丁不要把多个改动塞进一个补丁大改动可考虑使用 patch queue补丁队列方式管理通过全部单元测试运行方式见下文“运行测试”一节附带测试用例为修复的 Bug 或新增的功能各加至少一个测试用例公共 API 变更需同步文档若添加或修改了受文档记录的公共 API必须在同一补丁中包含文档变更规则见下文“文档策略”私有 API 需加入文档覆盖率豁免若新增的是私有 API需在 docs/conf.py 的coverage_ignore_pyobjects变量中添加一条正则把该私有 API 排除在文档覆盖率检查之外。验证方式tox -e docs-coverage该环境对应 tox.ini 中的[testenv:docs-coverage]其实际执行的是sphinx-build -b coverage . {envtmpdir}/coverage即启用 Sphinx 的 coverage 构建器检查文档覆盖情况。coverage_ignore_pyobjects中现存的条目都是“为什么豁免”的范例例如引自 docs/conf.py\bContract\.add_(pre|post)_hook$add_pre_hook/add_post_hook对合约开发者应是透明的文档只暴露pre_hook/post_hook^scrapy\.downloadermiddlewares\.\w*?\.(\w*?Middleware|DownloaderStats)\.下载器中间件的方法不做文档因为用户通过 Scrapy 设置settings控制它们只需文档化类本身^scrapy\.dupefilters\.[A-Z]\w*?\.(from_crawler|request_seen|open|close|log)$重复请求过滤器的接口方法已在DUPEFILTER_CLASS设置文档的接口说明中覆盖。移除弃用代码前先确认时间若你要移除被弃用deprecated的代码先确认距离引入弃用的版本发布至少已过 1 年12 个月详见 弃用策略。该策略明确弃用功能至少保留 1 年支持一年后的新发布可以移除所有移除都会在 release notes 中显式列出。Scrapy 的弃用警告基础设施如create_deprecated_class、deprecate_object等位于 scrapy/utils/deprecate.py。五、提交补丁Submitting patches的完整流程官方推荐的提交方式是向 GitHub 发起 Pull Request可选择先开一个新 issue。要点如下1. 说明修了什么或新增了什么。解释它是什么、为什么需要。信息越多核心开发者越容易理解和接受。2. 关联 issue。若 PR 旨在解决某个 open issue在描述中用关键字链接例如Resolves #1233. 可以先讨论但最好手握一个补丁。在正式写补丁前可以先讨论新想法比如在 Scrapy subreddit但始终建议手头有一个可用来说明观点的补丁——它可以足够简单仅用于示意想法文档和测试留到想法被验证之后再补。4. 接手停滞的 PR 是被鼓励的。若你发现问题已有一个因故停滞的 PR方向正确但维护者提出的修改意见原作者没来得及处理可以把它捡起来开一个新 PR包含原 PR 的所有 commit再加上回应意见的修改。保留原作者的 commit 以体现署名这不算失礼对项目帮助很大。5. 把他人 PR 拉到本地的命令git fetch upstream pull/$PR_NUMBER/head:$BRANCH_NAME_TO_CREATE其中upstream替换为 Scrapy 仓库的远端名$PR_NUMBER为 PR 编号$BRANCH_NAME_TO_CREATE为你要创建的本地分支名。6. PR 标题规范短但描述性强。官方给出的例子对于 bug #411 “Scrapy hangs if an exception raises in start_requests”标题应写 Fix hanging when exception occurs in start_requests (#411)而不是 Fix for #411。完整的标题让 issue tracker 更易快速扫读。7. 外观性改动与功能性改动分开提交。PEP 8 合规、删除未使用 import 之类的美化提交应与功能性改动放在不同 commit 中这样 PR 更易评审、也更容易被合并。六、代码风格与 pre-commit 钩子Ruff 格式化Scrapy 使用 Ruff 做代码格式化pre-commit 配置中装有对应钩子会在每次 commit 前自动格式化。也可以手动运行tox -e pre-commit该环境在 tox.ini 中定义为pre-commit run --all-files。Ruff 的完整规则集在 pyproject.toml 的[tool.ruff.lint]中配置extend-select启用了 flake8-builtins、flake8-async、flake8-bugbear、pydocstyleD约定为 PEP 257、pyupgrade、flake8-bandit 等约 30 组规则ignore列表则记录了刻意豁免的规则如全部 docstring 缺失类 D10x——呼应前文“不为了 docstring 而 docstring”的政策、per-file-ignores列出了待逐个处理的具体豁免。另一条代码风格约定不要在贡献的代码里署自己的名字——git 已提供足够的元数据标识作者作者信息应通过 git 的 user.name/user.email 配置。pre-commit 安装与钩子清单Scrapy 使用 pre-commit 在每次提交前自动处理简单代码问题。在本地 fork 的克隆仓库根目录执行安装 pre-commit运行pre-commit install此后每次git commit都会触发检查发现问题时中止提交要么自动修复此时直接再次 commit 即可成功要么仅报告、需手动处理。从 ​.pre-commit-config.yaml 可以确认当前实际启用的钩子及版本钩子作用ruff-check --fixRuff 静态检查并自动修复ruff-formatRuff 代码格式化blacken-docs用 Black 格式化文档中的 Python 代码块end-of-file-fixer保证文件以换行结尾trailing-whitespace清除行尾空白sphinx-lint检查 RST 文档语法sphinx-scrapyScrapy 定制 Sphinx 检查含 intersphinx 配置zizmor检查 GitHub Actions workflow 安全/正确性配置中还排除了docs/_static、docs/_tests与tests/sample_data目录因为这些是静态资源与测试数据。七、文档策略Documentation policies官方对“什么内容写在哪里”有明确分工API 参考文档用 docstring类、方法等 API 成员使用 docstring并保证 Sphinx 文档通过autodoc扩展拉取这些 docstring。API 参考文档应遵循 docstring 约定PEP 257且对 IDE 友好简短、切题、可附短示例教程与主题类文档写在docs/目录包括那些虽针对某个 API 成员、但超出 API 参考范畴的内容避免复制粘贴凡是 docstring 已覆盖的内容一律用autodoc拉取不要把 docstring 重复抄进docs/目录的文件中versionadded/versionchanged指令涉及新增或修改功能的文档更新必须使用 Sphinx 的这两个指令且版本号一律写VERSION占位符——发布前它会被替换成真实版本号当 Scrapy 发布新的主版本或次版本时早于 3 年的这些指令会被移除弃用文档要随弃用而删被弃用功能的文档必须在功能弃用的同时删除以免新读者踩坑新弃用项与移除项在 release notesNEWS中记录。docs/conf.py 中autodoc_member_order bysource等配置也值得注意API 文档按源码顺序呈现贡献 docstring 时应把说明放在定义处而不是文档目录。八、测试体系用 tox 运行 pytestScrapy 的测试基于 pytest运行测试需要 tox。官方文档给出的命令与当前 tox.ini 的实际配置互相印证如下。运行全部测试tox[testenv]的默认命令为pytest --cov-configpyproject.toml --covscrapy ... scrapy tests --doctest-modules即同时收集scrapy/包与tests/目录的用例并开启覆盖率统计。运行单个测试文件tox -- tests/test_loader.py指定 tox 环境用-e name指定 tox.inienvlist中的环境名。当前仓库的envlist覆盖py310py315、pypy3、min最低依赖、min-extra-deps、default-reactor、no-reactor、botocore、docs、docs-tests、docs-links、docs-coverage、pre-commit、pylint、mypy、benchmark等环境。例如用 Python 3.10 运行tox -e py310可以指定逗号分隔的多个环境并用 tox 的并行模式并行执行tox -e py39,py310 -p auto注意当前envlist中已不含 py39环境名请以仓库内 tox.ini 为准。向 pytest 传参通过--之后的参数把选项传给 pytest。由于--会覆盖tox.ini中定义的默认位置参数必须把默认位置参数scrapy tests一并写出来tox -- scrapy tests -x # 首个失败即停配合 pytest-xdist 插件并行跑满所有 CPU 核心tox -e py310 -- scrapy tests -n auto覆盖率报告安装 coveragepip install coverage后运行coverage report更多输出形式html、xml 等参见coverage --help。需要 mitmdump 的测试部分测试需要mitmdump可执行文件来自 mitmproxy来针对一个功能完整的代理服务器测试找不到时这些测试会被跳过。mitmproxy被有意不作为测试依赖装入测试 venv避免依赖冲突。让相关测试跑起来的三种方式安装mitmproxy使mitmdump进入PATH例如用 pipxpipx install mitmproxy或 uvuv tool install mitmproxy环境中已安装 uv 时测试会自动执行uvx --from mitmproxy mitmdump设置环境变量MITMDUMP指向某个mitmdump可执行文件路径。tox.ini 的passenv中显式列出了MITMDUMP证明该环境变量会透传进 tox 虚拟环境代理测试的基础设施见 tests/mockserver/mitm_proxy.py 与 tests/mockserver/mitm_proxy_addon.py。其他值得一提的 tox 环境docs-tests在docs/目录运行 pytest验证文档中的代码块配合 docs/conftest.py 与 sybil 插件docs-linkssphinx-build -W -b linkcheck把链接检查错误升级为构建失败no-reactor/default-reactor通过--reactornone/--reactordefault参数分别验证无 Twisted reactor 与默认 reactor 两种运行模式对应pytest-twisted与pytest-asynciomin把依赖钉在最低兼容版本上如Twisted21.7.0、lxml4.6.4并设置_SCRAPY_MINtrue用于守护最低支持线。九、编写测试的规范与目录约定任何功能——包括新特性与 Bug 修复——都必须附带测试用例希望补丁尽快被接受请务必包含测试。Scrapy 使用单元测试全部位于 tests/ 目录。模块命名惯例是与所测模块的完整路径相对应。例如item loaders 代码位于scrapy.loader实现见 scrapy/loader/init.py其单元测试位于tests/test_loader.py这一“镜像路径”约定在整个 tests/ 目录中成立tests/test_core_engine*、tests/test_downloadermiddleware_retry.py等文件名分别对应scrapy/core/、scrapy/downloadermiddlewares/下的实现。写测试时还应遵循第三节的政策面向真实场景、最小化 mock、优先端到端测试tests/ 下的目录如CrawlerProcess/、CrawlerRunner/下的大量独立进程脚本正是这种端到端风格的体现。十、小结一个补丁从动笔到合并的检查清单结合全文提交 Scrapy 补丁前可对照以下清单改动最小化一件事一个补丁美化 commit 与功能 commit 分离pre-commit install已就位ruff-check、ruff-format与文档 lint 全部通过tox全量测试通过并为新行为附了tests/下的镜像命名测试公共 API 变更已在docs/中同步且使用了versionadded/versionchangedVERSION占位符私有 API 已加入 docs/conf.py 的coverage_ignore_pyobjectstox -e docs-coverage验证通过移除弃用代码前确认已满足 弃用策略 的 12 个月窗口PR 标题描述性强并关联 issueResolves #123描述说清了“是什么、为什么需要”。【免费下载链接】scrapyScrapy, a fast high-level web crawling scraping framework for Python.项目地址: https://gitcode.com/GitHub_Trending/sc/scrapy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考