[PEAK] Config like metadata

Phillip J. Eby pje at telecommunity.com
Tue Dec 14 13:33:38 EST 2004


A couple of minor points I missed in my first reply...

At 11:19 AM 12/14/04 +0100, Radek Kanovsky wrote:

>'Title' class is kind of property that can be declared over class
>attributes via standard binding.declareAttribute function
>or binding.metadata advisor:
>
>   >>> binding.declareAttribute(Contact,'name',Title('Your name'))

Also, don't forget:

    binding.declareAttributes(Contact, name=Title('Your name'))

which is even more convenient for after-the-fact declarations.  You only 
need the 'declareAttribute' form if you are using '*' or 'None' or the 
attribute name is in a variable.



>Current limitations:
>
>     * metadata registry is global and is not thread-safe
>     * works only with new-style classes for now
>     * it would be better to raise exception when metadata is not found
>       instead of returning NOT_FOUND (if default is not given)
>     * registry allows redeclare metadata after they have been looked up

By the way, the generic function solution I proposed also has a (sort-of) 
fix for the last item, too.  If you declare two 'Title' objects as metadata 
for the same class and attribute, you'll get an AmbiguousMethod error at 
the point of invocation.

I'm thinking I'll probably incorporate something like this into PEAK, at 
least once I've put IsSubclass into the dispatch package.  I would probably 
distinguish between class metadata and attribute metadata, though, because 
class metadata ('None' in your examples) is different from wildcard 
attribute metadata ('"*"' in your examples), and the class metadata 
shouldn't really be going through 'declareAttribute'.  Instead, the binding 
package should probably include 'declareClassMetadata' or something like that.

Hm.  Maybe 'declareAttributes' should actually be 'declareMetadata', and 
take positional arguments for class metadata, and the 'metadata' advisor 
could do the same thing.  So, you could have, e.g.:

     class Foo(model.Element):
         binding.metadata( PrimaryKey('x','y') )

in order to declare class-level metadata.

One nice thing about this approach is that it means there's no need to 
write your own class advisors in order to get class-level metadata.

(Hm, I also just thought of a reasonable use-case for metadata that could 
be for either a class or an attribute, so I suppose it actually should be 
supported.  Still, also supporting class-only and attribute-only metadata 
is a good idea, I think.)

Last, but not least, it's interesting to note that with the generic 
function solution, one can subclass a particular kind of metadata in order 
to "inherit" its rules and declarations.  For example:

     class FancyTitle(Title): pass

Would create a 'FancyTitle' metadata that would fall back to using the 
'Title' metadata if there is no 'FancyTitle' for the target class and 
attribute.  Of course, using such inherited metadata can increase the 
possibility of having an ambiguity.




More information about the PEAK mailing list