如何贡献


我非常欢迎任何有助于改进和扩展 mlxtend 功能的贡献。

快速贡献者清单

这是 mlxtend(和其他开源项目)典型贡献步骤的快速清单。你可以考虑将此列表复制到本地文本文件(或问题跟踪器)中,并在进行时勾选完成项。

1) 进行并测试代码更改

  1. [ ] 在 GitHub 上打开一个新“问题”以讨论新功能/错误修复
  2. [ ] 从 GitHub 派生 mlxtend 仓库(如果之前没有做过)
  3. [ ] 创建并切换到新的主题分支(请不要在 master 分支中进行修改)
  4. [ ] 实现新功能或应用错误修复
  5. [ ] 在 mlxtend/*/tests 中添加适当的单元测试函数
  6. [ ] 运行 PYTHONPATH='.' pytest ./mlxtend -sv 并确保所有单元测试通过

  7. [ ] 确保新实现的功能具有良好的测试覆盖率

python -m pip install coverage
# test all: 
# coverage run --source=mlxtend --branch -m pytest .
coverage run --source=mlxtend --branch -m pytest mlxtend/<insert_path>
coverage html
  1. [ ] 修改 mlxtend/docs/sources/ 下相应位置的文档

  2. [ ] 在 ./docs/sources/changelog.md 文件中添加关于修改/贡献的说明

2) 检查代码风格

当你提交一个 PR 时,mlxtend 会通过 flak8 和 black 运行代码风格检查。为了让贡献者体验更轻松,我们建议你在将代码推送到仓库之前先在本地检查代码风格。这样可以减少自动化检查器报错并提示你进行修复的可能性。

你可以通过两种方式进行:

选项 A: 手动运行工具

  1. [ ] 通过运行 flake8 ./mlxtend 检查风格问题(在修改代码后,你可能希望再次运行 pytest
  2. [ ] 我们推荐使用 black 根据推荐的风格修改自动格式化代码。在安装 black 后,你可以通过以下方式进行:
black [source_file_or_directory]
  1. [ ] 运行 isort,它会按字母顺序排序导入。我们推荐以下命令:
isort -p mlxtend --line-length 88 --multi-line 3 --profile black mypythonfile.py

选项 B: 使用 pre-commit 钩子(推荐)

mlxtend 的 pre-commit 钩子会在你进行 git commit 之前自动通过 flake8blackisort 检查你的代码。你可以在此处阅读更多关于 pre-commit 钩子的信息。

  1. [ ] 通过 pip install pre-commit 安装 pre-commit 包。
  2. [ ] 在 mlxtend 文件夹中,运行 pre-commit install (只需运行一次)。

3) 提交你的代码

  1. [ ] 将主题分支推送到服务器并创建拉取请求。
  2. [ ] 检查自动化测试是否通过。
  3. [ ] 自动的 PEP8/black 集成可能会提示你在代码风格上进行修改。如果你能应用建议的更改,那就太好了。

贡献者提示

入门 - 创建新问题并派生仓库

  • 如果你还没有 GitHub 帐户,请创建一个以便为本项目做出贡献。
  • 在花费太多时间和精力进行实现之前,请为你遇到的问题提交一个工单,讨论修复或新功能。

  • 从 GitHub Web 界面派生 mlxtend 仓库。

  • 通过执行 git clone https://github.com/<your_username>/mlxtend.gitmlxtend 仓库克隆到你的本地机器。

同步现有派生

如果你之前已经派生了 mlxtend,你可以通过以下方式使你的“派生”与 master 分支同步:

1. 配置一个指向 GitHub 上游仓库的远程仓库

通过执行以下命令列出你的派生仓库当前配置的远程仓库:

$ git remote -v

如果你看到类似以下内容:

origin  https://github.com/<your username>/mlxtend.git (fetch)
origin  https://github.com/<your username>/mlxtend.git (push)

你需要通过以下方式指定一个新的远程 upstream 仓库:

$ git remote add upstream https://github.com/rasbt/mlxtend.git

现在,通过执行以下命令验证你为派生仓库指定的新上游仓库:

$ git remote -v

如果一切配置正确,你应该会看到以下输出:

origin  https://github.com/<your username>/mlxtend.git (fetch)
origin  https://github.com/<your username>/mlxtend.git (push)
upstream    https://github.com/rasbt/mlxtend.git (fetch)
upstream    https://github.com/rasbt/mlxtend.git (push)

2. 同步你的派生仓库

首先,通过执行以下命令获取原始项目 master 分支的更新:

$ git fetch upstream

你应该会看到以下输出:

remote: Counting objects: xx, done.
remote: Compressing objects: 100% (xx/xx), done.
remote: Total xx (delta xx), reused xx (delta x)
Unpacking objects: 100% (xx/xx), done.
From https://github.com/rasbt/mlxtend
 * [new branch]      master     -> upstream/master

这意味着 rasbt/mlxtend master 分支的提交现在存储在本地分支 upstream/master 中。

如果你当前不在本地项目的 master 分支上,执行:

$ git checkout master

最后,通过执行以下命令将 upstream/master 中的更改合并到你的本地 master 分支:

$ git merge upstream/master

这将给你一个看起来类似的输出:

Updating xxx...xxx
Fast-forward
SOME FILE1                    |    12 +++++++
SOME FILE2                    |    10 +++++++
2 files changed, 22 insertions(+),

*主要工作流程 - 在新主题分支中进行更改

下面列出了贡献的9个典型步骤。

1. 讨论功能或修改

在开始编码之前,请在项目的问题跟踪器上讨论新功能、错误修复或对项目的其他修改。在打开“新问题”之前,请快速搜索一下是否已提交了类似的问题。

2. 创建新的功能分支

请避免直接在 master 分支上工作,而是创建一个新的功能分支:

$ git branch <new_feature>

通过执行以下命令切换到新的功能分支:

$ git checkout <new_feature>

3. 开发新功能/错误修复

现在是修改现有代码或向项目贡献新代码的时候了。

4. 测试你的代码

添加相应的单元测试并检查它们是否通过:

$ PYTHONPATH='.' pytest ./mlxtend ---with-coverage

5. 记录更改

请在 mlxtend/docs/sources/changelog.md 文件中添加一个条目。如果是新功能,如果你能在 mlxtend/sources 的相应位置更新文档,那就更好了。

6. 提交更改

当你准备提交更改时,请提供一个有意义的 commit 消息:

$ git add <modifies_files> # or `git add .`
$ git commit -m '<meaningful commit message>'

7. 可选:合并提交(squash commits)

如果你进行了多个较小的提交,如果能将它们合并成一个更大的、总结性的提交,那就太好了。首先,通过以下方式列出你最近的提交:

注意
由于 GitHub UI 的改进,这已不再是必要或鼓励的做法。

$ git log

默认情况下,这将以以下格式列出提交,从最新到最旧:

commit 046e3af8a9127df8eac879454f029937c8a31c41
Author: rasbt <mail@sebastianraschka.com>
Date:   Tue Nov 24 03:46:37 2015 -0500

    fixed setup.py

commit c3c00f6ba0e8f48bbe1c9081b8ae3817e57ecc5c
Author: rasbt <mail@sebastianraschka.com>
Date:   Tue Nov 24 03:04:39 2015 -0500

        documented feature x

commit d87934fe8726c46f0b166d6290a3bf38915d6e75
Author: rasbt <mail@sebastianraschka.com>
Date:   Tue Nov 24 02:44:45 2015 -0500

        added support for feature x

假设将这 3 个提交合并成一个有意义,我们可以执行:

$ git rebase -i HEAD~3

这将打开你的默认 git 编辑器,其内容如下:

pick d87934f added support for feature x
pick c3c00f6 documented feature x
pick 046e3af fixed setup.py

由于 c3c00f6046e3affeature x 的原始提交相关,让我们保留 d87934f 并将随后的 2 个提交合并到这个初始提交中,将行更改为:

pick d87934f added support for feature x
squash c3c00f6 documented feature x
squash 046e3af fixed setup.py

现在,在编辑器中保存更改。退出编辑器将应用 rebase 更改,编辑器将再次打开,提示你输入新的提交消息。在这种情况下,我们可以输入 support for feature x 来总结贡献。

8. 上传更改

通过执行以下命令将你的更改推送到 git 服务器上的主题分支:

$ git push origin <feature_branch>

9. 提交 pull request

在线访问你的 GitHub 仓库,选择新的功能分支,然后提交新的拉取请求


开发者须知

构建文档

文档是使用 MkDocs 构建的;为了确保文档正确渲染,你可以从 mlxtend/docs 目录执行 mkdocs serve 命令在本地查看文档。

例如,

~/github/mlxtend/docs$ mkdocs serve

1. 构建 API 文档

要构建 API 文档,导航到 mlxtend/docs 目录,并通过以下方式执行此目录中的 make_api.py 文件:

~/github/mlxtend/docs$ python make_api.py

这应该会将 API 文档放置到以下两个正确目录中:

  • mlxtend/docs/sources/api_modules
  • mlxtend/docs/sources/api_subpackes

2. 编辑用户指南

“用户指南”中包含代码示例的文档是从 IPython Notebook 文件生成的。编辑后,要将 IPython notebook 文件转换为 markdown,请按照以下步骤操作:

  1. 修改或编辑现有的 notebook。
  2. 执行当前 notebook 中的所有单元格,并确保没有发生错误。
  3. 使用 ipynb2markdown.py 转换器将 notebook 转换为 markdown:
~/github/mlxtend/docs$ python ipynb2markdown.py --ipynb ./sources/user_guide/subpackage/notebookname.ipynb

注意

如果你正在添加新文档,请同时将其包含在 mlxtend/docs/mkdocs.yml 文件中的 pages 部分。

3. 构建文档的静态 HTML 文件

首先,请通过 localhost (https://127.0.0.1:8000/) 检查文档:

~/github/mlxtend/docs$ mkdocs serve

接下来,通过以下方式构建 mlxtend 文档的静态 HTML 文件:

~/github/mlxtend/docs$ mkdocs build --clean

要部署文档,执行:

~/github/mlxtend/docs$ mkdocs gh-deploy --clean

4. 生成文档的 PDF 版本

要生成文档的 PDF 版本,只需 cdmlxtend/docs 目录并执行:

python md2pdf.py

上传新版本到 PyPI

1. 创建新的测试环境

假设我们使用 conda,通过以下方式创建一个新的 python 环境:

$ conda create -n 'mlxtend-testing' python=3 numpy scipy pandas

接下来,通过执行以下命令激活环境:

$ source activate mlxtend-testing

2. 从本地文件安装包

在 mlxtend 主目录中执行以下命令测试安装:

$ pip install . -e

--record files.txt 标志将创建一个 files.txt 文件,列出这些文件的安装位置。

尝试导入包以查看它是否有效,例如,通过执行:

$ python -c 'import mlxtend; print(mlxtend.__file__)'

如果一切正常,通过以下方式删除安装:

$ cat files.txt | xargs rm -rf ; rm files.txt

接下来,测试 pip 是否能够安装这些包。首先,导航到另一个目录,然后从那里安装包:

$ pip uninstall
$ pip install mlxtend

然后再次卸载它:

$ pip uninstall mlxtend

3. 部署包

考虑先将包部署到 PyPI 测试服务器。设置说明可以在此处找到。

首先,如果尚未安装 Twine,请安装它。例如,使用以下命令安装所有推荐的包:

$ python -m pip install twine build

其次,创建发行版。默认情况下,这会在 ./dist 目录中创建一个 sdist 和一个 wheel。

$ python -m build

安装 wheel 和 sdist 以确保它们正常工作。发行文件的名称会随着每个版本而改变。

python -m pip install ./dist/mlxtend-0.23.0.dev0.tar.gz --force-reinstall
python -m pip install ./dist/mlxtend-0.23.0.dev0-py3-none-any.whl --force-reinstall
python -m pip uninstall mlxtend

第三,将包上传到测试服务器:

$ twine upload --repository-url https://upload.pypi.org/legacy dist/

然后,安装它并查看它是否有效:

$ pip install -i https://testpypi.python.org/pypi mlxtend

接下来,按照如下方式再次卸载它:

$ pip uninstall mlxtend

第四,在这次模拟运行成功后,使用“真正的”PyPI 重复此过程:

$ python -m twine upload  dist/*

4. 删除虚拟环境

最后,为了清理本地驱动器,通过以下方式删除虚拟测试环境:

$ conda remove --name 'mlxtend-testing' --all

注意:

如果你遇到类似以下错误:

HTTPError: 403 Forbidden from https://upload.pypi.org/legacy/

确保你安装了最新版本的 twine(对我来说,通过 conda 卸载并通过 pip 安装解决了问题)。

5. 更新 conda-forge 配方

一旦新版本的 mlxtend 上传到 PyPI,通过适当更改 recipe/meta.yaml 文件中的版本号来更新 https://github.com/conda-forge/mlxtend-feedstock 上的 conda-forge 构建配方。