coady / multimethod

Multiple argument dispatching.
https://coady.github.io/multimethod
Other
284 stars 23 forks source link

Support for Callable #59

Closed LuxMiranda closed 2 years ago

LuxMiranda commented 2 years ago

Currently, the following does not run:

from typing import Callable
from multimethod import multimethod

plusOne : Callable[[int],int] = lambda n : n + 1
addFrog : Callable[[str],str] = lambda s : s + ' and frogs!'

@multimethod
def nameMyFunc(f: Callable[[int], int]):
    print('My argument is a function that takes an int and returns an int')
    return

@nameMyFunc.register
def _(f: Callable[[str], str]):
    print('My argument is a function that takes a str and returns a str')
    return

nameMyFunc(plusOne)
nameMyFunc(addFrog)

The expected output is:

My argument is a function that takes an int and returns an int
My argument is a function that takes a str and returns a str

The actual output is:

Traceback (most recent call last):
  File "/home/lux/repos/cats/test.py", line 17, in <module>
    nameMyFunc(plusOne)
  File "/home/lux/miniconda3/lib/python3.9/site-packages/multimethod/__init__.py", line 298, in __call__
    func = self[tuple(func(arg) for func, arg in zip(self.type_checkers, args))]
  File "/home/lux/miniconda3/lib/python3.9/site-packages/multimethod/__init__.py", line 292, in __missing__
    raise DispatchError(msg, types, keys)
multimethod.DispatchError: ('nameMyFunc: 0 methods found', (<class 'function'>,), [])

Is supporting function arguments with specific argument and return types like this even possible?

coady commented 2 years ago

It could support checking Callable subscripts, but the input functions would have to have type hints.

def plusOne(n: int) -> int:
    return n + 1

def addFrog(s: str) -> str:
    return s + ' and frogs!'
LuxMiranda commented 2 years ago

That would make sense since the type hints are what differentiate each function. Would it also be possible to support things like generic types, the [...] thing, and custom TypeVars?

I really love the idea of just continually hacking Python into the purely functional language it was never meant to be :joy: Thank you for this library

coady commented 2 years ago

Added support for Callable in 5c9d985, and with Ellipsis. TypeVar is already supported.

mofeing commented 2 years ago

@coady are you preparing a new release soon with this included? i need it for my library and while i can install multimethod directly from the repo, it would be nice to have a version tag so i can put it in the requirements :)

coady commented 2 years ago

@coady are you preparing a new release soon with this included? i need it for my library and while i can install multimethod directly from the repo, it would be nice to have a version tag so i can put it in the requirements :)

Released in v1.8.