From aff3b8bb067c0273911d62bacd737d2487b820ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Cumplido?= Date: Thu, 23 Apr 2026 13:19:17 +0200 Subject: [PATCH 01/10] GH-49321: [C++][Python] Add pixi build for Arrow and PyArrow --- ci/docker/pixi-cpp.dockerfile | 39 ++++++++++++++++++++++ ci/pixi/.gitignore | 19 +++++++++++ ci/pixi/pixi.toml | 62 +++++++++++++++++++++++++++++++++++ compose.yaml | 29 ++++++++++++++++ dev/tasks/tasks.yml | 6 ++++ 5 files changed, 155 insertions(+) create mode 100644 ci/docker/pixi-cpp.dockerfile create mode 100644 ci/pixi/.gitignore create mode 100644 ci/pixi/pixi.toml diff --git a/ci/docker/pixi-cpp.dockerfile b/ci/docker/pixi-cpp.dockerfile new file mode 100644 index 000000000000..41efd45d10db --- /dev/null +++ b/ci/docker/pixi-cpp.dockerfile @@ -0,0 +1,39 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +ARG arch=amd64 +FROM ${arch}/ubuntu:24.04 + +# install build essentials +RUN export DEBIAN_FRONTEND=noninteractive && \ + apt-get update -y -q && \ + apt-get install -y -q \ + curl \ + gdb \ + libc6-dbg \ + tzdata \ + wget && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# install pixi +RUN curl -fsSL https://pixi.sh/install.sh -o /tmp/install-pixi.sh +RUN PIXI_HOME=/opt/pixi PIXI_NO_PATH_UPDATE=1 sh /tmp/install-pixi.sh && rm /tmp/install-pixi.sh +ENV PATH=/opt/pixi/bin:$PATH + +# Verify pixi installation +RUN pixi --version \ No newline at end of file diff --git a/ci/pixi/.gitignore b/ci/pixi/.gitignore new file mode 100644 index 000000000000..a4ac42feacaa --- /dev/null +++ b/ci/pixi/.gitignore @@ -0,0 +1,19 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +**/.pixi +**/pixi.lock \ No newline at end of file diff --git a/ci/pixi/pixi.toml b/ci/pixi/pixi.toml new file mode 100644 index 000000000000..cad28b928fbc --- /dev/null +++ b/ci/pixi/pixi.toml @@ -0,0 +1,62 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +[workspace] +channels = ["https://prefix.dev/conda-forge"] +platforms = ["linux-64", "linux-aarch64", "osx-arm64"] +preview = ["pixi-build"] + +[environments] +default = [] +test = ["test"] + +[feature.test.activation.env] +ARROW_TEST_DATA = "/arrow/testing/data" + +[feature.test.dependencies] +binutils = "*" +cmake = "*" +python = "*" + +[feature.test.tasks] +# This path mangling feels extremely finicky. Investigate alternatives to make this more robust. +test = "cd $(ls -d /arrow/ci/pixi/.pixi/build/work/arrow-cpp-*/work/build | head -n 1) && ctest --output-on-failure" + +[package] +name = "arrow-cpp" +# TODO: Incorporate this to the bump version script and tests +version = "25.0.0.dev" +authors = ["Apache Arrow"] + +[package.build] +source.path = "../../cpp" + +[package.build.backend] +name = "pixi-build-cmake" +version = "*" + +[package.build.config] +extra-args = ["-DCMAKE_BUILD_TYPE=Release", + "-DARROW_BUILD_TESTS=ON"] + +[package.host-dependencies] +gflags = "*" +gmock = ">=1.10.0" +gtest = ">=1.10.0" +libboost-devel = "*" +rapidjson = "*" +xsimd = ">=14.0" diff --git a/compose.yaml b/compose.yaml index be32a95dd945..541e06279d0e 100644 --- a/compose.yaml +++ b/compose.yaml @@ -138,6 +138,8 @@ x-hierarchy: - fedora-cpp: - fedora-python - fedora-r-clang + - pixi-cpp: + - pixi-python - python-sdist - ubuntu-cpp: - ubuntu-cpp-static @@ -201,6 +203,8 @@ volumes: name: python-wheel-manylinux-2-28-ccache python-wheel-musllinux-1-2-ccache: name: python-wheel-musllinux-1-2-ccache + pixi-cpp-build: + name: ${ARCH}-pixi-cpp-build ubuntu-ccache: name: ${ARCH}-ubuntu-${UBUNTU}-ccache @@ -1158,6 +1162,31 @@ services: volumes: *ubuntu-volumes command: *python-command + ############################ Pixi builds ################################## + + pixi-cpp: + # C++ build with pixi + # + # Usage: + # docker compose build pixi-cpp + # docker compose run --rm pixi-cpp + # Parameters: + # ARCH: amd64, arm32v7 + image: ${REPO}:${ARCH}-pixi + build: + context: . + dockerfile: ci/docker/pixi-cpp.dockerfile + cache_from: + - ${REPO}:${ARCH}-pixi-cpp + args: + arch: ${ARCH} + volumes: + - .:/arrow:delegated + - ${DOCKER_VOLUME_PREFIX}pixi-cpp-build:/arrow/ci/pixi/.pixi:delegated + command: > + /bin/sh -c "pixi build --path /arrow/ci/pixi && + pixi run --environment test --manifest-path /arrow/ci/pixi test" + ############################ Python wheels ################################## # See available versions at: diff --git a/dev/tasks/tasks.yml b/dev/tasks/tasks.yml index 32c6245fec5e..edd8ea1c3dd3 100644 --- a/dev/tasks/tasks.yml +++ b/dev/tasks/tasks.yml @@ -365,6 +365,12 @@ tasks: params: image: conda-cpp-valgrind + test-pixi-cpp: + ci: github + template: docker-tests/github.linux.yml + params: + image: pixi-cpp + test-ubuntu-22.04-cpp: ci: github template: docker-tests/github.linux.yml From 1eabd5dcc75e166c5e539ea01ef455439028491f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Cumplido?= Date: Thu, 23 Apr 2026 13:21:31 +0200 Subject: [PATCH 02/10] Minor clean-up --- ci/docker/pixi-cpp.dockerfile | 2 +- ci/pixi/.gitignore | 2 +- compose.yaml | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/ci/docker/pixi-cpp.dockerfile b/ci/docker/pixi-cpp.dockerfile index 41efd45d10db..1976253a9676 100644 --- a/ci/docker/pixi-cpp.dockerfile +++ b/ci/docker/pixi-cpp.dockerfile @@ -36,4 +36,4 @@ RUN PIXI_HOME=/opt/pixi PIXI_NO_PATH_UPDATE=1 sh /tmp/install-pixi.sh && rm /tmp ENV PATH=/opt/pixi/bin:$PATH # Verify pixi installation -RUN pixi --version \ No newline at end of file +RUN pixi --version diff --git a/ci/pixi/.gitignore b/ci/pixi/.gitignore index a4ac42feacaa..8913651c86dc 100644 --- a/ci/pixi/.gitignore +++ b/ci/pixi/.gitignore @@ -16,4 +16,4 @@ # under the License. **/.pixi -**/pixi.lock \ No newline at end of file +**/pixi.lock diff --git a/compose.yaml b/compose.yaml index 541e06279d0e..bc4a86a82209 100644 --- a/compose.yaml +++ b/compose.yaml @@ -138,8 +138,7 @@ x-hierarchy: - fedora-cpp: - fedora-python - fedora-r-clang - - pixi-cpp: - - pixi-python + - pixi-cpp - python-sdist - ubuntu-cpp: - ubuntu-cpp-static From 782941367e9bb354f41570b812767bab7509b191 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Cumplido?= Date: Fri, 24 Apr 2026 14:27:49 +0200 Subject: [PATCH 03/10] Add pixi build for Python --- .../{pixi-cpp.dockerfile => pixi.dockerfile} | 0 ci/pixi/{ => cpp}/pixi.toml | 35 +++++++- ci/pixi/python/pixi.toml | 85 +++++++++++++++++++ compose.yaml | 37 ++++++-- dev/tasks/tasks.yml | 6 ++ 5 files changed, 151 insertions(+), 12 deletions(-) rename ci/docker/{pixi-cpp.dockerfile => pixi.dockerfile} (100%) rename ci/pixi/{ => cpp}/pixi.toml (72%) create mode 100644 ci/pixi/python/pixi.toml diff --git a/ci/docker/pixi-cpp.dockerfile b/ci/docker/pixi.dockerfile similarity index 100% rename from ci/docker/pixi-cpp.dockerfile rename to ci/docker/pixi.dockerfile diff --git a/ci/pixi/pixi.toml b/ci/pixi/cpp/pixi.toml similarity index 72% rename from ci/pixi/pixi.toml rename to ci/pixi/cpp/pixi.toml index cad28b928fbc..6dc4ef5809fe 100644 --- a/ci/pixi/pixi.toml +++ b/ci/pixi/cpp/pixi.toml @@ -34,7 +34,7 @@ python = "*" [feature.test.tasks] # This path mangling feels extremely finicky. Investigate alternatives to make this more robust. -test = "cd $(ls -d /arrow/ci/pixi/.pixi/build/work/arrow-cpp-*/work/build | head -n 1) && ctest --output-on-failure" +test = "cd $(ls -d /arrow/ci/pixi/cpp/.pixi/build/work/arrow-cpp-*/work/build | head -n 1) && ctest --output-on-failure" [package] name = "arrow-cpp" @@ -43,20 +43,47 @@ version = "25.0.0.dev" authors = ["Apache Arrow"] [package.build] -source.path = "../../cpp" +source.path = "../../../cpp" [package.build.backend] name = "pixi-build-cmake" version = "*" [package.build.config] -extra-args = ["-DCMAKE_BUILD_TYPE=Release", - "-DARROW_BUILD_TESTS=ON"] +extra-args = [ + "-DCMAKE_BUILD_TYPE=Release", + "-DARROW_BUILD_TESTS=ON", + "-DARROW_COMPUTE=ON", + "-DARROW_CSV=ON", + "-DARROW_DATASET=ON", + "-DARROW_FILESYSTEM=ON", + "-DARROW_JSON=ON", + "-DARROW_PARQUET=ON", + "-DARROW_WITH_BROTLI=ON", + "-DARROW_WITH_BZ2=ON", + "-DARROW_WITH_LZ4=ON", + "-DARROW_WITH_SNAPPY=ON", + "-DARROW_WITH_ZLIB=ON", + "-DARROW_WITH_ZSTD=ON", + # libutf8proc on package-host-dependencies seems to fail. + # More investigation needed. In the meantime use bundled. + "-Dutf8proc_SOURCE=BUNDLED", + "-DOPENSSL_ROOT_DIR=$PREFIX", +] [package.host-dependencies] +brotli = "*" +bzip2 = "*" gflags = "*" gmock = ">=1.10.0" gtest = ">=1.10.0" libboost-devel = "*" +lz4-c = "*" +openssl = "*" rapidjson = "*" +re2 = "*" +snappy = "*" +thrift-cpp = ">=0.11.0" xsimd = ">=14.0" +zlib = "*" +zstd = "*" diff --git a/ci/pixi/python/pixi.toml b/ci/pixi/python/pixi.toml new file mode 100644 index 000000000000..6d096882d255 --- /dev/null +++ b/ci/pixi/python/pixi.toml @@ -0,0 +1,85 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +[workspace] +channels = ["https://prefix.dev/conda-forge"] +platforms = ["linux-64", "linux-aarch64", "osx-arm64"] +preview = ["pixi-build"] + +[environments] +default = [] +test = ["test"] + +[feature.test] +platforms = ["linux-64"] + +[feature.test.activation.env] +ARROW_TEST_DATA = "/arrow/testing/data" +PARQUET_TEST_DATA = "/arrow/cpp/submodules/parquet-testing/data" + +[feature.test.dependencies] +hypothesis = "*" +pyarrow = { path = "." } +pytest = "*" +pytest-timeout = "*" + +[feature.test.tasks] +test = "pytest -r s --pyargs pyarrow --timeout=60" + +[package] +name = "pyarrow" +# TODO: Incorporate this to the bump version script and tests +version = "25.0.0.dev" +authors = ["Apache Arrow"] + +[package.build] +source.path = "../../../python" + +[package.build.backend] +name = "pixi-build-python" +version = "*" + +[package.build.config] +noarch = false +compilers = ["c", "cxx"] +env = { + PYARROW_BUNDLE_ARROW_CPP = "0", + CMAKE_GENERATOR = "Ninja", + ARROW_HOME = "$PREFIX", +} + +[package.host-dependencies] +arrow-cpp = { path = "../cpp" } # source-dep on the arrow-cpp manifest +cmake = "*" +cython = ">=3.0" +gcc_linux-64 = "*" +git = "*" +gxx_linux-64 = "*" +ninja = "*" +numpy = "*" +pip = "*" +pkg-config = "*" +python = ">=3.10,<3.14" +scikit-build-core = "*" +setuptools-scm = "*" +sysroot_linux-64 = "*" +zlib = "*" + +[package.run-dependencies] +arrow-cpp = { path = "../cpp" } +python = ">=3.10,<3.14" +numpy = "*" diff --git a/compose.yaml b/compose.yaml index bc4a86a82209..ed9b4ddefbfd 100644 --- a/compose.yaml +++ b/compose.yaml @@ -198,12 +198,14 @@ volumes: name: ${ARCH}-fedora-${FEDORA}-ccache maven-cache: name: maven-cache + pixi-cpp-build: + name: ${ARCH}-pixi-cpp-build + pixi-python-build: + name: ${ARCH}-pixi-python-build python-wheel-manylinux-2-28-ccache: name: python-wheel-manylinux-2-28-ccache python-wheel-musllinux-1-2-ccache: name: python-wheel-musllinux-1-2-ccache - pixi-cpp-build: - name: ${ARCH}-pixi-cpp-build ubuntu-ccache: name: ${ARCH}-ubuntu-${UBUNTU}-ccache @@ -1174,17 +1176,36 @@ services: image: ${REPO}:${ARCH}-pixi build: context: . - dockerfile: ci/docker/pixi-cpp.dockerfile - cache_from: - - ${REPO}:${ARCH}-pixi-cpp + dockerfile: ci/docker/pixi.dockerfile args: arch: ${ARCH} volumes: - .:/arrow:delegated - - ${DOCKER_VOLUME_PREFIX}pixi-cpp-build:/arrow/ci/pixi/.pixi:delegated + - ${DOCKER_VOLUME_PREFIX}pixi-cpp-build:/arrow/ci/pixi/cpp/.pixi:delegated command: > - /bin/sh -c "pixi build --path /arrow/ci/pixi && - pixi run --environment test --manifest-path /arrow/ci/pixi test" + /bin/sh -c "pixi build --path /arrow/ci/pixi/cpp && + pixi run --environment test --manifest-path /arrow/ci/pixi/cpp test" + + pixi-python: + # CPython build with pixi + # + # Usage: + # docker compose build pixi-python + # docker compose run --rm pixi-python + # Parameters: + # ARCH: amd64, arm32v7 + image: ${REPO}:${ARCH}-pixi + build: + context: . + dockerfile: ci/docker/pixi.dockerfile + args: + arch: ${ARCH} + volumes: + - .:/arrow:delegated + - ${DOCKER_VOLUME_PREFIX}pixi-python-build:/arrow/ci/pixi/python/.pixi:delegated + command: > + /bin/sh -c "pixi build --path /arrow/ci/pixi/python && + pixi run --environment test --manifest-path /arrow/ci/pixi/python test" ############################ Python wheels ################################## diff --git a/dev/tasks/tasks.yml b/dev/tasks/tasks.yml index edd8ea1c3dd3..2ca52f238e07 100644 --- a/dev/tasks/tasks.yml +++ b/dev/tasks/tasks.yml @@ -371,6 +371,12 @@ tasks: params: image: pixi-cpp + test-pixi-python: + ci: github + template: docker-tests/github.linux.yml + params: + image: pixi-python + test-ubuntu-22.04-cpp: ci: github template: docker-tests/github.linux.yml From d621f4cc996bc394283a979ff5ab7cdc2a69112e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Cumplido?= Date: Fri, 24 Apr 2026 14:36:49 +0200 Subject: [PATCH 04/10] Minor fix to x-hierarchy on compose.yaml --- compose.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/compose.yaml b/compose.yaml index ed9b4ddefbfd..7a89058529bc 100644 --- a/compose.yaml +++ b/compose.yaml @@ -139,6 +139,7 @@ x-hierarchy: - fedora-python - fedora-r-clang - pixi-cpp + - pixi-python - python-sdist - ubuntu-cpp: - ubuntu-cpp-static From 8b19769389e9cb5aab4a0969c42718ec1ac6428d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Cumplido?= Date: Fri, 24 Apr 2026 16:18:31 +0200 Subject: [PATCH 05/10] Add missing PARQUET_TEST_DATA for arrow cpp build --- ci/pixi/cpp/pixi.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/pixi/cpp/pixi.toml b/ci/pixi/cpp/pixi.toml index 6dc4ef5809fe..6dfe95204279 100644 --- a/ci/pixi/cpp/pixi.toml +++ b/ci/pixi/cpp/pixi.toml @@ -26,6 +26,7 @@ test = ["test"] [feature.test.activation.env] ARROW_TEST_DATA = "/arrow/testing/data" +PARQUET_TEST_DATA = "/arrow/cpp/submodules/parquet-testing/data" [feature.test.dependencies] binutils = "*" From fafcb993895eacb0fc74cde788a7989ae3654d7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Cumplido?= Date: Tue, 28 Apr 2026 11:34:29 +0200 Subject: [PATCH 06/10] Add Pixi Arrow CPP sanitizer build --- ci/pixi/asan/cpp/pixi.toml | 98 ++++++++++++++++++++++++++ ci/pixi/{ => default}/cpp/pixi.toml | 4 +- ci/pixi/{ => default}/python/pixi.toml | 2 +- compose.yaml | 41 +++++++++-- dev/tasks/tasks.yml | 14 ++-- 5 files changed, 141 insertions(+), 18 deletions(-) create mode 100644 ci/pixi/asan/cpp/pixi.toml rename ci/pixi/{ => default}/cpp/pixi.toml (94%) rename ci/pixi/{ => default}/python/pixi.toml (98%) diff --git a/ci/pixi/asan/cpp/pixi.toml b/ci/pixi/asan/cpp/pixi.toml new file mode 100644 index 000000000000..36dad3e146e0 --- /dev/null +++ b/ci/pixi/asan/cpp/pixi.toml @@ -0,0 +1,98 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +[workspace] +channels = ["https://prefix.dev/conda-forge"] +platforms = ["linux-64"] +preview = ["pixi-build"] + +[environments] +default = [] +test = ["test"] + +[feature.test.activation.env] +ARROW_TEST_DATA = "/arrow/testing/data" +PARQUET_TEST_DATA = "/arrow/cpp/submodules/parquet-testing/data" +# GH-39973: debug memory pool conflicts with ASAN +ARROW_DEBUG_MEMORY_POOL = "none" +ASAN_OPTIONS = "allocator_may_return_null=1:detect_leaks=0:symbolize=1" +UBSAN_OPTIONS = "print_stacktrace=1" + +[feature.test.dependencies] +binutils = "*" +cmake = "*" +python = "*" + +[feature.test.tasks] +# This path mangling feels extremely finicky. Investigate alternatives to make this more robust. +test = "cd $(ls -d /arrow/ci/pixi/asan/cpp/.pixi/build/work/arrow-cpp-*/work/build | head -n 1) && ctest --output-on-failure" + +[package] +name = "arrow-cpp" +# TODO: Incorporate this to the bump version script and tests +version = "25.0.0.dev" +authors = ["Apache Arrow"] + +[package.build] +source.path = "../../../../cpp" + +[package.build.backend] +name = "pixi-build-cmake" +version = "*" + +[package.build.config] +extra-args = [ + "-DCMAKE_BUILD_TYPE=Debug", + "-DARROW_USE_ASAN=ON", + "-DARROW_USE_UBSAN=ON", + # Avoid creating huge static libraries with sanitizer instrumentation + "-DARROW_BUILD_STATIC=OFF", + "-DARROW_BUILD_TESTS=ON", + "-DARROW_COMPUTE=ON", + "-DARROW_CSV=ON", + "-DARROW_DATASET=ON", + "-DARROW_FILESYSTEM=ON", + "-DARROW_JSON=ON", + "-DARROW_PARQUET=ON", + "-DARROW_WITH_BROTLI=ON", + "-DARROW_WITH_BZ2=ON", + "-DARROW_WITH_LZ4=ON", + "-DARROW_WITH_SNAPPY=ON", + "-DARROW_WITH_ZLIB=ON", + "-DARROW_WITH_ZSTD=ON", + # libutf8proc on package-host-dependencies seems to fail. + # More investigation needed. In the meantime use bundled. + "-Dutf8proc_SOURCE=BUNDLED", + "-DOPENSSL_ROOT_DIR=$PREFIX", +] + +[package.host-dependencies] +brotli = "*" +bzip2 = "*" +gflags = "*" +gmock = ">=1.10.0" +gtest = ">=1.10.0" +libboost-devel = "*" +lz4-c = "*" +openssl = "*" +rapidjson = "*" +re2 = "*" +snappy = "*" +thrift-cpp = ">=0.11.0" +xsimd = ">=14.0" +zlib = "*" +zstd = "*" diff --git a/ci/pixi/cpp/pixi.toml b/ci/pixi/default/cpp/pixi.toml similarity index 94% rename from ci/pixi/cpp/pixi.toml rename to ci/pixi/default/cpp/pixi.toml index 6dfe95204279..ade4d1568511 100644 --- a/ci/pixi/cpp/pixi.toml +++ b/ci/pixi/default/cpp/pixi.toml @@ -35,7 +35,7 @@ python = "*" [feature.test.tasks] # This path mangling feels extremely finicky. Investigate alternatives to make this more robust. -test = "cd $(ls -d /arrow/ci/pixi/cpp/.pixi/build/work/arrow-cpp-*/work/build | head -n 1) && ctest --output-on-failure" +test = "cd $(ls -d /arrow/ci/pixi/default/cpp/.pixi/build/work/arrow-cpp-*/work/build | head -n 1) && ctest --output-on-failure" [package] name = "arrow-cpp" @@ -44,7 +44,7 @@ version = "25.0.0.dev" authors = ["Apache Arrow"] [package.build] -source.path = "../../../cpp" +source.path = "../../../../cpp" [package.build.backend] name = "pixi-build-cmake" diff --git a/ci/pixi/python/pixi.toml b/ci/pixi/default/python/pixi.toml similarity index 98% rename from ci/pixi/python/pixi.toml rename to ci/pixi/default/python/pixi.toml index 6d096882d255..0e753211fdc2 100644 --- a/ci/pixi/python/pixi.toml +++ b/ci/pixi/default/python/pixi.toml @@ -47,7 +47,7 @@ version = "25.0.0.dev" authors = ["Apache Arrow"] [package.build] -source.path = "../../../python" +source.path = "../../../../python" [package.build.backend] name = "pixi-build-python" diff --git a/compose.yaml b/compose.yaml index 7a89058529bc..d04af62969a1 100644 --- a/compose.yaml +++ b/compose.yaml @@ -138,7 +138,8 @@ x-hierarchy: - fedora-cpp: - fedora-python - fedora-r-clang - - pixi-cpp + - pixi-cpp: + - pixi-cpp-sanitizer - pixi-python - python-sdist - ubuntu-cpp: @@ -201,6 +202,8 @@ volumes: name: maven-cache pixi-cpp-build: name: ${ARCH}-pixi-cpp-build + pixi-cpp-sanitizer-build: + name: ${ARCH}-pixi-cpp-sanitizer-build pixi-python-build: name: ${ARCH}-pixi-python-build python-wheel-manylinux-2-28-ccache: @@ -1182,10 +1185,34 @@ services: arch: ${ARCH} volumes: - .:/arrow:delegated - - ${DOCKER_VOLUME_PREFIX}pixi-cpp-build:/arrow/ci/pixi/cpp/.pixi:delegated + - ${DOCKER_VOLUME_PREFIX}pixi-cpp-build:/arrow/ci/pixi/default/cpp/.pixi:delegated command: > - /bin/sh -c "pixi build --path /arrow/ci/pixi/cpp && - pixi run --environment test --manifest-path /arrow/ci/pixi/cpp test" + /bin/sh -c "pixi build --path /arrow/ci/pixi/default/cpp && + pixi run --environment test --manifest-path /arrow/ci/pixi/default/cpp test" + + pixi-cpp-sanitizer: + # C++ build with pixi and Address/Undefined Behavior sanitizers enabled + # + # Usage: + # docker compose build pixi-cpp-sanitizer + # docker compose run --rm pixi-cpp-sanitizer + # Parameters: + # ARCH: amd64, arm32v7 + image: ${REPO}:${ARCH}-pixi + cap_add: + # For LeakSanitizer + - SYS_PTRACE + build: + context: . + dockerfile: ci/docker/pixi.dockerfile + args: + arch: ${ARCH} + volumes: + - .:/arrow:delegated + - ${DOCKER_VOLUME_PREFIX}pixi-cpp-sanitizer-build:/arrow/ci/pixi/asan/cpp/.pixi:delegated + command: > + /bin/sh -c "pixi build --path /arrow/ci/pixi/asan/cpp && + pixi run --environment test --manifest-path /arrow/ci/pixi/asan/cpp test" pixi-python: # CPython build with pixi @@ -1203,10 +1230,10 @@ services: arch: ${ARCH} volumes: - .:/arrow:delegated - - ${DOCKER_VOLUME_PREFIX}pixi-python-build:/arrow/ci/pixi/python/.pixi:delegated + - ${DOCKER_VOLUME_PREFIX}pixi-python-build:/arrow/ci/pixi/default/python/.pixi:delegated command: > - /bin/sh -c "pixi build --path /arrow/ci/pixi/python && - pixi run --environment test --manifest-path /arrow/ci/pixi/python test" + /bin/sh -c "pixi build --path /arrow/ci/pixi/default/python && + pixi run --environment test --manifest-path /arrow/ci/pixi/default/python test" ############################ Python wheels ################################## diff --git a/dev/tasks/tasks.yml b/dev/tasks/tasks.yml index 2ca52f238e07..eb39f0b45743 100644 --- a/dev/tasks/tasks.yml +++ b/dev/tasks/tasks.yml @@ -365,17 +365,15 @@ tasks: params: image: conda-cpp-valgrind - test-pixi-cpp: - ci: github - template: docker-tests/github.linux.yml - params: - image: pixi-cpp - - test-pixi-python: +{% for image in ["pixi-cpp", + "pixi-cpp-sanitizer", + "pixi-python"] %} + test-{{ image }}: ci: github template: docker-tests/github.linux.yml params: - image: pixi-python + image: {{ image }} +{% endfor %} test-ubuntu-22.04-cpp: ci: github From 4757b86273cc9f6d47f672c8a7ac6eca6d124a49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Cumplido?= Date: Tue, 28 Apr 2026 14:12:57 +0200 Subject: [PATCH 07/10] Initial PyArrow build against sanitizer-instrumented CPython, NumPy and Arrow C++ --- ci/docker/pixi.dockerfile | 1 + ci/pixi/asan/cpp/pixi.toml | 1 - ci/pixi/asan/python/pixi.toml | 98 +++++++++++++++++++++++++++++++++++ ci/pixi/default/cpp/pixi.toml | 1 - compose.yaml | 30 ++++++++++- 5 files changed, 128 insertions(+), 3 deletions(-) create mode 100644 ci/pixi/asan/python/pixi.toml diff --git a/ci/docker/pixi.dockerfile b/ci/docker/pixi.dockerfile index 1976253a9676..9e91935b191e 100644 --- a/ci/docker/pixi.dockerfile +++ b/ci/docker/pixi.dockerfile @@ -24,6 +24,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get install -y -q \ curl \ gdb \ + git \ libc6-dbg \ tzdata \ wget && \ diff --git a/ci/pixi/asan/cpp/pixi.toml b/ci/pixi/asan/cpp/pixi.toml index 36dad3e146e0..68934fb06ce8 100644 --- a/ci/pixi/asan/cpp/pixi.toml +++ b/ci/pixi/asan/cpp/pixi.toml @@ -35,7 +35,6 @@ UBSAN_OPTIONS = "print_stacktrace=1" [feature.test.dependencies] binutils = "*" cmake = "*" -python = "*" [feature.test.tasks] # This path mangling feels extremely finicky. Investigate alternatives to make this more robust. diff --git a/ci/pixi/asan/python/pixi.toml b/ci/pixi/asan/python/pixi.toml new file mode 100644 index 000000000000..28c710fd069b --- /dev/null +++ b/ci/pixi/asan/python/pixi.toml @@ -0,0 +1,98 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +[workspace] +channels = ["https://prefix.dev/conda-forge"] +platforms = ["linux-64"] +preview = ["pixi-build"] + +[environments] +default = [] +test = ["test"] + +[feature.test] +platforms = ["linux-64"] + +[feature.test.activation.env] +ARROW_TEST_DATA = "/arrow/testing/data" +PARQUET_TEST_DATA = "/arrow/cpp/submodules/parquet-testing/data" +# GH-39973: debug memory pool conflicts with ASAN +ARROW_DEBUG_MEMORY_POOL = "none" +ASAN_OPTIONS = "detect_leaks=0:symbolize=1:strict_init_order=true:allocator_may_return_null=1:use_sigaltstack=0" +UBSAN_OPTIONS = "print_stacktrace=1" + +[feature.test.dependencies] +hypothesis = "*" +pyarrow = { path = "." } +pytest = "*" +pytest-timeout = "*" + +[feature.test.tasks] +test = "pytest -r s --pyargs pyarrow --timeout=60" + +[package] +name = "pyarrow" +# TODO: Incorporate this to the bump version script and tests +version = "25.0.0.dev" +authors = ["Apache Arrow"] + +[package.build] +source.path = "../../../../python" + +[package.build.backend] +name = "pixi-build-python" +version = "*" + +[package.build.config] +noarch = false +compilers = ["c", "cxx"] +env = { + PYARROW_BUNDLE_ARROW_CPP = "0", + CMAKE_GENERATOR = "Ninja", + ARROW_HOME = "$PREFIX", + PYARROW_CMAKE_OPTIONS = "-DARROW_USE_ASAN=ON -DARROW_USE_UBSAN=ON -DCMAKE_BUILD_TYPE=Debug", + ASAN_OPTIONS = "detect_leaks=0:symbolize=1:strict_init_order=true:allocator_may_return_null=1:use_sigaltstack=0" +} + +[package.host-dependencies] +# Sanitizer-instrumented Arrow C++ (sibling pixi package). +arrow-cpp = { path = "../cpp" } +cmake = "*" +cython = ">=3.0" +gcc_linux-64 = "*" +git = "*" +gxx_linux-64 = "*" +ninja = "*" +pip = "*" +pkg-config = "*" +scikit-build-core = "*" +setuptools-scm = "*" +sysroot_linux-64 = "*" +zlib = "*" +# Instrumented CPython built from source (v3.15.0a6). +# commit hash must match numpy's pixi-packages/asan pinned commit, +# so pixi-build doesn't build cpython twice with different versions. +python.git = "https://github.com/python/cpython" +python.subdirectory = "Tools/pixi-packages/asan" +python.rev = "15b216f30d0445469ec31bc7509fcc55a216ef7c" +# Instrumented NumPy built from source. +numpy.git = "https://github.com/numpy/numpy" +numpy.subdirectory = "pixi-packages/asan" +numpy.rev = "0419105da9cd0a15a4e02bc22019c2b65272c68a" + +[package.run-dependencies] +arrow-cpp = { path = "../cpp" } diff --git a/ci/pixi/default/cpp/pixi.toml b/ci/pixi/default/cpp/pixi.toml index ade4d1568511..4386bf592133 100644 --- a/ci/pixi/default/cpp/pixi.toml +++ b/ci/pixi/default/cpp/pixi.toml @@ -31,7 +31,6 @@ PARQUET_TEST_DATA = "/arrow/cpp/submodules/parquet-testing/data" [feature.test.dependencies] binutils = "*" cmake = "*" -python = "*" [feature.test.tasks] # This path mangling feels extremely finicky. Investigate alternatives to make this more robust. diff --git a/compose.yaml b/compose.yaml index d04af62969a1..53ed3bd4c59b 100644 --- a/compose.yaml +++ b/compose.yaml @@ -140,7 +140,8 @@ x-hierarchy: - fedora-r-clang - pixi-cpp: - pixi-cpp-sanitizer - - pixi-python + - pixi-python: + - pixi-python-sanitizer - python-sdist - ubuntu-cpp: - ubuntu-cpp-static @@ -206,6 +207,8 @@ volumes: name: ${ARCH}-pixi-cpp-sanitizer-build pixi-python-build: name: ${ARCH}-pixi-python-build + pixi-python-sanitizer-build: + name: ${ARCH}-pixi-python-sanitizer-build python-wheel-manylinux-2-28-ccache: name: python-wheel-manylinux-2-28-ccache python-wheel-musllinux-1-2-ccache: @@ -1235,6 +1238,31 @@ services: /bin/sh -c "pixi build --path /arrow/ci/pixi/default/python && pixi run --environment test --manifest-path /arrow/ci/pixi/default/python test" + pixi-python-sanitizer: + # PyArrow build with pixi against sanitizer-instrumented CPython, NumPy + # and Arrow C++. Builds CPython and NumPy from source via pixi-build. + # + # Usage: + # docker compose build pixi-python-sanitizer + # docker compose run --rm pixi-python-sanitizer + # Parameters: + # ARCH: amd64, arm32v7 + image: ${REPO}:${ARCH}-pixi + cap_add: + # For LeakSanitizer + - SYS_PTRACE + build: + context: . + dockerfile: ci/docker/pixi.dockerfile + args: + arch: ${ARCH} + volumes: + - .:/arrow:delegated + - ${DOCKER_VOLUME_PREFIX}pixi-python-sanitizer-build:/arrow/ci/pixi/asan/python/.pixi:delegated + command: > + /bin/sh -c "pixi build --path /arrow/ci/pixi/asan/python && + pixi run --environment test --manifest-path /arrow/ci/pixi/asan/python test" + ############################ Python wheels ################################## # See available versions at: From ad4a82997821c8f920c7fdfeda5492f450870be1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Cumplido?= Date: Tue, 28 Apr 2026 14:30:20 +0200 Subject: [PATCH 08/10] Add required instrumented numpy and python to test dependencies and add missing task for pixi-python-sanitizer --- ci/pixi/asan/python/pixi.toml | 6 ++++++ dev/tasks/tasks.yml | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ci/pixi/asan/python/pixi.toml b/ci/pixi/asan/python/pixi.toml index 28c710fd069b..f57e9c05fad0 100644 --- a/ci/pixi/asan/python/pixi.toml +++ b/ci/pixi/asan/python/pixi.toml @@ -40,6 +40,12 @@ hypothesis = "*" pyarrow = { path = "." } pytest = "*" pytest-timeout = "*" +python.git = "https://github.com/python/cpython" +python.subdirectory = "Tools/pixi-packages/asan" +python.rev = "15b216f30d0445469ec31bc7509fcc55a216ef7c" +numpy.git = "https://github.com/numpy/numpy" +numpy.subdirectory = "pixi-packages/asan" +numpy.rev = "0419105da9cd0a15a4e02bc22019c2b65272c68a" [feature.test.tasks] test = "pytest -r s --pyargs pyarrow --timeout=60" diff --git a/dev/tasks/tasks.yml b/dev/tasks/tasks.yml index eb39f0b45743..28befab364bf 100644 --- a/dev/tasks/tasks.yml +++ b/dev/tasks/tasks.yml @@ -367,7 +367,8 @@ tasks: {% for image in ["pixi-cpp", "pixi-cpp-sanitizer", - "pixi-python"] %} + "pixi-python", + "pixi-python-sanitizer"] %} test-{{ image }}: ci: github template: docker-tests/github.linux.yml From 9d4dd89628d5bb0cbe37fe39eafac73b4be17712 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Cumplido?= Date: Tue, 28 Apr 2026 16:13:35 +0200 Subject: [PATCH 09/10] Increase timeout and add ASAN and UBSAN flags to PyArrow --- ci/pixi/asan/python/pixi.toml | 6 +++++- dev/tasks/tasks.yml | 3 +++ python/CMakeLists.txt | 5 +++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/ci/pixi/asan/python/pixi.toml b/ci/pixi/asan/python/pixi.toml index f57e9c05fad0..05cc53fbaf7c 100644 --- a/ci/pixi/asan/python/pixi.toml +++ b/ci/pixi/asan/python/pixi.toml @@ -66,11 +66,15 @@ version = "*" [package.build.config] noarch = false compilers = ["c", "cxx"] +extra-args = [ + "-Ccmake.build-type=Debug", + "-Ccmake.define.ARROW_USE_ASAN=ON", + "-Ccmake.define.ARROW_USE_UBSAN=ON", +] env = { PYARROW_BUNDLE_ARROW_CPP = "0", CMAKE_GENERATOR = "Ninja", ARROW_HOME = "$PREFIX", - PYARROW_CMAKE_OPTIONS = "-DARROW_USE_ASAN=ON -DARROW_USE_UBSAN=ON -DCMAKE_BUILD_TYPE=Debug", ASAN_OPTIONS = "detect_leaks=0:symbolize=1:strict_init_order=true:allocator_may_return_null=1:use_sigaltstack=0" } diff --git a/dev/tasks/tasks.yml b/dev/tasks/tasks.yml index 28befab364bf..60e2805e5b08 100644 --- a/dev/tasks/tasks.yml +++ b/dev/tasks/tasks.yml @@ -374,6 +374,9 @@ tasks: template: docker-tests/github.linux.yml params: image: {{ image }} + {% if image == "pixi-python-sanitizer" %} + timeout: 120 + {% endif %} {% endfor %} test-ubuntu-22.04-cpp: diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index d0ddb9009f89..8fb9afad196f 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -158,7 +158,12 @@ if(NOT DEFINED ARROW_RUNTIME_SIMD_LEVEL) "MAX" CACHE STRING "Max runtime SIMD optimization level") endif() + +option(ARROW_USE_ASAN "Enable Address Sanitizer checks" OFF) +option(ARROW_USE_UBSAN "Enable Undefined Behavior sanitizer checks" OFF) + include(SetupCxxFlags) +include(san-config) if($ENV{PYODIDE}) # These variables are needed for building PyArrow on Emscripten. From aa462b6200ddf50c5ca76125e84057af6b6325e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Cumplido?= Date: Tue, 28 Apr 2026 18:12:34 +0200 Subject: [PATCH 10/10] Generate Cython and libarrow_python ASAN failures to validate instrumentation --- python/pyarrow/includes/libarrow_python.pxd | 2 ++ python/pyarrow/lib.pyx | 15 +++++++++ .../pyarrow/src/arrow/python/numpy_convert.cc | 8 +++++ .../pyarrow/src/arrow/python/numpy_convert.h | 4 +++ python/pyarrow/tests/test_misc.py | 31 +++++++++++++++++++ 5 files changed, 60 insertions(+) diff --git a/python/pyarrow/includes/libarrow_python.pxd b/python/pyarrow/includes/libarrow_python.pxd index 72c278d3e74b..4ad0195c1123 100644 --- a/python/pyarrow/includes/libarrow_python.pxd +++ b/python/pyarrow/includes/libarrow_python.pxd @@ -35,6 +35,8 @@ cdef extern from "arrow/python/api.h" namespace "arrow::py": # Requires GIL CResult[shared_ptr[CDataType]] InferArrowType( object obj, object mask, c_bool pandas_null_sentinels) + # TODO: ASAN sanity check; heap-buffer-overflow. Revert before final commit. + void AsanSanityOobNumpy() cdef extern from "arrow/python/api.h" namespace "arrow::py::internal": diff --git a/python/pyarrow/lib.pyx b/python/pyarrow/lib.pyx index 7e97177a6ec0..2e1d74f4bc86 100644 --- a/python/pyarrow/lib.pyx +++ b/python/pyarrow/lib.pyx @@ -29,6 +29,7 @@ import os import sys from cython.operator cimport dereference as deref +from libc.stdlib cimport malloc, free from pyarrow.includes.libarrow cimport * from pyarrow.includes.libarrow_python cimport * from pyarrow.includes.common cimport PyObject_to_object @@ -85,6 +86,20 @@ def set_cpu_count(int count): check_status(SetCpuThreadPoolCapacity(count)) +def _asan_sanity_oob(): + # TODO: ASAN sanity check; heap-buffer-overflow. Revert before final commit. + cdef int* a = malloc(sizeof(int)) + cdef int v = a[100] + free(a) + return v + + +def _asan_sanity_oob_numpy(): + # TODO: ASAN sanity check; calls libarrow_python.so's + # AsanSanityOobNumpy(). Revert before final commit. + libarrow_python.AsanSanityOobNumpy() + + def is_opentelemetry_enabled() -> bool: """ Returns True if OpenTelemetry is enabled in libarrow. diff --git a/python/pyarrow/src/arrow/python/numpy_convert.cc b/python/pyarrow/src/arrow/python/numpy_convert.cc index 4113cc67d2fc..e0202cab55f3 100644 --- a/python/pyarrow/src/arrow/python/numpy_convert.cc +++ b/python/pyarrow/src/arrow/python/numpy_convert.cc @@ -559,5 +559,13 @@ Status TensorToSparseCSFTensor(const std::shared_ptr& tensor, return SparseCSFTensor::Make(*tensor).Value(out); } +// TODO: ASAN sanity check; heap-buffer-overflow. Revert before final commit. +void AsanSanityOobNumpy() { + int* a = static_cast(std::malloc(sizeof(int))); + volatile int v = a[100]; + std::free(a); + (void)v; +} + } // namespace py } // namespace arrow diff --git a/python/pyarrow/src/arrow/python/numpy_convert.h b/python/pyarrow/src/arrow/python/numpy_convert.h index 2d1086e13552..0454281854ff 100644 --- a/python/pyarrow/src/arrow/python/numpy_convert.h +++ b/python/pyarrow/src/arrow/python/numpy_convert.h @@ -118,5 +118,9 @@ ARROW_PYTHON_EXPORT Status TensorToSparseCSFTensor(const std::shared_ptr& tensor, std::shared_ptr* csparse_tensor); +// TODO: ASAN sanity check; heap-buffer-overflow in libarrow_python's +// numpy conversion module. Revert before final commit. +ARROW_PYTHON_EXPORT void AsanSanityOobNumpy(); + } // namespace py } // namespace arrow diff --git a/python/pyarrow/tests/test_misc.py b/python/pyarrow/tests/test_misc.py index 856873f441b4..71be7640e837 100644 --- a/python/pyarrow/tests/test_misc.py +++ b/python/pyarrow/tests/test_misc.py @@ -30,6 +30,37 @@ def test_get_include(): assert os.path.exists(os.path.join(include_dir, 'arrow', 'api.h')) +def test_asan_sanity_oob(): + # TODO: ASAN sanity check (cython side). ASAN aborts the subprocess on + # the heap-buffer-overflow; the test fails with the report visible in the + # assertion message. Revert before final commit. + res = subprocess.run( + [sys.executable, "-c", + "import pyarrow.lib; pyarrow.lib._asan_sanity_oob()"], + capture_output=True, text=True, timeout=30, + ) + assert res.returncode == 0, ( + f"ASAN caught cython-emitted heap-buffer-overflow.\n" + f"returncode={res.returncode}\n" + f"stderr:\n{res.stderr}" + ) + + +def test_asan_sanity_oob_numpy(): + # TODO: ASAN sanity check (libarrow_python.so / numpy_convert.cc). + # Same pattern as test_asan_sanity_oob. Revert before final commit. + res = subprocess.run( + [sys.executable, "-c", + "import pyarrow.lib; pyarrow.lib._asan_sanity_oob_numpy()"], + capture_output=True, text=True, timeout=30, + ) + assert res.returncode == 0, ( + f"ASAN caught heap-buffer-overflow in libarrow_python.\n" + f"returncode={res.returncode}\n" + f"stderr:\n{res.stderr}" + ) + + @pytest.mark.skipif('sys.platform != "win32"') def test_get_library_dirs_win32(): assert any(os.path.exists(os.path.join(directory, 'arrow.lib'))