Skip to content

Comments

Preserve function signature#469

Merged
Otto-AA merged 3 commits intomainfrom
keep-signature
Feb 15, 2026
Merged

Preserve function signature#469
Otto-AA merged 3 commits intomainfrom
keep-signature

Conversation

@Otto-AA
Copy link
Collaborator

@Otto-AA Otto-AA commented Feb 14, 2026

Closes #454 and #465 .

@boxed In case you want to review, this is a slightly bigger change of trampoline internals. This PR adds some complexity at the trampoline wrapper (handling various possible parameter formats, async declarations and async generators), but I think it's worth it so we can preserve the original function signature. Also, don't need to manually copy the signature with trampoline.__signature__ = inspect.signature(original_method) anymore.

With this change, asyncio.iscoroutinefunction(async_func) also returns true after we mutated the function. This is done by using the same signature as it was originally, and adding some logic to pass our arguments to the trampoline.

For instance:

async def foo(a: str, b, *args, **kwargs) -> dict[str, int]:
    # ...

Will be mutated to:

async def foo(a: str, b, *args, **kwargs) -> dict[str, int]:
    args = [a, b, *args]
    kwargs = {**kwargs}
    return await _mutmut_trampoline(x_foo__mutmut_orig, x_foo__mutmut_mutants, args, kwargs, None)

In the commit 944d43f, I've also added inline-snapshot (+ruff formatting for the snapshots) to make it easier to work with regression snapshots. e.g. the tests/test_mutation regression.py are useful to have and with inline-snapshot it's easier to update them whenever some implementation detail changes.

The e2e tests and a sample repository I tried were not affected by this change, so I don't think it breaks existing functionality.

@Otto-AA Otto-AA requested a review from boxed February 14, 2026 19:42
@boxed
Copy link
Owner

boxed commented Feb 14, 2026

Nice!

@Otto-AA Otto-AA merged commit f631c40 into main Feb 15, 2026
10 checks passed
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.

Async functions get synchronous trampolines causing "coroutine was never awaited" errors

2 participants