[PEAK] Config like metadata
Phillip J. Eby
pje at telecommunity.com
Tue Dec 14 10:14:27 EST 2004
At 11:19 AM 12/14/04 +0100, Radek Kanovsky wrote:
>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)
Note that if the metadata registry were a generic function, it would solve
all of these issues and use simpler code. Instead of registering with a
(metadata_class,target_class,attrName) tuple, add a method to a generic
function with those parameters. For a default rule, don't specify the
target class. For a wildcard rule, don't specify the attribute name.
Anyway, it would then immediately work for classic classes, and it would
raise an exception (NoApplicableMethods) if the item was not found. You
would not need any of the search loops. Since your MetaRule class has a
'__call__' method, you can use MetaRule instances as methods of the generic
function. It would be something like:
import dispatch
from dispatch import strategy
[dispatch.generic()]
def get_metadata(kind, target_class, attrName):
"""Get metadata of 'kind' for target_class and attribute name"""
class Metadata(object):
def __init__(self,rule):
if isinstance(rule,MetaRule):
self.rule = rule
else:
self.rule = lambda kind,target_class,attrName: rule
def register(self, subj, attrName=None):
sig = strategy.Signature(
target_class = IsSubclass(subj),
kind = IsSubclass(self.__class__)
)
if attrName != '*':
sig &= strategy.Signature(
attrName=strategy.Inequality('==',attrName)
)
get_metadata.addMethod(sig, self.rule)
#... keep the old setDefault method, too
[dispatch.as(classmethod)]
def of(cls, subj, attrName=None, default=NOT_GIVEN):
try:
return get_metadata(cls, subj, attrName)
except dispatch.NoApplicableMethods:
if default is not NOT_GIVEN:
return default
raise
There you go. You should be able to ditch the _metadata_registry class.
Btw, it's best not to import stuff from modules like
peak.binding.attributes directly. PEAK itself has to in order to avoid
import circularity and early loading of APIs, but user code should always
import from the API.
More information about the PEAK
mailing list