Problem with properties in inherited ZClasses
Hi, I have got stuck with inheritance and properties while writing a simple task tracking product as a way to learn Zope (using a brand new 2.2.0 with no other products). My product AdminTools currently has two ZClasses, Folder and Task. The ZClass AdminTools:Folder inherits from CatalogAware and ObjectManager. Folder has a property sheet 'data', with properties 'title' (string) and 'description' (text). The Folder class has methods for displaying info about the folder and the objects it contains. I have tried to create another ZClass, AdminTools:Task that inherits from AdminTools:Folder that adds some task tracking functionality and uses/overrides the AdminTools:Folder methods for displaying objects. Task also has a property sheet named 'data' with properties 'title' (string), due date (date) and owner (string). I tried to add a final property 'description' (text) to AdminTools:Task, but get this error saying it is already in use: Invalid property id, description. It is in use. Traceback (innermost last): File D:\Dev\ZopeTestbed\lib\python\ZPublisher\Publish.py, line 222, in publish_module File D:\Dev\ZopeTestbed\lib\python\ZPublisher\Publish.py, line 187, in publish File D:\Dev\ZopeTestbed\lib\python\Zope\__init__.py, line 221, in zpublisher_exception_hook (Object: Traversable) File D:\Dev\ZopeTestbed\lib\python\ZPublisher\Publish.py, line 171, in publish File D:\Dev\ZopeTestbed\lib\python\ZPublisher\mapply.py, line 160, in mapply (Object: manage_addProperty) File D:\Dev\ZopeTestbed\lib\python\ZPublisher\Publish.py, line 112, in call_object (Object: manage_addProperty) File D:\Dev\ZopeTestbed\lib\python\OFS\PropertySheets.py, line 427, in manage_addProperty (Object: Traversable) File D:\Dev\ZopeTestbed\lib\python\OFS\PropertySheets.py, line 235, in _setProperty (Object: Task) Bad Request: (see above) I don't understand why I can add the 'title' property to Task but not 'description'. Both 'title' and 'description' are defined in the inherited class Folder, so they are being treated differently for some reason. A little while ago, I had the same error while trying to create a property named 'summary'. At the time, I thought it was because of a clash with the summary() method of CatalogAwareness. But now I'm confused. To conclude: (i) What is going on and how can I fix it? (ii) When using a ZClass as a base class, do instances inherit any properties, or do they just get access to the base class's methods? If ZClasses do inherit properties from parent ZClasses, how do I reach them via the property sheets? (iii) Is there a simple way to find out what methods and properties an object has? I would like to see what it defines, what it inherits and what it acquires. _______________________________ Stephen Simmons HealthArena B.V. phone +31 20 486 0555 mobile +31 6 1505 3086 stephen.simmons@healtharena.net
Stephen Simmons wrote:
I have tried to create another ZClass, AdminTools:Task that inherits from AdminTools:Folder that adds some task tracking functionality and uses/overrides the AdminTools:Folder methods for displaying objects
I tend to try not to have ZClasses derive from other ZClasses. You'd find it more straightforward either to derive both ZClasses from a common Python base class, or to keep both ZClasses independent of each other. In general, I try to avoid using inheritence. Python and Zope support polymorphism whether you derive classes from the same base-class or not. Also, I find the coupling introduced by inheritence more trouble than it is worth for the reduced redundancy. I realize that I have avoided trying to answer why ZClasses work in this way.
File D:\Dev\ZopeTestbed\lib\python\OFS\PropertySheets.py, line 235, in _setProperty (Object: Task) Bad Request: (see above)
I don't understand why I can add the 'title' property to Task but not 'description'.
Here's the code that is raising the exception: if hasattr(aq_base(self),id): if not (id=='title' and not self.__dict__.has_key(id)): raise 'Bad Request', ( 'Invalid property id, <em>%s</em>. It is in use.' % id) You can see that 'title' has a special status as a property.
To conclude:
(i) What is going on and how can I fix it?
Don't do things that way to start with.
(ii) When using a ZClass as a base class, do instances inherit any properties, or do they just get access to the base class's methods? If ZClasses do inherit properties from parent ZClasses, how do I reach them via the property sheets?
If you add propertysheets to instances of your classes, rather than to the classes, then you don't get conflicts over attributes. However, unless you use ZPatterns or something like that, you have to refer to the attributes of propertysheets explicitly naming the propertysheet.
(iii) Is there a simple way to find out what methods and properties an object has? I would like to see what it defines, what it inherits and what it acquires.
Yes. See the code above from PropertySheets.py. Use something like this in an external method to find out the attributes of an object. (In python, methods and fields are both attributes.) You can use the magic aq_* attributes of acquisition wrappers to walk through the objects that get considered during acquisition. You might also want to look at Shane Hathaway's Acquisition Explainer, an external method to show how acquisition works, that also demonstrates use of the aq_* attributes. -- Steve Alexander Software Engineer Cat-Box limited http://www.cat-box.net
participants (2)
-
Stephen Simmons -
Steve Alexander