Skip to content
New issue

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

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

Already on GitHub? # to your account

singledispatch(method).register should accept UnionType #13560

Closed
flying-sheep opened this issue Feb 28, 2025 · 4 comments · Fixed by #13578
Closed

singledispatch(method).register should accept UnionType #13560

flying-sheep opened this issue Feb 28, 2025 · 4 comments · Fixed by #13578
Labels
stubs: false positive Type checkers report false errors

Comments

@flying-sheep
Copy link
Contributor

This works perfectly fine at runtime:

from functools import singledispatch

@singledispatch
def greet(greetee: object):
    raise NotImplementedError

@greet.register(int | bool)
def _(greetee: int | bool):
    print(f"hi {greetee}!")

greet(1)

but mypy says (playground link)

main.py:7: error: No overload variant of "register" of "_SingleDispatchCallable" matches argument type "UnionType"  [call-overload]
main.py:7: note: Possible overload variants:
main.py:7: note:     def register(self, cls: type[Any], func: None = ...) -> Callable[[Callable[..., Any]], Callable[..., Any]]
main.py:7: note:     def register(self, cls: Callable[..., Any], func: None = ...) -> Callable[..., Any]
main.py:7: note:     def register(self, cls: type[Any], func: Callable[..., Any]) -> Callable[..., Any]
@srittau srittau added the stubs: false positive Type checkers report false errors label Feb 28, 2025
@srittau
Copy link
Collaborator

srittau commented Feb 28, 2025

I don't think there's a way to express this yet, although the Type Form PEP (PEP 747) might change that. Our best bet for now is an Any overload. PR welcome.

@flying-sheep
Copy link
Contributor Author

What do you mean? int | bool in value position should have type types.UnionType. Shouldn‘t this just be a change to

@overload
def register(self, cls: type[Any], func: None = None) -> Callable[[Callable[..., _T]], Callable[..., _T]]: ...

and

@overload
def register(self, cls: type[Any], method: None = None) -> Callable[[Callable[..., _T]], Callable[..., _T]]: ...

like

 @overload
-def register(self, cls: type[Any], func: None = None) -> Callable[[Callable[..., _T]], Callable[..., _T]]: ...
+def register(self, cls: type[Any] | UnionType, func: None = None) -> Callable[[Callable[..., _T]], Callable[..., _T]]: ...

@srittau
Copy link
Collaborator

srittau commented Mar 3, 2025

I didn't realize that we can use UnionType in type annotations (and that this actually works). If that's the case, this would of course be the better solution!

@flying-sheep
Copy link
Contributor Author

I didn't realize that we can use UnionType in type annotations (and that this actually works).

That’s why I started this issue with

This works perfectly fine at runtime

haha!

I made a PR.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
stubs: false positive Type checkers report false errors
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants