[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