"Is" is "is" [was: any way to customize the is operator?]

Steve Holden steve at holdenweb.com
Sat Feb 11 02:30:03 EST 2006


Lonnie Princehouse wrote:
>>Why did you want to customize "is"?
> 
> 
> Well, mostly out of principle ;-)
> 
> But also because I'm wrapping a C library which passes around C structs
> which are wrapped in shim C++ classes for a Boost.Python layer.  Boost
> Python does a marvelous job of translating between Python and C++ data
> types; when a C structure is returned, it magically translates that
> structure into a Python wrapper.   The problem is that a _new_ Python
> wrapper is created every time a pointer is returned, even if a  wrapper
> already exists for that particular pointer.
> 
> To illustrate:  Suppose you have a function in C++ which is a simple
> identity function, e.g.
> 
> template <typename T>
> T *identity (T *x) {
>     return x;
> }
> 
> Calling the wrapped version of this function from Python will produce a
> Python wrapper which represents the same underlying C++ object, but is
> not actually the same Python object:
> 
> 
>>>>b = identity(a)
>>>>b is a
> 
> False
> 
> I wanted to override the behavior of "is" so that (a is b) would be
> True --- which shouldn't have caused a problem, since the wrapper
> class's attributes are read-only from Python.  As it is, I've overriden
> __cmp__ and __hash__, so at least I get the correct dictionary behavior
> 
> 
>>>>mydict = { a : 'something' }
>>>>b = identity(a)
>>>>b in mydict
> 
> True
> 
> It's quite possible that there is some way to do this correctly from
> the Boost.Python side of things... my understanding of how to use
> Boost.Python is minimal.
> 
I will adopt my usual stance here of unequivocally stating that there is 
no way you can do what you want to. In the case of the "is" operator you 
can only expect truth when the left- and right-hand side operands refer 
to the same object.

This strategy is usually sound: typically, before the metaphorical ink 
has dried on my post some upstart comes along to prove me completely 
wrong. So, I have done about all I can to help you. It's up to the rest 
of the community now to prove me wrong (as they have so many times in 
the past :).

regards
  Steve

PS: I'm afraid I couldn't resisit shortening yur odds somewhat by doing 
what I usually fail to do and examining the source of is_() in 
Modules/operator.c. I'm afraid it's not looking good ... the result of 
"is" does appear to depend only on the memory addresses of the two 
operands being the same:

                 result = (a1 == a2) ? Py_True : Py_False;
                 Py_INCREF(result);

sorry ...
-- 
Steve Holden       +44 150 684 7255  +1 800 494 3119
Holden Web LLC                     www.holdenweb.com
PyCon TX 2006                  www.python.org/pycon/




More information about the Python-list mailing list