from ..fields import Field, List


import copy

class ListField(Field):
    def __init__(self, field_instance):
        super(self.__class__, self).__init__(list=True)

        # ListField is a list of the following (e.g., ForeignFields)
        self._field_instance = field_instance

        # Descriptor data is this type of list
        self._list_class = self._field_instance._list_class

        # Descriptor data is this type of list object, instantiated as our
        # default
        if self._field_instance._default and not hasattr(self._field_instance._default, '__iter__'):
            raise Exception(
                'Default value for list fields must be a list; received <{0}>'.format(
                    repr(self._field_instance._default)
                )
            )
        self._default = self._list_class(self._field_instance._default, field_instance=self._field_instance)

    def __set__(self, instance, value):
        if isinstance(value, self._default.__class__):
            self.data[instance] = value
        elif hasattr(value, '__iter__'):
            self.data[instance] = self._list_class(field_instance=self._field_instance)
            self.data[instance].extend(value)
        else:
            self.data[instance] = value

    def to_storage(self, value):
        '''
            value will come in as a List (MutableSequence)
        '''
        if value:
            return [self._field_instance.to_storage(i) for i in value]
        return []

    def on_after_save(self, parent, old_stored_data, new_value):
        if not hasattr(self._field_instance, 'on_after_save'):
            return

        if new_value and not old_stored_data:
            additions = new_value
            removes = []
        elif old_stored_data and not new_value:
            additions = []
            removes = old_stored_data
        elif old_stored_data and new_value:
            additions = [i for i in new_value if self._field_instance.to_storage(i) not in old_stored_data]
            removes = [i for i in old_stored_data if i not in new_value]
        else:
            # raise Exception('There shouldn\'t be a diff in the first place.')
            # todo: discuss -- this point can be reached when the object is not loaded and the new value is an empty list
            additions = []
            removes = []

        for i in additions:
            self._field_instance.on_after_save(parent, None, i)
        for i in removes:
            self._field_instance.on_after_save(parent, i, None)

    @property
    def base_class(self):
        if self._field_instance is None:
            return
        if not hasattr(self._field_instance, 'base_class'):
            return
        return self._field_instance.base_class
@@ -26,16 +26,54 @@
 d, List%0A
+from ..validators import validate_list
 %0A%0Aimport
@@ -103,16 +103,47 @@
 Field):%0A
+%0A    validate = validate_list%0A%0A
     def 
@@ -171,19 +171,30 @@
 instance
+, **kwargs
 ):%0A
+%0A
         
@@ -234,17 +234,128 @@
 t__(
-list=True
+**kwargs)%0A%0A        self._list_validate, self.list_validate = self._prepare_validators(kwargs.get('list_validate', False)
 )%0A%0A 
@@ -669,32 +669,34 @@
  default%0A       
+ #
  if self._field_
@@ -765,32 +765,101 @@
 t, '__iter__'):%0A
+        if self._default and not hasattr(self._default, '__iter__'):%0A
             rais
@@ -1049,24 +1049,26 @@
    )%0A       
+ #
  self._defau
@@ -1156,16 +1156,100 @@
 nstance)
+%0A        self._default = self._list_class(None, field_instance=self._field_instance)
 %0A%0A    de
@@ -1607,16 +1607,652 @@
  value%0A%0A
+    def do_validate(self, value):%0A%0A        # Child-level validation%0A        for part in value:%0A            self._field_instance.do_validate(part)%0A%0A        # Field-level list validation%0A        if hasattr(self.__class__, 'validate'):%0A            self.__class__.validate(value)%0A%0A        # # Schema-level list validation%0A        if self._list_validate:%0A            if hasattr(self.list_validate, '__iter__'):%0A                for validator in self.list_validate:%0A                    validator(value)%0A            elif hasattr(self.list_validate, '__call__'):%0A                self.list_validate(value)%0A%0A        # Success%0A        return True%0A%0A
     def 
@@ -2463,24 +2463,170 @@
  return %5B%5D%0A%0A
+    def from_storage(self, value):%0A%0A        if value:%0A            return %5Bself._field_instance.from_storage(i) for i in value%5D%0A        return %5B%5D%0A%0A
     def on_a

add separate list and item validation