贡献者指南#
Note
本文档假定您对使用GitHub拉取请求贡献到开源科学Python项目有一定了解。如果您不了解,请先查看 新贡献者常见问题解答 。
开发工作流程#
如果您是第一次贡献者:
前往 networkx/networkx 并点击 “fork” 按钮以创建项目的您自己的副本。
将项目克隆到您的本地计算机:
git clone git@github.com:your-username/networkx.git
导航到 networkx 文件夹并添加上游存储库:
git remote add upstream git@github.com:networkx/networkx.git
现在,您有以下命名的远程存储库:
upstream
,指向networkx
存储库origin
,指向您个人的分支
接下来,您需要设置构建环境。 这里是两个流行环境管理器的说明:
venv
(基于pip)# 创建名为 ``networkx-dev`` 的虚拟环境,位于同名目录中 python -m venv networkx-dev # 激活它 source networkx-dev/bin/activate # 安装 networkx 的主要开发和运行时依赖项 pip install -r requirements/default.txt -r requirements/test.txt -r requirements/developer.txt # # (可选) 安装 pygraphviz 和 pydot 包 # 这些包要求您的系统已正确配置 # 不同系统的配置方式各不相同 # pip install -r requirements/extra.txt # # 从源代码构建并安装 networkx pip install -e . # 测试您的安装 pytest --pyargs networkx
conda
(Anaconda 或 Miniconda)# 创建名为 ``networkx-dev`` 的 conda 环境 conda create --name networkx-dev # 激活它 conda activate networkx-dev # 安装 networkx 的主要开发和运行时依赖项 conda install -c conda-forge --file requirements/default.txt --file requirements/test.txt --file requirements/developer.txt # # (可选) 安装 pygraphviz 和 pydot 包 # 这些包要求您的系统已正确配置 # 不同系统的配置方式各不相同 # conda install -c conda-forge --file requirements/extra.txt # # 从源代码安装 networkx pip install -e . # 测试您的安装 pytest --pyargs networkx
最后,我们建议您安装 pre-commit,用于检查您的代码是否符合格式指南:
pre-commit install
2. 开发您的贡献: * 从上游拉取最新更改:
git checkout main git pull upstream main
为你想要处理的功能创建一个分支。由于分支名称将出现在合并消息中,请使用一个明智的名称,比如’bugfix-for-issue-1480’:
git checkout -b bugfix-for-issue-1480 main
随着进展在本地进行提交(
git add
和git commit
)
测试你的贡献:
在本地运行测试套件(有关详细信息,请参阅 `Testing`_ ):
PYTHONPATH=. pytest networkx
在提交拉取请求之前在本地运行测试有助于及早发现问题,并减少持续集成系统的负荷。
确保你的贡献格式正确。
如果你按照步骤1中建议安装了
pre-commit
,所有必要的代码检查应该会在提交时自动运行。如果存在任何格式问题,提交将不会成功,并且代码检查建议将自动应用到补丁中。 只需再次执行git add
和git commit
以接受建议的格式更改。如果以上步骤因任何原因失败,你也可以通过以下方式在整个代码库上运行代码检查:
pre-commit run –all-files
提交你的贡献:
将更改推送回你在GitHub上的分支:
git push origin bugfix-for-issue-1480
前往GitHub。新分支将显示一个绿色的拉取请求按钮—点击它。
如果你愿意,在 邮件列表 上解释你的更改或请求审查。
审查流程:
每次拉取请求(PR)更新都会触发一组 持续集成 服务,检查代码是否符合标准并通过所有测试。 这些检查必须通过才能合并你的PR。如果其中一个检查失败,你可以点击“失败”图标(红色叉号)查看失败的原因,并检查构建和测试日志。
审阅者(其他开发人员和感兴趣的社区成员)将在你的PR上写内联和/或一般评论,帮助你改进实现、文档和风格。每个参与项目的开发人员都会经过代码审查,我们已经将其视为友好的对话,我们都从中学习,整体代码质量也得到提升。 因此,请不要让审查使你对贡献产生气馁:它的唯一目的是提高项目的质量,而不是批评(毕竟,我们非常感激你所捐赠的时间!)。
要更新你的PR,请在本地仓库上进行更改并提交。一旦这些更改被推送(到与之前相同的分支),PR将自动更新。
记录弃用和API更改
如果您的更改引入了任何API修改,包括弃用,请确保PR带有
type: API
标签。要设置一个函数进行弃用:
使用弃用警告来警告用户。例如:
msg = “curly_hair is deprecated and will be removed in v3.0. Use sum() instead.” warnings.warn(msg, DeprecationWarning)
在
networkx/conftest.py
中添加一个警告过滤器:- warnings.filterwarnings(
“ignore”, category=DeprecationWarning, message=<start of message>
)
在
doc/developer/deprecations.rst
中为团队添加一个弃用功能的提醒。例如:* 在 ``utils/misc.py`` 中移除 ``generate_unique_node`` 和相关测试。
Note
对于审阅者:确保合并消息中简要描述了更改,并且如果PR关闭了一个问题,请添加类似于“Closes #123”的内容,其中123是问题编号。
与 upstream main
的分支偏离#
如果GitHub指示您的Pull Request分支无法自动合并,请将主分支合并到您的分支中:
git fetch upstream main git merge upstream/main
如果出现任何冲突,需要在继续之前解决冲突。使用以下命令查看存在冲突的文件:
git status
会显示类似以下消息:
- Unmerged paths:
(use “git add <file>…” to mark resolution)
both modified: file_with_conflict.txt
在冲突的文件中,您会找到类似以下部分:
<<<<<<< HEAD 分支中文本的样子 ======= 主分支中文本的样子 >>>>>>> main
选择应保留的文本版本,并删除其余部分:
分支中文本的样子
现在,添加已修复的文件:
git add file_with_conflict.txt
一旦解决了所有合并冲突,执行:
git commit
Note
高级Git用户可能希望使用rebase而不是merge,但我们无论如何都会压缩和合并PR。
指南#
所有代码都应该有测试。
所有代码都应该按照与NumPy和SciPy相同的 标准 进行文档编写。
所有更改都会经过审查。如果您的Pull Request没有得到回应,请在 邮件列表 上询问。
默认依赖项列在
requirements/default.txt
中,额外(即可选)依赖项列在requirements/extra.txt
中。
我们通常不会经常添加新的默认依赖项和额外依赖项。如果您考虑添加具有依赖关系的代码,您应首先考虑添加一个示例图库。通常,新提议的依赖项应首先作为额外依赖项添加。额外依赖项应该易于在所有平台上安装,并且被广泛使用。新的默认依赖项应该易于在所有平台上安装,在社区中被广泛使用,并且已经展示了在NetworkX中广泛使用的潜力。
使用以下导入约定:
import numpy as np import scipy as sp import matplotlib as mpl import matplotlib.pyplot as plt import pandas as pd import networkx as nx
在导入
scipy
的sp
之后:import scipy as sp
从顶层
sp
命名空间访问相关的scipy子包,例如:sp.sparse.linalg
而不是
from scipy.sparse import linalg
或import scipy.sparse.linalg as spla
。例如,许多库都有一个
linalg
子包:nx.linalg
、np.linalg
、sp.linalg
、sp.sparse.linalg
。上述导入模式使得任何特定linalg
实例的来源明确。在
networkx/utils/decorators.py
中使用装饰器not_implemented_for
来指定一个函数不接受’directed’、’undirected’、’multigraph’或’graph’。装饰函数的第一个参数应该是要检查的图对象。@nx.not_implemented_for("directed", "multigraph") def function_not_for_MultiDiGraph(G, others): # 仅适用于既是有向图又是多重图的函数 pass @nx.not_implemented_for("directed") @nx.not_implemented_for("multigraph") def function_only_for_Graph(G, others): # 仅适用于非有向图或非多重图的函数 pass
测试#
networkx
有一个广泛的测试套件,确保在您的系统上正确执行。在合并拉取请求之前,测试套件必须通过,并且应添加测试以覆盖对代码库的任何修改。
我们使用 pytest 测试框架,测试位于各种 networkx/submodule/tests
文件夹中。
运行所有测试:
$ PYTHONPATH=. pytest networkx
或特定子模块的测试:
$ PYTHONPATH=. pytest networkx/readwrite
或特定文件的测试:
$ PYTHONPATH=. pytest networkx/readwrite/tests/test_edgelist.py
或该文件中的单个测试:
$ PYTHONPATH=. pytest networkx/readwrite/tests/test_edgelist.py::test_parse_edgelist_with_data_list
使用 --doctest-modules
运行doctests。
例如,运行所有测试和所有doctests 使用:
$ PYTHONPATH=. pytest --doctest-modules networkx
模块的测试应该理想情况下覆盖该模块中的所有代码,即语句覆盖率应达到100%。
要测量测试覆盖率,请运行:: ```rst $ PYTHONPATH=. pytest –cov=networkx networkx
这将打印一个报告,每个文件在 networkx
中都会有一行,详细说明测试覆盖率:
Name Stmts Miss Branch BrPart Cover
----------------------------------------------------------------------------------
networkx/__init__.py 33 2 2 1 91%
networkx/algorithms/__init__.py 114 0 0 0 100%
networkx/algorithms/approximation/__init__.py 12 0 0 0 100%
networkx/algorithms/approximation/clique.py 42 1 18 1 97%
...
添加测试#
如果您**是测试新手**,请查看现有的测试文件,以获取示例操作。 不要因为测试而阻止您提交贡献! 如果您不确定如何做或遇到问题,请提交您的拉取请求。 我们将帮助您创建测试并在代码审查期间解决任何问题。
图像比较#
要运行图像比较:
$ PYTHONPATH=. pytest --mpl --pyargs networkx.drawing
``--mpl`` 告诉 ``pytest`` 使用 ``pytest-mpl`` 来比较生成的图与存储在 ``networkx/drawing/tests/baseline`` 中的基准图。
要添加新测试,将一个返回 Matplotlib 图(或具有 savefig 方法的任何图形对象)的测试函数添加到 networkx/drawing/tests
中,并进行如下装饰:
@pytest.mark.mpl_image_compare
def test_barbell():
fig = plt.figure()
barbell = nx.barbell_graph(4, 6)
# 确保修复任何随机性
pos = nx.spring_layout(barbell, seed=42)
nx.draw(barbell, pos=pos)
return fig
然后创建一个基准图像以供以后比较:
$ pytest -k test_barbell --mpl-generate-path=networkx/drawing/tests/baseline
Note
为了避免存储库大小过大,我们更倾向于限制包含的基准图像的大小和数量。
并进行测试:
$ pytest -k test_barbell --mpl
文档#
我们使用Sphinx来生成API和参考文档。
可以在以下网址找到预构建版本:
分别适用于稳定版本和最新版本(即开发版本)。
指令#
在安装NetworkX及其依赖项后,通过进入根目录并执行以下命令安装构建文档所需的Python包:
pip install -r requirements/doc.txt
构建示例画廊还需要安装 requirements/extra.txt
和 requirements/example.txt
中列出的依赖项:
pip install -r requirements/extra.txt pip install -r requirements/example.txt
要构建HTML文档,请进入 doc/
目录并执行:
make html
这将生成一个包含构建文档的 build/html
子目录。如果未安装 extra.txt
和 example.txt
中的依赖项,则可以通过以下方式构建HTML文档而不生成图形:
make html-noplot
要构建PDF文档,请输入:
make latexpdf
您需要安装LaTeX才能执行此操作。
添加示例#
- 画廊示例由
sphinx-gallery 管理。
示例画廊的源文件是 examples/
中的 .py
脚本,生成一个或多个图。
当构建文档时,sphinx-gallery 会自动执行它们。输出将被收集并组装到画廊中。
在本地构建示例画廊需要在开发环境中安装 requirements/example.txt
中的额外依赖项。
您可以通过将新的 .py
文件放置在存储库的 examples
目录中的一个目录中来**添加新**绘图。查看其他示例以了解格式。
Note
画廊示例应以 plot_
开头,例如 plot_new_example.py
``` 创建良好画廊图的一般指导原则:
示例应突出显示单个特性/命令。
尽量使示例尽可能简单。
示例所需的数据应包含在同一目录和示例脚本中。
添加注释以解释从代码中阅读不明显的事物。
描述您展示的特性并链接到文档的其他相关部分。
添加参考文献#
如果您正在贡献新算法(或改进当前算法),函数文档字符串中还应提供参考文献或资源。 对于已发表的论文引用,我们尽量遵循 芝加哥引文风格 。 在此风格中生成引文的最快方法是在 Google Scholar 上搜索论文,然后点击“cite”按钮。 它将弹出该论文的引文以多种格式呈现,并复制“芝加哥”风格。
我们更倾向于为URL添加DOI链接。如果DOI链接指向了文章的付费版本,我们更喜欢添加指向arXiv版本(如果有的话)或文章的任何其他公开可访问副本的链接。
参考文献的示例:
.. [1] Cheong, Se-Hang, and Yain-Whar Si. "Force-directed algorithms for schematic drawings and
placement: A survey." Information Visualization 19, no. 1 (2020): 65-91.
https://doi.org/10.1177%2F1473871618821740
如果资源以PDF/DOCX/PPT形式上传到网络上(讲座笔记、演示文稿),最好使用 wayback machine 创建资源的快照并链接到互联网档案馆链接。 资源的URL可能会更改,这会导致文档中的链接无法访问。
在文档中使用数学公式和Latex格式#
在包含数学符号或公式的文档字符串中使用原始字符串( r"""
)以确保正确呈现。
虽然LaTeX格式可以改善呈现文档的外观,但最好保持简单和可读。
数学公式的示例:
.. math::
Ax = \lambda x
一些内联数学:
这些是\d-正则图的Cheeger不等式:
$\frac{d- \lambda_2}{2} \leq h(G) \leq \sqrt{2d(d- \lambda_2)}$
这些是d-正则图的Cheeger不等式: \(\frac{d- \lambda_2}{2} \leq h(G) \leq \sqrt{2d(d- \lambda_2)}\)
错误#
请在GitHub上 报告错误 。
政策#
与项目的所有互动都受到 NetworkX行为准则 的约束。
我们还遵循这些政策: