On Dec 22, 2007, at 12:34 AM, Andreas Jung wrote:

>
>
> --On 21. Dezember 2007 16:33:34 -0500 Michael Bayer <[EMAIL PROTECTED] 
> > wrote:
>
>>
>> On Dec 21, 2007, at 3:13 PM, Rick Morrison wrote:
>
>>
>>
>> I think the only way something like this should be done is as a test
>> fixture which decorates classes during unit tests.    It would be
>> fairly clumsy to have in production code.
>>
>> If you have coworkers who write broken code, the way you solve that  
>> is
>> by having unit tests which will fail when the coworkers in question  
>> do
>> something theyre not supposed to.   If other people are writing code
>> that sets attrbutes its not supposed to and breaks things, you need
>> more tests to catch those conditions.  If youre putting code into
>> production that hasnt been tested, then you need a build process,
>> automated testing, etc.    There is definitely a "best practice" here
>> and test driven development is it.
>
> With all respect, this is not a useful answer. Even with tests  
> (unittests and weeks of manual tests) I had the case that a simple  
> programming error
> (of my own) produced a data disaster after some weeks. There is no  
> 100% test coverage. Tests don't solve all problems. There is  
> sometimes the need for a better security belt.
>

I am certainly suggesting a fixture that detects illegal assignments  
to attributes.  That it be limited to just unit tests is only a  
suggestion.    To establish this functionality regardless of  
environment, like Rick said just create properties which prohibit  
assignment.  Create mappers like this:

class AttrGetter(object):
     def __init__(self, name):
         self.name = name
     def __get__(self, instance, name):
         if instance is None:
             return self
         return getattr(instance, '_' + name)
     def __set__(self, instance, value):
         raise AssertionError("Sets are not allowed")
     def __delete__(self, instance):
         raise AssertionError("Deletes are not allowed")

class MyClass(object):
        somecolumn = AttrGetter('somecolumn')
         someothercolumn = AttrGetter('someothercolumn')

mapper(MyClass, sometable, properties={
        '_somecolumn':sometable.c.somecolumn,
        '_someothercolumn':sometable.c.someothercolumn
})

To automate the above process with no modifications to source code,  
create an instrumented mapper() function which applies the above  
recipe to all table columns:

from sqlalchemy.orm import mapper as _mapper
def mapper(cls, table, **kwargs):
     attrs = {}
     for c in table.c:
         attrs['_' + c.key] = c
         setattr(cls, c.key, AttrGetter(c.key))
     properties = kwargs.setdefault('properties', {})
     properties.update(attrs)
     return _mapper(cls, table, **kwargs)


Hope this helps.

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to