Lisandro Dalcin wrote:
> On Fri, Apr 17, 2009 at 12:06 PM, Stefan Behnel wrote:
>> Lisandro Dalcin wrote:
>>> What I do not know is what to do
>>> if a class defines both special methods...
>> Good question. I think if __long__ is defined, that's what best resembles
>> nb_int in Py3. People are more likely to expect C-int compatibility in
>> __int__, so the only reason why one would define __long__ is to pass
>> larger numbers.

BTW, in Py3, PyNumber_Int() was replaced in favour of PyNumber_Long(). That
makes it a bit funny, the C layer uses "long", whereas the Python layer
uses "int".


>>> Also note that the in implementation of __Pyx_PyNumber_Int() (from my
>>> patch for C-int conversion), "nb_long" takes precedence over "nb_int"
>>> in Python 2. IMHO, that was the best thing to do...
>> What's CPython doing here?
> 
> CPython is a real mess here... At the price of manually inspecting the
> existence of nb_int/nb_long slots, __Pyx_PyNumber_Int(ob) is my best
> attempt for making all work as expected for Cython. I've worked hard
> to make to avoid the PyInt/PyLong distinction. So if you do "cdef
> short j = obj" it will work for PyInt/PyLong in all supported Python
> runtimes.
> 
> The only possible issue is that if a integral-like type defines both
> nb_int/nb_long and they return Python integrals with different values
> (in the == sense), then the return of "nb_long" will be used and
> "nb_int" will not be ever called. However, what would be the use case
> for such implementations of __int__() and __long__() ???. However,
> this work on Python.

I don't see a major use case either, but calling nb_int when we convert to
a C-int or a smaller type might still make sense in Py2. The function might
actually do some work (as opposed to returning a constant value). I'd
suspect an __int__() function to be potentially more optimised by users
than something that already knows that it has to return a PyLong.

Note that Py2 allows __int__() to return a PyLong if the value doesn't fit
into a PyInt, while __long__() must return a PyLong:

http://docs.python.org/c-api/number.html#PyNumber_Int

"""
PyObject* PyNumber_Int(PyObject *o)
    Return value: New reference.

    Returns the o converted to an integer object on success, or NULL on
failure. If the argument is outside the integer range a long object will be
returned instead. This is the equivalent of the Python expression int(o).

PyObject* PyNumber_Long(PyObject *o)
    Return value: New reference.

    Returns the o converted to a long integer object on success, or NULL on
failure. This is the equivalent of the Python expression long(o).
"""

Stefan
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to