Documentation
¶
Overview ¶
Package python implements omnibump support for Python projects.
It supports both manifest mode (editing pyproject.toml, requirements.txt, setup.cfg, or Pipfile in-place) and venv mode (upgrading packages directly in a staged Python virtualenv).
Build tool detection ¶
Manifest mode auto-detects build tools from the [build-system].build-backend field in pyproject.toml and can be overridden with the --tool flag. Supported build tools:
- pip / uv — requirements.txt or PEP 621 pyproject.toml
- poetry — [tool.poetry.dependencies] in pyproject.toml
- hatch — PEP 621 [project].dependencies via hatchling backend
- pdm — PEP 621 [project].dependencies; detected by pdm.lock
- flit — PEP 621 [project].dependencies via flit_core backend
- setuptools — PEP 621 pyproject.toml, setup.cfg, or setup.py
- maturin — PEP 621 [project].dependencies for Rust+Python (PyO3) projects; used by polars, pydantic-core, orjson, ruff, and other performance-critical packages
- scikit-build-core — PEP 621 [project].dependencies for C/C++ extension modules
All PEP 621 backends (hatch, flit, pdm, maturin, scikit-build-core, setuptools) share the same parsing path since they use the standard [project].dependencies array. Only Poetry requires a separate parser for its [tool.poetry.dependencies] section.
Manifest files ¶
Supported manifest file formats, checked in priority order: pyproject.toml, requirements.txt, setup.cfg, setup.py (read-only), Pipfile.
Lockfile handling ¶
For uv and pdm projects, omnibump updates pyproject.toml directly. The user must re-run `uv lock` or `pdm lock` afterwards to regenerate the lockfile from the updated constraints. Lockfile detection (uv.lock, pdm.lock) is used to identify the build tool, but lockfiles themselves are not modified.
Venv mode ¶
Venv mode is designed for application/leaf packages that bundle dependencies in a staged virtualenv. It validates strict == pinning, rejects downgrades, and verifies environment consistency with pip check. It supports both uv pip and standard pip installers.
Both modes integrate with omnibump's language interface for unified dependency version bumping across multiple ecosystems.
Package python implements omnibump support for Python projects. Supports multiple build tools (pip, uv, hatch, poetry, pdm, maturin, scikit-build-core, setuptools) through a unified interface.
Example ¶
package main
import (
"fmt"
"github.com/chainguard-dev/omnibump/pkg/languages"
)
func main() {
// Get the Python language from the registry.
lang, err := languages.Get("python")
if err != nil {
fmt.Println("error:", err)
return
}
fmt.Println("Language:", lang.Name())
}
Output: Language: python
Index ¶
- Constants
- Variables
- func HasPDMLock(dir string) bool
- func HasUVLock(dir string) bool
- func UpdatePipfile(path, packageName, newVersion string) error
- func UpdatePyprojectDep(path, packageName, newVersion string) error
- func UpdateRequirement(path, packageName, newVersion string) error
- func UpdateSetupCfg(path, packageName, newVersion string) error
- type Analyzer
- func (a *Analyzer) Analyze(_ context.Context, projectPath string) (*analyzer.AnalysisResult, error)
- func (a *Analyzer) AnalyzeRemote(_ context.Context, files map[string][]byte) (*analyzer.RemoteAnalysisResult, error)
- func (a *Analyzer) RecommendStrategy(_ context.Context, _ *analyzer.AnalysisResult, deps []analyzer.Dependency) (*analyzer.Strategy, error)
- type BuildTool
- type ManifestInfo
- type Python
- func (p *Python) Detect(_ context.Context, dir string) (bool, error)
- func (p *Python) GetManifestFiles() []string
- func (p *Python) Name() string
- func (p *Python) SupportsAnalysis() bool
- func (p *Python) Update(ctx context.Context, cfg *languages.UpdateConfig) error
- func (p *Python) Validate(ctx context.Context, cfg *languages.UpdateConfig) error
- type VersionResolver
- type VersionSpec
Examples ¶
Constants ¶
const ( // LanguagePython is the language identifier for Python. LanguagePython = "python" // UVCommand is the uv package manager command. UVCommand = "uv" // PipCommand is the pip package manager command. PipCommand = "pip" // ManifestPyprojectTOML is the pyproject.toml manifest type. ManifestPyprojectTOML = "pyproject.toml" // ManifestRequirementsTxt is the requirements.txt manifest type. ManifestRequirementsTxt = "requirements.txt" // ManifestSetupCfg is the setup.cfg manifest type. ManifestSetupCfg = "setup.cfg" // ManifestSetupPy is the setup.py manifest type. ManifestSetupPy = "setup.py" // ManifestPipfile is the Pipfile manifest type. ManifestPipfile = "Pipfile" // ManifestRequirementsPinnedTxt is a pinned variant of requirements.txt // used by some projects (e.g. in-toto). ManifestRequirementsPinnedTxt = "requirements-pinned.txt" )
Manifest file type constants.
Variables ¶
var ( // ErrManifestNotFound is returned when no Python manifest is found. ErrManifestNotFound = errors.New("no Python manifest file found") // ErrPackageNotFound is returned when the target package is not in the manifest. ErrPackageNotFound = errors.New("package not found in manifest") // ErrInvalidVersion is returned when a version string fails validation. ErrInvalidVersion = errors.New("invalid version string") ErrVersionResolverUnavailable = errors.New("version resolver unavailable") // ErrUnsupportedManifestType is returned for unsupported manifest types. ErrUnsupportedManifestType = errors.New("unsupported manifest type") // ErrVenvDowngrade is returned when a version downgrade is attempted. ErrVenvDowngrade = errors.New("downgrade rejected") // ErrVenvEmptyVersion is returned when a version is empty. ErrVenvEmptyVersion = errors.New("empty version for package") // ErrVenvInvalidPackageName is returned when a package name is invalid (e.g., starts with '-'). ErrVenvInvalidPackageName = errors.New("invalid package name") // ErrVenvInvalidVersionFormat is returned when a version format is invalid. ErrVenvInvalidVersionFormat = errors.New("invalid version format") // ErrPipInstallFailed is returned when pip install fails. ErrPipInstallFailed = errors.New("pip install failed") // ErrPipCheckFailed is returned when pip check fails. ErrPipCheckFailed = errors.New("pip check failed") // ErrSetupPyReadOnly is returned when attempting to modify setup.py. ErrSetupPyReadOnly = errors.New("setup.py is read-only: omnibump cannot safely update setup.py; migrate to setup.cfg or pyproject.toml") // ErrVersionNotFound is returned when no versions are found in registry. ErrVersionNotFound = errors.New("no versions found in registry") // ErrInvalidVersionResponse is returned when version response is invalid. ErrInvalidVersionResponse = errors.New("invalid version in response") // ErrHTTPNotFound is returned for 404 HTTP responses. ErrHTTPNotFound = errors.New("not found") // ErrUnexpectedHTTPStatus is returned for unexpected HTTP status codes. ErrUnexpectedHTTPStatus = errors.New("unexpected HTTP status") // ErrInvalidPath is returned when a manifest path is not absolute. ErrInvalidPath = errors.New("invalid path") // ErrInvalidPathAfterClean is returned when a path is still invalid after filepath.Clean. ErrInvalidPathAfterClean = errors.New("invalid path after clean") // ErrInvalidManifestFile is returned when the file is not a known manifest type. ErrInvalidManifestFile = errors.New("invalid manifest file") )
Functions ¶
func HasPDMLock ¶
HasPDMLock returns true when a pdm.lock file exists in dir.
func UpdatePipfile ¶
UpdatePipfile updates the version of a named package in a Pipfile. The existing operator is preserved. newVersion is a bare version number.
func UpdatePyprojectDep ¶
UpdatePyprojectDep updates the version of a named dependency in pyproject.toml. It preserves comments and formatting by operating on the raw file text. newVersion should be just the version number (e.g. "2.32.0"), not include an operator. The existing operator is preserved.
func UpdateRequirement ¶
UpdateRequirement updates the version of the named package in a requirements.txt file. The existing version operator is preserved (==, >=, ~=, etc.). newVersion is the bare version number without an operator.
func UpdateSetupCfg ¶
UpdateSetupCfg updates the version of a package in the install_requires section of a setup.cfg file. The existing operator is preserved.
Types ¶
type Analyzer ¶
type Analyzer struct{}
Analyzer implements analyzer.Analyzer for Python projects.
func (*Analyzer) Analyze ¶
Analyze parses all manifest files in projectPath and returns a dependency map.
func (*Analyzer) AnalyzeRemote ¶
func (a *Analyzer) AnalyzeRemote(_ context.Context, files map[string][]byte) (*analyzer.RemoteAnalysisResult, error)
AnalyzeRemote analyzes manifest files provided as raw bytes. files is a map of filename to content (e.g. "pyproject.toml" -> bytes).
func (*Analyzer) RecommendStrategy ¶
func (a *Analyzer) RecommendStrategy(_ context.Context, _ *analyzer.AnalysisResult, deps []analyzer.Dependency) (*analyzer.Strategy, error)
RecommendStrategy always recommends direct updates for Python deps. Python doesn't have a "property" abstraction like Maven.
type BuildTool ¶
type BuildTool string
BuildTool identifies the Python build system in use.
const ( // BuildToolPip indicates the pip build tool. BuildToolPip BuildTool = "pip" // BuildToolUV indicates the uv build tool. BuildToolUV BuildTool = "uv" // BuildToolHatch indicates the hatch build tool. BuildToolHatch BuildTool = "hatch" // BuildToolPoetry indicates the poetry build tool. BuildToolPoetry BuildTool = "poetry" // BuildToolPDM indicates the pdm build tool. BuildToolPDM BuildTool = "pdm" // BuildToolMaturin indicates the maturin build tool. BuildToolMaturin BuildTool = "maturin" // BuildToolSetuptools indicates the setuptools build tool. BuildToolSetuptools BuildTool = "setuptools" // BuildToolScikitBuild indicates the scikit-build tool. BuildToolScikitBuild BuildTool = "scikit-build" // BuildToolScikitBuildCore indicates the scikit-build-core tool. BuildToolScikitBuildCore BuildTool = "scikit-build-core" // BuildToolFlit indicates the flit build tool. // Flit uses PEP 621 [project].dependencies, same as hatch/setuptools. BuildToolFlit BuildTool = "flit" // BuildToolUnknown indicates an unknown build tool. BuildToolUnknown BuildTool = "unknown" )
func DetectBuildToolFromBytes ¶
DetectBuildToolFromBytes reads [build-system].build-backend from raw pyproject.toml bytes.
func DetectBuildToolFromPyproject ¶
DetectBuildToolFromPyproject reads [build-system].build-backend from a pyproject.toml file on disk.
type ManifestInfo ¶
type ManifestInfo struct {
// Path is the absolute path to the manifest file.
Path string
// Type is the manifest filename (e.g. "pyproject.toml", "requirements.txt").
Type string
// BuildTool is the detected build backend.
BuildTool BuildTool
}
ManifestInfo describes a detected Python manifest file.
func DetectManifest ¶
func DetectManifest(dir string) (*ManifestInfo, error)
DetectManifest returns the highest-priority manifest file found in dir. The returned ManifestInfo includes the build tool inferred from the file.
func DetectManifestWithHint ¶
func DetectManifestWithHint(dir, toolHint string) (*ManifestInfo, error)
DetectManifestWithHint returns a manifest file with optional tool preference. If toolHint is non-empty, it reorders the priority to check the preferred manifest for that tool first, then falls back to the standard order. toolHint examples: "pip" → requirements.txt, "poetry" → pyproject.toml, etc.
type Python ¶
type Python struct{}
Python implements the Language interface for Python projects. It auto-detects the build tool and delegates updates to the appropriate handler.
func (*Python) Detect ¶
Detect checks whether a Python manifest file exists in dir.
Example ¶
package main
import (
"context"
"fmt"
"os"
"path/filepath"
"github.com/chainguard-dev/omnibump/pkg/languages/python"
)
func main() {
// Create a temporary directory with a pyproject.toml to simulate a Python project.
dir, err := os.MkdirTemp("", "python-example-*")
if err != nil {
fmt.Println("error:", err)
return
}
defer func() { _ = os.RemoveAll(dir) }()
pyproject := filepath.Join(dir, "pyproject.toml")
if err := os.WriteFile(pyproject, []byte("[project]\nname = \"example\"\ndependencies = [\"requests>=2.28.0\"]\n"), 0o644); err != nil {
fmt.Println("error:", err)
return
}
p := &python.Python{}
detected, err := p.Detect(context.Background(), dir)
if err != nil {
fmt.Println("error:", err)
return
}
fmt.Println("Detected:", detected)
}
Output: Detected: true
func (*Python) GetManifestFiles ¶
GetManifestFiles returns all Python manifest filenames omnibump can process.
Example ¶
package main
import (
"fmt"
"github.com/chainguard-dev/omnibump/pkg/languages/python"
)
func main() {
p := &python.Python{}
files := p.GetManifestFiles()
for _, f := range files {
fmt.Println(f)
}
}
Output: pyproject.toml requirements.txt setup.cfg setup.py Pipfile
func (*Python) SupportsAnalysis ¶
SupportsAnalysis returns true since Python has full analysis capabilities.
func (*Python) Update ¶
Update performs dependency version updates on a Python project. For each dependency in cfg.Dependencies, it locates the highest-priority manifest and updates the version in-place. If Options["venv"] is set, uses venv mode (uv/pip install into a staged venv). Otherwise uses manifest mode (edit pyproject.toml, requirements.txt, etc. in-place).
type VersionResolver ¶
type VersionResolver struct {
// contains filtered or unexported fields
}
VersionResolver resolves Python package versions. It checks the Chainguard GAR-backed registry first, then falls back to PyPI.
func NewVersionResolver ¶
func NewVersionResolver() *VersionResolver
NewVersionResolver creates a VersionResolver from environment variables.
func (*VersionResolver) GetLatestVersion ¶
GetLatestVersion returns the latest available version of a Python package. Checks the Chainguard registry first; falls back to PyPI.
func (*VersionResolver) VersionExists ¶
VersionExists checks whether a specific version of a package is available.
type VersionSpec ¶
type VersionSpec struct {
// Package is the normalized package name.
Package string
// Specifier is the version operator(s), e.g. ">=", "==", "~=", "^".
Specifier string
// Version is the version string without the operator.
Version string
// RawLine is the original unparsed line from the manifest.
RawLine string
}
VersionSpec represents a single parsed dependency entry.
func ParsePipfile ¶
func ParsePipfile(data []byte) ([]VersionSpec, error)
ParsePipfile parses [packages] and [dev-packages] from a Pipfile.
func ParsePyprojectDeps ¶
func ParsePyprojectDeps(data []byte, buildTool BuildTool) ([]VersionSpec, error)
ParsePyprojectDeps parses dependencies from pyproject.toml content. For Poetry projects, it reads [tool.poetry.dependencies]. For all others (PEP 621), it reads [project].dependencies plus [project.optional-dependencies] and [dependency-groups] (PEP 735). Optional and group dependencies are included in the result with their source annotated in RawLine for informational purposes.
func ParseRequirements ¶
func ParseRequirements(data []byte) []VersionSpec
ParseRequirements parses a requirements.txt byte slice and returns dependency specs. Comment lines, blank lines, and option flags (-r, -c, -e, -i, --index-url) are skipped.
func ParseSetupCfg ¶
func ParseSetupCfg(data []byte) []VersionSpec
ParseSetupCfg parses install_requires from a setup.cfg file.
func ParseSetupPy ¶
func ParseSetupPy(data []byte) []VersionSpec
ParseSetupPy extracts install_requires entries from setup.py using regex. This handles the common pattern: install_requires=["pkg>=1.0", ...] or install_requires=[ ... ] across multiple lines.