Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

OpenRewrite Python

OpenRewrite automated refactoring for Python source code. This package provides the recipe framework, the Python Lossless Semantic Tree (LST), and the testing helpers you use to author and test Python recipes.

Installation

pip install openrewrite

How it works

OpenRewrite for Python uses a split JVM/Python architecture. You author and unit-test recipes in pure Python, but running a recipe against a real codebase is orchestrated by the JVM runtime via the Moderne CLI (with Python support configured) over an RPC bridge. There is no standalone, in-process Python parser entry point.

Quick start

The fastest way to author and exercise a recipe is the test harness, which parses a before snippet, runs your recipe, and asserts the result matches after:

from rewrite.test import RecipeSpec, python

def test_renames_a_call():
    spec = RecipeSpec(recipe=RenameFunctionCall(
        old_name="assertEquals",
        new_name="assertEqual",
    ))
    spec.rewrite_run(
        python("assertEquals(a, b)", "assertEqual(a, b)"),
    )

python(before, after) asserts a change; python(before) asserts no change.

Writing a recipe

A recipe is a @dataclass subclassing Recipe that returns a visitor from editor(). Each option must have a default value, or the recipe cannot be discovered or run.

from dataclasses import dataclass, field

from rewrite import ExecutionContext, Recipe, TreeVisitor, option
from rewrite.java import J
from rewrite.java.tree import MethodInvocation
from rewrite.python.visitor import PythonVisitor


@dataclass
class RenameFunctionCall(Recipe):
    """Rename calls to a function from one name to another."""

    old_name: str = field(default="", metadata=option(
        display_name="Old function name",
        description="The name of the function whose calls should be renamed.",
        example="assertEquals",
    ))

    new_name: str = field(default="", metadata=option(
        display_name="New function name",
        description="The name to rename matching calls to.",
        example="assertEqual",
    ))

    @property
    def name(self) -> str:
        return "com.yourorg.RenameFunctionCall"

    @property
    def display_name(self) -> str:
        return "Rename a function call"

    @property
    def description(self) -> str:
        return "Rename calls to a function from one name to another."

    def editor(self) -> TreeVisitor[J, ExecutionContext]:
        old_name = self.old_name
        new_name = self.new_name

        class Visitor(PythonVisitor[ExecutionContext]):
            def visit_method_invocation(self, method: MethodInvocation, p: ExecutionContext) -> J:
                method = super().visit_method_invocation(method, p)
                if method.name.simple_name == old_name:
                    renamed = method.name.replace(_simple_name=new_name)
                    return method.replace(_name=renamed)
                return method

        return Visitor()

Returning None from a visit method removes the node entirely — which is how recipes delete code.

Running recipes with the Moderne CLI

Expose an activate() function so the CLI can discover your recipe:

from rewrite.marketplace import RecipeMarketplace, Python

def activate(marketplace: RecipeMarketplace) -> None:
    marketplace.install(RenameFunctionCall, Python)

Then install and run it against a repository whose Python LSTs you've built, passing each option as a -P parameter:

# From your recipe project directory, install it into the CLI's marketplace:
mod config recipes pip install .

# Build the LSTs for the repository you want to refactor, then run the recipe:
mod build /path/to/your/repo
mod run /path/to/your/repo --recipe=com.yourorg.RenameFunctionCall \
    -P old_name=assertEquals -P new_name=assertEqual

Learn more

License

Moderne Source Available License - see LICENSE.md

Metadata

Release files for openrewrite 8.90.0.dev20260813110628

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for openrewrite 8.90.0.dev20260813110628
File Size Uploaded
openrewrite-8.90.0.dev20260813110628.tar.gz 355.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for openrewrite 8.90.0.dev20260813110628
File Interpreter ABI Platform
openrewrite-8.90.0.dev20260813110628-py3-none-any.whl Python 3 none any Details

Total release size: 749.9 kB

Release files / openrewrite-8.90.0.dev20260813110628.tar.gz

Download URL openrewrite-8.90.0.dev20260813110628.tar.gz
Size 355.7 kB
Tags Source
SHA-256 checksum
How to use checksums
86807647b5dad2e9146515c8014c0a96f522b4527fcbcc1e911d979be97bd1cd
BLAKE2b-256 checksum
How to use checksums
8e2c290275443c7a852bf31789df6e97488e00b6f3b6f777765bcd560823c2a0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / openrewrite-8.90.0.dev20260813110628-py3-none-any.whl

Download URL openrewrite-8.90.0.dev20260813110628-py3-none-any.whl
Size 394.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a7cfb564772c163e6c82742c2b921a36b5f27f4c6ac90747814b4ac50bfdb7d5
BLAKE2b-256 checksum
How to use checksums
2ebbf0efb489fe1bc6825a1025e150de3be2d9c9d2109a5bb49cce3a719dc871
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release history Release notifications | RSS feed

8.92.9

2 release files

8.92.8

2 release files

8.92.7

2 release files

8.92.6

2 release files

8.92.5

2 release files

8.92.4

2 release files

8.92.3

2 release files

8.92.2

2 release files

8.91.3

2 release files

8.91.2

2 release files

8.91.1

2 release files

8.91.0

2 release files

8.90.4

2 release files

8.90.3

2 release files

8.90.2

2 release files

8.90.1

2 release files

8.90.0

2 release files

This release

8.89.2

2 release files

8.89.1

2 release files

8.89.0

2 release files

8.88.5

2 release files

8.88.4

2 release files

8.88.0

2 release files

8.87.7

2 release files

8.87.6

2 release files

8.87.5

2 release files

8.87.4

2 release files

8.87.3

2 release files

8.87.2

2 release files

8.87.1

2 release files

8.87.0

2 release files

8.86.5

2 release files

8.86.4

2 release files

8.85.7

2 release files

8.85.6

2 release files

8.85.5

2 release files

8.85.4

2 release files

8.85.3

2 release files

8.85.2

2 release files

8.85.1

2 release files

8.85.0

2 release files

8.84.9

2 release files

8.84.8

2 release files

8.84.7

2 release files

8.83.4

2 release files

8.83.3

2 release files

8.83.2

2 release files

8.83.1

2 release files

8.83.0

2 release files

8.82.1

2 release files

8.82.0

2 release files

8.81.1

2 release files

8.81.0

2 release files

8.80.1

2 release files

8.80.0

2 release files

8.79.6

2 release files

8.79.5

2 release files

8.79.4

2 release files

8.79.3

2 release files

8.79.2

2 release files

8.78.0

2 release files

8.77.2

2 release files

8.77.1

2 release files

8.77.0

2 release files

8.76.4

2 release files

8.76.3

2 release files

8.76.2

2 release files

8.76.1

2 release files

8.76.0

2 release files

8.75.9

2 release files

8.75.8

2 release files

8.75.7

2 release files

8.75.6

2 release files

8.75.5

2 release files

8.75.4

2 release files

8.75.3

2 release files

8.74.3

2 release files

8.74.2

2 release files

8.74.1

2 release files

8.74.0

2 release files

8.73.2

2 release files

8.73.1

2 release files

8.73.0

2 release files

8.72.3

2 release files

8.72.2

2 release files

8.72.1

2 release files

8.72.0

2 release files

1.44.3

2 release files

1.44.1

2 release files

1.43.1

2 release files

1.43.0

2 release files

1.42.1

2 release files

1.42.0

2 release files

1.41.0

2 release files

1.40.0

2 release files

1.39.3

2 release files

1.39.2

2 release files

1.39.0

2 release files

1.38.0

2 release files

1.36.0

2 release files

1.35.1

2 release files

1.34.0

2 release files

1.33.1

2 release files

1.33.0

2 release files

1.32.1

2 release files

1.32.0

2 release files

1.30.0

2 release files

1.29.0

2 release files

1.28.0

2 release files

1.27.5

2 release files

1.27.4

2 release files

1.27.3

2 release files

1.27.2

2 release files

1.26.2

2 release files

1.25.2

2 release files

1.25.1

2 release files

1.25.0

2 release files

1.24.7

2 release files

1.24.6

2 release files

1.24.5

2 release files

1.24.4

2 release files

1.24.3

2 release files

1.24.2

2 release files

1.24.1

2 release files

1.24.0

2 release files

1.22.6

2 release files

1.22.5

2 release files

1.22.4

2 release files

1.22.3

2 release files

1.22.2

2 release files

1.22.1

2 release files

1.22.0

2 release files

1.21.2

2 release files

1.21.1

2 release files

1.21.0

2 release files

1.20.4

2 release files

1.20.3

2 release files

1.20.2

2 release files

1.20.1

2 release files

1.20.0

2 release files

1.19.3

2 release files

1.19.0

2 release files

1.18.2

2 release files

1.18.0

2 release files

1.17.2

2 release files

1.15.4

2 release files

1.15.3

2 release files

1.15.2

2 release files

1.15.1

2 release files

0.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page