Skip to content

Commit 31cbefd

Browse files
committed
Fix positional-only parameters order
1 parent 944d43f commit 31cbefd

File tree

2 files changed

+65
-3
lines changed

2 files changed

+65
-3
lines changed

src/mutmut/file_mutation.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,10 +258,10 @@ def function_trampoline_arrangement(function: cst.FunctionDef, mutants: Iterable
258258

259259
def create_trampoline_wrapper(function: cst.FunctionDef, mangled_name: str, class_name: str | None) -> cst.FunctionDef:
260260
args: list[cst.Element | cst.StarredElement] = []
261-
for param in function.params.params:
262-
args.append(cst.Element(param.name))
263261
for pos_only_param in function.params.posonly_params:
264262
args.append(cst.Element(pos_only_param.name))
263+
for param in function.params.params:
264+
args.append(cst.Element(param.name))
265265
if isinstance(function.params.star_arg, cst.Param):
266266
args.append(cst.StarredElement(function.params.star_arg.name))
267267

tests/test_mutation regression.py

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,68 @@
11
from inline_snapshot import snapshot
2+
import libcst as cst
23

3-
from mutmut.file_mutation import mutate_file_contents
4+
from mutmut.file_mutation import mutate_file_contents, create_trampoline_wrapper
5+
6+
7+
def _get_trampoline_wrapper(
8+
source: str, mangled_name: str, class_name: str | None = None
9+
) -> str:
10+
function = cst.ensure_type(cst.parse_statement(source), cst.FunctionDef)
11+
trampoline = create_trampoline_wrapper(
12+
function, mangled_name, class_name=class_name
13+
)
14+
return cst.Module([trampoline]).code.strip()
15+
16+
17+
def test_create_trampoline_wrapper_async_method():
18+
source = "async def foo(a: str, b, *args, **kwargs) -> dict[str, int]: pass"
19+
20+
assert _get_trampoline_wrapper(source, "x_foo__mutmut") == snapshot("""\
21+
async def foo(a: str, b, *args, **kwargs) -> dict[str, int]:
22+
args = [a, b, *args]
23+
kwargs = {**kwargs}
24+
return await _mutmut_trampoline(x_foo__mutmut_orig, x_foo__mutmut_mutants, args, kwargs, None)\
25+
""")
26+
27+
28+
def test_create_trampoline_wrapper_async_generator():
29+
source = """
30+
async def foo():
31+
for i in range(10):
32+
yield i
33+
"""
34+
35+
assert _get_trampoline_wrapper(source, "x_foo__mutmut") == snapshot("""\
36+
async def foo():
37+
args = []
38+
kwargs = {}
39+
async for i in _mutmut_trampoline(x_foo__mutmut_orig, x_foo__mutmut_mutants, args, kwargs, None):
40+
yield i\
41+
""")
42+
43+
44+
def test_create_trampoline_wrapper_with_positionals_only_args():
45+
source = "def foo(p1, p2=None, /, p_or_kw=None, *, kw): pass"
46+
47+
assert _get_trampoline_wrapper(source, "x_foo__mutmut") == snapshot("""\
48+
def foo(p1, p2=None, /, p_or_kw=None, *, kw):
49+
args = [p1, p2, p_or_kw]
50+
kwargs = {'kw': kw}
51+
return _mutmut_trampoline(x_foo__mutmut_orig, x_foo__mutmut_mutants, args, kwargs, None)\
52+
""")
53+
54+
55+
def test_create_trampoline_wrapper_for_class_method():
56+
source = "def foo(self, a, b): pass"
57+
58+
assert _get_trampoline_wrapper(
59+
source, "x_foo__mutmut", class_name="Person"
60+
) == snapshot("""\
61+
def foo(self, a, b):
62+
args = [a, b]
63+
kwargs = {}
64+
return _mutmut_trampoline(object.__getattribute__(self, 'x_foo__mutmut_orig'), object.__getattribute__(self, 'x_foo__mutmut_mutants'), args, kwargs, self)\
65+
""")
466

567

668
def test_module_mutation():

0 commit comments

Comments
 (0)