j2labs/schematics — pull request #233 by bintoro (2014-06-03 14:22:45+00:00)
Title: Correctly serialize None items in ListType/DictType containers

This patch fixes an issue where `ListType` and `DictType` fail to consult their contained items on whether the items should be serialized when None.

Before the patch, the attribute indicating whether a None-valued `ListType/DictType` field should be serialized as part of its containing model was also applied to items _within_ the list/dict. The actual attribute relating to the nested items (`ListType/DictType.field.serialize_when_none`) was ignored.

Additionally, `ListType/DictType.field` did not have its `owner_model` set and therefore the `allow_none()` check wouldn't fall back to the correct default (that of the model) even if it were performed. This is also fixed.

### Testcase:

```python
# ModelA: Default configuration. `None` values should be serialized.
#
# Works as expected in the development branch.

class ModelA(Model):
listfield = ListType(StringType())
dictfield = DictType(StringType())

a = ModelA()
a.listfield = [None]
a.dictfield = {'foo': None}

# ModelB: Parameter on the nested field. Should yield an empty list & dict.
#
# Fails in the development branch (parameter has no effect).

class ModelB(Model):
listfield = ListType(StringType(serialize_when_none=False))
dictfield = DictType(StringType(serialize_when_none=False))

b = ModelB()
b.listfield = [None]
b.dictfield = {'foo': None}

# ModelC: Parameter on the compound field. This should have no effect
# because the nested field is supposed to be serialized by default and
# thus the container shouldn't end up empty.
#
# Fails in the development branch (the nested item is not serialized).

class ModelC(Model):
listfield = ListType(StringType(), serialize_when_none=False)
dictfield = DictType(StringType(), serialize_when_none=False)

c = ModelC()
c.listfield = [None]
c.dictfield = {'foo': None}

print a.serialize()
print b.serialize()
print c.serialize()
```

Output before patch:

```python
{'listfield': [None], 'dictfield': {'foo': None}}
{'listfield': [None], 'dictfield': {'foo': None}}
None
```

Output after patch:

```python
{'listfield': [None], 'dictfield': {'foo': None}}
{'listfield': [], 'dictfield': {}}
{'listfield': [None], 'dictfield': {'foo': None}}
```

Existing serialization tests continue to pass because they always
* set `serialize_when_none` on the compound field
* pass a class (e.g., `StringType`) instead of an instance (e.g., `StringType()`) as the nested field, causing the nested field to inherit its configuration from the compound field via `kwargs` in `init_compound_field()`.