Skip to content

Commit e96d649

Browse files
committed
fix(python-uv): take into account dependencies on other workspace members
This commit fixes an issue where an application created as a member of a uv workspace would fail to build if they depended on other workspace members. The following shows the problematic workspace structure and the error message. ``` workspace root ├── lib │   ├── pyproject.toml │   └── src ├── pyproject.toml ├── sam-app │   ├── __init__.py │   ├── app.py │   ├── pyproject.toml │   ├── samconfig.toml │   └── template.yaml └── uv.lock ``` ``` Build Failed Error: PythonUvBuilder:ResolveDependencies - UV package build failed: Failed to build from pyproject.toml: Lock file operation failed: Failed to install dependencies using uv: UV pip install failed: Using CPython 3.13.0 interpreter at: /path/to/workspace/.venv/bin/python3 error: Distribution not found at: file:///path/to/workspace/sam-app/lib ``` Even though `lib` and `sam-app` are in the same directory level in the workspace, the workflow attempts to install `lib` under `sam-app`. In the workflow, `uv export` outputs a list of dependency packages, which is then passed to `uv pip install` for installation. When doing so, [`uv export` outputs relative paths from the workspace root][1]. Therefore, `uv pip install` must be run from the workspace root, not from the application directory. Additionally, dependencies on other packages within the workspace are exported as editable installations (e.g., `-e ./lib`) by default. When this is passed to `uv pip install`, only the `.pth` (path configuration) file for the package will be installed without the package body. To prevent this, the `--no-editable` option needs to be used. [1]: astral-sh/uv#20238
1 parent 37cd1d1 commit e96d649

1 file changed

Lines changed: 11 additions & 1 deletion

File tree

aws_lambda_builders/workflows/python_uv/packager.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ def _build_from_lock_file(
332332
"--no-emit-project", # Don't include the project itself, only dependencies
333333
"--no-hashes", # Skip hashes for cleaner output (optional)
334334
"--no-default-groups", # Exclude PEP 735 default groups (e.g. dev/test) from Lambda zips
335+
"--no-editable", # Export editable dependencies as non-editable
335336
"--output-file",
336337
temp_requirements,
337338
# We want to specify the version because `uv export` might default to using a different one
@@ -344,6 +345,15 @@ def _build_from_lock_file(
344345
if rc != 0:
345346
raise LockFileError(reason=f"Failed to export lock file: {stderr}")
346347

348+
# Get the workspace root (or project directory if no workspace is used)
349+
# For packages in the workspace, exported paths are relative to the workspace root,
350+
# regardless of where in the workspace uv export is called
351+
workspace_args = ["workspace", "dir"]
352+
rc, stdout, stderr = self._uv_runner._uv.run_uv_command(workspace_args, cwd=project_dir)
353+
if rc != 0:
354+
raise LockFileError(reason=f"Failed to get workspace root: {stderr}")
355+
workspace_dir = stdout.strip()
356+
347357
# Install with platform targeting
348358
self._uv_runner.install_requirements(
349359
requirements_path=temp_requirements,
@@ -352,7 +362,7 @@ def _build_from_lock_file(
352362
config=config,
353363
python_version=python_version,
354364
platform="linux",
355-
cwd=project_dir,
365+
cwd=workspace_dir,
356366
architecture=architecture,
357367
)
358368
except LockFileError:

0 commit comments

Comments
 (0)