Should dexterity and z3cform support getters and setters?

There is a really annoying bug in zope that if you use @property then self losses its acquisition wrapper. Thats not easy to solve.

Where this bites you is if you want a custom getter or setter using z3cform or dexterity. The obvious way to do that is using @property. If your code doesn't require acquisition it will still work but if it does it fail fail in unexpected ways.

There is a work around. Support explicit or implicit getters and setters like Archetypes used to. Here is code I used to do this for my usecase.
Should something like this be inplace by default in dexterity?
I'm surprised this issue hasn't come up more often.

class GetterSetterAttributeField(z3c.form.datamanager.AttributeField):
    """Special datamanager to get around loss on acquisition when using @property"""
        IPlominoForm, zope.schema.interfaces.IField)

    def get(self):
        """See z3c.form.interfaces.IDataManager"""
        getter = "get%s"%self.field.__name__.capitalize()
        if hasattr(self.adapted_context, getter):
            return getattr(self.adapted_context, getter)()
            return getattr(self.adapted_context, self.field.__name__)

    def set(self, value):
        """See z3c.form.interfaces.IDataManager"""
        if self.field.readonly:
            raise TypeError("Can't set values on read-only fields "
                            "(name=%s, class=%s.%s)"
                            % (self.field.__name__,
        setter = "set%s"%self.field.__name__.capitalize()
        if hasattr(self.adapted_context, setter):
            getattr(self.adapted_context, setter)(value)
            # get the right adapter or context
            setattr(self.adapted_context, self.field.__name__, value)

I am not sure this is related. We often use context_property() or variants of it in DX projects.

Related: also had issues with a missing storage layer in Dexterity in the context of workaround we used dedicated DataManagers.


1 Like