def __init__(self, name, typedValue, id=0): self.id = id self.name = name self.typedValue = iformless.ITyped(typedValue) # pull these out to remove one level of indirection... if typedValue.description is not None: self.description = typedValue.description if typedValue.label is not None: self.label = typedValue.label if self.label is None: self.label = nameToLabel(name) self.default = typedValue.default self.complexType = typedValue.complexType
class ChoiceRenderer(BaseInputRenderer): default_select = select( id=slot('id'), name=slot('name'), render=directive('sequence'))[option( pattern="item", value=valToKey, render=isSelected)[lambda c, d: iformless.ITyped(c).stringify(d)]] def input(self, context, slot, data, name, value): tv = data.typedValue choices = tv.choices if value: context.remember(value, csv) else: context.remember('', csv) try: selector = context.tag.patternGenerator('selector') except NodeNotFound: selector = self.default_select return selector(data=choices)
class RadioRenderer(ChoiceRenderer): default_select = span(id=slot('id'), render=directive('sequence'))[div( pattern="item", _class="freeform-radio-option")[input( type="radio", name=slot('name'), value=valToKey, render=isChecked)[lambda c, d: iformless.ITyped(c).stringify(d)]]]
def valToKey(c, d): return iformless.ITyped(c).valueToKey(d)
def __new__(cls, name, bases, dct): dct['__id__'] = nextId() dct['__methods__'] = methods = [] dct['__properties__'] = properties = [] possibleActions = [] actionAttachers = [] for key, value in dct.items(): if key[0] == '_': continue if isinstance(value, MetaTypedInterface): ## A Nested TypedInterface indicates a GroupBinding properties.append(GroupBinding(key, value, value.__id__)) elif callable(value): try: result = value(_Marker) except: ## Allow non-autocallable methods in the interface; ignore them continue names, _, _, typeList = inspect.getargspec(value) if typeList is None: argumentTypes = [] else: argumentTypes = [ Argument(n, argtype, argtype.id) for n, argtype in zip(names[1:], typeList) ] label = None description = None if getattr(value, 'autocallable', None): # autocallables have attributes that can set label and description label = value.attributes.get('label', None) description = value.attributes.get('description', None) adapted = iformless.ITyped(result, None) if adapted is None: adapted = Object(result) # ITyped has label and description we can use if label is None: label = adapted.label if description is None: description = adapted.description defaultLabel, defaultDescription = labelAndDescriptionFromDocstring( value.__doc__) if defaultLabel is None: # docstring had no label, try the action if it is an autocallable if getattr(value, 'autocallable', None): if label is None and value.action is not None: # no explicit label, but autocallable has action we can use defaultLabel = value.action if defaultLabel is None: # final fallback: use the function name as label defaultLabel = nameToLabel(key) if label is None: label = defaultLabel if description is None: description = defaultDescription theMethod = Method(adapted, argumentTypes, label=label, description=description) if getattr(value, 'autocallable', None): methods.append( MethodBinding(key, theMethod, value.id, value.action, value.attributes)) else: possibleActions.append( (value, MethodBinding(key, theMethod))) else: if not value.label: value.label = nameToLabel(key) if implements(value, iformless.IActionableType): actionAttachers.append(value) properties.append(Property(key, value, value.id)) for attacher in actionAttachers: attacher.attachActionBindings(possibleActions) methods.sort(_sorter) properties.sort(_sorter) dct['__spec__'] = spec = methods + properties spec.sort(_sorter) dct['name'] = name # because attributes "label" and "description" would become Properties, # check for ones with an underscore prefix. dct['label'] = dct.get('_label', None) dct['description'] = dct.get('_description', None) defaultLabel, defaultDescription = labelAndDescriptionFromDocstring( dct.get('__doc__')) if defaultLabel is None: defaultLabel = nameToLabel(name) if dct['label'] is None: dct['label'] = defaultLabel if dct['description'] is None: dct['description'] = defaultDescription # What the heck...work around strange bug in Zope C Optimizations # whose cause I cannot figure out. try: return MetaInterface.__new__(cls, name, bases, dct) except TypeError, e: if len(e.args) == 1 and e.args[ 0] == '_interface_coptimizations.SpecificationBase.__new__(MetaTypedInterface) is not safe, use object.__new__()': return object.__new__(cls, name, bases, dct) raise
def __new__(cls, name, bases, dct): rv = cls = InterfaceClass.__new__(cls) cls.__id__ = nextId() cls.__methods__ = methods = [] cls.__properties__ = properties = [] cls.default = 'DEFAULT' cls.complexType = True possibleActions = [] actionAttachers = [] for key, value in dct.items(): if key[0] == '_': continue if isinstance(value, MetaTypedInterface): ## A Nested TypedInterface indicates a GroupBinding properties.append(GroupBinding(key, value, value.__id__)) ## zope.interface doesn't like these del dct[key] setattr(cls, key, value) elif callable(value): names, _, _, typeList = inspect.getargspec(value) _testCallArgs = () if typeList is None: typeList = [] if len(names) == len(typeList) + 1: warnings.warn( "TypeInterface method declarations should not have a 'self' parameter", DeprecationWarning, stacklevel=2) del names[0] _testCallArgs = (_Marker, ) if len(names) != len(typeList): ## Allow non-autocallable methods in the interface; ignore them continue argumentTypes = [ Argument(n, argtype, argtype.id) for n, argtype in zip(names[-len(typeList):], typeList) ] result = value(*_testCallArgs) label = None description = None if getattr(value, 'autocallable', None): # autocallables have attributes that can set label and description label = value.attributes.get('label', None) description = value.attributes.get('description', None) adapted = iformless.ITyped(result, None) if adapted is None: adapted = Object(result) # ITyped has label and description we can use if label is None: label = adapted.label if description is None: description = adapted.description defaultLabel, defaultDescription = labelAndDescriptionFromDocstring( value.__doc__) if defaultLabel is None: # docstring had no label, try the action if it is an autocallable if getattr(value, 'autocallable', None): if label is None and value.action is not None: # no explicit label, but autocallable has action we can use defaultLabel = value.action if defaultLabel is None: # final fallback: use the function name as label defaultLabel = nameToLabel(key) if label is None: label = defaultLabel if description is None: description = defaultDescription theMethod = Method(adapted, argumentTypes, label=label, description=description) if getattr(value, 'autocallable', None): methods.append( MethodBinding(key, theMethod, value.id, value.action, value.attributes)) else: possibleActions.append( (value, MethodBinding(key, theMethod))) else: if not value.label: value.label = nameToLabel(key) if iformless.IActionableType.providedBy(value): actionAttachers.append(value) properties.append(Property(key, value, value.id)) for attacher in actionAttachers: attacher.attachActionBindings(possibleActions) methods.sort(_sorter) properties.sort(_sorter) cls.__spec__ = spec = methods + properties spec.sort(_sorter) cls.name = name # because attributes "label" and "description" would become Properties, # check for ones with an underscore prefix. cls.label = dct.get('_label', None) cls.description = dct.get('_description', None) defaultLabel, defaultDescription = labelAndDescriptionFromDocstring( dct.get('__doc__')) if defaultLabel is None: defaultLabel = nameToLabel(name) if cls.label is None: cls.label = defaultLabel if cls.description is None: cls.description = defaultDescription return rv