Modified:
branches/unhork/grassyknoll/lib/Model.py
branches/unhork/grassyknoll/tests/test_Model.py
Log:
Issue #159: Made Model raise error when Schema tries to assign a field or
attr when one is already assigned.
Modified: branches/unhork/grassyknoll/lib/Model.py
==============================================================================
--- branches/unhork/grassyknoll/lib/Model.py (original)
+++ branches/unhork/grassyknoll/lib/Model.py Fri Jan 2 11:08:54 2009
@@ -79,6 +79,8 @@
if isinstance(value, self.FieldType):
self.addField(name, value)
else:
+ if name in self.__fields__:
+ raise AttributeError('%r already exists as a field
on %r' % (name, self))
super(Schema, self).__setattr__(name, value)
def __getattr__(self, name):
@@ -102,6 +104,8 @@
@arg field: type of the field (usually a builtin)
@type field: field
"""
+ if name in self.__dict__:
+ raise AttributeError('%r already exists as an attr on %r' %
(name, self))
if isinstance(field, self.FieldType):
self.setField(name, field)
elif field in SCALAR_TYPES:
Modified: branches/unhork/grassyknoll/tests/test_Model.py
==============================================================================
--- branches/unhork/grassyknoll/tests/test_Model.py (original)
+++ branches/unhork/grassyknoll/tests/test_Model.py Fri Jan 2 11:08:54 2009
@@ -8,16 +8,17 @@
from grassyknoll.lib.Model import Model, Schema, SchemaProxy, Field
from grassyknoll.lib import Norman
from grassyknoll.collection.backends.sql import TableMaker
-from grassyknoll.collection.backends.lucene import LuceneCollection, Smarts
+
class MyType1(object):
pass
+
class MyType2(object):
pass
+
class Wrapper(Field):
-
def __init__(self, wrapped, pants=None, shirt=None):
self.wrapped = wrapped
self.pants = pants
@@ -25,10 +26,20 @@
# XXX idField?
+
class MySchema(Schema):
-
FieldType = Wrapper
+
+def test_Schema_setattr_rejects_dups():
+ s = MySchema()
+ s.addField('foo', int)
+ assert_raises(AttributeError, setattr, s, 'foo', 1)
+
+ del s.foo
+ s.foo = 1 # Sets not-a-field
+ assert_raises(AttributeError, s.addField, 'foo', int)
+
def test_Schema():
# make sure we no longer support arbitrary kwargs
assert_raises(TypeError, MySchema, pants = "jeans", shirt="cotton")
@@ -261,44 +272,49 @@
assert_sorted_equals(table.__fields__,
['__id__', 'size', 'color', 'price', 'description'])
-def test_Model_with_LuceneNorman():
- norm = LuceneCollection.LuceneNorman()
-
- with Model(norm = norm) as model:
-
- assert model.norm is norm
-
- model.size = int
- assert model.size is int
- assert isinstance(norm.size, LuceneCollection.SmartFieldNorman),
repr(norm.size)
- #assert norm.size.fact.getCallable() is Smarts.SmartField
-
+try:
+ from grassyknoll.collection.backends.lucene import LuceneCollection,
Smarts
+except ImportError:
+ pass
+else:
+ def test_Model_with_LuceneNorman():
+ norm = LuceneCollection.LuceneNorman()
+
+ with Model(norm = norm) as model:
+
+ assert model.norm is norm
+
+ model.size = int
+ assert model.size is int
+ assert isinstance(norm.size,
LuceneCollection.SmartFieldNorman), \
+ repr(norm.size)
+ #assert norm.size.fact.getCallable() is Smarts.SmartField
+
+ def test_Realistic_Model():
+ with Model(fixture = Norman.Object(unknown='delete').\
+ default(optional=False), # XXX this
won't work right
+ lucene =
LuceneCollection.LuceneNorman(unknown='delete').\
+ default(store = True), # XXX
nor this
+ table = TableMaker.Table('nsf')
+ ) as model:
+
+ #model.fixture.newField.bind(store = True, optional = False)
+
+ assert isinstance(model, Model)
+
+ with model.Date(type = datetime.date) as _:
+ _.lucene.store = True
+ _.lucene.index = 'untokenized'
+ _.lucene.optional = True
+
+ assert isinstance(model.fixture.Date, Norman.Date)
+ assert isinstance(model.table.Date, TableMaker.Column)
+ assert model.table.Date.type is datetime.date
+ assert isinstance(model.lucene.Date, Norman.FactoryNorman)
+ assert model.lucene.Date.getCallable() is Smarts.SmartField
+ assert model.lucene.Date.optional == True
+ assert model.lucene.Date.store == True
+ assert model.lucene.Date.index == 'untokenized'
-def test_Realistic_Model():
- with Model(fixture = Norman.Object(unknown='delete').\
- default(optional=False), # XXX this won't
work right
- lucene = LuceneCollection.LuceneNorman(unknown='delete').\
- default(store = True), # XXX nor
this
- table = TableMaker.Table('nsf')
- ) as model:
-
- #model.fixture.newField.bind(store = True, optional = False)
-
- assert isinstance(model, Model)
-
- with model.Date(type = datetime.date) as _:
- _.lucene.store = True
- _.lucene.index = 'untokenized'
- _.lucene.optional = True
-
- assert isinstance(model.fixture.Date, Norman.Date)
- assert isinstance(model.table.Date, TableMaker.Column)
- assert model.table.Date.type is datetime.date
- assert isinstance(model.lucene.Date, Norman.FactoryNorman)
- assert model.lucene.Date.getCallable() is Smarts.SmartField
- assert model.lucene.Date.optional == True
- assert model.lucene.Date.store == True
- assert model.lucene.Date.index == 'untokenized'
-
- model.lucene.Date.optional = False
- assert model.lucene.Date.optional == False
+ model.lucene.Date.optional = False
+ assert model.lucene.Date.optional == False