pythonsetterzoperestrictedpython

setter methods and Restricted Python


I have a class "MyClass" with a class attribute and its methods.

class MyClass:
    def __init__(self):
        self._my_attr = None

    @property
    def my_attr(self):
        return self._my_attr

    @my_attr.setter
    def my_attr(self, value):
        self._my_attr = value

    def set_my_attr(self, value):
        self._my_attr = value

When I try to assign a value in Zope (in a Python Script, which uses Restricted Python), I get a TypeError attribute-less object (assign or del) when I try to assign the value with =.

It also says in the traceback: AttributeError: 'MyClass' object has no attribute '__guarded_setattr__'

obj = MyClass()
obj.my_attr = 42  # error in Restricted Python
obj.set_my_attr(value=42)  # does work in Restricted Python

What does the error mean? Is there a way to allow setter methods for direct assignment in Restricted Python or do I have to implement a normal method to set the value?


Solution

  • You can bypass the the check if you set the following flag:

    class MyClass:
        _guarded_writes = 1
    

    Usually code gets wrapped with...:

        class Wrapper:
            def __init__(self, ob):
                self.__dict__['ob'] = ob
    
            __setitem__ = _handler(
                '__guarded_setitem__',
                'object does not support item or slice assignment')
    
            __delitem__ = _handler(
                '__guarded_delitem__',
                'object does not support item or slice assignment')
    
            __setattr__ = _handler(
                '__guarded_setattr__',
                'attribute-less object (assign or del)')
    
            __delattr__ = _handler(
                '__guarded_delattr__',
                'attribute-less object (assign or del)')
        return Wrapper
    

    which disallows setting anything.