Browse Source

[typing] allow Field to have a default of None

Previously we used None as the sentinel for determining that a user had
not specified a default value for a field. This meant that a user could
never select `None` as the default value. We now properly use UNSET to
determine if a default was passed, this aligns better with the code as
it stands given that if no default is passed we'll use UNSET anyway.
develop
andrei 8 years ago
parent
commit
5b5f29865a
  1. 14
      disco/types/base.py
  2. 10
      tests/types/base.py

14
disco/types/base.py

@ -55,7 +55,7 @@ class ConversionError(Exception):
class Field(object): class Field(object):
def __init__(self, value_type, alias=None, default=None, create=True, ignore_dump=None, cast=None, **kwargs): def __init__(self, value_type, alias=None, default=UNSET, create=True, ignore_dump=None, cast=None, **kwargs):
# TODO: fix default bullshit # TODO: fix default bullshit
self.true_type = value_type self.true_type = value_type
self.src_name = alias self.src_name = alias
@ -64,21 +64,23 @@ class Field(object):
self.cast = cast self.cast = cast
self.metadata = kwargs self.metadata = kwargs
if default is not None: # Only set the default value if we where given one
if default is not UNSET:
self.default = default self.default = default
# Attempt to use the instances default type (e.g. from a subclass)
elif not hasattr(self, 'default'): elif not hasattr(self, 'default'):
self.default = None self.default = UNSET
self.deserializer = None self.deserializer = None
if value_type: if value_type:
self.deserializer = self.type_to_deserializer(value_type) self.deserializer = self.type_to_deserializer(value_type)
if isinstance(self.deserializer, Field) and self.default is None: if isinstance(self.deserializer, Field) and self.default is UNSET:
self.default = self.deserializer.default self.default = self.deserializer.default
elif (inspect.isclass(self.deserializer) and elif (inspect.isclass(self.deserializer) and
issubclass(self.deserializer, Model) and issubclass(self.deserializer, Model) and
self.default is None and create): self.default is UNSET and create):
self.default = self.deserializer self.default = self.deserializer
@property @property
@ -94,7 +96,7 @@ class Field(object):
self.src_name = name self.src_name = name
def has_default(self): def has_default(self):
return self.default is not None return self.default is not UNSET
def try_convert(self, raw, client, **kwargs): def try_convert(self, raw, client, **kwargs):
try: try:

10
tests/types/base.py

@ -29,3 +29,13 @@ def test_cached_property_clear_on_update(model):
assert inst.value == 4 assert inst.value == 4
inst.inplace_update(model(a=2, b=3)) inst.inplace_update(model(a=2, b=3))
assert inst.value == 5 assert inst.value == 5
def test_defaults():
class TestModel(Model):
a = Field(int, default=None)
b = Field(int, default=0)
model = TestModel()
assert model.a is None
assert model.b == 0

Loading…
Cancel
Save