Skip to content

Commit a9ea607

Browse files
committed
Issue #22: Proposal for raise exception if default is not valid type.
1 parent 935ace6 commit a9ea607

File tree

3 files changed

+45
-11
lines changed

3 files changed

+45
-11
lines changed

domain_models/fields.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,13 @@ def set_value(self, model, value):
6262
value = self._converter(value)
6363
setattr(model, self.storage_name, value)
6464

65+
def is_valid_type(self, value):
66+
"""Check whether the value is valid type.
67+
68+
:param value:
69+
"""
70+
return self._converter(value) == value
71+
6572
def _converter(self, value):
6673
"""Convert raw input value of the field."""
6774
return value

domain_models/models.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,10 +185,27 @@ def __data__(self):
185185
for field in self.__class__.__fields__)
186186

187187
def get(self, field_name, default=None):
188-
"""DomainModel analogue for dict.get python built-in method.
188+
"""Return the value of the field.
189+
190+
Analogue for `dict.get()` python method.
191+
`field_name` must be a string. If the string is the name of
192+
one of the existent fields, the result is the value of that field.
193+
For example, `model.get('foobar')` is equivalent to `model.foobar`.
194+
If the filed does not have a value, `default` is returned if provided.
195+
It will raise `AttributeError` if `default` is not the same type
196+
as field value.
197+
If the field does not exist, `AttributeError` is raised as well.
189198
190199
:param string field_name:
191200
:param mixed default:
192201
"""
193202
value = getattr(self, field_name)
203+
204+
if default is not None and value is None:
205+
field = dict((field.name, field) for field in
206+
self.__class__.__fields__).get(field_name)
207+
if not field.is_valid_type(default):
208+
raise AttributeError(
209+
"default must be the same type as the field.")
210+
194211
return value if value else default

tests/test_models.py

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -165,28 +165,38 @@ class Model2(models.DomainModel):
165165
field = Model1.field
166166

167167
def test_get_method(self):
168+
mock_id = 2
169+
mock_name = 'foobar'
170+
168171
class SomeModel(models.DomainModel):
169172
"""Test domain model."""
170173
id = fields.Int()
171174
name = fields.String()
172-
not_required = fields.String()
175+
string = fields.String()
176+
177+
model = SomeModel(id=mock_id, name=mock_name)
173178

174-
model = SomeModel()
175-
model.id = 2
176-
model.name = 'some-name'
179+
self.assertEqual(model.get('id'), mock_id)
180+
self.assertEqual(model.get('id', 0), mock_id)
181+
self.assertEqual(model.get('id', 123), mock_id)
177182

178-
id = model.get('id', 0)
179-
self.assertEqual(id, 2)
183+
self.assertEqual(model.get('name'), mock_name)
184+
self.assertEqual(model.get('name', ''), mock_name)
185+
self.assertEqual(model.get('name', 'another-name'), mock_name)
180186

181-
name = model.get('name', '')
182-
self.assertEqual(name, 'some-name')
187+
self.assertEqual(model.get('string'), None)
188+
self.assertEqual(model.get('string', ''), '')
189+
self.assertEqual(model.get('string', 'not-empty'), 'not-empty')
183190

184-
not_required = model.get('not_required', '')
185-
self.assertEqual(not_required, '')
191+
string = model.get('string', '')
192+
self.assertEqual(string, '')
186193

187194
with self.assertRaises(AttributeError):
188195
model.get('unknown')
189196

197+
with self.assertRaises(AttributeError):
198+
model.get('string', 0)
199+
190200

191201
class ModelReprTests(unittest.TestCase):
192202
"""Tests for model Pythonic representation."""

0 commit comments

Comments
 (0)