Package org.openrewrite.python.internal
Class PyProjectHelper
java.lang.Object
org.openrewrite.python.internal.PyProjectHelper
Shared utilities for Python dependency recipes operating on pyproject.toml files.
-
Nested Class Summary
Nested Classes -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionstatic org.openrewrite.SourceFileapplyResolvedDependencies(org.openrewrite.SourceFile depsFile, String regeneratedLockContent) Overlay resolved-dependency information from regenerated lock content onto the source file's existingPythonResolutionResultmarker.static PathcorrespondingPipfilePath(Path pipfileLockPath) Derive the Pipfile path that corresponds to a Pipfile.lock path.static PathcorrespondingPyprojectPath(Path uvLockPath) Derive the pyproject.toml path that corresponds to a uv.lock path.editAndRegenerate(PythonDependencyFile trait, Function<PythonDependencyFile, PythonDependencyFile> editFn, @Nullable String capturedLockContent) Apply a recipe-specific trait edit to a deps tree, refresh its marker, and regenerate the lock file.static @Nullable StringextractKeyName(org.openrewrite.toml.tree.Toml.KeyValue kv) Read the unquoted key name from a TOML key-value, ornullif the key isn't a plainToml.Identifier.static @Nullable StringextractPackageName(String pep508Spec) Extract the package name from a PEP 508 dependency spec string.static @Nullable PythonResolutionResult.DependencyfindDependencyInScope(PythonResolutionResult marker, String packageName, @Nullable String scope, @Nullable String groupName) Find a dependency in the specified scope of the marker.static @Nullable org.openrewrite.SourceFilegetLiveDepsTree(org.openrewrite.ExecutionContext ctx, Path depsPath) Read the latest known chain-modified deps tree for a given path from the sharedExecutionContextside channel, ornullif no recipe has written one yet.static booleanisInsideDependencyArray(org.openrewrite.Cursor cursor, @Nullable String scope, @Nullable String groupName) Check whether a cursor path represents a position inside a dependency array for the given scope and optional group name.static booleanisInsidePdmOverridesTable(org.openrewrite.Cursor cursor) Check whether a cursor path represents a position inside the[tool.pdm.overrides]table in a pyproject.toml.static booleanisInsideProjectDependencies(org.openrewrite.Cursor cursor) Check whether a cursor path represents a position inside the[project].dependenciesarray in a pyproject.toml.static StringnormalizeVersionConstraint(String version) Normalize a version constraint so it is valid PEP 508.static voidputLiveDepsTree(org.openrewrite.ExecutionContext ctx, Path depsPath, org.openrewrite.SourceFile depsTree) Publish the current chain-modified deps tree for a given path to the sharedExecutionContextside channel.static org.openrewrite.SourceFilerefreshMarker(org.openrewrite.SourceFile depsFile) Re-derive thePythonResolutionResultmarker on a modified dependency source file by re-parsing its current document content.static @Nullable LockFileRegeneration.ResultregenerateLockContent(org.openrewrite.SourceFile depsFile, @Nullable String capturedLockContent) Regenerate the lock file for a dependencies-file source by dispatching to the package manager indicated by itsPythonResolutionResultmarker.static org.openrewrite.json.tree.Json.DocumentreparseJson(org.openrewrite.json.tree.Json.Document original, String newContent) Reparse a JSON document from new content while preserving the original document's identity (id) and markers.static org.openrewrite.toml.tree.Toml.DocumentreparseToml(org.openrewrite.toml.tree.Toml.Document original, String newContent) Reparse a TOML document from new content while preserving the original document's identity (id) and markers.
-
Constructor Details
-
PyProjectHelper
public PyProjectHelper()
-
-
Method Details
-
normalizeVersionConstraint
Normalize a version constraint so it is valid PEP 508. When the value does not start with a comparison operator (>=,<=, etc.) we default to>=. -
extractKeyName
Read the unquoted key name from a TOML key-value, ornullif the key isn't a plainToml.Identifier. Quote stripping is handled by the TOML parser itself ("urllib3"andurllib3both expose"urllib3"viagetName()). -
extractPackageName
Extract the package name from a PEP 508 dependency spec string. The name is the first token before any version specifier, extras, or marker. -
correspondingPyprojectPath
Derive the pyproject.toml path that corresponds to a uv.lock path. -
correspondingPipfilePath
Derive the Pipfile path that corresponds to a Pipfile.lock path. -
reparseJson
public static org.openrewrite.json.tree.Json.Document reparseJson(org.openrewrite.json.tree.Json.Document original, String newContent) Reparse a JSON document from new content while preserving the original document's identity (id) and markers. -
reparseToml
public static org.openrewrite.toml.tree.Toml.Document reparseToml(org.openrewrite.toml.tree.Toml.Document original, String newContent) Reparse a TOML document from new content while preserving the original document's identity (id) and markers. -
refreshMarker
public static org.openrewrite.SourceFile refreshMarker(org.openrewrite.SourceFile depsFile) Re-derive thePythonResolutionResultmarker on a modified dependency source file by re-parsing its current document content. This is needed after structural edits (adding/removing/changing dependencies) so that the marker's declared-dependency list reflects the new content; otherwise idempotency checks in subsequent recipe cycles see stale data and re-apply the edit. Returns the source file unchanged if no marker is present or the file shape is not recognised. -
applyResolvedDependencies
public static org.openrewrite.SourceFile applyResolvedDependencies(org.openrewrite.SourceFile depsFile, String regeneratedLockContent) Overlay resolved-dependency information from regenerated lock content onto the source file's existingPythonResolutionResultmarker. Dispatches on the marker's package manager (uv →UvLockParser; pipenv →PipfileLockParser). Returns the source file unchanged if there is no marker, no recognised package manager, or the lock content has no resolved dependencies. -
getLiveDepsTree
public static @Nullable org.openrewrite.SourceFile getLiveDepsTree(org.openrewrite.ExecutionContext ctx, Path depsPath) Read the latest known chain-modified deps tree for a given path from the sharedExecutionContextside channel, ornullif no recipe has written one yet. -
putLiveDepsTree
public static void putLiveDepsTree(org.openrewrite.ExecutionContext ctx, Path depsPath, org.openrewrite.SourceFile depsTree) Publish the current chain-modified deps tree for a given path to the sharedExecutionContextside channel. Subsequent recipes — and lock-file visits within the same recipe pass that arrive after this one — read this to apply their edit on top of prior recipes' modifications. -
editAndRegenerate
public static PyProjectHelper.EditAndRegenerateResult editAndRegenerate(PythonDependencyFile trait, Function<PythonDependencyFile, PythonDependencyFile> editFn, @Nullable String capturedLockContent) Apply a recipe-specific trait edit to a deps tree, refresh its marker, and regenerate the lock file. Used both by deps-file visits (which obtain the trait from the framework's live cursor) and by lock-file lazy-compute visits (which obtain the trait via a synthetic cursor over a tree pulled from the accumulator or thectx side channel).- Parameters:
trait- the trait wrapping the deps tree to editeditFn- applies the recipe-specific edit (e.g.t -> t.withAddedDependencies(...))capturedLockContent- the lock content captured during scanning, ornullwhen no lock file was seen- Returns:
- a result describing what changed
-
regenerateLockContent
public static @Nullable LockFileRegeneration.Result regenerateLockContent(org.openrewrite.SourceFile depsFile, @Nullable String capturedLockContent) Regenerate the lock file for a dependencies-file source by dispatching to the package manager indicated by itsPythonResolutionResultmarker. Returnsnullwhen the source has no marker, no package manager, or no regeneration adapter for that package manager. -
isInsideProjectDependencies
public static boolean isInsideProjectDependencies(org.openrewrite.Cursor cursor) Check whether a cursor path represents a position inside the[project].dependenciesarray in a pyproject.toml. -
isInsideDependencyArray
public static boolean isInsideDependencyArray(org.openrewrite.Cursor cursor, @Nullable String scope, @Nullable String groupName) Check whether a cursor path represents a position inside a dependency array for the given scope and optional group name.Scope values use TOML dotted-key path syntax:
nullor"project.dependencies"→[project].dependencies"build-system.requires"→[build-system].requires"project.optional-dependencies"→[project.optional-dependencies].<groupName>"dependency-groups"→[dependency-groups].<groupName>"tool.uv.constraint-dependencies"→[tool.uv].constraint-dependencies"tool.uv.override-dependencies"→[tool.uv].override-dependencies
-
findDependencyInScope
public static @Nullable PythonResolutionResult.Dependency findDependencyInScope(PythonResolutionResult marker, String packageName, @Nullable String scope, @Nullable String groupName) Find a dependency in the specified scope of the marker.- Parameters:
marker- the resolution result markerpackageName- the package name to findscope- the scope to search (null means project.dependencies)groupName- the group name (required for optional-dependencies and dependency-groups)- Returns:
- the dependency, or null if not found
-
isInsidePdmOverridesTable
public static boolean isInsidePdmOverridesTable(org.openrewrite.Cursor cursor) Check whether a cursor path represents a position inside the[tool.pdm.overrides]table in a pyproject.toml.
-