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 [email protected]
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
-~----------~----~----~----~------~----~------~--~---