[Ron Garret] > Why doesn't this work? > > >>> from weakref import ref > >>> class C(str): pass > ... > >>> ref(C()) > Traceback (most recent call last): > File "<stdin>", line 1, in ? > TypeError: cannot create weak reference to 'C' object . . . > Everything but strs.
Also subclasses of tuple are not weak referencable. The issue is in the design of the C structure as a variable-sized immutable object. Both strings and tuples allocate as a single unit of memory that holds both the header information and the content information (the characters in a string or the array of object pointers for a tuple). Since the size varies from one string or tuple to the next, there is no straight-forward way for a subclass to add an additional header field pointing to a list of weak references. For lists and dicts, this is not a problem because the object is allocated in two sections, a fixed size header component and a pointer to another area of memory to hold the contents of the collection. This makes it possible for a subclass to graft-on a weak reference pointer at a known, fixed offset from the beginning of the header. There are two ways to fix this. One is to add a weak reference pointer to every string object -- that way you wouldn't even have to subclass it. Another way is to break the object into two pieces as is done for mutable containers like dicts and lists. Both approaches consume time and space. In general, that is not a big deal, but fast, memory efficient strings and tuples are at the center of all things Python. The need to weak reference this objects is somewhat rare in comparison to the frequency of their other uses. It did not make sense to always pay a time/space penalty just to create the possibility of weak referencing. While the design decision is unlikely to change, the docs could certainly be improved. A doc patch would be welcome. FWIW, the work-arounds are to weak-reference instances of UserString or to create a custom class with a has-a relationship instead of an is-a relationship. Raymond Hettinger -- http://mail.python.org/mailman/listinfo/python-list