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/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:需要大量系统 RAM 的测试

  • 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 虚拟环境,并创建一个目标安装文件夹

$ 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

注意

要安装可编辑的 PyArrow 构建,请在 arrow/python 目录中运行 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#

要使用 gdb 调试 C++ 库并在运行 Python 单元测试时,首先使用 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 组件的进程数

''

构建 PyArrrow 时禁用或启用组件默认基于 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 具有用于测试目的的每日构建轮子和 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