Repository: RustPython/RustPython
File: scripts/fix_test.py (Python)

Code before:
                indent = " " * node.col_offset
                lines.insert(node.lineno - 1, indent + fixture)
                lines.insert(node.lineno - 1, indent + "# TODO: RUSTPYTHON")
                break
    return "\n".join(lines)


def modify_test_v2(file: str, test: list[str], for_platform: bool = False) -> str:
    a = ast.parse(file)
    lines = file.splitlines()
    fixture = "@unittest.expectedFailure"
    for key, node in ast.iter_fields(a):
        if key == "body":
            for i, n in enumerate(node):
                match n:
                    case ast.ClassDef():
                        if len(test) == 2 and test[0] == n.name:
                            # look through body for function def
                            for i, fn in enumerate(n.body):
                                match fn:
                                    case ast.FunctionDef():
                                        if fn.name == test[-1]:
                                            assert not for_platform
                                            indent = " " * fn.col_offset
                                            lines.insert(
                                                fn.lineno - 1, indent + fixture
                                            )
                                            lines.insert(
                                                fn.lineno - 1,
                                                indent + "# TODO: RUSTPYTHON",
                                            )
                                            break
                    case ast.FunctionDef():
                        if n.name == test[0] and len(test) == 1:
                            assert not for_platform
                            indent = " " * n.col_offset
                            lines.insert(n.lineno - 1, indent + fixture)
                            lines.insert(n.lineno - 1, indent + "# TODO: RUSTPYTHON")
                            break
                if i > 500:
                    exit()
    return "\n".join(lines)


def run_test(test_name):
    print(f"Running test: {test_name}")
    rustpython_location = "./target/release/rustpython"
    import subprocess

    result = subprocess.run(
        [rustpython_location, "-m", "test", "-v", test_name],

Review comment (suggestion):
We should consider to make this script to generate the json payload `lib_updater` is expecting, and (and use its python API to patch the files). both are doing the same thing (ish)

Code after:
            res = res.split(" ")[0]
            test_results.tests_result = res
    return test_results


def path_to_test(path) -> list[str]:
    # path format: test.module_name[.submodule].ClassName.test_method
    # We need [ClassName, test_method] - always the last 2 elements
    parts = path.split(".")
    return parts[-2:]  # Get class name and method name


def find_test_lineno(file: str, test: list[str]) -> tuple[int, int] | None:
    """Find the line number and column offset of a test function.
    Returns (lineno, col_offset) or None if not found.
    """
    a = ast.parse(file)
    for key, node in ast.iter_fields(a):
        if key == "body":
            for n in node:
                match n:
                    case ast.ClassDef():
                        if len(test) == 2 and test[0] == n.name:
                            for fn in n.body:
                                match fn:
                                    case ast.FunctionDef() | ast.AsyncFunctionDef():
                                        if fn.name == test[-1]:
                                            return (fn.lineno, fn.col_offset)
                    case ast.FunctionDef() | ast.AsyncFunctionDef():
                        if n.name == test[0] and len(test) == 1:
                            return (n.lineno, n.col_offset)
    return None


def apply_modifications(file: str, modifications: list[tuple[int, int]]) -> str:
    """Apply all modifications in reverse order to avoid line number offset issues."""
    lines = file.splitlines()
    fixture = "@unittest.expectedFailure"
    # Sort by line number in descending order
    modifications.sort(key=lambda x: x[0], reverse=True)
    for lineno, col_offset in modifications:
        indent = " " * col_offset
        lines.insert(lineno - 1, indent + fixture)
        lines.insert(lineno - 1, indent + "# TODO: RUSTPYTHON")
    return "\n".join(lines)


def run_test(test_name):
    print(f"Running test: {test_name}")
    rustpython_location = "./target/release/rustpython"
    if sys.platform == "win32":