-
If a dispatched method has a
(and you might not want to allow complex numbers, for example) Shouldn't this then also be possible with plum? Example code: from plum import dispatch
class Test:
@dispatch
def test_method(self, arg: float):
print(arg)
@dispatch
def test_method(self, string_arg: str):
print(string_arg)
if __name__ == '__main__':
test = Test()
test.test_method(1.0)
test.test_method("test")
test.test_method(1) Output:
|
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 1 reply
-
Hey @bariod! Thanks for opening a discussion. :) That's an interesting point. Since @leycec, if you have a spare moment, what does @beartype say about (An easy workaround, of course, would be to use |
Beta Was this translation helpful? Give feedback.
-
@leycec has been summoned! Thanks a heap for pinging me on, @wesselb. Indeed, @beartype complies with almost all PEP standards... almost. @beartype even complies with super-bad PEP standards that everybody else tries hard to ignore like PEP 563 (i.e., Occasionally, a subset of a PEP standard is so bad that @beartype quietly rejects that subset by default. When @beartype does this, @beartype also provides a configuration option allowing users to conditionally enable support for that rejected subset. What I'm trying to say is... @beartype Rejects the Implicit Numeric Tower By DefaultThe implicit numeric tower is dumb. Seriously. It's so dumb I should write a FAQ entry about how dumb the implicit numeric tower is. Sadly, I am lazy. Still, this is Python. PEP 20 requires us to believe that:
PEP 20 is usually right. This is no exception. There's no practical advantage for @beartype to enable something that's implicitly dumb by default and considerably practical disadvantage. In the case of the implicit numeric tower, integers are not floats. They just aren't. Trying to pretend they are is usually a bad idea – even when you don't think it is. Most integers have no exact representation as floats. Likewise, most floats have no exact representation as integers. This means that whenever you coerce an integer into a float or vice versa, there's a loss of numerical precision. The more numbers you coerce, the larger the loss of numerical precision. This loss magnifies when you start exponentiating these numbers. That's fine for some use cases; that's not fine for other cases. @beartype makes no assumptions about user use cases. Therefore, @beartype disables the implicit numeric tower by default. "Safety first" is the @beartype motto. We protect everyone from themselves – even when they don't want us to. For users that really want to pretend that integers and floats are basically the same, though, @beartype provides the # Import the requisite machinery.
from beartype import beartype, BeartypeConf
# Dynamically create a new @beartowertype decorator enabling the tower.
beartowertype = beartype(conf=BeartypeConf(is_pep484_tower=True))
# Decorate with this decorator rather than @beartype everywhere.
@beartowertype
def crunch_numbers(numbers: list[float]) -> float:
return sum(numbers)
# This is now fine.
crunch_numbers([3, 1, 4, 1, 5, 9])
# This is still fine, too.
crunch_numbers([3.1, 4.1, 5.9]) Problem solved. 🥳 But, Uhh. This Is Plum?Right. I... have no idea whether the public Plum API accepts @beartype configurations or not. Like the implicit numeric tower, I too am dumb. If the from beartype import BeartypeConf
from numbers import Number
from plum import dispatch
# @beartype configuration enabling the implicit numeric tower.
beartype_conf_tower = BeartypeConf(is_pep484_tower=True)
@dispatch(conf=beartype_conf_tower)
def f(x: str):
return "This is a string!"
@dispatch(conf=beartype_conf_tower)
def f(x: int):
return "This is an integer!"
@dispatch(conf=beartype_conf_tower)
def f(x: Number):
return "This is a general number, but I don't know which type." Problem solved. 🥳 🍰 🎈 But, Uhh. You Just Made That Up?...uhm. Yes. I just made that up. Very well! I admit it. It's all lies over here. That almost certainly doesn't work. As @wesselb suggests, at least there's always |
Beta Was this translation helpful? Give feedback.
-
A crystal clear reply! I fully agree on all counts. (Of course.) At this point, though, I'm spoiled, used to no less by @leycec. 😎 Thanks for taking the time to write this up. :) @bariod, I hope this answers your question. :) |
Beta Was this translation helpful? Give feedback.
@leycec has been summoned! Thanks a heap for pinging me on, @wesselb. Indeed, @beartype complies with almost all PEP standards... almost. @beartype even complies with super-bad PEP standards that everybody else tries hard to ignore like PEP 563 (i.e.,
from future import __annotations__
). Even Guido can admit that PEP 563 really sucks. That's when you know a PEP standard is bad.Occasionally, a subset of a PEP standard is so bad that @beartype quietly rejects that subset by default. When @beartype does this, @beartype also provides a configuration option allowing users to conditionally enable support for that rejected subset.
What I'm trying to say is...
@beartype Rejects the Implicit Nume…