<s> from __future__ import unicode_literals <EOL> import inspect <EOL> from collections import defaultdict <EOL> from django . core . exceptions import ValidationError <EOL> from django . utils . six import with_metaclass <EOL> from . import fields <EOL> from . meta import Meta <EOL> class MetaSerialiser ( type ) : <EOL> meta_class = Meta <EOL> def __new__ ( mcs , name , bases , attrs ) : <EOL> attrs [ '<STR_LIT>' ] = { } <EOL> meta = attrs . pop ( '<STR_LIT:Meta>' , None ) <EOL> declared_fields = { } <EOL> for field_name , field in list ( attrs . items ( ) ) : <EOL> if isinstance ( field , fields . Field ) : <EOL> declared_fields [ field_name ] = attrs . pop ( field_name ) <EOL> new_class = super ( MetaSerialiser , mcs ) . __new__ ( mcs , name , bases , attrs ) <EOL> base_fields = { } <EOL> for base in reversed ( inspect . getmro ( new_class ) ) : <EOL> base_fields . update ( getattr ( base , '<STR_LIT>' , { } ) ) <EOL> base_fields . update ( declared_fields ) <EOL> new_class . _fields = base_fields <EOL> new_class . _meta = mcs . meta_class ( meta ) <EOL> return new_class <EOL> class Serialiser ( with_metaclass ( MetaSerialiser , object ) ) : <EOL> obj_class = None <EOL> def __init__ ( self ) : <EOL> '''<STR_LIT>''' <EOL> self . _field_deflaters = [ ] <EOL> self . _custom_deflaters = [ ] <EOL> self . _field_inflaters = [ ] <EOL> self . _custom_inflaters = [ ] <EOL> for name , field in self . _fields . items ( ) : <EOL> self . _field_deflaters . append ( ( name , field . deflate ) ) <EOL> method = getattr ( self , '<STR_LIT>' % name , None ) <EOL> if method is not None : <EOL> self . _custom_deflaters . append ( ( name , method ) ) <EOL> if field . readonly : <EOL> continue <EOL> method = getattr ( self , '<STR_LIT>' % name , None ) <EOL> if method : <EOL> self . _custom_inflaters . append ( ( name , method ) ) <EOL> else : <EOL> self . _field_inflaters . append ( ( name , field . inflate ) ) <EOL> def object_deflate ( self , obj , ** kwargs ) : <EOL> data = { } <EOL> for name , method in self . _field_deflaters : <EOL> method ( name , obj = obj , data = data , ** kwargs ) <EOL> for name , method in self . _custom_deflaters : <EOL> data [ name ] = method ( obj = obj , data = data , ** kwargs ) <EOL> return data <EOL> def list_deflate ( self , obj_list , ** kwargs ) : <EOL> return [ <EOL> self . object_deflate ( obj , ** kwargs ) <EOL> for obj in iter ( obj_list ) <EOL> ] <EOL> def object_inflate ( self , data , instance = None , ** kwargs ) : <EOL> objdata = { } <EOL> errors = defaultdict ( list ) <EOL> for name , method in self . _field_inflaters : <EOL> try : <EOL> method ( <EOL> name , <EOL> data = data , <EOL> obj = objdata , <EOL> instance = instance , <EOL> ** kwargs <EOL> ) <EOL> except ValidationError as exc : <EOL> errors [ name ] . append ( exc ) <EOL> for name , method in self . _custom_inflaters : <EOL> try : <EOL> objdata [ name ] = method ( <EOL> data = data , <EOL> obj = objdata , <EOL> instance = instance , <EOL> ** kwargs <EOL> ) <EOL> except ValidationError as exc : <EOL> errors [ name ] . append ( exc ) <EOL> if errors : <EOL> raise ValidationError ( errors ) <EOL> return self . restore_object ( objdata , instance = instance , ** kwargs ) <EOL> def list_inflate ( self , data_list , ** kwargs ) : <EOL> return [ <EOL> self . object_inflate ( data , ** kwargs ) <EOL> for data in data_list <EOL> ] <EOL> def restore_object ( self , objdata , ** kwargs ) : <EOL> if not self . obj_class : <EOL> raise NotImplementedError <EOL> return self . obj_class ( objdata ) </s>
