Extending semantic intelligence and transformation to Python and the AI/data stack

Bryan Friedman
|
February 19, 2026
Contents

Key Takeaways

As teams experiment with AI and coding agents, they’re discovering something predictable: better context and more structure lead to faster and more reliable outcomes.

With OpenRewrite, that context comes from the Lossless Semantic Tree (LST), a type-attributed model of code that resolves symbols, tracks relationships, and preserves intent so source can be analyzed and changes can be applied safely. With both Java and JavaScript/TypeScript already modeled this way, both humans and agents can understand and evolve systems using shared, verified context.

Today, Moderne is introducing Python language support in the LST. Python code can now be parsed, analyzed, and transformed alongside Java and JavaScript.

Support for Python in the LST extends semantic coverage beyond backend and frontend application code into the data and AI layer. Teams can now analyze, migrate, and coordinate changes across Python repositories with the same level of visibility and control already available for Java and JavaScript, including large-scale upgrades and cross-repository campaigns.

From dynamic code to structured understanding

Once Python is modeled in the LST, teams can evaluate impact across repositories before changes are made, moving from file-by-file updates to coordinated, large-scale transformation.

Python’s flexibility is part of its power. Even in well-organized systems, much of its meaning lives in how modules, imports, and usage patterns relate to one another.

Humans navigate those relationships through context and experience. Tools and agents can interpret them as well, but when that meaning remains implicit, it has to be reconstructed from source text. Parsing Python into a type-attributed LST makes it explicit.

Symbols are resolved. Imports are traced. Relationships between modules become navigable. Control and data flow are represented directly. Formatting and intent are preserved. Instead of reasoning over text alone, both humans and agents can work from a semantic representation of the codebase, making it easier to analyze, evolve, and act upon.

Executing against the model

The LST models the code. Recipes execute against that model.

For OpenRewrite users, this is familiar. Recipes have long operated on semantic models to support analysis, migration, and coordinated change. Python now participates in that same workflow.

Teams can use recipes to manage Python systems at scale, including:

  • Surfacing usage of specific modules or symbols across Python repositories
  • Upgrading Python runtime versions and updating deprecated language features
  • Managing dependencies in pyproject.toml, including transitive upgrades
  • Cleaning up redundant or outdated constructs

These workflows remain fully available to developers and platform teams.

Agents can assist in identifying patterns or drafting transformations. Recipes provide the mechanism for applying those changes consistently within existing review and CI/CD workflows. (When paired with Prethink, agents can also analyze that structure more efficiently before recommending action.)

A single underlying model now spans the application layer and the AI and data layer alike.

Exploring Python recipes available today

A growing catalog of Python recipes is already available, including migrations, dependency management, and structural transformations.

These recipes support practical workflows such as:

  • Upgrading to newer Python versions like 3.12, 3.13, and 3.14 by modernizing deprecated APIs and patterns
  • Adding, changing, or removing dependencies in pyproject.toml
  • Finding, fixing, and upgrading direct and transitive dependencies across repositories
  • Removing redundant constructs like unnecessary pass statements
  • Applying consistent formatting transformations to standardize code structure

These are not one-off edits. They are repeatable, reviewable transformations built on the same semantic execution model already familiar to OpenRewrite users in Java and JavaScript ecosystems.

Python support launches with these recipes available out of the box. As with Java and JavaScript, teams can author their own recipes, written in Python, to reflect internal standards or recurring transformations. Agents can assist in drafting those recipes, helping translate intent into executable change.

Coordinating change across languages

Modern systems rarely evolve in isolation. A Java service may expose an API consumed by a Python integration. A shared dependency may appear in backend services, frontend tooling, and Python automation scripts. A security advisory may require updates across multiple languages in a shared codebase. 

With Python participating in the same semantic and recipe model, those coordinated efforts extend further across the stack. Campaigns can now include Python repositories as part of the same workflow. Research, dependency alignment, and large-scale transformation efforts can span backend services, frontend applications, and the Python code that connects, supports, or powers them.

In practice, that means:

  • Dependency upgrades can be aligned across multiple languages in a single campaign
  • API changes in one service can be paired with updates in dependent Python systems
  • Security remediations can be analyzed and applied across runtimes together
  • Portfolio-wide research can surface patterns across services, applications, and supporting Python code

Rather than running separate efforts per runtime, teams can orchestrate change across the stack using a shared execution model. Those efforts can span dozens or hundreds of repositories, with changes delivered as reviewable pull requests rather than one-off edits.

The mechanism stays the same regardless of language.

Reusing recipes across ecosystems

Just as with the added coverage of JavaScript and TypeScript, Python support does not introduce a parallel ecosystem. It extends the existing one.

Many recipes are built on shared semantic constructs such as types, method usages, or symbol relationships. Where those constructs are modeled consistently, the same recipes can apply across Java, JavaScript, and Python repositories.

In the documentation, recipes that apply to Python now appear alongside native Python recipes, making it clear when an existing recipe can run against Python code. This includes recipes such as:

  • Change method name
  • Rename package name
  • Change type
  • Delete method argument
  • Reorder method arguments
  • Find method usages
  • Find types

When a recipe operates on the underlying semantic structure rather than surface syntax, it can participate wherever that structure exists.

Real-world example: Migrating Python 3.10 to 3.12 

Consider a team preparing to upgrade to a newer Python runtime, such as Python 3.12. Over time, deprecated APIs and outdated patterns accumulate across services.

For example, older Python code might use from imp import reload, inspect.getargspec(), deprecated mixed-case calendar constants, and datetime.utcnow(). These were all removed or deprecated between 3.10 and 3.12.

Before:

from imp import reload
import inspect
import calendar
from datetime import datetime

reload(my_module)
spec = inspect.getargspec(my_func)
quarter_start = calendar.October
now = datetime.utcnow()

After applying the migration recipe:

from importlib import reload
import inspect
import calendar
from datetime import datetime

reload(my_module)
spec = inspect.getfullargspec(my_func)
quarter_start = calendar.OCTOBER
now = datetime.now(datetime.UTC)

Instead of manually searching repositories for deprecated usage, the migration recipe identifies and updates affected code consistently. For changes that can't be easily fixed with automation, the recipe flags the usage for review. The transformation is grounded in semantic structure rather than string matching, and each change is produced as a deterministic diff that teams can review and approve with confidence.

Getting started with Python transformation 

Python recipes are executed using the same CLI workflows already familiar to Moderne users.

To explore available recipes and learn how to build Python LSTs and run recipes, see the documentation:

Expanding the semantic surface

Modern software doesn’t stop at backend services or frontend applications. Python now sits alongside them powering data workflows, automation, integrations, and increasingly, AI-driven systems.

Python now extends the same semantic execution model across the data, automation, and AI layers of modern systems. Analysis, migration, and coordinated change can extend into Python codebases without introducing new tooling or parallel processes.

For developers and platform teams, bringing Python into this model means clearer visibility across more of their systems and safer ways to evolve them at scale.

For AI-assisted workflows, it means less time reconstructing context and more time executing change across Python repositories as well as Java and JavaScript projects. Agents can let recipes handle the structured, repeatable transformations more efficiently across many repositories.

More of your code is now structurally visible and ready to evolve.