Skip to content

Replace Uint(len(...)) with ulen(...)#2580

Draft
SamWilsn wants to merge 2 commits intoethereum:forks/amsterdamfrom
SamWilsn:ulen
Draft

Replace Uint(len(...)) with ulen(...)#2580
SamWilsn wants to merge 2 commits intoethereum:forks/amsterdamfrom
SamWilsn:ulen

Conversation

@SamWilsn
Copy link
Copy Markdown
Contributor

@SamWilsn SamWilsn commented Mar 27, 2026

Prompt

Using libcst (you can find some examples in src/ethereum_spec_tools/new_fork if you need them), write a
codemod to transform Uint(len(...)) into ulen(...) from ethereum/ethereum-types, and then apply the codemod to the whole repository.

Codemod

from pathlib import Path

import libcst as cst
import libcst.matchers as m
from libcst.codemod import CodemodContext, VisitorBasedCodemodCommand
from libcst.codemod.visitors import AddImportsVisitor, RemoveImportsVisitor
from typing_extensions import override


class UintLenToUlen(VisitorBasedCodemodCommand):
    """
    Replace `Uint(len(...))` with `ulen(...)`.
    """

    DESCRIPTION: str = "Replace Uint(len(...)) with ulen(...)."

    _transformed: bool

    def __init__(self, context: CodemodContext) -> None:
        super().__init__(context)
        self._transformed = False

    @override
    def leave_Call(
        self, original_node: cst.Call, updated_node: cst.Call
    ) -> cst.BaseExpression:
        # Match Uint(len(...))
        if not m.matches(
            updated_node,
            m.Call(
                func=m.Name("Uint"),
                args=[
                    m.Arg(
                        value=m.Call(func=m.Name("len")),
                        keyword=None,
                        star="",
                    )
                ],
            ),
        ):
            return updated_node

        if not self._transformed:
            self._transformed = True
            AddImportsVisitor.add_needed_import(
                self.context, "ethereum_types.numeric", "ulen"
            )
            RemoveImportsVisitor.remove_unused_import(
                self.context, "ethereum_types.numeric", "Uint"
            )

        # Extract the inner len() call's arguments
        inner_call = updated_node.args[0].value
        assert isinstance(inner_call, cst.Call)

        # Build ulen(...) preserving the inner arguments
        return updated_node.with_changes(
            func=cst.Name("ulen"),
            args=inner_call.args,
        )


def main() -> None:
    src_dir = Path("src/ethereum")
    files = sorted(src_dir.rglob("*.py"))

    for path in files:
        source = path.read_text()

        context = CodemodContext()
        tree = cst.parse_module(source)
        new_tree = UintLenToUlen(context).transform_module(tree)
        new_source = new_tree.code

        if new_source != source:
            path.write_text(new_source)
            print(f"  Modified: {path}")


if __name__ == "__main__":
    main()

Cute Animal Picture

Put a link to a cute animal picture inside the parenthesis-->

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 27, 2026

Codecov Report

❌ Patch coverage is 95.83333% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.35%. Comparing base (c1d8f42) to head (58a1584).

Files with missing lines Patch % Lines
src/ethereum/forks/amsterdam/block_access_lists.py 50.00% 1 Missing ⚠️
...orks/frontier/vm/precompiled_contracts/identity.py 50.00% 1 Missing ⚠️
.../forks/frontier/vm/precompiled_contracts/sha256.py 50.00% 1 Missing ⚠️
...rks/homestead/vm/precompiled_contracts/identity.py 50.00% 1 Missing ⚠️
...forks/homestead/vm/precompiled_contracts/sha256.py 50.00% 1 Missing ⚠️
Additional details and impacted files
@@               Coverage Diff                @@
##           forks/amsterdam    #2580   +/-   ##
================================================
  Coverage            86.35%   86.35%           
================================================
  Files                  599      599           
  Lines                36904    36904           
  Branches              3771     3771           
================================================
  Hits                 31868    31868           
  Misses                4485     4485           
  Partials               551      551           
Flag Coverage Δ
unittests 86.35% <95.83%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant