[Feature Request] Support `typing.get_overloads()` under Python ≥ 3.11
See original GitHub issueGreetings
Hi, dear weird bear aficionado! First of all, thanks for this awesome library! I’ve just started using it and it looks great, I can’t wait to write runtime-type-safe functions everywhere.
What I would like to see
One functionality that I would love to see here is the ability to write overloaded functions, akin to typing.overload
, but at runtime. Something like this:
from beartype import overload
@overload
def greet(name: str, age: int) -> None: ...
@greet.overload
def greet(age: int) -> None: ...
@greet.implement
def greet(name_or_age, age=None):
if age is None:
age = name_or_age
if age > 20:
print('Hello, unknown person! You are allowed to enter.')
else:
print('Go back home, unknown child!')
else:
name = name_or_age
if age > 20:
print(f'Hello, {name}! You are allowed to enter.')
else:
print(f'Go back home, {name}!')
greet('Ruan', 24) # prints "Hello, Ruan! You are allowed to enter."
greet(24) # prints "Hello, unknown person! You are allowed to enter."
greet('Ruan') # ROOOOAARRR!!! - because there are no overloads matching the signature "greet(str)"
Note that this is not equivalent to writing greet(name_or_age: Union[str, int], age: Optional[int])
since, for instance, greet(10, 10)
is invalid.
Basically, beartype should test function calls against all of the overloaded signatures. If any of them matches, it’s okay. Otherwise, ROAR!
Also note that here I separated the @overload
part from the @implement
one. This is because…
What I am not proposing
I am not proposing function dispatching here. So the following is not what I wish to see:
from beartype import dispatch
@dispatch
def greet(name: str, age: int) -> None:
if age > 20:
print(f'Hello, {name}! You are allowed to enter.')
else:
print(f'Go back home, {name}!')
@dispatch
def greet(age: int) -> None:
if age > 20:
print('Hello, unknown person! You are allowed to enter.')
else:
print('Go back home, unknown child!')
Function dispatching brings a lot of issues such as deciding which implementation to choose for a given signature. And also, there are already some libraries out there that implement single and even multiple dispatching, I don’t believe that that is a job for beartype.
So…
That is why I separated the @overload
and the @implement
parts. The way I see it, beartype should first check for the first overload, and then the second, the third and so on until one matching overload is found. If this is the case, then beartype should just call the @implement
part without any further checks.
Does that make sense to you? Looking forward to seeing your opinion on this!
Issue Analytics
- State:
- Created 2 years ago
- Reactions:1
- Comments:27 (15 by maintainers)
Top GitHub Comments
An update:
typing.get_overloads()
was merged for both 3.11 andtyping_extensions
, so a beartype-specific version isn’t as required.Super-hype. I’m delighted I no longer need to do anything, because 2022 is hard enough. Let’s rename this issue accordingly.
Thanks so much for inspiring and driving the details behind upstream CPython support, Spence! You’re a living phenomena in the typing community.