clarete / forbiddenfruit

Patch built-in python objects

Home Page:https://clarete.li/forbiddenfruit/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Unable to perfectly re-curse to __add__

kentkolze opened this issue · comments

After cursing np.ndarray.__add__ , even if I re-curse after storing the original in a variable, the __radd__ method breaks.

Way to reproduce

import numpy as np
import forbiddenfruit

orig = np.ndarray.__add__

forbiddenfruit.curse(np.ndarray, '__add__', lambda x, y: 42)
arr = np.arange(5)
print(arr + 2)  # prints 42
print(1 + arr)  # prints 42

forbiddenfruit.curse(np.ndarray, '__add__', orig)
arr2 = np.arange(5)
print(arr + 3)  # prints [3, 4, 5, 6, 7]
print(4 + arr)  # raises: TypeError: descriptor '__add__' requires a 'numpy.ndarray' object but received a 'int'

Questions for cursing __radd__ (and others, such as __rsub__)

  1. Is it possible? Or perhaps dependent on the underlying class?
  2. Do you know where can I find documentation on the nb_* methods so I can find these things out for myself? I attempted to follow common patterns to include __radd__ to the as_number list (wouldve expected nb_radd to be its equivalent) and such to no success

For the record, in the spirit of being a deviant, I can use this as a workaround, but would be nice to know how to do it in a more proper way

def try_both(*args, **kwargs):
    try:
        return orig(*args, **kwargs)
    except TypeError:
        rev_args = tuple(reversed(args))
        return orig(*rev_args, **kwargs)

forbiddenfruit.curse(np.ndarray, '__add__', try_both)
commented

how to hook str.__ add __ and str.__ mod __?