Skip to content

Commit 65e431b

Browse files
committed
[mypyc] feat: PyObject_CallObject op for fn(*args)
1 parent 2f0e0fe commit 65e431b

File tree

4 files changed

+31
-26
lines changed

4 files changed

+31
-26
lines changed

mypyc/annotate.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ def __init__(self, message: str, priority: int = 1) -> None:
7777
"PyNumber_Rshift": Annotation('Generic ">>" operation.'),
7878
"PyNumber_Invert": Annotation('Generic "~" operation.'),
7979
"PyObject_Call": Annotation("Generic call operation."),
80+
"PyObject_CallObject": Annotation("Generic call operation."),
8081
"PyObject_RichCompare": Annotation("Generic comparison operation."),
8182
"PyObject_GetItem": Annotation("Generic indexing operation."),
8283
"PyObject_SetItem": Annotation("Generic indexed assignment."),

mypyc/irbuild/ll_builder.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@
138138
generic_ssize_t_len_op,
139139
py_call_op,
140140
py_call_with_kwargs_op,
141+
py_call_with_posargs_op,
141142
py_getattr_op,
142143
py_method_call_op,
143144
py_vectorcall_method_op,
@@ -801,7 +802,7 @@ def _construct_varargs(
801802
value = self.primitive_op(list_tuple_op, [value], line)
802803
elif not is_tuple_rprimitive(value.type):
803804
value = self.primitive_op(sequence_tuple_op, [value], line)
804-
return value, self._create_dict([], [], line)
805+
return value, None
805806
elif len(args) == 2 and args[1][1] == ARG_STAR2:
806807
# fn(*args, **kwargs)
807808
if is_tuple_rprimitive(value.type):
@@ -939,13 +940,16 @@ def py_call(
939940
if arg_kinds is None or all(kind == ARG_POS for kind in arg_kinds):
940941
return self.call_c(py_call_op, [function] + arg_values, line)
941942

942-
# Otherwise fallback to py_call_with_kwargs_op.
943+
# Otherwise fallback to py_call_with_posargs_op or py_call_with_kwargs_op.
943944
assert arg_names is not None
944945

945946
pos_args_tuple, kw_args_dict = self._construct_varargs(
946947
list(zip(arg_values, arg_kinds, arg_names)), line, has_star=True, has_star2=True
947948
)
948-
assert pos_args_tuple and kw_args_dict
949+
assert pos_args_tuple
950+
951+
if kw_args_dict is None:
952+
return self.call_c(py_call_with_posargs_op, [function, pos_args_tuple], line)
949953

950954
return self.call_c(py_call_with_kwargs_op, [function, pos_args_tuple, kw_args_dict], line)
951955

mypyc/primitives/generic_ops.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,15 @@
307307
error_kind=ERR_MAGIC,
308308
)
309309

310+
# Call callable object with positional args only: func(*args)
311+
# Arguments are (func, *args tuple).
312+
py_call_with_posargs_op = custom_op(
313+
arg_types=[object_rprimitive, object_rprimitive],
314+
return_type=object_rprimitive,
315+
c_function_name="PyObject_CallObject",
316+
error_kind=ERR_MAGIC,
317+
)
318+
310319
# Call method with positional arguments: obj.method(arg1, ...)
311320
# Arguments are (object, attribute name, arg1, ...).
312321
py_method_call_op = custom_op(

mypyc/test-data/irbuild-basic.test

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1676,20 +1676,18 @@ def g():
16761676
r2 :: str
16771677
r3, r4 :: object
16781678
r5 :: tuple
1679-
r6 :: dict
1680-
r7 :: object
1681-
r8 :: tuple[int, int, int]
1679+
r6 :: object
1680+
r7 :: tuple[int, int, int]
16821681
L0:
16831682
r0 = (2, 4, 6)
16841683
r1 = __main__.globals :: static
16851684
r2 = 'f'
16861685
r3 = CPyDict_GetItem(r1, r2)
16871686
r4 = box(tuple[int, int, int], r0)
16881687
r5 = PySequence_Tuple(r4)
1689-
r6 = PyDict_New()
1690-
r7 = PyObject_Call(r3, r5, r6)
1691-
r8 = unbox(tuple[int, int, int], r7)
1692-
return r8
1688+
r6 = PyObject_CallObject(r3, r5)
1689+
r7 = unbox(tuple[int, int, int], r6)
1690+
return r7
16931691
def h():
16941692
r0 :: tuple[int, int]
16951693
r1 :: dict
@@ -3568,15 +3566,12 @@ def wrapper_deco_obj.__call__(__mypyc_self__, args):
35683566
__mypyc_self__ :: __main__.wrapper_deco_obj
35693567
args :: tuple
35703568
r0 :: __main__.deco_env
3571-
r1 :: object
3572-
r2 :: dict
3573-
r3 :: object
3569+
r1, r2 :: object
35743570
L0:
35753571
r0 = __mypyc_self__.__mypyc_env__
35763572
r1 = r0.fn
3577-
r2 = PyDict_New()
3578-
r3 = PyObject_Call(r1, args, r2)
3579-
return r3
3573+
r2 = PyObject_CallObject(r1, args)
3574+
return r2
35803575
def deco(fn):
35813576
fn :: object
35823577
r0 :: __main__.deco_env
@@ -3619,15 +3614,13 @@ def wrapper_deco_obj.__call__(__mypyc_self__, args):
36193614
r0 :: __main__.deco_env
36203615
r1 :: object
36213616
r2 :: tuple
3622-
r3 :: dict
3623-
r4 :: object
3617+
r3 :: object
36243618
L0:
36253619
r0 = __mypyc_self__.__mypyc_env__
36263620
r1 = r0.fn
36273621
r2 = PyList_AsTuple(args)
3628-
r3 = PyDict_New()
3629-
r4 = PyObject_Call(r1, r2, r3)
3630-
return r4
3622+
r3 = PyObject_CallObject(r1, r2)
3623+
return r3
36313624
def deco(fn):
36323625
fn :: object
36333626
r0 :: __main__.deco_env
@@ -3726,15 +3719,13 @@ def wrapper_deco_obj.__call__(__mypyc_self__, args):
37263719
r0 :: __main__.deco_env
37273720
r1 :: object
37283721
r2 :: tuple
3729-
r3 :: dict
3730-
r4 :: object
3722+
r3 :: object
37313723
L0:
37323724
r0 = __mypyc_self__.__mypyc_env__
37333725
r1 = r0.fn
37343726
r2 = PySequence_Tuple(args)
3735-
r3 = PyDict_New()
3736-
r4 = PyObject_Call(r1, r2, r3)
3737-
return r4
3727+
r3 = PyObject_CallObject(r1, r2)
3728+
return r3
37383729
def deco(fn):
37393730
fn :: object
37403731
r0 :: __main__.deco_env

0 commit comments

Comments
 (0)