[Zope3-dev] Interface questions

Jim Fulton jim@zope.com
Tue, 05 Mar 2002 13:55:02 -0500


Rather than addressing individual points I'll just point 
out that the interface package has become a bit chaotic.  
I've decided to undertake a pretty brutal refactoring:

- Make the Interface package almost soley a container
  package. The only name you'll be able to import directly
  from the package will be the base interface "Interface".

- I will reorganize the public package modules as follows:

  o Attribute has the implementation for interface attributes
    for people who want to build interfaces by hand.
    (Maybe someone should cry YAGNI for this. ;)

  o Document has a utility for documenting an interface as structured text.

  o Exceptions has the interface-defined exceptions

  o IAttribute defines the attribute descriptor interface.

  o IElement defined the base interface for IAttribute, IInterface, and IMethod.

  o IInterface defines the interface interface

  o IMethod defined the method interface.

  o Implements has various utilities for examining interface assertions.

  o Method has the implementation for interface methods. See above.

  o Verify has utilities for verifying (sort of) interfaces.

  o pyskel.py, the skeletin generator script.

  I will add documentation of the above to the package doc string.
  I'll add documentation of the utility modules, Document, Implements, and Verify
  to their module doc strings.

- I'll get the unit tests to pass in this package and in the Zope 3 packages.

If anyone has a problem with this refactoring, see me in #zope3-dev. :)  

Jim



Jeremy Hylton wrote:
> 
> I uncovered a small bug in the cPersistence implementation today.  It
> doesn't currently have an __implements__ attribute.  This is
> straightforward to fix, but I want to add a test for it first.
> I've never used the Interface package before, but I thought it was a
> great time to try.
> 
> I've hit a bunch of small obstacles, and I'm not sure where to direct
> questions.  So here they are to the whole list.  I don't intend this
> message to sound testy; I worry that it will come off as negative
> because I'm reporting bugs.  :-)
>
> The test I want to write is a test that Persistent implements
> IPersistent.  So I read the section of README.txt titled "Testing
> assertions."  It says:
> 
>     Similarly, you can test whether, by default, instances of a class
>     implement an interface by calling the 'implementedByInstancesOf'
>     method on the interface and passing the class::
> 
>       I1.implementedByInstancesOf(A)
> 
> I've loaded IPersistent:
> 
> >>> from Persistence.IPersistent import IPersistent
> >>> IPersistent
> <InterfaceFromClass Persistence.IPersistent.IPersistent at 81d0374>
> 
> but it doesn't have an "implementedByInstancesOf" attribute:
> 
> >>> IPersistent.implementedByInstancesOf
> Traceback (most recent call last):
>   File "<stdin>", line 1, in ?
> AttributeError: interface_loader instance has no attribute 'implementedByInstancesOf'
> 
> I don't understand where interface_loader comes from or why it's
> showing up in the getattr?  (Okay.  After puzzling for a while, I did
> conclude that IPersistent is an instance of something.)  I think the
> interface name should be present in the error message.
> 
> I tried to find out what went wrong by looking at the source for
> Interface, since IPersistent inherits from Interface.Interface.  The
> source is a nest of imports with renames and import *.  It would be
> *really* helpful if this could be refactored to make it easier to
> read.
> 
> Interface.Interface is an alias for Interface.Standard.Base.
> Interface.Standard uses import * three separate times.
> It gets Based from Interface.Basic.
> Interface.Basic.Base is an alias for Interface.iclass.Base.
> Interface.iclass.Base is an instance of InterfaceFromClass,
>     which is also defined in Interface.iclass.
> InterfaceFromClass is a class that extends Interface.
> 
>     I thought I was looking for the definition of Interface,
>     so I seem to have hit a circular reference!
> 
> Interface.iclass.Interface is a class, which is related only
>    tangentially to the public Interface.Interface.
> 
> Interace.iclass.Interface defines as isImplementedByInstancesOf()
>    method.
> 
> Either the code or the documentation is wrong, but I'm not sure
> which.  If someone tells me which is right, I'll fix the one that is
> wrong.
> 
> The "interface_loader" name that confused me in the AttributeError
> seems to be a side-effect of the way Interfaces are made persistent.
> In particular, this code:
> 
>     class InterfaceLoader:
> 
>         __safe_for_unpickling__ = 1
> 
>         def __call__(self, module, name):
>             __import__(module)
>             mod = sys.modules[module]
>             i = getattr(mod, name)
>             return i
> 
>     interface_loader = InterfaceLoader()
> 
>     InterfaceFromClass.__name__ = 'interface_loader'  # Trick unpicklers.
> 
>     Base = InterfaceFromClass("Interface")
> 
> Wouldn't it be clearer to define a reduce function for
> InterfaceFromClass that called an InterfaceLoader function?
> Then we could leave the __name__ attribute alone.
> 
> Jeremy
> 
> _______________________________________________
> Zope3-dev mailing list
> Zope3-dev@zope.org
> http://lists.zope.org/mailman/listinfo/zope3-dev

--
Jim Fulton           mailto:jim@zope.com       Python Powered!        
CTO                  (888) 344-4332            http://www.python.org  
Zope Corporation     http://www.zope.com       http://www.zope.org