
Hello, Currently, the built-in Python round (which is different from np.round) when called on a np.float64 returns a np.float64, due to its __round__ method. A congruous statement is true for np.float32. However, since Python 3, the default behavior of round is to return a Python int when it operates on a Python float. This is a mismatch according to the Liskov Substitution Principle<https://en.wikipedia.org/wiki/Liskov_substitution_principle>, as both these types subclass Python’s float. This has been brought up in gh-15297<https://github.com/numpy/numpy/issues/15297>. Here is the problem summed up in code:
type(round(np.float64(5))) <class 'numpy.float64'> type(round(np.float32(5))) <class 'numpy.float32'> type(round(float(5))) <class 'int'>
This problem manifests itself most prominently when trying to index into collections:
np.arange(6)[round(float(5))] 5 np.arange(6)[round(np.float64(5))] Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices
There still remains the question, do we return Python ints or np.int64s? * Python ints have the advantage of not overflowing. * If we decide to add __round__ to arrays in the future, Python ints may become inconsistent with our design, as such a method will return an int64 array. This was issue was discussed in the weekly triage meeting today, and the following plan of action was proposed: * change scalar floats to return integers for __round__ (which integer type was not discussed, I propose np.int64) * not change anything else: not 0d arrays and not other numpy functionality Does anyone have any thoughts on the proposal? Best regards, Hameer Abbasi