def get_schema_fields(obj=None, type_name=None, behaviors=True): """ Get all fields on content or type from its schema and its behaviors. Return a list of field name and field object. """ portal_types = api.portal.get_tool('portal_types') if obj: type_name = obj.portal_type try: fti = portal_types[type_name] except: return [] fti_schema = fti.lookupSchema() fields = [field for field in fti_schema.namesAndDescriptions(all=True) if not IMethod.providedBy(field)] if not behaviors: return fields # also lookup behaviors for behavior_id in fti.behaviors: behavior = getUtility(IBehavior, behavior_id).interface fields.extend(behavior.namesAndDescriptions(all=True)) # keep only fields as interface methods are also returned by namesAndDescriptions fields = [(field_name, field) for (field_name, field) in fields if not IMethod.providedBy(field)] return fields
def test(self): field = Text(title=u"Foo thing") class I(Interface): getFoo, setFoo = accessors(field) class Bad(object): implements(I) class Good(object): implements(I) def __init__(self): self.set = 0 def getFoo(self): return u"foo" def setFoo(self, v): self.set += 1 names = I.names() names.sort() self.assertEqual(names, ['getFoo', 'setFoo']) self.assertEqual(I['getFoo'].field, field) self.assertEqual(I['getFoo'].__name__, 'getFoo') self.assertEqual(I['getFoo'].__doc__, u'get Foo thing') self.assertEqual(I['getFoo'].__class__, FieldReadAccessor) self.assertEqual(I['getFoo'].writer, I['setFoo']) # test some field attrs for attr in ('title', 'description', 'readonly'): self.assertEqual(getattr(I['getFoo'], attr), getattr(field, attr)) self.assert_(IText.providedBy(I['getFoo'])) self.assert_(IMethod.providedBy(I['getFoo'])) self.assert_(IMethod.providedBy(I['setFoo'])) self.assertEqual(I['setFoo'].field, field) self.assertEqual(I['setFoo'].__name__, 'setFoo') self.assertEqual(I['setFoo'].__doc__, u'set Foo thing') self.assertEqual(I['setFoo'].__class__, FieldWriteAccessor) self.assertRaises(Exception, verifyClass, I, Bad) self.assertRaises(Exception, verifyObject, I, Bad()) self.assertEquals(I['getFoo'].query(Bad(), 42), 42) self.assertRaises(AttributeError, I['getFoo'].get, Bad()) verifyClass(I, Good) verifyObject(I, Good()) self.assertEquals(I['getFoo'].query(Good(), 42), u'foo') self.assertEquals(I['getFoo'].get(Good()), u'foo') instance = Good() I['getFoo'].set(instance, u'whatever') self.assertEquals(instance.set, 1)
def get_schema_fields(obj=None, type_name=None, behaviors=True, prefix=False): """ Get all fields on dexterity content or type from its schema and its behaviors. Return a list of field name and field object. """ portal_types = api.portal.get_tool('portal_types') if obj: type_name = obj.portal_type try: fti = portal_types[type_name] except: return [] fti_schema = fti.lookupSchema() fields = [(field_name, field) for (field_name, field) in fti_schema.namesAndDescriptions(all=True) if not IMethod.providedBy(field)] if not behaviors: return fields # also lookup behaviors for behavior_id in fti.behaviors: behavior = getUtility(IBehavior, behavior_id).interface for (field_name, field) in behavior.namesAndDescriptions(all=True): # keep only fields as interface methods are also returned by namesAndDescriptions if IMethod.providedBy(field): continue if prefix: field_name = '{}.{}'.format(behavior.__name__, field_name) fields.append((field_name, field)) return fields
def make_schema(self): """ Create the JSON schema. Individual fields of the schema will be checked and returned. See the various ``TAG`` constants for ways that the schema externalization can be influenced. :return: A dictionary consisting of dictionaries, one for each field. All the keys are strings and the values are strings, bools, numbers, or lists of primitives. Will be suitable for writing to JSON. """ ext_schema = {} for k, v in self._iter_names_and_descriptions(): __traceback_info__ = k, v if IMethod.providedBy(v): continue # v could be a schema field or an interface.Attribute if not self.allow_field(k, v): # If we disallow at the top level, we don't even # hint to its existence. continue item_schema = self._make_field_schema(v, k) self.post_process_field(k, v, item_schema) ext_schema[k] = item_schema return ext_schema
def __call__(self, data): for name in self.schema: field = self.schema[name] if IMethod.providedBy(field): continue if data.get(name) is None: data[name] = self.schema[name].default name = data.get('name') site = self.context # we just wanna have one util = component.queryUtility(interfaces.IMemcachedClient, context=site, name=name) if util is not None: return # needed to be called TTW sm = removeSecurityProxy(site.getSiteManager()) default = sm['default'] util = utility.MemcachedClient() zope.event.notify(ObjectCreatedEvent(util)) for attr in ['trackKeys', 'defaultNS', 'servers', 'defaultLifetime']: setattr(util, attr, data[attr]) default[u'memcachedclient_' + name] = util sm.registerUtility(util, interfaces.IMemcachedClient, name=name)
def setup(self, catalog, name, context, module_info): # If the user supplied attribute= when instantiating us, we # allow that value to override the attribute name under which we # are actually stored inside of the `grokcore.catalog.Indexes` # instance. if self._attribute is not None: field_name = self._attribute else: field_name = name if IInterface.providedBy(context): try: method = context[field_name] except KeyError: raise GrokError( "grokcore.catalog.Indexes in %r refers to an attribute or " "method %r on interface %r, but this does not " "exist." % (module_info.getModule(), field_name, context), None) call = IMethod.providedBy(method) else: call = callable(getattr(context, field_name, None)) context = None # no interface lookup catalog[name] = self.index_class( field_name=field_name, interface=context, field_callable=call, *self._args, **self._kw)
def migrate_schema_fields(self): for schemata in iterSchemataForType('DashboardPODTemplate'): for fieldName, field in getFieldsInOrder(schemata): # bypass interface methods if not IMethod.providedBy(field): # special handling for file field setattr(self.new, fieldName, getattr(self.old, fieldName, None))
def _validate_fields(schema, value, errors=None): if errors is None: errors = [] # Interface can be used as schema property for Object fields that plan to # hold values of any type. # Because Interface does not include any Attribute, it is obviously not # worth looping on its methods and filter them all out. if schema is Interface: return errors # if `value` is part of a cyclic graph, we need to break the cycle to avoid # infinite recursion. # # (use volatile attribute to avoid persistency/conflicts) if hasattr(value, '_v_schema_being_validated'): return errors # Mark the value as being validated. value._v_schema_being_validated = True # (If we have gotten here, we know that `value` provides an interface # other than zope.interface.Interface; # iow, we can rely on the fact that it is an instance # that supports attribute assignment.) try: for name in schema.names(all=True): if not IMethod.providedBy(schema[name]): try: attribute = schema[name] if IField.providedBy(attribute): # validate attributes that are fields attribute.validate(getattr(value, name)) except ValidationError, error: errors.append(error) except AttributeError, error: # property for the given name is not implemented errors.append(SchemaNotFullyImplemented(error))
def get_schema_validation_errors(schema, value, _validating_objects=_ObjectsBeingValidated()): """ Validate that *value* conforms to the schema interface *schema*. All :class:`zope.schema.interfaces.IField` members of the *schema* are validated after being bound to *value*. (Note that we do not check for arbitrary :class:`zope.interface.Attribute` members being present.) :return: A `dict` mapping field names to `ValidationError` subclasses. A non-empty return value means that validation failed. """ errors = {} # Interface can be used as schema property for Object fields that plan to # hold values of any type. # Because Interface does not include any Attribute, it is obviously not # worth looping on its methods and filter them all out. if schema is Interface: return errors # if `value` is part of a cyclic graph, we need to break the cycle to avoid # infinite recursion. Collect validated objects in a thread local dict by # it's python represenation. A previous version was setting a volatile # attribute which didn't work with security proxy id_value = id(value) ids_being_validated = _validating_objects.ids_being_validated if id_value in ids_being_validated: return errors ids_being_validated.add(id_value) # (If we have gotten here, we know that `value` provides an interface # other than zope.interface.Interface; # iow, we can rely on the fact that it is an instance # that supports attribute assignment.) try: for name in schema.names(all=True): attribute = schema[name] if IMethod.providedBy(attribute): continue # pragma: no cover try: if IValidatable.providedBy(attribute): # validate attributes that are fields field_value = getattr(value, name) attribute = attribute.bind(value) attribute.validate(field_value) except ValidationError as error: errors[name] = error except AttributeError as error: # property for the given name is not implemented errors[name] = SchemaNotFullyImplemented( error).with_field_and_value(attribute, None) finally: ids_being_validated.remove(id_value) return errors
def get_schema_validation_errors(schema, value, _validating_objects=_ObjectsBeingValidated()): """ Validate that *value* conforms to the schema interface *schema*. All :class:`zope.schema.interfaces.IField` members of the *schema* are validated after being bound to *value*. (Note that we do not check for arbitrary :class:`zope.interface.Attribute` members being present.) :return: A `dict` mapping field names to `ValidationError` subclasses. A non-empty return value means that validation failed. """ errors = {} # Interface can be used as schema property for Object fields that plan to # hold values of any type. # Because Interface does not include any Attribute, it is obviously not # worth looping on its methods and filter them all out. if schema is Interface: return errors # if `value` is part of a cyclic graph, we need to break the cycle to avoid # infinite recursion. Collect validated objects in a thread local dict by # it's python represenation. A previous version was setting a volatile # attribute which didn't work with security proxy id_value = id(value) ids_being_validated = _validating_objects.ids_being_validated if id_value in ids_being_validated: return errors ids_being_validated.add(id_value) # (If we have gotten here, we know that `value` provides an interface # other than zope.interface.Interface; # iow, we can rely on the fact that it is an instance # that supports attribute assignment.) try: for name in schema.names(all=True): attribute = schema[name] if IMethod.providedBy(attribute): continue # pragma: no cover try: if IValidatable.providedBy(attribute): # validate attributes that are fields field_value = getattr(value, name) attribute = attribute.bind(value) attribute.validate(field_value) except ValidationError as error: errors[name] = error except AttributeError as error: # property for the given name is not implemented errors[name] = SchemaNotFullyImplemented(error).with_field_and_value(attribute, None) finally: ids_being_validated.remove(id_value) return errors
def SchemaChecker(schema, readonly=False): """returns a checker that allows read and write access to fields in schema. """ get = {} set = {} for name, field in getFieldsInOrder(schema): get[name] = True if not field.readonly: if IMethod.providedBy(field): get[field.writer.__name__] = True else: set[name] = True assert not readonly return DummyChecker(get, set)
def __getattr__(self, name): try: field = self.interface[name] except KeyError: raise AttributeError(name) if IMethod.providedBy(field): raise RuntimeError("Data value is not a schema field", name) value = self.data.getWithDefault(name) if value is NO_VALUE: raise AttributeError(name) return value
def _validate_fields(schema, value, errors=None): if errors is None: errors = [] for name in schema.names(all=True): if not IMethod.providedBy(schema[name]): try: attribute = schema[name] if IField.providedBy(attribute): # validate attributes that are fields attribute.validate(getattr(value, name)) except ValidationError, error: errors.append(error) except AttributeError, error: # property for the given name is not implemented errors.append(SchemaNotFullyImplemented(error))
def SchemaChecker(schema, readonly=False): """returns a checker that allows read and write access to fields in schema. """ get = {} set = {} for name, field in getFieldsInOrder(schema): get[name] = True if not field.readonly: if IMethod.providedBy(field): get[field.writer.__name__] = True else: set[name] = True if readonly: for nm in set: set[nm] = False return DummyChecker(get, set)
def _validate_fields(schema, value, errors=None): if errors is None: errors = [] # Interface can be used as schema property for Object fields that plan to # hold values of any type. # Because Interface does not include any Attribute, it is obviously not # worth looping on its methods and filter them all out. if schema is Interface: return errors # if `value` is part of a cyclic graph, we need to break the cycle to avoid # infinite recursion. Collect validated objects in a thread local dict by # it's python represenation. A previous version was setting a volatile # attribute which didn't work with security proxy if id(value) in VALIDATED_VALUES.__dict__: return errors VALIDATED_VALUES.__dict__[id(value)] = True # (If we have gotten here, we know that `value` provides an interface # other than zope.interface.Interface; # iow, we can rely on the fact that it is an instance # that supports attribute assignment.) try: for name in schema.names(all=True): if not IMethod.providedBy(schema[name]): try: attribute = schema[name] if IChoice.providedBy(attribute): # Choice must be bound before validation otherwise # IContextSourceBinder is not iterable in validation bound = attribute.bind(value) bound.validate(getattr(value, name)) elif IField.providedBy(attribute): # validate attributes that are fields attribute.validate(getattr(value, name)) except ValidationError as error: errors.append(error) except AttributeError as error: # property for the given name is not implemented errors.append(SchemaNotFullyImplemented(error)) finally: del VALIDATED_VALUES.__dict__[id(value)] return errors
def _validate_fields(schema, value, errors=None): if errors is None: errors = [] # Interface can be used as schema property for Object fields that plan to # hold values of any type. # Because Interface does not include any Attribute, it is obviously not # worth looping on its methods and filter them all out. if schema is Interface: return errors # if `value` is part of a cyclic graph, we need to break the cycle to avoid # infinite recursion. Collect validated objects in a thread local dict by # it's python represenation. A previous version was setting a volatile # attribute which didn't work with security proxy if id(value) in VALIDATED_VALUES: return errors VALIDATED_VALUES[id(value)] = True # (If we have gotten here, we know that `value` provides an interface # other than zope.interface.Interface; # iow, we can rely on the fact that it is an instance # that supports attribute assignment.) try: for name in schema.names(all=True): if not IMethod.providedBy(schema[name]): try: attribute = schema[name] if IChoice.providedBy(attribute): # Choice must be bound before validation otherwise # IContextSourceBinder is not iterable in validation bound = attribute.bind(value) bound.validate(getattr(value, name, None)) elif IField.providedBy(attribute): # validate attributes that are fields attribute.validate(getattr(value, name, None)) except ValidationError as error: errors.append(error) except AttributeError as error: # property for the given name is not implemented errors.append(SchemaNotFullyImplemented(error)) finally: del VALIDATED_VALUES[id(value)] return errors
def __getattr__(self, name): schema = self._Data_schema___ data = self._Data_data___ try: field = schema[name] except KeyError as err: raise AttributeError(name) from err # If the found field is a method, then raise an error. if IMethod.providedBy(field): raise RuntimeError("Data value is not a schema field", name) # Try to get the value for the field value = data.get(name, data) if value is data: if self.__context__ is None: raise NoInputData(name) registry = get_current_registry() dman = registry.getMultiAdapter((self.__context__, field), IDataManager) value = dman.get() # Optimization: Once we know we have a good value, set it as an # attribute for faster access. setattr(self, name, value) return value
def __getattr__(self, name): try: field = self.interface[name] except KeyError: raise AttributeError(name) if IMethod.providedBy(field): raise RuntimeError("Data value is not a schema field", name) try: value = self.data.getWithDefault(name) except KeyError: value = NO_VALUE if value is NO_VALUE: try: return self.dataManager.get(name) except KeyError: # an attribute error is more sane here raise AttributeError(name) return value
def get_interface_informations(self, iface): """Gets all useful informations from an iface * name * dotted name * trimmed doc string * base interfaces * methods with signature and trimmed doc string * attributes with trimemd doc string """ bases = [base for base in iface.getBases()] attributes = [] methods = [] for name, desc in iface.namesAndDescriptions(): if IMethod.providedBy(desc): methods.append({ 'signature': desc.getSignatureString(), 'name': desc.getName(), 'doc': _trim_doc_string(desc.getDoc()) }) else: attributes.append({ 'name': desc.getName(), 'doc': _trim_doc_string(desc.getDoc()), }) result = { 'name': iface.getName(), 'dotted_name': getDottedName(iface), 'doc': _trim_doc_string(desc.getDoc()), 'bases': bases, 'base_names': [getDottedName(iface) for base in bases], 'attributes': attributes, 'methods': methods, } return result
def get_interface_informations(self, iface): """Gets all useful informations from an iface * name * dotted name * trimmed doc string * base interfaces * methods with signature and trimmed doc string * attributes with trimemd doc string """ bases = [base for base in iface.getBases()] attributes = [] methods = [] for name, desc in iface.namesAndDescriptions(): if IMethod.providedBy(desc): methods.append({'signature': desc.getSignatureString(), 'name': desc.getName(), 'doc': _trim_doc_string(desc.getDoc()) } ) else: attributes.append({'name': desc.getName(), 'doc': _trim_doc_string(desc.getDoc()), } ) result = { 'name': iface.getName(), 'dotted_name': getDottedName(iface), 'doc': _trim_doc_string(iface.getDoc()), 'bases': bases, 'base_names': [getDottedName(iface) for base in bases], 'attributes': attributes, 'methods': methods, } return result
def setup(self, catalog, name, context, module_info): if self._attribute is not None: field_name = self._attribute else: field_name = name if IInterface.providedBy(context): try: method = context[field_name] except KeyError: raise GrokError( "grok.Indexes in %r refers to an attribute or " "method %r on interface %r, but this does not " "exist." % (module_info.getModule(), field_name, context), None) call = IMethod.providedBy(method) else: call = callable(getattr(context, field_name, None)) context = None # no interface lookup catalog[name] = self.index_class(field_name=field_name, interface=context, field_callable=call, *self._args, **self._kw)
def get(self, k, default=None): v = self.__schema.get(k, self) if v is self or IMethod.providedBy(v): return default return v
def getAttributes(iface): """Returns a list of attributes specified in the interface.""" return [(name, attr) for name, attr in getElements(iface, IAttribute).items() if not (IField.providedBy(attr) or IMethod.providedBy(attr))]
def setUpEditWidgets(view, schema, source=None, prefix=None, ignoreStickyValues=False, names=None, context=None, degradeInput=False, degradeDisplay=False): """Sets up widgets to collect input on a view. See `setUpWidgets` for details on `view`, `schema`, `prefix`, `ignoreStickyValues`, `names`, and `context`. `source`, if specified, is an object from which initial widget values are read. If source is not specified, the view context is used as the source. `degradeInput` is a flag that changes the behavior when a user does not have permission to edit a field in the names. By default, the function raises Unauthorized. If degradeInput is True, the field is changed to an IDisplayWidget. `degradeDisplay` is a flag that changes the behavior when a user does not have permission to access a field in the names. By default, the function raises Unauthorized. If degradeDisplay is True, the field is removed from the form. Returns a list of names, equal to or a subset of the names that were supposed to be drawn, with uninitialized undrawn fields missing. """ if context is None: context = view.context if source is None: source = view.context security_proxied = isProxy(source, Proxy) res_names = [] for name, field in _fieldlist(names, schema): try: value = field.get(source) except ForbiddenAttribute: raise except AttributeError: value = no_value except Unauthorized: if degradeDisplay: continue else: raise if field.readonly: viewType = IDisplayWidget else: if security_proxied: is_accessor = IMethod.providedBy(field) if is_accessor: set_name = field.writer.__name__ authorized = security.canAccess(source, set_name) else: set_name = name authorized = security.canWrite(source, name) if not authorized: if degradeInput: viewType = IDisplayWidget else: raise Unauthorized(set_name) else: viewType = IInputWidget else: # if object is not security proxied, might be a standard # adapter without a registered checker. If the feature of # paying attention to the users ability to actually set a # field is decided to be a must-have for the form machinery, # then we ought to change this case to have a deprecation # warning. viewType = IInputWidget setUpWidget(view, name, field, viewType, value, prefix, ignoreStickyValues, context) res_names.append(name) return res_names
""" user_status = [] users = api.user.get_users() print [user.id for user in users] for user in users: username = user.id country_report = self.get_country_report(username) progress = 0 doclink = '' status = 'not started' css_class = "%s %s" % (username,'not-started') country_data = [] if country_report: for name, desc in ICountryReport.namesAndDescriptions(): value = getattr(country_report,name) if IMethod.providedBy(desc): value = value() country_data.append(value) progress = 5 doclink = country_report.absolute_url() status = api.content.get_state(country_report) css_class = "%s %s" % (username,'started') for idx in range(len(country_data)): #print country_data[idx] if country_data[idx]: progress = progress + 1 progress = int(math.ceil(float(progress) / float(len(country_data)) * 100)) print "prg",progress props = {}
try: value = field.get(source) except ForbiddenAttribute: raise except AttributeError, v: value = no_value except Unauthorized: if degradeDisplay: continue else: raise if field.readonly: viewType = IDisplayWidget else: if security_proxied: is_accessor = IMethod.providedBy(field) if is_accessor: set_name = field.writer.__name__ authorized = security.canAccess(source, set_name) else: set_name = name authorized = security.canWrite(source, name) if not authorized: if degradeInput: viewType = IDisplayWidget else: raise Unauthorized(set_name) else: viewType = IInputWidget else: # if object is not security proxied, might be a standard
def all_values(self): """ Return a dict containing all values of all schema fields """ assert isinstance(self, FolderishAnimationView) context = aq_inner(self.context) assert isinstance(context, FolderishAnimation) res = {} # https://stackoverflow.com/a/12178741/1051649: for name, desc in IFolderishAnimation.namesAndDescriptions(): value = getattr(context, name, None) logger.info('.all_values %(name)r: %(desc)s', locals()) if IMethod.providedBy(desc): logger.info('%(name)s: a method', locals()) # It's a method --> call it: value = value() res[name] = value try: name = 'FolderishAnimation' schema = getUtility(IDexterityFTI, name=name).lookupSchema() logger.info('schema is %(schema)r', locals()) except Exception as e: logger.exception(e) logger.error('Could not get schema for name %(name)r', locals()) behavior_assignable = IBehaviorAssignable(context) if behavior_assignable: first = 1 for behavior in behavior_assignable.enumerateBehaviors(): logger.info('behavior: %(behavior)r', locals()) for name, field in getFieldsInOrder(behavior.interface): if name == 'subjects': continue try: value = field.get(context) if callable(value): value = value() res[name] = value logger.info(' %(name)r --> %(value)r', locals()) except Exception as e: # XXX Access to the fields from my behaviors doesn't work! logger.exception(e) logger.error('name=%(name)r, field=%(field)r', locals()) set_trace() value = field.get(context) if callable(value): value = value() res[name] = value if 'height' in res and 'width' in res: res['_calculated'] = { 'style': ';'.join(['%s:%spx' % (k, res[k]) for k in ('height', 'width') ]), } logger.info('style=%(style)s', res['_calculated']) pp(res) res['file_elements'] = self._file_elements() res['preload_img'] = self._preload_img scales = getMultiAdapter((context, context.REQUEST), name='images') scale = scales.scale('image', scale='preview') if scale: res['preview_image_tag'] = scale.tag(title=None, alt=_('Open a new window to start the animation')) else: res['preview_image_tag'] = self._clickable_text() logger.warn('No preview image found for %(context)r', locals()) return res
def __iter__(self): s = self.__schema return iter(k for k in s if not IMethod.providedBy(s[k]))