-
Notifications
You must be signed in to change notification settings - Fork 465
Support pyproject.toml and uv.lock for Python dependency management in func pack #4716
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Co-authored-by: vrdmr <[email protected]>
Co-authored-by: vrdmr <[email protected]>
Co-authored-by: vrdmr <[email protected]>
|
@copilot The test needs update - THis isn't checking tool.uv but checking tool.poertry in the Also - can there be a check where uvlock isn't present |
…ements.txt Co-authored-by: vrdmr <[email protected]>
Fixed in 93e21b0:
|
| var hasUvLock = FileSystemHelpers.FileExists(Path.Combine(directory, Constants.UvLock)); | ||
| var hasRequirementsTxt = FileSystemHelpers.FileExists(Path.Combine(directory, Constants.RequirementsTxt)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we're not checking this till line 53, we should not read the value so early as it might never be used.
| { | ||
| PythonDependencyManager.Pip => Constants.RequirementsTxt, | ||
| PythonDependencyManager.Poetry => Constants.PyProjectToml, | ||
| PythonDependencyManager.Uv => $"{Constants.PyProjectToml} + {Constants.UvLock}", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it make sense for the file name to be two file names in one string? "pyproject.toml uv.lock" - if we're seperating this later, doesn't it make more sense to use a delimeter like , = "pyproject.toml,uv.lock"
| { | ||
| PythonDependencyManager.Pip => $"{Constants.RequirementsTxt}.md5", | ||
| PythonDependencyManager.Poetry => $"{Constants.PyProjectToml}.md5", | ||
| PythonDependencyManager.Uv => "uv.md5", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is uv not a const like the other two are?
|
|
||
| namespace Azure.Functions.Cli.Helpers | ||
| { | ||
| public enum PythonDependencyManager |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In .NET maming something as a manager often refers to classes that perform management operations. Could we use something like PythonPackageTool, PythonDependencyTool or PythonPackageSystem instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We would also update any reference to dependencyManager to something that makes sense like packageTool
| { | ||
| File.WriteAllText(Path.Combine(_tempDirectory, Constants.PyProjectToml), "[tool.poetry]\nname = \"test\""); | ||
| File.WriteAllText(Path.Combine(_tempDirectory, Constants.UvLock), "version = 1"); | ||
| // Should not throw |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we validate actual output/return instead of just hoping for "does not throw"
Issue describing the changes in this PR
resolves #4709
Python projects using
poetryoruvfor dependency management were blocked from usingfunc pack --no-builddue to hard requirement forrequirements.txt. Additionally,func packwithout--no-buildwould fail for uv-created venvs lacking pip.Validation:
func pack --no-buildnow accepts:requirements.txt(existing)pyproject.toml(poetry)pyproject.toml+uv.lock(uv)Dependency Resolution:
func packauto-detects and uses appropriate tool:pyproject.tomlanduv.lockpresent →uv export→pip downloadpyproject.tomlpresent →poetry export→pip downloadrequirements.txtpresent →pip download(unchanged)Priority logic when multiple files present:
pyproject.toml+uv.lock+requirements.txt→ uses uvpyproject.toml+requirements.txt(nouv.lock) → uses poetryrequirements.txtonly → uses pipDocker builds (
--build-native-deps): Exports from poetry/uv to temporaryrequirements.txtbefore Docker build, cleanup in finally block.Checksum handling: Separate MD5 files per tool (
requirements.txt.md5,pyproject.toml.md5,uv.md5) to avoid conflicts when switching tools.Implementation:
PythonDependencyManagerenum and detection logicRestorePythonRequirementsWithPoetry()andRestorePythonRequirementsWithUv()GetPythonDeploymentPackage()to route to appropriate restore methodPull request checklist
release_notes.mdAdditional information
Backward compatibility: 100% compatible - existing
requirements.txtworkflows unchanged.Tool availability: Graceful failure with actionable error messages if poetry/uv not installed.
Priority rationale: Matches Oryx behavior - uv (most specific) > poetry > pip (fallback).
Test coverage: Added comprehensive tests including edge cases for all file combinations:
Original prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.