Skip to content

Commit 033d0eb

Browse files
superbobrycopybara-github
authored andcommitted
Fixed handling of *args in the functools overlay
See added test for an example where pytype previously crashed. PiperOrigin-RevId: 831282244
1 parent 8b1f6bd commit 033d0eb

File tree

2 files changed

+20
-3
lines changed

2 files changed

+20
-3
lines changed

pytype/overlays/functools_overlay.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,18 @@ def __init__(self, ctx: "context.Context", module: str):
4949
def new_slot(
5050
self, node, cls, func, /, *args, **kwargs
5151
) -> tuple[cfg.CFGNode, cfg.Variable]:
52+
# We are not using ``cls``, because it is set to unsolvable when
53+
# functools.partial is called with *args.
54+
del cls
55+
5256
# Make sure the call is well typed before binding the partial
5357
new = self.ctx.convert.convert_pytd_function(self._pytd_new)
5458
_, specialized_obj = function.call_function(
5559
self.ctx,
5660
node,
5761
new.to_variable(node),
5862
function.Args(
59-
(cls, func, *args),
63+
(self.to_variable(node), func, *args),
6064
kwargs,
6165
call_context.starargs,
6266
call_context.starstarargs,
@@ -65,8 +69,7 @@ def new_slot(
6569
)
6670
[specialized_obj] = specialized_obj.data
6771
type_arg = specialized_obj.get_formal_type_parameter("_T")
68-
[cls] = cls.data
69-
cls = abstract.ParameterizedClass(cls, {"_T": type_arg}, self.ctx)
72+
cls = abstract.ParameterizedClass(self, {"_T": type_arg}, self.ctx)
7073
obj = bind_partial(node, cls, func, args, kwargs, self.ctx)
7174
return node, obj.to_variable(node)
7275

pytype/tests/test_functions1.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,6 +1070,20 @@ def f(a, b) -> None: ...
10701070
""",
10711071
)
10721072

1073+
def test_functools_partial_star(self):
1074+
self.Check("""
1075+
from typing import Any
1076+
import functools
1077+
def f() -> int :
1078+
return 42
1079+
def test(*args):
1080+
assert_type(functools.partial(*args), functools.partial[Any])
1081+
1082+
# This is WAI in pytype, since *args currently overwrite *all* other
1083+
# arguments, including the ones bound positionally prior to *args.
1084+
assert_type(functools.partial(f, *args), functools.partial[Any])
1085+
""")
1086+
10731087
def test_functools_partial_kw(self):
10741088
self.Check("""
10751089
import functools

0 commit comments

Comments
 (0)