Skip to content

Commit 889141a

Browse files
authored
GH-49831: [Python] Withhold annotations from Python wheel until they are complete (#50168)
### Rationale for this change Since 24.0, pyarrow ships annotations and `py.typed` marker while the type stubs are still incomplete. This makes type checkers trust the partial stubs and report false errors in downstream code (e.g. Module has no attribute "all" for `pyarrow.compute`). Some type checkers also consume bundled `.pyi` files even without `py.typed`, so the stubs need to be withheld from wheels for now. See #49831. ### What changes are included in this PR? This temporarily omits both `pyarrow/py.typed` and the bundled `pyarrow-stubs` / `.pyi` files from built wheels until the stubs are complete. Wheel-content validation now asserts that neither `py.typed` nor `.pyi` files are present, and wheel build scripts no longer request stub docstring injection while stubs are not installed. ### Are these changes tested? Wheel-content validation has been updated to check the intended absence of `py.typed` and `.pyi` files. ### Are there any user-facing changes? Type checkers no longer pick up pyarrow's incomplete stubs from wheels. * GitHub Issue: #49831 Authored-by: Rok Mihevc <rok@mihevc.org> Signed-off-by: Raúl Cumplido <raulcumplido@gmail.com>
1 parent 4f60019 commit 889141a

6 files changed

Lines changed: 55 additions & 34 deletions

ci/scripts/python_wheel_macos_build.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@ popd
148148

149149
echo "=== (${PYTHON_VERSION}) Building wheel ==="
150150
export PYARROW_BUNDLE_ARROW_CPP=ON
151-
export PYARROW_REQUIRE_STUB_DOCSTRINGS=ON
151+
# TODO(GH-32609): Re-enable when pyarrow-stubs are shipped in wheels again.
152+
# export PYARROW_REQUIRE_STUB_DOCSTRINGS=ON
152153
export PYARROW_WITH_ACERO=${ARROW_ACERO}
153154
export PYARROW_WITH_AZURE=${ARROW_AZURE}
154155
export PYARROW_WITH_DATASET=${ARROW_DATASET}

ci/scripts/python_wheel_validate_contents.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ def _count_docstrings(source):
3737
return count
3838

3939

40+
# TODO(GH-48970): Check stubs ARE present once annotations are complete
4041
def validate_wheel(path):
4142
p = Path(path)
4243
wheels = list(p.glob('*.whl'))
@@ -54,9 +55,9 @@ def validate_wheel(path):
5455
info.filename.split("/")[-1] == filename for info in wheel_zip.filelist
5556
), f"{filename} is missing from the wheel."
5657

57-
assert any(
58+
assert not any(
5859
info.filename == "pyarrow/py.typed" for info in wheel_zip.filelist
59-
), "pyarrow/py.typed is missing from the wheel."
60+
), "pyarrow/py.typed is present in the wheel."
6061

6162
source_root = Path(__file__).resolve().parents[2]
6263
stubs_dir = source_root / "python" / "pyarrow-stubs" / "pyarrow"
@@ -73,19 +74,22 @@ def validate_wheel(path):
7374
if info.filename.startswith("pyarrow/") and info.filename.endswith(".pyi")
7475
}
7576

76-
assert wheel_stub_files == expected_stub_files, (
77-
"Wheel .pyi files differ from python/pyarrow-stubs/pyarrow.\n"
77+
assert not (wheel_stub_files == expected_stub_files), (
78+
"Wheel .pyi files do not differ from python/pyarrow-stubs/pyarrow.\n"
7879
f"Missing in wheel: {sorted(expected_stub_files - wheel_stub_files)}\n"
7980
f"Unexpected in wheel: {sorted(wheel_stub_files - expected_stub_files)}"
8081
)
82+
assert not wheel_stub_files, (
83+
f"Wheel contains unexpected .pyi files: {sorted(wheel_stub_files)}"
84+
)
8185

8286
wheel_docstring_count = sum(
8387
_count_docstrings(wheel_zip.read(wsf).decode("utf-8"))
8488
for wsf in wheel_stub_files
8589
)
8690

8791
print(f"Found {wheel_docstring_count} docstring(s) in wheel stubs.")
88-
assert wheel_docstring_count, "No docstrings found in wheel stub files."
92+
assert wheel_docstring_count == 0, "Docstrings found in wheel stub files."
8993

9094
print(f"The wheel: {wheels[0]} seems valid.")
9195

ci/scripts/python_wheel_windows_build.bat

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,8 @@ popd
116116

117117
echo "=== (%PYTHON%) Building wheel ==="
118118
set PYARROW_BUNDLE_ARROW_CPP=ON
119-
set PYARROW_REQUIRE_STUB_DOCSTRINGS=ON
119+
rem TODO(GH-32609): Re-enable when pyarrow-stubs are shipped in wheels again.
120+
rem set PYARROW_REQUIRE_STUB_DOCSTRINGS=ON
120121
set PYARROW_WITH_ACERO=%ARROW_ACERO%
121122
set PYARROW_WITH_AZURE=%ARROW_AZURE%
122123
set PYARROW_WITH_DATASET=%ARROW_DATASET%

ci/scripts/python_wheel_xlinux_build.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,8 @@ check_arrow_visibility
157157

158158
echo "=== (${PYTHON_VERSION}) Building wheel ==="
159159
export PYARROW_BUNDLE_ARROW_CPP=ON
160-
export PYARROW_REQUIRE_STUB_DOCSTRINGS=ON
160+
# TODO(GH-32609): Re-enable when pyarrow-stubs are shipped in wheels again.
161+
# export PYARROW_REQUIRE_STUB_DOCSTRINGS=ON
161162
export PYARROW_WITH_ACERO=${ARROW_ACERO}
162163
export PYARROW_WITH_AZURE=${ARROW_AZURE}
163164
export PYARROW_WITH_DATASET=${ARROW_DATASET}

python/CMakeLists.txt

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,32 +1041,40 @@ endif()
10411041
#
10421042
# Type stubs with docstring injection
10431043
#
1044+
# TODO(GH-32609): Reintroduce type stubs into PyArrow wheels.
1045+
# GH-49831: Temporarily do not install pyarrow-stubs into wheels.
10441046
# Stubs live in pyarrow-stubs/pyarrow/ during development but are installed
10451047
# alongside the package so type checkers can find them (PEP 561).
1046-
set(PYARROW_STUBS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/pyarrow-stubs/pyarrow")
1047-
if(EXISTS "${PYARROW_STUBS_SOURCE_DIR}")
1048-
install(DIRECTORY "${PYARROW_STUBS_SOURCE_DIR}/"
1049-
DESTINATION "."
1050-
FILES_MATCHING
1051-
PATTERN "*.pyi")
1052-
1053-
if(PYARROW_REQUIRE_STUB_DOCSTRINGS)
1054-
install(CODE "
1055-
execute_process(
1056-
COMMAND \"${Python3_EXECUTABLE}\"
1057-
\"${CMAKE_CURRENT_SOURCE_DIR}/scripts/update_stub_docstrings.py\"
1058-
\"${CMAKE_INSTALL_PREFIX}\"
1059-
\"${CMAKE_CURRENT_SOURCE_DIR}\"
1060-
RESULT_VARIABLE _pyarrow_stub_docstrings_result
1061-
)
1062-
if(NOT _pyarrow_stub_docstrings_result EQUAL 0)
1063-
message(FATAL_ERROR \"Stub docstring injection failed (exit code: \${_pyarrow_stub_docstrings_result})\")
1064-
endif()
1065-
")
1066-
endif()
1067-
else()
1068-
if(PYARROW_REQUIRE_STUB_DOCSTRINGS)
1069-
message(FATAL_ERROR "PyArrow stub source directory not found at ${PYARROW_STUBS_SOURCE_DIR}; "
1070-
"cannot build wheel without .pyi files.")
1071-
endif()
1048+
# The stubs are currently incomplete, and some type checkers consume .pyi files
1049+
# even without the py.typed marker. Re-enable this when the stubs are complete.
1050+
if(PYARROW_REQUIRE_STUB_DOCSTRINGS)
1051+
message(FATAL_ERROR "PYARROW_REQUIRE_STUB_DOCSTRINGS cannot be used while "
1052+
"pyarrow-stubs are omitted from wheels (GH-49831).")
10721053
endif()
1054+
# set(PYARROW_STUBS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/pyarrow-stubs/pyarrow")
1055+
# if(EXISTS "${PYARROW_STUBS_SOURCE_DIR}")
1056+
# install(DIRECTORY "${PYARROW_STUBS_SOURCE_DIR}/"
1057+
# DESTINATION "."
1058+
# FILES_MATCHING
1059+
# PATTERN "*.pyi")
1060+
#
1061+
# if(PYARROW_REQUIRE_STUB_DOCSTRINGS)
1062+
# install(CODE "
1063+
# execute_process(
1064+
# COMMAND \"${Python3_EXECUTABLE}\"
1065+
# \"${CMAKE_CURRENT_SOURCE_DIR}/scripts/update_stub_docstrings.py\"
1066+
# \"${CMAKE_INSTALL_PREFIX}\"
1067+
# \"${CMAKE_CURRENT_SOURCE_DIR}\"
1068+
# RESULT_VARIABLE _pyarrow_stub_docstrings_result
1069+
# )
1070+
# if(NOT _pyarrow_stub_docstrings_result EQUAL 0)
1071+
# message(FATAL_ERROR \"Stub docstring injection failed (exit code: \${_pyarrow_stub_docstrings_result})\")
1072+
# endif()
1073+
# ")
1074+
# endif()
1075+
# else()
1076+
# if(PYARROW_REQUIRE_STUB_DOCSTRINGS)
1077+
# message(FATAL_ERROR "PyArrow stub source directory not found at ${PYARROW_STUBS_SOURCE_DIR}; "
1078+
# "cannot build wheel without .pyi files.")
1079+
# endif()
1080+
# endif()

python/pyproject.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,12 @@ metadata.version.provider = "scikit_build_core.metadata.setuptools_scm"
8888
sdist.include = ["pyarrow/_generated_version.py", "cmake_modules/", "pyarrow-stubs/"]
8989
wheel.packages = ["pyarrow"]
9090
wheel.install-dir = "pyarrow"
91+
# TODO(GH-32609): Remove this when stubfiles are complete
92+
# Withhold the PEP 561 marker until the type stubs are complete. The .pyi files
93+
# are also temporarily omitted from wheels, so type checkers don't rely on the
94+
# incomplete stubs and break downstream users (GH-49831). py.typed is kept
95+
# in-tree for CI type-checking.
96+
wheel.exclude = ["pyarrow/py.typed"]
9197

9298
[tool.scikit-build.cmake.define]
9399
PYARROW_BUNDLE_ARROW_CPP = {env = "PYARROW_BUNDLE_ARROW_CPP", default = "OFF"}

0 commit comments

Comments
 (0)