[Python-Dev] Fixing _PyEval_SliceIndex so that integer-like objects can be used

Bob Ippolito bob at redivi.com
Fri Feb 18 22:54:25 CET 2005


On Feb 18, 2005, at 4:36 PM, David Ascher wrote:

> On Fri, 18 Feb 2005 13:28:34 -0800, Guido van Rossum
> <gvanrossum at gmail.com> wrote:
>>> Would it be possible to change
>>>
>>> _PyEval_SliceIndex  in ceval.c
>>>
>>> so that rather than throwing an error if the indexing object is not 
>>> an
>>> integer, the code first checks to see if the object has a
>>> tp_as_number->nb_int method and calls it instead.
>>
>> I don't think this is the right solution; since float has that method,
>> it would allow floats to be used as slice indices, but that's not
>> supposed to work (to protect yourself against irreproducible results
>> due to rounding errors).
>
> I wonder if floats are the special case here, not "integer like 
> objects".
>
> I've never been particularly happy about the confusion between the two
> roles of int() and it's C equivalents, i.e. casting and conversion.

All of the __special__ methods for this purpose seem to be usable only 
for conversion, not casting (__str__, __unicode__, etc.).  The only way 
I've found to pass for a particular value type is to subclass one.   We 
do this a lot in PyObjC.

It ends up being a net win anyway, because you get free implementations 
of all the relevant methods, at the expense of having two copies of the 
value.  The fact that these proxy objects are no longer 
visible-from-Python subclasses of Objective-C objects isn't really a 
big deal in our case, because the canonical Objective-C way to checking 
inheritance still work.  The wrapper types use an attribute protocol 
for casting (__pyobjc_object__), and delegate to this object with 
__getattr__.

 >>> from Foundation import *
 >>> one = NSNumber.numberWithInt_(1)
 >>> type(one).mro()
[<class 'objc._pythonify.OC_PythonInt'>, <type 'int'>, <type 'object'>]
 >>> isinstance(one, NSNumber)
False
 >>> isinstance(one.__pyobjc_object__, NSNumber)
True
 >>> one.isKindOfClass_(NSNumber)
1
 >>> type(one)
<class 'objc._pythonify.OC_PythonInt'>
 >>> type(one.__pyobjc_object__)
<objective-c class NSCFNumber at 0x300620>

-bob



More information about the Python-Dev mailing list