[Zope3-dev] interface/schema example

Terry Hancock hancock at anansispaceworks.com
Sat Jun 19 04:31:18 EDT 2004


This is an instructive example of how verification actually
works with an example of my "subinterface" to check. The
idea is that we have a "helper object" that we want to patch
into an existing object as an attribute.  We'll just define
it at the class-level here, but it's more likely that it
would've been added by sub-classing or "monkey-patching".

(This is from an interactive session with Python 2.3, you
should be able to paste the code parts in to follow)

# My imports:

from zope import interface, schema
from zope.interface import verify

# First define the "sub-interface" -- the interface of the object which will
# be contained in a parent object in order for the parent object to meet it's
# interface spec:

class IPatch(interface.Interface):
    spam = interface.Attribute("I'm an attribute and I'm okay")
    def viking(ham):
        """
	Spam, spam, spam, wonderful spam!
	"""

# Now define the interface/schema for the parent object:

class IPatched(interface.Interface):
    patch = schema.Object(schema=IPatch)

# Now define a class which implements IPatch:

class Patch:
    interface.implements(IPatch)
    spam = 1
    def viking(ham):
        print "Spam, spam " + ham + " and spam!"

# and a class which contains it:

class Patched:
    interface.implements(IPatched)
    patch = Patch()

# Now, does Patched really implement IPatched (and therefore
# do instances of Patched have an attribute "patch" which
# provides IPatch?)

p = Patched()

verify.verifyObject(IPatched, p)
verify.verifyObject(IPatch, p.patch)

####
Yields:
"""
>>> verify.verifyObject(IPatched, p)
True
>>> verify.verifyObject(IPatch, p.patch)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "/usr/local/lib/python2.3/site-packages/zope/interface/verify.py", line 82, in verifyObject
    return _verify(iface, candidate, tentative, vtype='o')
  File "/usr/local/lib/python2.3/site-packages/zope/interface/verify.py", line 74, in _verify
    raise BrokenMethodImplementation(n, mess)
zope.interface.exceptions.BrokenMethodImplementation: The implementation of viking violates its contract
        because implementation doesn't allow enough arguments.
"""
Only half-right -- because IPatched should've failed, too (verification should recurse through
Object attributes which specify an interface).
####

class Patch:
    interface.implements(IPatch)
    spam = 1
    def viking(self, ham):
        print "Spam, spam " + ham + " and spam!"

class Patched:
    interface.implements(IPatched)
    patch = Patch()

p = Patched()

verify.verifyObject(IPatched, p)
verify.verifyObject(IPatch, p.patch)

####
Now we've fixed the bug in Patch, but we had to verify the sub-interface manually:
"""
>>>
>>> verify.verifyObject(IPatched, p)
True
>>> verify.verifyObject(IPatch, p.patch)
True
>>>
"""
####

What did I learn?

Well, first of all, "verify" does more than simply look for a declaration
that an interface is provided -- it at least checks for methods and method
signatures that match.  So far, so good.

But I'm disappointed by the behavior w.r.t. to "Object" -- it should, IMHO,
have recursively checked for Object to comply with the schema (or interface)
that we declared it with.

How to fix?

Well, first of all, maybe nobody else thinks it should do this?  Or maybe
an alternate function "verify_recursively" or maybe add a behavior option
like "tentative" called "recursive"?

Secondly, there's the "_validate" method that could be defined for Object,
which is what Stephan Richter recommended when we discussed this in 
February.
( http://mail.zope.org/pipermail/zope3-dev/2004-February/010002.html )
Jim Fulton went on to say that there *was* an Object type that allowed the
schema/interface to be specified -- which is what I used above, of course.

Perusing the schema source code, it looks like I may be looking for the
Field.validate() method, but it's not clear to me how I would use it in
this context.

Which is the best approach to get my recursive check? And does that belong
in interface (or schema)?

Cheers,
Terry

--
Terry Hancock ( hancock at anansispaceworks.com )
Anansi Spaceworks  http://www.anansispaceworks.com




More information about the Zope3-dev mailing list