"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