Skip to content

Commit 30a5245

Browse files
committed
Fix TestSingleDispatch.test_method_signatures to put annotations on the right params
See https://github.com/python/cpython/pull/130309/changes#r2663516538. These functions don't annotate parameters for values used in single-dispatching (`item`), they annotate parameters one later (`arg`). This being legal relies on a bug -- GH-84644, which is that `singledispatch` doesn't verify the annotation is on the "first" parameter. I think these functions should look like ```diff @functools.singledispatchmethod - def func(self, item, arg: int) -> str: + def func(self, item: int, arg) -> str: return str(item) @func.register - def _(self, item, arg: bytes) -> str: + def _(self, item: bytes, arg) -> str: return str(item) ``` (and signature tests updated accordingly) In practice, it doesn't matter how you annotate `func` here, because it's a default callback. But what matters is that any function passed to `register()` annotates the target parameter (always first positional in `singledispatch` and always second positional in `singledispatchmethod` (unless staticmethod, then the first) etc.) for the value to single-dispatch on; not some other, unrelated parameter (or return type, as presented in GH-84644). Let's have a class with the same registree signature as these from the test: ```py class A: @functools.singledispatchmethod def func(self, item, arg: int) -> str: return 'argint' @func.register def _(self, item, arg: bytes) -> str: return 'argbytes' a = A() print(a.func(b'', 1)) ``` For this code, the output would be `argbytes`, even though `arg` is an integer `1`.
1 parent b866a1c commit 30a5245

File tree

1 file changed

+12
-12
lines changed

1 file changed

+12
-12
lines changed

Lib/test/test_functools.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3448,44 +3448,44 @@ def _(item: int, arg: bytes) -> str:
34483448

34493449
def test_method_signatures(self):
34503450
class A:
3451-
def m(self, item, arg: int) -> str:
3451+
def m(self, item: int, arg) -> str:
34523452
return str(item)
34533453
@classmethod
3454-
def cm(cls, item, arg: int) -> str:
3454+
def cm(cls, item: int, arg) -> str:
34553455
return str(item)
34563456
@functools.singledispatchmethod
3457-
def func(self, item, arg: int) -> str:
3457+
def func(self, item: int, arg) -> str:
34583458
return str(item)
34593459
@func.register
3460-
def _(self, item, arg: bytes) -> str:
3460+
def _(self, item: bytes, arg) -> str:
34613461
return str(item)
34623462

34633463
@functools.singledispatchmethod
34643464
@classmethod
3465-
def cls_func(cls, item, arg: int) -> str:
3465+
def cls_func(cls, item: int, arg) -> str:
34663466
return str(arg)
34673467
@func.register
34683468
@classmethod
3469-
def _(cls, item, arg: bytes) -> str:
3469+
def _(cls, item: bytes, arg) -> str:
34703470
return str(item)
34713471

34723472
@functools.singledispatchmethod
34733473
@staticmethod
3474-
def static_func(item, arg: int) -> str:
3474+
def static_func(item: int, arg) -> str:
34753475
return str(arg)
34763476
@func.register
34773477
@staticmethod
3478-
def _(item, arg: bytes) -> str:
3478+
def _(item: bytes, arg) -> str:
34793479
return str(item)
34803480

34813481
self.assertEqual(str(Signature.from_callable(A.func)),
3482-
'(self, item, arg: int) -> str')
3482+
'(self, item: int, arg) -> str')
34833483
self.assertEqual(str(Signature.from_callable(A().func)),
3484-
'(self, item, arg: int) -> str')
3484+
'(self, item: int, arg) -> str')
34853485
self.assertEqual(str(Signature.from_callable(A.cls_func)),
3486-
'(cls, item, arg: int) -> str')
3486+
'(cls, item: int, arg) -> str')
34873487
self.assertEqual(str(Signature.from_callable(A.static_func)),
3488-
'(item, arg: int) -> str')
3488+
'(item: int, arg) -> str')
34893489

34903490
def test_method_non_descriptor(self):
34913491
class Callable:

0 commit comments

Comments
 (0)