@@ -16,6 +16,8 @@ UV_PYTHON_INSTALL_ROOT="$BUILD_DIR/.uv/python"
1616PYTHON_SHIM_DIR=" $BUILD_DIR /.python/bin"
1717
1818install_uv () {
19+ # Prefer an existing uv binary, but fall back to the standalone installer so
20+ # the buildpack can bootstrap itself on stacks that do not ship uv.
1921 if command -v uv > /dev/null 2>&1 ; then
2022 UV_BIN=" $( command -v uv) "
2123 return 0
@@ -55,6 +57,8 @@ install_managed_python() {
5557
5658 python_request=" $( resolve_python_request) "
5759 if [ -n " $python_request " ]; then
60+ # Honor the app's requested runtime version so staging and runtime use the
61+ # same Python family the project was locked and tested against.
5862 echo " Installing Python $python_request from .python-version."
5963 " $UV_BIN " python install " $python_request "
6064 PYTHON_BIN=" $( " $UV_BIN " python find --managed-python " $python_request " ) "
@@ -71,6 +75,9 @@ write_python_shim() {
7175
7276 python_executable_name=" $( basename " $PYTHON_BIN " ) "
7377
78+ # Cloud Foundry relocates the droplet between staging and runtime, so the
79+ # wrapper must discover the managed interpreter relative to the app root
80+ # instead of embedding an absolute staging path.
7481 cat > " $shim_path " << EOF
7582#!/usr/bin/env bash
7683set -euo pipefail
@@ -132,12 +139,16 @@ if [ -f "pyproject.toml" ] && [ -f "uv.lock" ]; then
132139 # If the project uses a `src/` layout, include that too because the local
133140 # project itself is not installed by the exported third-party requirements.
134141 if [ -d " $SRC_DIR " ]; then
142+ # Build droplet-relative paths at runtime because the app will launch from
143+ # /home/vcap/app, not from the temporary staging directory used here.
135144 cat > " $PROFILE_DIR /python.sh" << EOF
136145export APP_DIR="\$ {HOME}/app"
137146export PATH="\$ APP_DIR/.python/bin:\$ APP_DIR/.python_packages/bin:\$ {PATH}"
138147export PYTHONPATH="\$ APP_DIR/src:\$ APP_DIR/.python_packages/lib/python${PYTHON_VERSION} /site-packages:\$ {PYTHONPATH}"
139148EOF
140149 else
150+ # Non-src-layout apps only need the staged site-packages directory plus the
151+ # buildpack-managed interpreter and console scripts on PATH.
141152 cat > " $PROFILE_DIR /python.sh" << EOF
142153export APP_DIR="\$ {HOME}/app"
143154export PATH="\$ APP_DIR/.python/bin:\$ APP_DIR/.python_packages/bin:\$ {PATH}"
0 commit comments