Skip to content

Commit

Permalink
Support generic annotations in overload.
Browse files Browse the repository at this point in the history
Generic aliases pass as `callable`, even though they are not. A related issue found in #90: prior to Python 3.11, a parameter with a default of `None` was automatically coerced to `Optional` by `get_type_hints`.
  • Loading branch information
coady committed Mar 30, 2023
1 parent d3560af commit 9cfdccd
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ dev
* Python >=3.8 required
* `Type[...]` dispatches on class arguments
* `|` syntax for union types
* `overload` supports generics

1.9.1

Expand Down
2 changes: 1 addition & 1 deletion multimethod/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ def __new__(cls, func):

def __init__(self, func: Callable):
for name, value in get_type_hints(func).items():
if not callable(value) or isinstance(value, type):
if not callable(value) or isinstance(value, type) or hasattr(value, '__origin__'):
func.__annotations__[name] = isa(value)
self[inspect.signature(func)] = func

Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ classifiers = [
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Software Development :: Libraries :: Python Modules",
"Typing :: Typed",
]
Expand Down
11 changes: 10 additions & 1 deletion tests/test_overload.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import pytest
from typing import List, Literal
from typing import List, Literal, Optional
from multimethod import DispatchError, isa, overload


Expand Down Expand Up @@ -45,3 +45,12 @@ def test_generic():
assert not pred([0.0])
assert pred(0.0)
assert not pred(1.0)

@overload
def func(arg: Optional[str]):
return arg

assert func('') == ''
assert func(None) is None
with pytest.raises(DispatchError):
func(0)

0 comments on commit 9cfdccd

Please sign in to comment.