Closed hzhangxyz closed 3 years ago
It seems change __init__.py:subtype.__subclasscheck__
to this works, but it is really an ugly solution
def __subclasscheck__(self, subclass):
origin = getattr(subclass, '__extra__', getattr(subclass, '__origin__', subclass))
args = getattr(subclass, '__args__', ())
if origin is typing.Union:
return all(issubclass(cls, self) for cls in args)
if self.__origin__ is typing.Union:
return issubclass(subclass, self.__args__)
issubclass_fixed = lambda x, y : x == y == Ellipsis or (x != Ellipsis and y != Ellipsis and issubclass(x, y))
return ( # check args first to avoid a recursion error in ABCMeta
len(args) == len(self.__args__)
and issubclass(origin, self.__origin__)
and all(map(issubclass_fixed, args, self.__args__))
)
The above change cannot solve ellipsis, see
from multimethod import multimethod
@multimethod
def p(a: tuple[tuple[int, int], ...]):
print(a)
p(((1,2),(3,4)))
it report:
Traceback (most recent call last):
File "/mnt/d/Home/Downloads/main.py", line 10, in <module>
p(((1,2),(3,4)))
File "/usr/lib/python3.9/site-packages/multimethod/__init__.py", line 185, in __call__
return self[tuple(map(self.get_type, args))](*args, **kwargs)
File "/usr/lib/python3.9/site-packages/multimethod/__init__.py", line 181, in __missing__
raise DispatchError(msg, types, keys)
multimethod.DispatchError: ('p: 0 methods found', (<class 'multimethod.<class 'tuple'>'>,), [])
Maybe it is correct way to update something in class subclass
? I don't know about it
For this use case, it would be simpler (and faster) to use Iterable
or Sequence
. But I guess it might as well be supported, to not look like a bug. Thanks.
In my case, I want tuple[tuple[int, int], ...]
to be the key of dict, so it seems Iterable
or Sequence
not work.
Thanks for solving this.
Currently multimethod cannot recognize type contaning ellipsis such as
tuple[int, ...]
However it is a standard way to declare variable-length tuple ref: https://docs.python.org/3/library/typing.html#typing.TupleMaybe add another check in
__init__.py:subtype.__subclasscheck__
would help