f



Force exception on attribute write access only one object

Hi,

for debugging I want to raise an exception if an attribute is
changed on an object. Since it is only for debugging I don't want
to change the integer attribute to a property.

This should raise an exception:

myobj.foo=1

Background:
Somewhere this value gets changed. But I don't now where.



-- 
Thomas Guettler, http://www.thomas-guettler.de/
E-Mail: guettli (*) thomas-guettler + de
0
hv (74)
1/8/2009 9:38:01 AM
comp.lang.python 77058 articles. 6 followers. Post Follow

4 Replies
369 Views

Similar Articles

[PageSpeed] 5

On Thu, Jan 8, 2009 at 1:38 AM, Thomas Guettler <hv@tbz-pariv.de> wrote:
> Hi,
>
> for debugging I want to raise an exception if an attribute is
> changed on an object. Since it is only for debugging I don't want
> to change the integer attribute to a property.
>
> This should raise an exception:
>
> myobj.foo=1
>
> Background:
> Somewhere this value gets changed. But I don't now where.

Completely untested:

class Protector(object):
    def __init__(self, delegate, *forbidden):
        self.__delegate = delegate
        self.__forbidden = set(forbidden)
    def __getattr__(self, name):
        return getattr(self.__delegate, name)
    def __setattr__(self, name, value):
        if name in self.__forbidden:
            raise TypeError("attempt to assign to forbidden attribute
'%s'" % name)
        setattr(self.__delegate, name, value)

x = Foo()
x = Protector(x, "bar")
x.bar = 6 #should raise TypeError

Cheers,
Chris

-- 
Follow the path of the Iguana...
http://rebertia.com
0
clp2 (1575)
1/8/2009 9:59:55 AM
Thomas Guettler wrote:

> for debugging I want to raise an exception if an attribute is
> changed on an object. Since it is only for debugging I don't want
> to change the integer attribute to a property.

Why?
 
> This should raise an exception:
> 
> myobj.foo=1
> 
> Background:
> Somewhere this value gets changed. But I don't now where.

If you change your mind:

class A(object):
    def __init__(self): 
        self.foo = 42

a = A()
b = A()

class B(A):
    @property
    def foo(self):
        return self.__dict__["foo"]

b.__class__ = B

a.foo = "whatever"
print b.foo
b.foo = "whatever"

Peter
0
__peter__ (4031)
1/8/2009 11:29:19 AM
Hi Peter and others,

your idea was good, but it does not work with Django ORM Models:

Traceback (most recent call last):
  File "/localhome/modw/django/core/handlers/base.py", line 87, in get_response
    response = callback(request, *callback_args, **callback_kwargs)
  File "/localhome/modw/foo/views/filter.py", line 473, in add
    return edit(request, 'add')
  File "/localhome/modw/foo/views/filter.py", line 493, in edit
    filter=form.save()
  File "/localhome/modw/foo/views/filter.py", line 457, in save
    action=form.save()
  File "/localhome/modw/django/forms/models.py", line 315, in save
    if self.instance.pk is None:
  File "/localhome/modw/django/db/models/base.py", line 292, in _get_pk_val
    return getattr(self, meta.pk.attname)
AttributeError: 'MyAction' object has no attribute 'filter_action_ptr_id'


Peter Otten schrieb:
> Thomas Guettler wrote:
> 
>> for debugging I want to raise an exception if an attribute is
>> changed on an object. Since it is only for debugging I don't want
>> to change the integer attribute to a property.
> 
> Why?
>  
>> This should raise an exception:
>>
>> myobj.foo=1
>>
>> Background:
>> Somewhere this value gets changed. But I don't now where.
> 
> If you change your mind:
> 
> class A(object):
>     def __init__(self): 
>         self.foo = 42
> 
> a = A()
> b = A()
> 
> class B(A):
>     @property
>     def foo(self):
>         return self.__dict__["foo"]
> 
> b.__class__ = B
> 
> a.foo = "whatever"
> print b.foo
> b.foo = "whatever"
> 
> Peter


-- 
Thomas Guettler, http://www.thomas-guettler.de/
E-Mail: guettli (*) thomas-guettler + de
0
hv (74)
1/9/2009 1:01:10 PM
Thomas Guettler wrote:

> Peter Otten schrieb:
>> Thomas Guettler wrote:
>> 
>>> for debugging I want to raise an exception if an attribute is
>>> changed on an object. Since it is only for debugging I don't want
>>> to change the integer attribute to a property.

>> class A(object):
>>     def __init__(self):
>>         self.foo = 42
>> 
>> a = A()
>> b = A()
>> 
>> class B(A):
>>     @property
>>     def foo(self):
>>         return self.__dict__["foo"]
>> 
>> b.__class__ = B
>> 
>> a.foo = "whatever"
>> print b.foo
>> b.foo = "whatever"

> your idea was good, but it does not work with Django ORM Models:
> 
> Traceback (most recent call last):
>   File "/localhome/modw/django/core/handlers/base.py", line 87, in
>   get_response
>     response = callback(request, *callback_args, **callback_kwargs)
>   File "/localhome/modw/foo/views/filter.py", line 473, in add
>     return edit(request, 'add')
>   File "/localhome/modw/foo/views/filter.py", line 493, in edit
>     filter=form.save()
>   File "/localhome/modw/foo/views/filter.py", line 457, in save
>     action=form.save()
>   File "/localhome/modw/django/forms/models.py", line 315, in save
>     if self.instance.pk is None:
>   File "/localhome/modw/django/db/models/base.py", line 292, in
>   _get_pk_val
>     return getattr(self, meta.pk.attname)
> AttributeError: 'MyAction' object has no attribute 'filter_action_ptr_id'

I can't tell what's happening from the traceback alone.
Is "filter_action_ptr_id"" your actual "foo" and "MyAction" your "B"?
Maybe the relevant setup code would help...

Peter

0
__peter__ (4031)
1/10/2009 7:53:47 AM
Reply: