0

I made a custom C-module to Python 2 a few years ago, which I now upgrade to Python 3. The PyNumberMethods definition changed between 2 and 3, to register a class supporting certain operators.

Python 2

The class had two division operators. I used the first one and it worked.

typedef struct {
    binaryfunc nb_add;
    binaryfunc nb_subtract;
    binaryfunc nb_multiply;
    binaryfunc nb_divide; <-------
    binaryfunc nb_remainder;
    [...]
    binaryfunc nb_true_divide; <-------
    [...]
} PyNumberMethods;

Python 3

nb_divide got removed, and instead there is nb_remainder. Is this supposed to be the new function?

typedef struct {
    binaryfunc nb_add;
    binaryfunc nb_subtract;
    binaryfunc nb_multiply;
    binaryfunc nb_remainder; <-------
    [...]
    binaryfunc nb_true_divide; <-------
    [...]
} PyNumberMethods;

I tried nb_true_divide instead, and it also works. What is the difference between all these functions, and which one should I use if I want to support foo.vector() / 100.0

Daniel Stephens
  • 596
  • 4
  • 14
  • 39

1 Answers1

2

There's also np_floor_divide which, as the docs state:

Return the floor of o1 divided by o2, or NULL on failure. This is equivalent to the “classic” division of integers.

This is what was added. As for the differences, this has been asked already, see here for example.

In a nutshell, if you want to attach behavior for your custom type based on / being used, define the np_true_divide slot. For //, use np_floor_divide.

Dimitris Fasarakis Hilliard
  • 119,766
  • 27
  • 228
  • 224
  • Just wondering, so in my example I also need it for floats so `nb_true_divide` seems to be the better choice? – Daniel Stephens May 26 '20 at 20:12
  • @DanielStephens Since `np_floor_divide` will allow you to attach behavior to the `//` symbol and `np_true_divide` to the `/` symbol I'd say that the `true_divide` slot is indeed what you're after. – Dimitris Fasarakis Hilliard May 27 '20 at 08:20