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
: 需要大量系统 RAM 的测试orc
: Apache ORC 测试parquet
: Apache Parquet 测试s3
: Amazon S3 的测试tensorflow
: 涉及 TensorFlow 的测试
Doctest#
我们使用 doctest 来检查 docstring 示例是否为最新且正确。 您也可以通过运行以下命令在本地执行此操作
$ 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 启用的 GPUARROW_DATASET
:支持 Apache Arrow DatasetARROW_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
生成一个同时启用了优化和调试信息的构建。
另请参阅
如果在你的环境中安装了多个 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 main 最新拉取而重建,则不需要此步骤。
现在,构建 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.
另请参阅
在 Windows 上构建#
在 Windows 上构建需要安装以下编译器之一
Visual Studio 2017
在设置构建工具期间,请确保至少选择一个 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
,请记住这一点。
注意
如果你将 Conda 与 Python 3.9 或更早版本一起使用,则必须设置 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 的构建类型(release、debug 或 relwithdebinfo),设置 |
|
|
例如: |
|
|
额外的 CMake 和 Arrow 选项(例如, |
|
|
额外的 C++ 编译器标志 |
|
|
将 |
|
|
捆绑 Arrow C++ 库 |
|
|
捆绑 Cython 生成的 C++ 文件 |
|
|
启用 Makefile 构建的详细输出 |
|
|
用于编译 PyArrow 的 C++/Cython 组件的进程数 |
|
在构建 PyArrrow 时禁用或启用的组件默认情况下基于 Arrow C++ 的构建方式(即,它遵循 ARROW_$COMPONENT
标志)。 但是,PYARROW_WITH_$COMPONENT
环境变量仍然可以在构建 PyArrow 时用于覆盖此设置(例如,禁用组件或强制构建某些组件)
Arrow 标志/选项 |
PyArrow 的相应环境变量 |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
删除过时的构建产物#
当 Arrow C++ 库或 PyArrow 的结构发生更改时,建议首先彻底清理,以尝试修复构建错误。
注意
从错误本身不一定能直观地看出问题是由于过时的产物导致的。来自过时产物的构建错误示例是“Unknown CMake command “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
或者,可以创建一个具有不同名称的不同环境,破坏性较小。
安装 Nightly 包#
警告
这些包不是官方版本。 使用它们需要您自担风险。
PyArrow 有用于测试目的的 nightly wheels,托管在 scientific-python-nightly-wheels。
这些可能适用于下游库在其持续集成设置中,以保持与即将推出的 PyArrow 功能、弃用和/或功能移除的兼容性。
要安装最新 nightly 版本的 PyArrow,请运行
pip install \
-i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple \
pyarrow