Transformation Migration Guide
LunaModel 0.6.0
LunaModel 0.6.0 introduces breaking changes to the Python transformation API.
The old transformation API is completely removed in 0.6.0. This guide is for
users upgrading from an earlier release to the new API, which separates:
- transformation artifacts used for backward replay
- analysis results exposed through
PassContext - transformation history exposed through
TransformationRecord
If you were only using built-in passes and PassManager, migration is usually
small. If you implemented custom transformation passes, you will likely need to
update your pass classes and decorators.
What Changed
PassManager.run(...) now returns TransformationOutput
Old code often treated the pass manager result as an IR-style object.
Use:
from luna_model.transformation import PassManager
output = PassManager([...]).run(model)
result_model = output.model
record = output.record
ctx = output.context
Instead of the old IR, use TransformationOutput.
Backward transformation is record-driven
Use:
instead of relying on the old manager-level or outcome-style flow from earlier releases.
Analysis results are no longer accessed through the old cache model
The old AnalysisCache-oriented API has been replaced by:
PassContextfor reading analysis results during pass executionTransformationRecordfor inspecting what happened during execution
Use:
instead of old name-based cache access patterns.
IfElsePass now belongs under .passes
Use:
instead of importing it from the root transformation package used in earlier releases.
Custom transformation pass semantics changed
In the new API, TransformationPass returns:
If your old custom transformation pass returned extra result state, it is
conceptually closer to a new CompositePass, which returns:
That is the main conceptual migration for custom pass authors.
Import Migrations
Replace old imports
Use the new imports directly:
# old
from luna_model.transformation import IR, IfElsePass, TransformationOutcome
# new
from luna_model.transformation.output import TransformationOutput
from luna_model.transformation.passes import IfElsePass
TransformationOutcome does not have a direct new equivalent. In the new API:
TransformationPass.forward(...)returnstuple[Model, Artifact]CompositePass.forward(...)returnstuple[Model, Artifact, Result]
Decorators
Decorator names remain available, but their semantics follow the new pass model.
The most important change is @transform: the decorated function must now return
an artifact-based result rather than the old outcome/action-style result.
Custom Pass Migration
Old transformation pass
from luna_model.transformation import TransformationPass, TransformationOutcome
class MyPass(TransformationPass):
@property
def name(self) -> str:
return "my-pass"
def run(self, model, cache):
return TransformationOutcome(model, ...)
def backwards(self, solution, cache):
return solution
New transformation pass
from luna_model.solution.sol import Solution
from luna_model.transformation import TransformationPass
from luna_model.transformation.artifact import NothingArtifact
from luna_model.transformation.context import PassContext
class MyPass(TransformationPass[NothingArtifact]):
def name(self) -> str:
return "my-pass"
def forward(self, model, ctx: PassContext) -> tuple:
return model, NothingArtifact()
@classmethod
def backward(cls, artifact: NothingArtifact, solution: Solution) -> Solution:
return solution
When to use CompositePass
Use CompositePass if your old transformation pass also produced a result that
later passes consumed.
from luna_model.solution.sol import Solution
from luna_model.transformation import CompositePass
from luna_model.transformation.artifact import NothingArtifact
class MyComposite(CompositePass[NothingArtifact, float]):
PROVIDES = "my-result"
def name(self) -> str:
return "my-composite"
def forward(self, model, ctx) -> tuple:
result = 1.0
return model, NothingArtifact(), result
@classmethod
def backward(cls, artifact: NothingArtifact, solution: Solution) -> Solution:
return solution
Analysis and Meta-Analysis Migration
Analysis passes
Old analysis passes often relied on the cache object directly.
Use PassContext in the new API:
from luna_model.transformation import AnalysisPass
class MyAnalysis(AnalysisPass[float]):
PROVIDES = "my-analysis"
def name(self) -> str:
return "my-analysis"
def run(self, model, ctx) -> float:
return 1.0
Reading analysis results
Use typed keys:
Recommended Migration Path
- Replace root compatibility imports with the new module paths.
- Replace
IRusage withTransformationOutput. - Replace old backward calls with
output.record.backward(...). - Migrate old analysis-cache access to
PassContext. - Migrate custom transformation passes:
- use
TransformationPassif you only needModel + Artifact - use
CompositePassif you also produce a result - Remove any dependency on
luna_model.transformation.legacy
Version Boundary
There is no intermediate compatibility release between the old and new
transformation APIs. Earlier LunaModel releases used the old transformation API.
LunaModel 0.6.0 uses only the new transformation API described in this guide.