@@ -21,7 +21,7 @@ def {orig_name}({'self, ' if class_name is not None else ''}*args, **kwargs):
2121 result = { trampoline_name } ({ access_prefix } { mangled_name } __mutmut_orig{ access_suffix } , { access_prefix } { mangled_name } __mutmut_mutants{ access_suffix } , args, kwargs{ self_arg } )
2222 return result
2323
24- { orig_name } .__signature__ = _mutmut_signature( { mangled_name } __mutmut_orig)
24+ _mutmut_copy_signature( { orig_name } , { mangled_name } __mutmut_orig)
2525{ mangled_name } __mutmut_orig.__name__ = '{ mangled_name } '
2626"""
2727
@@ -37,11 +37,30 @@ def mangle_function_name(*, name, class_name):
3737# noinspection PyUnresolvedReferences
3838# language=python
3939trampoline_impl = """
40- from inspect import signature as _mutmut_signature
40+ import inspect as _mutmut_inspect
41+ import sys as _mutmut_sys
4142from typing import Annotated
4243from typing import Callable
4344from typing import ClassVar
4445
46+ def _mutmut_copy_signature(trampoline, original_method):
47+ if _mutmut_sys.version_info >= (3, 14):
48+ # PEP 649 introduced deferred loading for annotations
49+ # When some_method.__annotations__ is accessed, Python uses some_method.__annotate__(format) to compute it
50+ # By copying the original __annotate__ method, we provide get the original annotations
51+ trampoline.__annotate__ = original_method.__annotate__
52+ else:
53+ # On Python 3.13 and earlier, __annotations__ can be accessed immediately
54+ trampoline.__annotations__ = original_method.__annotations__
55+
56+ try:
57+ trampoline.__signature__ = _mutmut_inspect.signature(original_method)
58+ except NameError:
59+ # Also, because of PEP 649, it can happen that we cannot eagerly evaluate the signature
60+ # In this case, fall back to stringifying the signature (which could cause different behaviour with runtime introspection)
61+ trampoline.__signature__ = _mutmut_inspect.signature(original_method, annotation_format=_mutmut_inspect.Format.STRING)
62+
63+
4564
4665MutantDict = Annotated[dict[str, Callable], "Mutant"]
4766
0 commit comments