Idiom gone, or did it really ever exist? () is ()

Tim Peters tim.one at home.com
Wed Apr 18 03:51:26 EDT 2001


[Mike C. Fletcher]
> Over the years, I've occasionally used this idiom:
>
> NULLARGUMENT = ()
>
> def someFunctionOrMethod  (argument = NULLARGUMENT ):
>     if argument is NULLARGUMENT:
>         doSomething()
>     else:
>         doSomethingElse()
>
> That is, I was attempting to distinguish between a call where
> argument is passed a NULL tuple and a call where argument is
> passed nothing at all.  When I was working on unit tests for
> my current piece of code, however, I discovered that this no
> longer works (Python 1.5.2).  No idea for how long it hasn't
> worked.

It has never worked by design.  It stopped working by accident when Guido
added empty-tuple caching in revision 2.9 of tupleobject.c.  He did that in
October of 1993.  Have you been in a time warp <wink>?

Any code relying on unique object identity for literals of any object of any
immutable type is simply wrong.  The language doesn't guarantee anything
here, and the implementation can & does vary across releases, or even
bugfixes.  The Reference Manual has always said (section "Objects, values and
types"):

    for immutable types, operations that compute new values may
    actually return a reference to any existing object with the
    same type and value, while for mutable objects this is not
    allowed

One of the nasty bugs fixed late in the 2.1 release cycle was that
asynchat.py used

    somestring is ""

to check whether somestring was empty.  Given the way null strings *happen*
to be cached today, this one is very likely to work most of the time, but
certain to fail rarely.

I don't know what accounts for this.  Do users not understand how object
identity works in Python, or are they so fanatically devoted to tricks that
they're willing to chance it despite knowing it isn't safe?  'Fess up, Mike:
my bet is that when you *started* using this trick, you knew you were
cheating.

> ...
> Apparently optimisation has come to the tuples of the world, so
> using tuple identities is now a no-no.

It always was a no-no, and the implementation accident you were relying on
changed 7 1/2 years(!) ago.

> All those who have used null-tuple identities should now go and
> fix their code.

More generally, people using "is" without knowing what they're doing should
simply stop using it, tuples or not.  How to tell if you're one of them:  if
when you use "is", you feel a twinge of pride in being clever <0.5 wink>.
Safe (intended, documented and supported) uses for "is" are dull as dog food.

except-perhaps-to-a-dog-ly y'rs  - tim





More information about the Python-list mailing list