[Zope-dev] Re: ...but I want to access 'a particular tuple' inthat context!

Tim Peters tim at zope.com
Tue Mar 23 16:09:26 EST 2004


[Tres Seaver]
>> The 'iteritems' method of a dictionary returns an object of type
>> 'dictionary-iterator';  AccessControl.ZopeGuards makes no container
>> assertions about that type, although it *does* permit calling the
>> 'iteritems' method which returns an instance of it.
>>
>> I find it interesting that that module wraps 'iterkeys' and
>> 'itervalues' in its 'get_iter' checker, but allows unrestricted
>> access to 'iteritems'.

[Jamie Heilman]
> Yeah I saw that, which is why I asked about it, I couldn't decide if
> it was left sort of half-baked on purpose or not.  I assume not, but I
> wanted to make sure.

It was deliberate.  iterkeys() and itervalues() reveal objects held by the
dict directly, and so require security checks before handing those objects
out.  iteritems() returns 2-tuples, though, and there's no security
implication there until you do something to extract the contained keys and
values from the 2-tuples.  The security checks in the iteritems() case occur
in all the ways of picking apart the 2-tuples.

>> The following patch will make your use case work (it would need to be
>> prettied up for Python < 2.3):

[a patch that inserted

    ContainerAssertions[type({}.iteritems())] = 1
]

Unfortunately,

    type({}.iteritems()) is type({}.iterkeys()) is type({}.itervalues())

They all return a dictionary-iterator object.  The .next() method of a
dictionary-iterator object is safe to hand out for the iteritems flavor
(again because it returns 2-tuples), but the .next() methods of the others
aren't safe (again because they reveal contained objects directly).

> OK, but really I'm more interested in having this supported in Zope
> proper,

Sure -- I'm sure Tres was just trying to get you unstuck in a hurry.

> I can always use .items() instead of .iteritems() and soak the
> associated costs if I have to.  Surely making iteritems use a guarded
> interator is the Right thing, yes?

The thing going wrong here is subtler than that.  For example, change
iteritems() to itervalues() in your original example, and I bet it still
won't work.  OTOH, if you use list(yourdict.iterkeys()) instead, I bet it
will work.




More information about the Zope-Dev mailing list