Undoc Assumption that Container Keys Cannot Be Non-String Immutables

Bug #98332 reported by Jeff Rush on 2006-04-12
Affects Status Importance Assigned to Milestone
Zope 3

Bug Description

The traversal code makes an undocumented assumption that keys() are strings or something that list(path) can be called on. But containers that have non-string but immutable values as keys raise the exception:

  path = list(path)
  TypeError: iteration over non-sequence

from within zope/app/traversing/adapters.py

In my case, my keys are small integers, which (correctly) fail to test as strings, and then raise the above exception when the code in adapters.py tries to coerce an integer to a list(). My workaround is to change my keys() to stringified ints. This issue should be reviewed as to whether this restriction is intentional/desirable and either removed or documented. There shouldn't be an unclear unassumption of the return type of IContainer.keys().

To duplicate the problem, just toss together a minimal IContainer, have keys() return unique integers, and traverse it, in my case, using @@singleBranchTree.xml from within the Rotterdam skin. But it fails for any traversal.

The assumption is that container names are unicodes. Because of Python's (stupid) feature that strings can be compared to unicodes and are considered equal sometimes (e.g. 'hi' == u'hi'), ASCII strings are also acceptable.

If this is undocumented (I couldn't find any documetnation in IWriteContainer), then this indeed needs to be documented. Feel free to round up a patch, Jeff. :)

By the way, the traversing API is also documented by interfaces. Perhaps it should be made clear that names are always expected to be unicodes for traversal as well.

Stephan Richter (srichter) wrote :

Changes: submitter email, edited transcript, importance (medium => critical), revised version_info, new comment

I have fallen into this trap before as well. This really deserves a few lines of writing in the interfaces.

Status: Pending => Resolved

IWriteContainer says:

    def __setitem__(name, object):
        """Add the given `object` to the container under the given name.

        Raises a ``TypeError`` if the key is not a unicode or ascii string.
        Raises a ``ValueError`` if key is empty.

So, it's pretty clear that names must be Unicode objects or ASCII strings. I have no idea how new this docstring is, but at least it's there now.

In addition to that I went through the traversal interfaces in zope.publisher and zope.traversing and added notes wherever applicable that traversed names must be ASCII or unicode strings as well. Checked in in r69595/r69596.

To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers