Skip to content

Fix handling of default arguments in generated glue methods #10825

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions mypyc/ir/func_ir.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,32 @@ class RuntimeArg:
Argument kind is one of ARG_* constants defined in mypy.nodes.
"""

def __init__(self, name: str, typ: RType, kind: ArgKind = ARG_POS) -> None:
def __init__(
self, name: str, typ: RType, kind: ArgKind = ARG_POS, pos_only: bool = False) -> None:
self.name = name
self.type = typ
self.kind = kind
self.pos_only = pos_only

@property
def optional(self) -> bool:
return self.kind.is_optional()

def __repr__(self) -> str:
return 'RuntimeArg(name=%s, type=%s, optional=%r)' % (self.name, self.type, self.optional)
return 'RuntimeArg(name=%s, type=%s, optional=%r, pos_only=%r)' % (
self.name, self.type, self.optional, self.pos_only)

def serialize(self) -> JsonDict:
return {'name': self.name, 'type': self.type.serialize(), 'kind': int(self.kind.value)}
return {'name': self.name, 'type': self.type.serialize(), 'kind': int(self.kind.value),
'pos_only': self.pos_only}

@classmethod
def deserialize(cls, data: JsonDict, ctx: DeserMaps) -> 'RuntimeArg':
return RuntimeArg(
data['name'],
deserialize_type(data['type'], ctx),
ArgKind(data['kind']),
data['pos_only'],
)


Expand Down
24 changes: 20 additions & 4 deletions mypyc/irbuild/function.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
from mypyc.primitives.dict_ops import dict_set_item_op
from mypyc.common import SELF_NAME, LAMBDA_NAME, decorator_helper_name
from mypyc.sametype import is_same_method_signature
from mypyc.irbuild.util import concrete_arg_kind, is_constant
from mypyc.irbuild.util import is_constant
from mypyc.irbuild.context import FuncInfo, ImplicitClass
from mypyc.irbuild.targets import AssignmentTarget
from mypyc.irbuild.statement import transform_try_except
Expand Down Expand Up @@ -660,9 +660,10 @@ def get_args(builder: IRBuilder, rt_args: Sequence[RuntimeArg], line: int) -> Ar
fake_vars = [(Var(arg.name), arg.type) for arg in rt_args]
args = [builder.read(builder.add_local_reg(var, type, is_arg=True), line)
for var, type in fake_vars]
arg_names = [arg.name if arg.kind.is_named() else None
arg_names = [arg.name
if arg.kind.is_named() or (arg.kind.is_optional() and not arg.pos_only) else None
for arg in rt_args]
arg_kinds = [concrete_arg_kind(arg.kind) for arg in rt_args]
arg_kinds = [arg.kind for arg in rt_args]
return ArgInfo(args, arg_names, arg_kinds)


Expand Down Expand Up @@ -705,9 +706,24 @@ def f(builder: IRBuilder, x: object) -> int: ...
arg_info = get_args(builder, rt_args, line)
args, arg_kinds, arg_names = arg_info.args, arg_info.arg_kinds, arg_info.arg_names

# We can do a passthrough *args/**kwargs with a native call, but if the
# args need to get distributed out to arguments, we just let python handle it
if (
any(kind.is_star() for kind in arg_kinds)
and any(not arg.kind.is_star() for arg in target.decl.sig.args)
):
do_pycall = True

if do_pycall:
if target.decl.kind == FUNC_STATICMETHOD:
# FIXME: this won't work if we can do interpreted subclasses
first = builder.builder.get_native_type(cls)
st = 0
else:
first = args[0]
st = 1
retval = builder.builder.py_method_call(
args[0], target.name, args[1:], line, arg_kinds[1:], arg_names[1:])
first, target.name, args[st:], line, arg_kinds[st:], arg_names[st:])
else:
retval = builder.builder.call(target.decl, args, arg_kinds, arg_names, line)
retval = builder.coerce(retval, sig.ret_type, line)
Expand Down
Loading