贡献者指南#

Note

本文档假定您对使用GitHub拉取请求贡献到开源科学Python项目有一定了解。如果您不了解,请先查看 新贡献者常见问题解答

开发工作流程#

  1. 如果您是第一次贡献者:

    • 前往 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 addgit commit

  1. 测试你的贡献:

    • 在本地运行测试套件(有关详细信息,请参阅 `Testing`_ ):

      PYTHONPATH=. pytest networkx

    • 在提交拉取请求之前在本地运行测试有助于及早发现问题,并减少持续集成系统的负荷。

  2. 确保你的贡献格式正确。

    • 如果你按照步骤1中建议安装了 pre-commit ,所有必要的代码检查应该会在提交时自动运行。如果存在任何格式问题,提交将不会成功,并且代码检查建议将自动应用到补丁中。 只需再次执行 git addgit commit 以接受建议的格式更改。

    • 如果以上步骤因任何原因失败,你也可以通过以下方式在整个代码库上运行代码检查:

      pre-commit run –all-files

  3. 提交你的贡献:

    • 将更改推送回你在GitHub上的分支:

      git push origin bugfix-for-issue-1480

    • 前往GitHub。新分支将显示一个绿色的拉取请求按钮—点击它。

    • 如果你愿意,在 邮件列表 上解释你的更改或请求审查。

  4. 审查流程:

    • 每次拉取请求(PR)更新都会触发一组 持续集成 服务,检查代码是否符合标准并通过所有测试。 这些检查必须通过才能合并你的PR。如果其中一个检查失败,你可以点击“失败”图标(红色叉号)查看失败的原因,并检查构建和测试日志。

    • 审阅者(其他开发人员和感兴趣的社区成员)将在你的PR上写内联和/或一般评论,帮助你改进实现、文档和风格。每个参与项目的开发人员都会经过代码审查,我们已经将其视为友好的对话,我们都从中学习,整体代码质量也得到提升。 因此,请不要让审查使你对贡献产生气馁:它的唯一目的是提高项目的质量,而不是批评(毕竟,我们非常感激你所捐赠的时间!)。

    • 要更新你的PR,请在本地仓库上进行更改并提交。一旦这些更改被推送(到与之前相同的分支),PR将自动更新。

  5. 记录弃用和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
    

    在导入 scipysp 之后:

    import scipy as sp
    

    从顶层 sp 命名空间访问相关的scipy子包,例如:

    sp.sparse.linalg
    

    而不是 from scipy.sparse import linalgimport scipy.sparse.linalg as spla

    例如,许多库都有一个 linalg 子包: nx.linalgnp.linalgsp.linalgsp.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.txtrequirements/example.txt 中列出的依赖项:

pip install -r requirements/extra.txt pip install -r requirements/example.txt

要构建HTML文档,请进入 doc/ 目录并执行:

make html

这将生成一个包含构建文档的 build/html 子目录。如果未安装 extra.txtexample.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行为准则 的约束。

我们还遵循这些政策: