Python 开发#

此页面提供适用于所有平台的 Python 开发通用指南和源代码构建说明。

代码风格#

我们遵循与 pandas 项目 类似的 PEP8 代码风格。要检查代码风格问题,请使用 Archery 子命令 lint

$ pip install -e "arrow/dev/archery[lint]"
$ archery lint --python

某些问题可以通过传递 --fix 选项来自动修复。

$ archery lint --python --fix

Python 代码库还包含一些 C++ 文件。要修复这些文件中的格式,请添加 --clang-format 选项。

$ archery lint --python --clang-format --fix

单元测试#

我们正在使用 pytest 来开发我们的单元测试套件。构建项目后(见下文),您可以像这样运行其单元测试:

$ pushd arrow/python
$ python -m pytest pyarrow
$ popd

运行单元测试所需的包依赖项位于 requirements-test.txt 中,如果需要,可以使用 pip install -r requirements-test.txt 安装。

如果在尝试运行测试时,pyarrow._lib 或其他 PyArrow 模块出现导入错误,请运行 python -m pytest arrow/python/pyarrow 并检查 pyarrow 的可编辑版本是否已正确安装。

该项目有一些用于其测试套件的自定义命令行选项。例如,某些测试默认情况下是禁用的。要查看所有选项,请运行:

$ python -m pytest pyarrow --help

并查找“自定义选项”部分。

注意

有一些底层测试直接用 C++ 编写。这些测试在 pyarrow/src/arrow/python/python_test.cc 中实现,但它们也被包装在一个基于 pytest测试模块 中,作为 PyArrow 测试套件的一部分自动运行。

测试组#

我们有许多测试使用 pytest 标记分组在一起。其中一些默认情况下是禁用的。要启用测试组,请传递 --$GROUP_NAME,例如 --parquet。要禁用测试组,请添加前缀 disable,例如 --disable-parquet。要**仅**运行特定组的单元测试,请添加前缀 only-,例如 --only-parquet

测试组目前包括:

  • dataset:Apache Arrow Dataset 测试

  • flight:Flight RPC 测试

  • gandiva:Gandiva 表达式编译器测试(使用 LLVM)

  • hdfs:使用 libhdfs 访问 Hadoop 文件系统的测试

  • hypothesis:使用 hypothesis 模块生成随机测试用例的测试。请注意,由于 pytest 的一个怪癖,--hypothesis 不起作用,因此您必须传递 --enable-hypothesis

  • large_memory:需要大量系统内存的测试

  • orc:Apache ORC 测试

  • parquet:Apache Parquet 测试

  • s3:Amazon S3 测试

  • tensorflow:涉及 TensorFlow 的测试

文档测试 (Doctest)#

我们正在使用 doctest 来检查文档字符串示例是否是最新的和正确的。您也可以通过运行以下命令在本地执行此操作:

$ pushd arrow/python
$ python -m pytest --doctest-modules
$ python -m pytest --doctest-modules path/to/module.py # checking single file
$ popd

用于 .py 文件,或

$ pushd arrow/python
$ python -m pytest --doctest-cython
$ python -m pytest --doctest-cython path/to/module.pyx # checking single file
$ popd

用于 .pyx.pxi 文件。在这种情况下,您还需要安装 pytest-cython 插件。

基准测试#

要运行基准测试,请参阅 基准测试

在 Linux 和 macOS 上构建#

系统要求#

在 macOS 上,任何现代 XCode(6.4 或更高版本;当前版本为 13)或 Xcode 命令行工具 (xcode-select --install) 就足够了。

在本指南中,Linux 上至少需要 gcc 4.8 或 clang 3.7。您可以通过运行以下命令检查您的版本:

$ gcc --version

如果系统编译器早于 gcc 4.8,则可以使用 $CC$CXX 环境变量将其设置为较新版本:

$ export CC=gcc-4.8
$ export CXX=g++-4.8

环境设置和构建#

首先,让我们克隆 Arrow git 仓库:

$ git clone https://github.com/apache/arrow.git

拉取测试数据并设置环境变量:

$ pushd arrow
$ git submodule update --init
$ export PARQUET_TEST_DATA="${PWD}/cpp/submodules/parquet-testing/data"
$ export ARROW_TEST_DATA="${PWD}/testing/data"
$ popd

使用 Conda#

conda 包管理器允许将 Arrow C++ 和 PyArrow 的构建时依赖项安装为预构建的二进制文件,这可以使 Arrow 开发更轻松、更快捷。

让我们创建一个 conda 环境,其中包含来自 conda-forge 的所有 C++ 构建和 Python 依赖项,目标是针对 Python 3.10 进行开发:

在 Linux 和 macOS 上:

$ conda create -y -n pyarrow-dev -c conda-forge \
       --file arrow/ci/conda_env_unix.txt \
       --file arrow/ci/conda_env_cpp.txt \
       --file arrow/ci/conda_env_python.txt \
       --file arrow/ci/conda_env_gandiva.txt \
       compilers \
       python=3.10 \
       pandas

截至 2019 年 1 月,在许多 Linux 发行版上都需要 compilers 包才能使用 conda-forge 中的包。

完成此操作后,您现在可以激活 conda 环境:

$ conda activate pyarrow-dev

对于 Windows,请参阅下面的 在 Windows 上构建 部分。

我们需要设置一些环境变量,让 Arrow 的构建系统了解我们的构建工具链:

$ export ARROW_HOME=$CONDA_PREFIX

使用系统和捆绑的依赖项#

警告

如果您使用 Anaconda 发行版或 Miniconda 安装了 Python,则当前无法使用基于 pip 的虚拟环境。请改为遵循基于 conda 的开发说明。

如果不使用 conda,您必须安排您的系统提供所需的构建工具和依赖项。请注意,如果缺少某些依赖项,Arrow C++ 构建链仍然可以动态下载和编译它们,但这将比使用预安装的二进制文件花费更长的时间。

在 macOS 上,使用 Homebrew 安装构建 Arrow C++ 所需的所有依赖项:

$ brew update && brew bundle --file=arrow/cpp/Brewfile

有关您可能需要的依赖项列表,请参阅 此处

在 Debian/Ubuntu 上,您需要以下最小的依赖项集:

$ sudo apt-get install build-essential ninja-build cmake python3-dev

现在,让我们在与存储库相同的文件夹中创建一个包含所有 Python 依赖项的 Python 虚拟环境,以及一个目标安装文件夹:

$ python3 -m venv pyarrow-dev
$ source ./pyarrow-dev/bin/activate
$ pip install -r arrow/python/requirements-build.txt

$ # This is the folder where we will install the Arrow libraries during
$ # development
$ mkdir dist

如果您的 CMake 版本在 Linux 上过旧,您可以通过 pip install cmake 获取较新的版本。

我们需要设置一些环境变量,让 Arrow 的构建系统了解我们的构建工具链:

$ export ARROW_HOME=$(pwd)/dist
$ export LD_LIBRARY_PATH=$(pwd)/dist/lib:$LD_LIBRARY_PATH
$ export CMAKE_PREFIX_PATH=$ARROW_HOME:$CMAKE_PREFIX_PATH

构建和测试#

现在构建 Arrow C++ 库并将它们安装到我们上面创建的目录中(存储在 $ARROW_HOME 中):

$ cmake -S arrow/cpp -B arrow/cpp/build \
        -DCMAKE_INSTALL_PREFIX=$ARROW_HOME \
        --preset ninja-release-python
$ cmake --build arrow/cpp/build --target install

ninja-release-python 不是唯一可用的预设 - 如果您想要具有更多功能(如 CUDA、Flight 和 Gandiva 支持)的构建,您可以选择 ninja-release-python-maximal 预设。如果您想要的功能更少(即删除 ORC 和数据集支持),您可以选择 ninja-release-python-minimal 预设。将上述任何预设中的 release 更改为 debug 将生成 Arrow 的调试版本。

预设是为了方便起见而提供的,但您可以选择指定各个组件:

可以通过添加值为 ON 的标志来启用许多可选组件。

  • ARROW_CUDA:支持启用 CUDA 的 GPU。

  • ARROW_DATASET:支持 Apache Arrow Dataset。

  • ARROW_FLIGHT:Flight RPC 框架。

  • ARROW_GANDIVA:基于 LLVM 的表达式编译器。

  • ARROW_ORC:支持 Apache ORC 文件格式。

  • ARROW_PARQUET:支持 Apache Parquet 文件格式。

  • PARQUET_REQUIRE_ENCRYPTION:支持 Parquet 模块化加密。

以上设置为 ON 的任何组件也可以关闭。请注意,建议使用一些压缩库来获得完整的 Parquet 支持。

您可以选择不同的 C++ 构建类型。

  • -DCMAKE_BUILD_TYPE=Release(默认值)生成启用优化并禁用调试信息的版本;

  • -DCMAKE_BUILD_TYPE=Debug 生成禁用优化并启用调试信息的版本;

  • -DCMAKE_BUILD_TYPE=RelWithDebInfo 生成同时启用优化和调试信息的版本。

另请参阅

构建 Arrow C++.

如果您的环境中安装了多个版本的 Python,您可能需要向 CMake 传递额外的参数,以便它可以找到正确的可执行文件、头文件和库。例如,指定 -DPython3_EXECUTABLE=<path/to/bin/python> 可以让 CMake 选择您正在使用的 Python 可执行文件。

注意

在支持多架构构建的 Linux 系统上,make 默认情况下可能会将库安装在 lib64 目录中。因此,我们建议传递 -DCMAKE_INSTALL_LIBDIR=lib,因为 Python 构建脚本假定库目录是 lib

注意

如果您安装了 conda 但没有使用它来管理依赖项,并且在构建 C++ 库时遇到问题,您可能需要设置 -DARROW_DEPENDENCY_SOURCE=AUTO 或其他值(此处有描述)来明确告诉 CMake 不要使用 conda。

有关任何其他 C++ 构建问题,请参阅 C++ 开发

如果由于过程中出现错误而需要重新构建 C++ 部分,建议使用命令 rm -rf arrow/cpp/build 删除构建文件夹。如果构建已成功通过,并且您需要因从 git 主分支拉取最新代码而重新构建,则无需执行此步骤。

现在,构建 pyarrow。

$ pushd arrow/python
$ export PYARROW_PARALLEL=4
$ python setup.py build_ext --inplace
$ popd

如果您确实在 C++ 中构建了可选组件之一,则默认情况下,构建 pyarrow 时将启用相应的组件。可以通过将相应的 PYARROW_WITH_$COMPONENT 环境变量设置为 0 或 1 来覆盖此默认值,请参阅下面的 相关组件和环境变量

要设置用于编译 PyArrow 的 C++/Cython 组件的线程数,请设置 PYARROW_PARALLEL 环境变量。

如果希望在重建之前删除过时的 PyArrow 构建工件,请导航到 arrow/python 文件夹并运行 git clean -Xfd .

默认情况下,即使 Arrow C++ 以调试模式构建,PyArrow 也会以发布模式构建。要创建 PyArrow 的调试版本,请在运行上述 python setup.py build_ext --inplace 之前运行 export PYARROW_BUILD_TYPE=debug。可以类似地创建 relwithdebinfo 版本。

现在您可以安装测试依赖项并运行上述 单元测试

要构建一个自包含的 wheel 文件(包括 Arrow 和 Parquet C++ 库),可以设置 --bundle-arrow-cpp

$ pip install wheel  # if not installed
$ python setup.py build_ext --build-type=$ARROW_BUILD_TYPE \
         --bundle-arrow-cpp bdist_wheel

注意

要在 arrow/python 目录中安装可编辑的 PyArrow 构建,请运行 pip install -e . --no-build-isolation

Docker 示例#

如果您在从源代码构建 Python 库时遇到困难,请查看 python/examples/minimal_build 目录,该目录说明了使用基于 conda 和 pip 的构建方法从源代码进行完整构建和测试。

调试#

由于 pyarrow 依赖于 Arrow C++ 库,因此调试经常涉及在 Python 和 C++ 共享库之间切换。为了获得最佳体验,请确保您已在调试模式下构建了 Arrow C++ (-DCMAKE_BUILD_TYPE=Debug) 和 PyArrow (export PYARROW_BUILD_TYPE=debug)。

在 Linux 上使用 gdb#

要在运行 Python 单元测试时使用 gdb 调试 C++ 库,首先使用 gdb 启动 pytest。

$ gdb --args python -m pytest pyarrow/tests/test_to_run.py -k $TEST_TO_MATCH

要设置断点,请使用与调试 C++ 程序时相同的 gdb 语法,例如:

(gdb) b src/arrow/python/arrow_to_pandas.cc:1874
No source file named src/arrow/python/arrow_to_pandas.cc.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (src/arrow/python/arrow_to_pandas.cc:1874) pending.

另请参阅

Arrow C++ 的 GDB 扩展

在 Windows 上构建#

在 Windows 上构建需要安装以下编译器之一:

在安装构建工具期间,请确保至少选择一个 Windows SDK。

我们引导一个类似于上述的 conda 环境,但跳过了一些仅限 Linux/macOS 的软件包。

首先,从 Apache Arrow 的全新克隆开始。

$ git clone https://github.com/apache/arrow.git
$ conda create -y -n pyarrow-dev -c conda-forge ^
      --file arrow\ci\conda_env_cpp.txt ^
      --file arrow\ci\conda_env_python.txt ^
      --file arrow\ci\conda_env_gandiva.txt ^
      python=3.10
$ conda activate pyarrow-dev

现在,我们构建并安装 Arrow C++ 库。

我们将 Arrow C++ 库的安装目录路径设置为 ARROW_HOME。使用 conda 环境时,Arrow C++ 安装在环境目录中,其路径保存在 CONDA_PREFIX 环境变量中。

$ set ARROW_HOME=%CONDA_PREFIX%\Library

让我们配置、构建和安装 Arrow C++ 库。

$ mkdir arrow\cpp\build
$ pushd arrow\cpp\build
$ cmake -G "Ninja" ^
      -DCMAKE_INSTALL_PREFIX=%ARROW_HOME% ^
      -DCMAKE_UNITY_BUILD=ON ^
      -DARROW_COMPUTE=ON ^
      -DARROW_CSV=ON ^
      -DARROW_CXXFLAGS="/WX /MP" ^
      -DARROW_DATASET=ON ^
      -DARROW_FILESYSTEM=ON ^
      -DARROW_HDFS=ON ^
      -DARROW_JSON=ON ^
      -DARROW_PARQUET=ON ^
      -DARROW_WITH_LZ4=ON ^
      -DARROW_WITH_SNAPPY=ON ^
      -DARROW_WITH_ZLIB=ON ^
      -DARROW_WITH_ZSTD=ON ^
      ..
$ cmake --build . --target install --config Release
$ popd

现在,我们可以构建 pyarrow。

$ pushd arrow\python
$ set CONDA_DLL_SEARCH_MODIFICATION_ENABLE=1
$ python setup.py build_ext --inplace
$ popd

注意

برای ساختن pyarrow، متغیرهای محیطی تعریف شده در بالا نیز باید تنظیم شوند. اگر می خواهید pyarrow را پس از ساخت اولیه خود دوباره بسازید، این را به خاطر بسپارید.

注意

如果您使用的是带有 Python 3.9 或更早版本的 Conda,则必须设置 CONDA_DLL_SEARCH_MODIFICATION_ENABLE=1

然后使用以下命令运行单元测试:

$ pushd arrow\python
$ python -m pytest pyarrow
$ popd

注意

根据上述说明,Arrow C++ 库不会与 Python 扩展捆绑在一起。建议用于开发,因为它允许单独重新构建 C++ 库。

如果您使用的是 conda 包管理器,则 conda 将确保找到 Arrow C++ 库。如果您*不*使用 conda,则必须:

  • 在每次导入 pyarrow 之前,将已安装的 DLL 库的路径添加到 PATH 中,或者

  • 将 Arrow C++ 库与 pyarrow 捆绑在一起。

如果要将 Arrow C++ 库与 pyarrow 捆绑在一起,请在构建 pyarrow 之前设置 PYARROW_BUNDLE_ARROW_CPP 环境变量。

$ set PYARROW_BUNDLE_ARROW_CPP=1
$ python setup.py build_ext --inplace

请注意,捆绑的 Arrow C++ 库在重新构建 Arrow C++ 时不会自动更新。

注意事项#

相关组件和环境变量#

可用于构建 PyArrow 的相关环境变量列表如下:

PyArrow 环境变量

说明

默认值

PYARROW_BUILD_TYPE

PyArrow 的构建类型(release、debug 或 relwithdebinfo),设置 CMAKE_BUILD_TYPE

release

PYARROW_CMAKE_GENERATOR

例如:'Visual Studio 15 2017 Win64'

''

PYARROW_CMAKE_OPTIONS

额外的 CMake 和 Arrow 选项(例如 "-DARROW_SIMD_LEVEL=NONE -DCMAKE_OSX_ARCHITECTURES=x86_64;arm64")。

''

PYARROW_CXXFLAGS

额外的 C++ 编译器标志。

''

PYARROW_GENERATE_COVERAGE

为 Cython 编译器设置 Xlinetrace 标志为 true。

false

PYARROW_BUNDLE_ARROW_CPP

捆绑 Arrow C++ 库。

0 (OFF)

PYARROW_BUNDLE_CYTHON_CPP

捆绑 Cython 生成的 C++ 文件。

0 (OFF)

PYARROW_BUILD_VERBOSE

启用 Makefile 构建的详细输出。

0 (OFF)

PYARROW_PARALLEL

用于编译 PyArrow 的 C++/Cython 组件的进程数。

''

默认情况下,构建 PyArrow 时禁用或启用的组件取决于 Arrow C++ 的构建方式(即遵循 ARROW_$COMPONENT 标志)。但是,在构建 PyArrow 时,仍然可以使用 PYARROW_WITH_$COMPONENT 环境变量来覆盖此设置(例如,禁用组件或强制构建某些组件)。

Arrow 标志/选项

PyArrow 的对应环境变量

ARROW_GCS

PYARROW_WITH_GCS

ARROW_S3

PYARROW_WITH_S3

ARROW_AZURE

PYARROW_WITH_AZURE

ARROW_HDFS

PYARROW_WITH_HDFS

ARROW_CUDA

PYARROW_WITH_CUDA

ARROW_SUBSTRAIT

PYARROW_WITH_SUBSTRAIT

ARROW_FLIGHT

PYARROW_WITH_FLIGHT

ARROW_ACERO

PYARROW_WITH_ACERO

ARROW_DATASET

PYARROW_WITH_DATASET

ARROW_PARQUET

PYARROW_WITH_PARQUET

PARQUET_REQUIRE_ENCRYPTION

PYARROW_WITH_PARQUET_ENCRYPTION

ARROW_ORC

PYARROW_WITH_ORC

ARROW_GANDIVA

PYARROW_WITH_GANDIVA

删除过时的构建工件#

如果 Arrow C++ 库或 PyArrow 的结构发生更改,建议先彻底清理,以此作为修复构建错误的首次尝试。

注意

从错误本身并不一定能直观地看出问题是由于过时的工件引起的。“未知的 CMake 命令“arrow_keep_backward_compatibility””就是一个由过时工件导致的构建错误示例。

要删除过时的 Arrow C++ 构建工件

$ rm -rf arrow/cpp/build

要删除过时的 PyArrow 构建工件

$ git clean -Xfd python

如果使用 Conda 环境,则会在 $ARROW_HOME(也称为 $CONDA_PREFIX)中安装一些构建工件。例如,$ARROW_HOME/lib/cmake/Arrow*$ARROW_HOME/include/arrow$ARROW_HOME/lib/libarrow* 等。

可以手动删除这些文件。如果不确定要删除哪些文件,一种方法是重新创建 Conda 环境。

删除当前环境,然后重新开始

$ conda deactivate
$ conda remove -n pyarrow-dev

或者,采用一种破坏性较小的方法,使用不同的名称创建不同的环境。

安装每日构建包#

警告

这些软件包并非正式版本。使用它们需要您自担风险。

PyArrow 提供了用于测试目的的每日构建 wheel 包和 Conda 包。

下游库可以在其持续集成设置中使用这些包,以保持与即将推出的 PyArrow 功能、弃用和/或功能删除的兼容性。

arrow-nightlies conda 频道安装 PyArrow 的开发版本

conda install -c arrow-nightlies pyarrow

请注意,这要求所有其他软件包都使用 conda-forge 频道(conda config --add channels conda-forge)。

备用 PyPI 索引安装开发版本

pip install --extra-index-url https://pypi.fury.io/arrow-nightlies/ \
    --prefer-binary --pre pyarrow