[Python-ideas] Add additional special method lookups to math module

Case Van Horsen casevh at gmail.com
Thu Nov 10 01:55:16 CET 2011


On Wed, Nov 9, 2011 at 3:02 PM, Steven D'Aprano <steve at pearwood.info> wrote:
> Case Van Horsen wrote:
>>
>> Currently the functions round(), math.ceil(), math.floor(), and
>> math.trunc() all check for the existence of a special method
>> (__round__, __ceil__, __floor__, and __trunc__). Would it be possible
>> to enhance the math and cmath modules to check for the existence of a
>> special method for (almost) functions? For example, math.sin(obj)
>> would first check for obj.__sin__.
>
> I would not object to this.
>
> The only function I can honestly say I have had a concrete use-case for is
> math.sqrt. This comes up from time to time, e.g.:
>
> http://bytes.com/topic/python/answers/463861-how-overload-sqrt-module
> http://permalink.gmane.org/gmane.comp.python.general/694849
>
> However, how far should we go? Does every function in the math module
> require a dunder method, e.g. __degrees__ ? What happens if we add more
> functions, say math.bessel? Do we really expect that all numeric types must
> support a __bessel__ method? I suspect that this proposal is actually bigger
> than it seems at first glance.

It would be completely optional for a numeric type to support these
methods. If they're not supported, the numeric type is converted to a
float and then math.function proceeds as it currently does.

>
> We can:
>
> * Do nothing (the status quo). If you write a numeric type, you can support
> a small number of mathematical operations, such as + and math.floor, but not
> others, such as math.sqrt or math.sin.
>
> * Officially recommend that people monkey-patch the math module if they want
> to write a drop-in replacement for numeric types. I consider this
> unspeakable, but mention it for completeness since others have raised the
> possibility.
>
> * Add support for dunder methods in an ad hoc manner, when and as requested,
> without making any promises about any other functions.

I hacked mathmodule.c FUNC1 macro to perform the lookup the many of
math module functions. It was only about 15 lines of code (but it
doesn't check if NotImplemented is returned.) Unfortunately, it
increases the running time of math.sin, for example, by 15%. I need to
look at the Identifier API to see if that helps the performance but I
don't think 15% is a penalty everyone should pay.

>
> * Add support for dunder methods in a systematic way. This would require
> distinguishing between fundamental operations that should support dunder
> methods, and those that shouldn't (if any). This will probably need a PEP.
>
Especially true if new nb_slots need to be created to avoid the
performance impact. I was hoping the performance impact of the special
method lookup was negligible so it could be a low impact change.

> * Instead of having to decide what operations should be supported ahead of
> time, perhaps there is a way for types to register themselves with the math
> module, e.g. say "I support sin, but not sinh". Somewhat akin to the way
> ABCs work, at least conceptually. One advantage of that may be that numeric
> classes won't have to use dunder methods for supporting the math module,
> e.g. MyNumber might register sin rather than __sin__.

As long as they support __float__, they'll continue to work with the
math module.
>
>
> --
> Steven
>
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> http://mail.python.org/mailman/listinfo/python-ideas
>



More information about the Python-ideas mailing list