Skip to content

Commit cbc4641

Browse files
committed
Add varargs support to multiple dispatch
1 parent d41b440 commit cbc4641

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed

unpythonic/dispatch.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
__all__ = ["generic", "specific"]
2222

2323
from functools import wraps
24+
from itertools import chain
2425
import inspect
2526
import typing
2627

@@ -83,9 +84,15 @@ def generic(f):
8384
def multidispatch(*args, **kwargs):
8485
# signature comes from typing.get_type_hints.
8586
def match_argument_types(signature):
86-
# TODO: handle *args (bindings["vararg"], bindings["vararg_name"])
8787
# TODO: handle **kwargs (bindings["kwarg"], bindings["kwarg_name"])
88-
for parameter, value in bindings["args"].items():
88+
args_items = bindings["args"].items()
89+
if bindings["vararg_name"]:
90+
vararg_item = (bindings["vararg_name"], bindings["vararg"]) # *args
91+
all_items = tuple(chain(args_items, (vararg_item,)))
92+
else:
93+
all_items = args_items
94+
95+
for parameter, value in all_items:
8996
assert parameter in signature # resolve_bindings should already TypeError when not.
9097
expected_type = signature[parameter]
9198
if not match_value_to_typespec(value, expected_type):

unpythonic/test/test_dispatch.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,19 @@ def example(start: int, step: int, stop: int):
3535
def _example_impl(start, step, stop):
3636
return start, step, stop
3737

38+
# varargs are supported via `typing.Tuple`
39+
@generic
40+
def gargle(): ...
41+
@gargle.register
42+
def gargle(*args: typing.Tuple[int, ...]): # any number of ints
43+
return "int"
44+
@gargle.register
45+
def gargle(*args: typing.Tuple[float, ...]): # any number of floats
46+
return "float"
47+
@gargle.register
48+
def gargle(*args: typing.Tuple[int, float, str]): # three args, matching the given types
49+
return "int, float, str"
50+
3851
# One-method pony.
3952
@specific
4053
def blubnify(x: int, y: float):
@@ -62,6 +75,11 @@ def test():
6275
assert example(1, 1, 5) == (1, 1, 5)
6376
assert example(1, 2, 5) == (1, 2, 5)
6477

78+
assert gargle(1, 2, 3, 4, 5) == "int"
79+
assert gargle(2.71828, 3.14159) == "float"
80+
assert gargle(42, 6.022e23, "hello") == "int, float, str"
81+
assert gargle(1, 2, 3) == "int" # as many as in the [int, float, str] case
82+
6583
assert blubnify(2, 21.0) == 42
6684
try:
6785
blubnify(2, 3)

0 commit comments

Comments
 (0)