@@ -90,6 +90,11 @@ case ${TEST_TYPE} in
9090 nox -s unit-3.14
9191 retval=$?
9292 ;;
93+ " 3.15" )
94+ # This is needed to speed up builds
95+ nox --force-venv-backend uv -s unit-3.15
96+ retval=$?
97+ ;;
9398 * )
9499 echo " unsupported PY_VERSION"
95100 exit 1
@@ -98,13 +103,35 @@ case ${TEST_TYPE} in
98103 ;;
99104 import_profile)
100105 if [ -f setup.py ] || [ -f pyproject.toml ]; then
106+ PACKAGE_NAME=$( basename $( pwd) )
107+
108+ # TODO(https://github.com/googleapis/google-cloud-python/issues/18035):
109+ # Remove this skip once Python 3.15 is officially released and upstream binary wheels
110+ # (e.g. numpy, pyarrow, pandas, geopandas, pikepdf) are published on PyPI.
111+ # Packages with heavy C/Rust dependencies attempt full source compilation on pre-release Python,
112+ # taking 5-10+ minutes before failing due to unreleased CPython 3.15 C-API changes.
113+ if [[ " ${PY_VERSION} " == " 3.15" * ]]; then
114+ UNSUPPORTED_PRE_RELEASE_PACKAGES=(
115+ " bigframes"
116+ " pandas-gbq"
117+ " google-cloud-documentai-toolbox"
118+ " db-dtypes"
119+ " bigquery-magics"
120+ )
121+ for unsupported in " ${UNSUPPORTED_PRE_RELEASE_PACKAGES[@]} " ; do
122+ if [ " ${PACKAGE_NAME} " = " ${unsupported} " ]; then
123+ echo " WARNING: Skipping import_profile for ${PACKAGE_NAME} : package has heavy C/Rust dependencies not yet supported on pre-release Python ${PY_VERSION} ."
124+ exit 0
125+ fi
126+ done
127+ fi
128+
101129 echo " Creating temporary virtualenv for import profile..."
102130 python3 -m venv .venv-profiler
103131 source .venv-profiler/bin/activate
104132 export PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1
105133 python -m pip install --upgrade pip setuptools
106134
107- PACKAGE_NAME=$( basename $( pwd) )
108135 PROFILER_TEMP_DIR=$( mktemp -d)
109136 cp ../../scripts/import_profiler/profiler.py " ${PROFILER_TEMP_DIR} /profiler.py"
110137 PROFILER_SCRIPT=" ${PROFILER_TEMP_DIR} /profiler.py"
@@ -121,13 +148,26 @@ case ${TEST_TYPE} in
121148 WORKTREE_DIR=$( mktemp -d)
122149 rmdir " ${WORKTREE_DIR} "
123150 if git worktree add " ${WORKTREE_DIR} " " ${BASELINE_COMMIT} " 2> /dev/null; then
124- (
151+ if ! (
125152 cd " ${WORKTREE_DIR} /${REPO_PREFIX} "
126153 if [ -f setup.py ] || [ -f pyproject.toml ]; then
127- pip install -e .
128- python " ${PROFILER_SCRIPT} " --package " ${PACKAGE_NAME} " --iterations 11 --csv " ${BASELINE_CSV} "
154+ if pip install -e . ; then
155+ echo " INFO: Successfully installed baseline dependencies for ${PACKAGE_NAME} ."
156+ python " ${PROFILER_SCRIPT} " --package " ${PACKAGE_NAME} " --iterations 11 --csv " ${BASELINE_CSV} "
157+ if [ $? -eq 0 ]; then
158+ echo " INFO: Successfully ran baseline profiler for ${PACKAGE_NAME} ."
159+ fi
160+ elif [[ " ${PY_VERSION} " != " 3.15" * ]]; then
161+ exit 1
162+ fi
129163 fi
130- )
164+ ); then
165+ git worktree remove -f " ${WORKTREE_DIR} "
166+ deactivate
167+ rm -rf .venv-profiler
168+ rm -rf " ${PROFILER_TEMP_DIR} "
169+ exit 1
170+ fi
131171 git worktree remove -f " ${WORKTREE_DIR} "
132172 else
133173 echo " Failed to create git worktree for baseline. Skipping baseline generation."
@@ -137,14 +177,28 @@ case ${TEST_TYPE} in
137177 fi
138178 fi
139179
140- pip install -e .
141-
142- if [ -f " ${BASELINE_CSV} " ]; then
143- python ${PROFILER_SCRIPT} --package ${PACKAGE_NAME} --iterations 11 --fail-threshold 5000 --diff-baseline " ${BASELINE_CSV} " --diff-threshold 100
180+ # TODO(https://github.com/googleapis/google-cloud-python/issues/18035):
181+ # Clean up this fallback once Python 3.15 is officially released and upstream binary wheels are available on PyPI.
182+ # On pre-release Python versions, packages with complex C/Rust dependencies (e.g. bigframes) fail during pip install due to missing pre-built wheels.
183+ if ! pip install -e . ; then
184+ if [[ " ${PY_VERSION} " == " 3.15" * ]]; then
185+ echo " WARNING: Could not install dependencies for ${PACKAGE_NAME} on Python ${PY_VERSION} (missing pre-built binary wheels for pre-release Python). Skipping import_profile."
186+ retval=0
187+ else
188+ retval=1
189+ fi
144190 else
145- python ${PROFILER_SCRIPT} --package ${PACKAGE_NAME} --iterations 11 --fail-threshold 5000
191+ echo " INFO: Successfully installed dependencies for ${PACKAGE_NAME} on Python ${PY_VERSION} ."
192+ if [ -f " ${BASELINE_CSV} " ]; then
193+ python ${PROFILER_SCRIPT} --package ${PACKAGE_NAME} --iterations 11 --fail-threshold 5000 --diff-baseline " ${BASELINE_CSV} " --diff-threshold 100
194+ else
195+ python ${PROFILER_SCRIPT} --package ${PACKAGE_NAME} --iterations 11 --fail-threshold 5000
196+ fi
197+ retval=$?
198+ if [ $retval -eq 0 ]; then
199+ echo " INFO: Successfully completed import_profile for ${PACKAGE_NAME} ."
200+ fi
146201 fi
147- retval=$?
148202 deactivate
149203 rm -rf .venv-profiler
150204 rm -rf " ${PROFILER_TEMP_DIR} "
0 commit comments