Undoc Assumption that Container Keys Cannot Be Non-String Immutables
| Affects | Status | Importance | Assigned to | Milestone | |
|---|---|---|---|---|---|
| Zope 3 |
Fix Released
|
Critical
|
Unassigned | ||
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/
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/
To duplicate the problem, just toss together a minimal IContainer, have keys() return unique integers, and traverse it, in my case, using @@singleBranchT
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.
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.