[Zope3-dev] Re: help with directlyProvides

luis lparrab at gmx.net
Tue May 9 17:38:58 EDT 2006


Hi again,

>> If there is a bug in the container framework my assumption would be
>> that that the following part of code causes your problem. The regular
>> container asserts IContained either by the directlyProvides mechanism
>> if the item provides ILocation or else by a ContainedProxy.
>>
>> zope.app.container.contained line 325:
>>   [...]
>>    if not IContained.providedBy(object):
>>        if ILocation.providedBy(object):
>>            zope.interface.directlyProvides(
>>                object, IContained,
>>                zope.interface.directlyProvidedBy(object))
>>        else:
>>            object = ContainedProxy(object)
>>   [...]
>>
[...]
> 

well... I'm not sure but it seems not to be a bug in ContainedProxy, but
just a "display bug" in the  @@introspector.html...

I couldn't trace into the ContainedProxy, but put some debug messages and
got something interesting....

I put this code in a pacage called "dprovide"

###################################################
### dprovide/__init__.py
from zope import interface
from zope import schema
from zope.formlib import form
from zope.app.file import File
from zope.app.folder import Folder
from zope.location import ILocation

class IMarker(interface.Interface):
    """ test marker interface for directlyProvides """
    
class ITestSchema(interface.Interface):
    """ test schema for directlyprovides """
    file      = schema.Bool( 
        title = u'Create File and directlyProvide IMarker' )
    file2    = schema.Bool( 
        title = u'Create File and directlyProvide ILocation and IMarker' )
    folder = schema.Bool( 
        title = u'Create Folder and directlyProvide IMarker' )

class DirectlyProvidesTest(form.AddForm):
    form_fields = form.Fields( ITestSchema )
    
    def create( self, data ):
        r = {}
        if data['file']:
            f = File()
            interface.directlyProvides( f, IMarker )
            r['file'] = f
            if not IMarker.providedBy( r['file'] ):
                raise Error
        if data['file2']:
            f = File()
            f.__name__ = ''
            f.__parent__ = ''
            interface.directlyProvides( f, ILocation, IMarker )
            r['file2'] = f
            if not IMarker.providedBy( r['file2'] ):
                raise Error
        if data['folder']:
            f = Folder()
            interface.directlyProvides(f, IMarker)
            r['folder'] = f
            if not IMarker.providedBy( r['folder'] ):
                raise Error
        return r
    
    def add( self, r ):
        if r.has_key('file'):
            self.context.add( r['file'] )
        if r.has_key('file2'):
            self.context.add( r['file2'] )
        if r.has_key('folder'):
            self.context.add( r['folder'] )
        self._finished_add = True
###################################################
and in dprovide/configure.zcml
    <page
        class=".DirectlyProvidesTest"
        name="directlyProvides.html"
        permission="zope.Public"
        for="zope.app.container.interfaces.IAdding"
        title="Test page for directlyProvides"
        menu="zmi_views"
        />
####################################################
and I "patched" zope.app.container.contained @ 325 to look like this:

    if not IContained.providedBy(object):
        if ILocation.providedBy(object):
            zope.interface.directlyProvides(
                object, IContained,
                zope.interface.directlyProvidedBy(object))
        else:
            print_provides = False
            if object.__class__.__name__ == 'File' or\
               object.__class__.__name__ == 'Folder':
                   from dprovide import IMarker
                   print "!!!!!!!!!!!!! BEFORE ContainedProxy: ",
object.__provides__
                   print " IMarker.providedBy = ",
IMarker.providedBy(object)
                   print_provides = True
            object = ContainedProxy(object)
            if print_provides:
                print "############### AFTER ContainedProxy: ",
object.__provides__
                print " IMarker.providedBy = ", IMarker.providedBy(object)

###################################################

now.. after adding a File (without) ILocation, I see the output
!!!!!!!!!!!!! BEFORE ContainedProxy:  <zope.interface.Provides object at
0xb455ea0c>
 IMarker.providedBy =  True
############### AFTER ContainedProxy:  <implementedBy
zope.app.container.contained.ContainedProxy>
 IMarker.providedBy =  True

so, the IMarker is provided by the file, but in a "different" way.. so I
think the introspector is just not showing it correctly...
if I add a File w/ ILocation, it doesnt go into the ContainedProxy and the
introspector shows the directlyProvided intefaces correctly...


regards.
luis


ps. if you want to try that... you have to add the files "one by one".. if
you select two checkboxes at once you get a "dupplicate names" error.. not
sure why.




More information about the Zope3-dev mailing list